Proper websites, done properly

Part 2: File and folder structure

5 minute read time / 650 words

We've already got our development environment running, so now we can start to familiarise ourselves with where things live in an Astro site.

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 a pages 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".