Proper websites, done properly

Part 3: Basic components

3 minute read time / 397 words

Now we've got the basics running, we can start to build things a bit more cleverly

Our first component

The obvious place to start componentising is by creating a header, footer and navigation block. These will be used on every page, and make sense to split into smaller, more digestible parts. First, let's make our new <Header /> component. Create a new file at src/components/Header.astro with the following content:

---

---
<header>
    <a href="/">My Sexy Astro Site</a>
</header>

Now, let's create our footer and nav components. Create two new files in the components folder called Footer.astro and Nav.astro and add the following code into them.

---

---
<footer>
    &copy; Me, 2024.
</footer>
---

---
<nav>
    Navigation to go here
</nav>

Now we need to import these into our template layout file so we can use them. Open up our layout file src/layouts/Layout.astro and right at the top just inside the frontmatter block, import our new three components.

---
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import Nav from '../components/Nav.astro';
---

Now that we have access to these components in our layout, we can just drop them in wherever we need them.

<!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>
        <Header />
        <Nav />
        <slot />
        <Footer />
    </body>
</html>

Check the site in your browser and you'll see these new components being output above and below the content.

Basic navigation

Unlike Eleventy, Astro has no easy almost-out-of-the-box way to do navigation in a automated way. We can create our own navigation components to do the basics though. First we need to create an array of pages, and for each page we need to know a URL and a title.

---
const navPages = [
    {
        url: '/about',
        title: 'About Me'
    },
    {
        url: '/stuff',
        title: 'Stuff and Things'
    }
];
---
<nav>
    {navPages.map(page =>
        <a href={page.url}>{page.title}</a>
    )}
</nav>

Using a .map() function, we loop through the array of objects and tell Astro to output a link for each.