Back to Withastro

Combine layouts to get the best of both worlds

src/content/docs/en/tutorial/4-layouts/3.mdx

latest5.2 KB
Original Source

import Blanks from '/components/tutorial/Blanks.astro'; import Box from '/components/tutorial/Box.astro'; import Checklist from '/components/Checklist.astro'; import MultipleChoice from '/components/tutorial/MultipleChoice.astro'; import Option from '/components/tutorial/Option.astro'; import PreCheck from '/components/tutorial/PreCheck.astro'; import { Steps } from '@astrojs/starlight/components';

Now that you have added a layout to each blog post, it's time to make your posts look like the rest of the pages on your website!

<PreCheck> - Nest your blog post layout inside your main page layout </PreCheck>

Nest your two layouts

You already have a BaseLayout.astro for defining the overall layout of your pages.

MarkdownPostLayout.astro gives you some additional templating for common blog post properties such as title and date, but your blog posts don't look like the other pages on your site. You can match the look of your blog posts to the rest of your site by nesting layouts.

<Steps> 1. In `src/layouts/MarkdownPostLayout.astro`, import `BaseLayout.astro` and use it to wrap the entire template content. Don't forget to pass the `pageTitle` prop:
```astro title="src/layouts/MarkdownPostLayout.astro" ins={2,5,13}
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout pageTitle={frontmatter.title}>
  <meta charset="utf-8" />
  <h1>{frontmatter.title}</h1>
  <p>{frontmatter.pubDate.toString().slice(0,10)}</p>
  <p><em>{frontmatter.description}</em></p>
  <p>Written by: {frontmatter.author}</p>
  
  <slot />
</BaseLayout>
```

2. In src/layouts/MarkdownPostLayout.astro, you can now remove the meta tag as it is already included in your BaseLayout:

```astro title="src/layouts/MarkdownPostLayout.astro" del={6}
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout pageTitle={frontmatter.title}>
  <meta charset="utf-8" />
  <h1>{frontmatter.title}</h1>
  <p>{frontmatter.pubDate.toString().slice(0,10)}</p>
  <p><em>{frontmatter.description}</em></p>
  <p>Written by: {frontmatter.author}</p>
  
  <slot />
</BaseLayout>
```

3. Check your browser preview at http://localhost:4321/posts/post-1. Now you should see content rendered by:

- Your **main page layout**, including your styles, navigation links, and social footer.
- Your **blog post layout**, including frontmatter properties like the description, date, title, and image.
- Your **individual blog post Markdown content**, including just the text written in this post.

4. Notice that your page title is now displayed twice, once by each layout.

Remove the line that displays your page title from `MarkdownPostLayout.astro`:

```astro title="src/layouts/MarkdownPostLayout.astro" del={2}
<BaseLayout pageTitle={frontmatter.title}>
  <h1>{frontmatter.title}</h1>
  <p>{frontmatter.pubDate.toString().slice(0,10)}</p>
  <p><em>{frontmatter.description}</em></p>
  <p>Written by: {frontmatter.author}</p>
  
  <slot />
</BaseLayout>
```

5. Check your browser preview again at http://localhost:4321/posts/post-1 and verify that this line is no longer displayed and that your title is only displayed once. Make any other adjustments necessary to ensure that you do not have any duplicated content. </Steps>

Make sure that:

- Each blog post shows the same page template, and no content is missing. (If one of your blog posts is missing content, check its frontmatter properties.)

- No content is duplicated on a page. (If something is being rendered twice, then be sure to remove it from `MarkdownPostLayout.astro`.)

If you'd like to customize your page template, you can.
<Box icon="question-mark">

Test your knowledge

  1. This allows you to nest one layout inside another and take advantage of working with modular pieces.

    <MultipleChoice> <Option> continuous deployment </Option> <Option> responsive design </Option> <Option isCorrect> component-based design </Option> </MultipleChoice>
  2. Multiple layouts are particularly useful for projects that contain Markdown pages, like a...

    <MultipleChoice> <Option isCorrect> blog </Option> <Option> dashboard </Option> <Option> chat app </Option> </MultipleChoice>
  3. Which of these provides templating for all your pages?

    <MultipleChoice> <Option> `index.astro` </Option> <Option isCorrect> `BaseLayout.astro` </Option> <Option> `post-1.md` </Option> </MultipleChoice>
</Box> <Box icon="check-list">

Checklist

<Checklist> - [ ] I can nest layouts, checking for any duplicated elements. </Checklist> </Box>

Resources