Layouts are the way to create a consistent user experience across different pages within our application.
By default, Astro ships with a
<Layout> component that wraps the pages that are generated using the CLI. We'll look at what is already in our page layouts and add a nav and footer to them as well. We'll see that the layout has a
<slot /> element which is very similar to Reacts
children which is where the html of nested pages will get placed when you use that layout.
Layout's are not automatically applied to pages in an application so we will also see what it looks like to add a layout to the about page that we created before.
Instructor: [0:00] If we open the index page, we'll see that the first element that we're using is a layout element, which is defined in the source/layouts/layout.astro file.
[0:13] It's basically a template HTML file that also defines an interface called props, and destructures the title property from the astro.props property. This is the default layout that comes with every Astro project.
[0:28] The props interface define which properties can be provided to the layout on every page, and as you saw, we can obtain those values through astro.props.
[0:38] Astro is pretty smart. It recognizes the props interface, so if we add a description property, which is going to be a string, it will know that this property now exists, so we can destructure it.
[0:51] Also, if we go back to our index page, we're going to see that it throws an error because we're not providing the description property, and we also didn't define it as an optional property.
[1:01] Whatever you put into the interface props will be recognized by Astro. Let's remove this for now. Further down the page, we have the HTML template. Most of this probably looks familiar to you. It starts at the very top by defining the HTML5 doc type declaration, then it opens the HTML element and adds the head element and the body element.
[1:26] It adds all the necessary meta tags, but it also adds a slot element. A slot element is actually a known HTML tag, which defines a placeholder for external HTML content and allows us to inject, or to slot child elements from other files. If you've worked with React before, it will remind you of the built-in children property.
[1:50] If we go back to our index page, everything inside of the layout, which in this case is the main element with all of its contents, is going to be injected into the slot in the layout component. Actually, the slot will be replaced with the contents of the index page. This is how we can define a layout for our website.
[2:11] I'm going to replace the body with a simple layout that has a header, a nav with a few links. It wraps the slot with a main tag, and it has a simple footer. Feel free to pause the lesson right now if you want to type it out, or check out the lesson code in the description below if you want to copy-paste it.
[2:32] If we save this file and refresh the page, we're going to see that we have the header and the links at the top, but we can't see them, because this page has a dark background. To fix this, we can scroll down to the HTML style and remove the background, or set it to something lighter, like F6F6F6.
[2:54] Now, we can see our header. We can see our nav links, and of course, if we scroll down, we're going to see our footer. If we open the About page, we'll see that the header, the footer, and the nav links aren't there.
[3:07] Let's fix that. Let's open the About page. First, we're going to define our component script by adding the three dashes. We're going to import our layout from one level up /layout/layout.astro. Then, we're going to wrap the paragraph with our layout component. Of course, we need to define the title, because it's defined in the props.
[3:35] If we save this page, now, we can see that the About page has the header, the nav links, and the footer. We're now effectively sharing the same layout between those two pages. We can do this for any page in our project. Let's do a quick recap.
[3:52] Sharing the same layout between multiple pages in Astro is done by defining the layout file. If we want our layout to accept properties, we should define them in a props interface. The layout defines the entire markup of the page, including the HTML5 declaration, the head and the body tags, and all the meta tags.
[4:11] We use the slot tag to indicate where the contents of our page is going to be injected. To use our layout, we simply imported it from its file and wrapped our page's content with it.