DEV Community

Elian Van Cutsem
Elian Van Cutsem

Posted on Originally published at elian.codes on

Using slots to build layouts in Astro

Using slots to build layout in Astro

Coming from frameworks like NuxtJS and NextJS, I always liked the layout feature. You basically write a new component, add some original content to it and add a layout which contains all the mutual components like headers, footers and such.

When I first started learning Astro, I didn't directly see a way to realise this. Astro feels a lot more like writing super-powered HTML, which is nice, but I hated to re-import my header component in every page.

After some time experimenting somewhat more with Astro, I actually understood that this was possible, it's just a different way of approach then NuxtJS which I'm so used to.

Building Layouts in NuxtJS

Building layouts in Nuxt is really easy (or I'm just very used to it). There's a layouts folder in which you create a new file

<template>
  <div>
    <TheHeader />
    <Nuxt /> <!-- The page content will then go here -->
    <TheFooter />
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

If the Nuxt layout component was named Default.vue you can just add layout: 'default in a page to use the layout. The <Nuxt /> element will then be replaced by the <template> contents of your page Vue template.

<template>
  <main>
    <h1>Look ma, a layout</h1>
    <p>works great right?</p>
  </main>
</template>

<script>
export default {
  layout: 'default',
}
</script>
Enter fullscreen mode Exit fullscreen mode

It's an easy way to define and use templates and layouts and I actually got quite familiar with it, which is (I think) why I never used it before in Astro.

The Astro way

In Astro, it's actually quite simple to also do this, you just gotta forget what you know about other frameworks.

Define a layout

Let's define a new Astro template in the /src/layouts folder and call it Default.astro. In this template, we make use of the Astro <slot /> component to tell Astro where to render in the content of our page. Every page will then ofcourse have different content, with a shared <YourHeadComponent />, <YourHeaderComponent /> and <YourFooterComponent />.

---
import YourHeadComponent from '../components/layout/Head.astro
import YourHeaderComponent from '../components/layout/Header.astro
import YourFooterComponent from '../components/layout/Footer.astro
---
<html lang="en">
  <head>
    <YourHeadComponent />
  </head>
  <body>
    <YourHeaderComponent />
    <slot /> <!-- The page will render it's content here -->
    <YourFooterComponent />
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Make a page use a layout

To then also use the layout we defined above, we just have to create a new page in the /src/pages folder and import our <DefaultLayout> component we just defined.

---
import DefaultLayout from '../layouts/Default.astro
---
<DefaultLayout>
  <main>
    <h1>Look ma, a layout</h1>
    <p>works great right?</p>
  </main>
</DefaultLayout>
Enter fullscreen mode Exit fullscreen mode

This makes Astro even more powerful and versatile.

Top comments (0)