Astro: The structure of an Astro site

Now that you’ve installed the basic Astro sample site, it’s time to take a look around in the site structure.

See, we have 2 folders, except for the VS Code configuration .vscode and the Node packages in node_modules: public and src, and some configuration files.

public is (as in most frameworks) where you store assets like images that do not need any kind of processing and are served as-is. For example public contains the favicon.svg file, and you access it using the URL http://localhost:4321/favicon.svg.

Configuration files include astro.config.mjs, which (as we’ll see later) you can extend to add more features (and configuration) to Astro.

Everything else is under src.

The src folder now includes those subfolders:

  • src/components
  • src/layouts
  • src/pages

src/pages contains the Astro page routes.

You now see src/pages/index.astro. This is the entry point for the / route, the one that serves the homepage.

This is an Astro component, as the file ends with the .astro extension.

Being under src/pages makes it special because it’s also a route, so Astro knows this component is what it will serve on that / route.

We’ll see how to add more routes later.

But let’s analyze this component.

We can see 3 parts basically.

The first is the upper part, between the two --- blocks, called frontmatter:

That’s where we can write some JavaScript (TypeScript) code that runs when the page is built.

This is not client-side JavaScript. It’s also not server-side JavaScript. It’s build-time JavaScript.

Since the end result of an Astro site is a static site, it will not have a backend.

So here we can do various things, like fetching data across the network or look for data in the filesystem.

In this case we import a layout, and a component.

The layout is the “outer HTML” that this page will use.

See, inside the “main” part of the component, we don’t define the DOCTYPE, an <html> tag, <body> and so on.

That’s defined in the layout:

See? That’s defined in the layout:

The layout is the “container”.

We do this so it can be reused by multiple pages, without duplicating the page structure that’s common across the site.

We’ll see more about layouts later.

The last thing I want to show you in the page is the third part, the one wrapped in <style>:

This contains CSS that is scoped to the page.

In other words, it’s only applied to the current component, and does not “leak” to other components. This is a nice built-in feature.

So we’ve seen how Astro page components can have a frontmatter that executes JavaScript at build time and can be used to import other components, and then can also have a part that defines style.

You could also add a <script> tag with some JavaScript that runs client-side, but we’ll see more about that later.

Finally the last item in this basic starter kit is an example of separating some piece of UI to a separate component, not a page component, that is defined in src/components as a convention:

We can define components to create little units of code that we can reuse across the site.

In this example the Card component is used in the src/pages/index.astro component by first importing it in the component frontmatter:

import Card from '../components/Card.astro';

and then it’s used multiple times to define some HTML markup that would otherwise be duplicated:

This syntax is similar to HTML. There’s a Card component and we use it like an HTML tag:

<Card />

with some attributes, called props.

Components are great because they avoid duplication.

We’ll talk more about them next, and we’ll see how cool they are.

Lessons in this unit:

0: Introduction
1: Your first Astro site
2: ▶︎ The structure of an Astro site
3: Astro components
4: Adding more pages
5: Dynamic routing
6: Markdown in Astro
7: Images
8: Content collections
9: CSS in Astro
10: JavaScript in Astro
11: Client-side routing and view transitions
12: SSR in Astro
13: API endpoints in Astro
Want to learn more? Check out our courses