Skip to content

Build your first layout

Get ready to…

  • Refactor common elements into a page layout
  • Use an Astro <slot /> element to place page contents within a layout
  • Pass page-specific values as props to its layout

You still have some Astro components repeatedly rendered on every page. It’s time to refactor again to create a shared page layout!

Create your first layout component

Section titled Create your first layout component
  1. Create a new file at the location src/layouts/BaseLayout.astro. (You will need to create a new layouts folder first.)

  2. Copy the entire contents of index.astro into your new file, BaseLayout.astro.

    src/layouts/BaseLayout.astro
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "Home Page";
    ---
    <html lang="en">
    <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>{pageTitle}</title>
    </head>
    <body>
    <Header />
    <h1>{pageTitle}</h1>
    <Footer />
    <script>
    import "../scripts/menu.js";
    </script>
    </body>
    </html>
  1. Replace the code at src/pages/index.astro with the following:

    src/pages/index.astro
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    const pageTitle = "Home Page";
    ---
    <BaseLayout>
    <h2>My awesome blog subtitle</h2>
    </BaseLayout>
  2. Check the browser preview again to notice what did (or, spoiler alert: did not!) change.

  3. Add a <slot /> element to src/layouts/BaseLayout.astro just above the footer component, then check the browser preview of your Home page and notice what really did change this time!

    src/layouts/BaseLayout.astro
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "Home Page";
    ---
    <html lang="en">
    <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>{pageTitle}</title>
    </head>
    <body>
    <Header />
    <h1>{pageTitle}</h1>
    <slot />
    <Footer />
    <script>
    import "../scripts/menu.js";
    </script>
    </body>
    </html>

The <slot /> allows you to inject (or “slot in”) child content written between opening and closing <Component></Component> tags to any Component.astro file.

Pass page-specific values as props

Section titled Pass page-specific values as props
  1. Pass the page title to your layout component from index.astro using a component attribute:

    src/pages/index.astro
    ---
    import BaseLayout from '../layouts/BaseLayout.astro';
    const pageTitle = "Home Page";
    ---
    <BaseLayout pageTitle={pageTitle}>
    <h2>My awesome blog subtitle</h2>
    </BaseLayout>
  2. Change the script of your BaseLayout.astro layout component to receive a page title via Astro.props instead of defining it as a constant.

    src/layouts/BaseLayout.astro
    ---
    import Header from '../components/Header.astro';
    import Footer from '../components/Footer.astro';
    import '../styles/global.css';
    const pageTitle = "Home Page";
    const { pageTitle } = Astro.props;
    ---
  3. Check your browser preview to verify that your page title has not changed. It has the same value, but is now being rendered dynamically. And now, each individual page can specify its own title to the layout.

Try it yourself - Use your layout everywhere

Section titled Try it yourself - Use your layout everywhere

Refactor your other pages (blog.astro and about.astro) so that they use your new <BaseLayout> component to render the common page elements.

Don’t forget to:

  • Pass a page title as props via a component attribute.

  • Let the layout be responsible for the HTML rendering of any common elements.

  • Delete anything from each page that that page is no longer responsible for rendering, because it is being handled by the layout, including:

    • HTML elements
    • Components and their imports
    • CSS rules in a <style> tag (e.g. <h1> in your About page)
    • <script> tags
  1. An Astro component (.astro file) can function as a:

  2. To display a page title on the page, you can:

  3. Information can be passed from one component to another by: