File and folder structure
The Astro docs have in-depth documentation around site structure, but to get started let's just see what we've got so far:
./
├── README.md
├── astro.config.mjs
├── package-lock.json
├── package.json
├── public/
│ └── favicon.svg
├── src/
│ ├── env.d.ts
│ └── pages/
│ └── index.astro
└── tsconfig.json
-
astro.config.mjs
is our Astro main configuration file. This is where we'll later configure any integrations we need too. -
public
is where all of our assets will live like fonts, images, videos, audio, favicons, etc. -
src
is where our pages, layouts, components, source CSS, and all other site code will live. -
Within the
src
folder you'll see apages
folder. This is where all our site content pages will go. -
As we expand our site and start to implement other functionality, we'll add other folders into the mix in the
src
folder too:-
components
: this is where our individual React/Astro components will be. If you're not familiar with React components, these are similar to what includes and macros are and can do in Nunjucks. -
content
: this is where our 'collections' will live, such as a latest news section, or blog articles, or any other sort of collection of content that can be grouped together nicely. -
layouts
: our base template files will be stored here.
-
Creating templates
Let's go ahead and do that now. Create a new folder inside src
called layouts
and make a new file called Layout.astro
in there.
Let put the basics into this new layout file:
---
---
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>My Sexy Astro Site</title>
</head>
<body>
<slot />
</body>
</html>
The top section inbetween the two sets of three hyphens (---) is what's known as frontmatter. Many other Static Site Generators, such as Eleventy, Hugo, or Jekyll, use frontmatter too so you'll have probably come into contact with this before. If not, it's just page metadata - page settings and configuration. In frontmatter we can set the page title, description, which layout to use and many other things too.
Our base layout doesn't need much for now, but it would be great if we could pass the page title to it from each content page as well as the content. So let's add that:
---
const { title } = Astro.props;
---
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>{title} | My Sexy Astro Site</title>
</head>
<body>
<slot />
</body>
</html>
The <slot />
component is where our content will be inserted from any page using this layout file.
In our layout file's frontmatter, we're using destructuring to pull out specific values from our page-specific frontmatter data. We're going to need to update our home page content file too to make this work. Go ahead and open up src/pages/index.astro
and replace its contents with this:
---
---
<h1>Hello World!</h1>
At the moment this won't do anything, because the page doesn't know what template it's meant to be using. We can change that by pulling in our layout as a component for the page and wrapping it around our content.
---
import Layout from '../layouts/Layout.astro';
---
<Layout title={"Hello World!"}>
<h1>Hello World!</h1>
</Layout>
This works just like passing props
in React components. For now, we're just passing the title through to the Layout
template. Take a look at the page, and you'll see that the <title>
now says "Hello World! | My Sexy Astro Site".