Skip to content

Creating an Astro layout - screencast and transcript

Trying out some new technology, and since I canā€™t fit the entire transcript in the YouTube video description, here it is all on this page.

Transcript:

0:01
Here, weā€™re going to take a look at creating an astro layout component. So Iā€™m just gonna open my project up in Gitpod and get it arranged the way I want.

0:15
The intro to any Astro project is going to be at source/pages/index.astro. So letā€™s jump in there and take a look at what this looks like.

0:27
Any Astro page is going to be separated into two sections: weā€™ve got this code fence block section at the top, and then weā€™ve got our HTML rendering part at the bottom. So what I want to do is look down and see that the second part of an Astro page file will render to a complete HTML document. You can see it starts with open HTML, and finishes with a closing HTML tag. To make that a little easier to see, Iā€™m just going to clean up some of these code comments, and Iā€™m going to collapse some of these tags so we can just get a sense of the structure and see whatā€™s going on with this rendering here. Collapsingā€¦ collapsingā€¦ navigating throughā€¦ just so we can see that essentially what we have within HTML tags is a head and a body.

1:29
And in our body, weā€™ve got main, weā€™ve got header, weā€™ve got some components. And Iā€™m going to add a little bit of text, just to separate that out, because maybe weā€™re not sure what this Tour component is doing and how thatā€™s different from the header. So now, I can refresh my browser preview here in Gitpod.

1:51
Iā€™m just going to organize things the way I like to see them, I can have a couple of panes going, and I can make my browser preview kind of small on the right, because I just want to see at a glance whatā€™s going on here and I want more space for my code.

2:08
So now we can see that yes, we do have some text on the page, letā€™s do the same with the frontmatter. Letā€™s delete some of these code comments where theyā€™re guiding us for the places to put our JavaScript and TypeScript. And at the very top of the page is where an Astro File expects to receive its component imports, whether theyā€™re Astro components, or React components or Svelte components.

2:41
And now we are ready to make our first layout. So weā€™re going to go back to source, create a layouts folder. And weā€™ll create the file BaseLayout.astro. Itā€™s empty, but it exists. So before we forget, letā€™s go back into index.astro, and import BaseLayout. And weā€™re going to import it exactly the same way we import our other componentsā€¦ noting that with all these Astro components and framework components that do get imported into an Astro File, you DO need to include the file extension.

3:27
So a quick refresh shows we didnā€™t break anything. We also didnā€™t really do anything, but at least weā€™re importing a file that exists. Now, letā€™s choose some stuff to go into that BaseLayout folder. And Iā€™m thinking, what we donā€™t want to have to copy each time we make a new Astro page is HTML and head. So letā€™s start there.

3:53
Weā€™re going to cut it out of index. And weā€™ll clean it up a bit and move it into our base layout. Right now BaseLayout.astro is providing HTML and head, so we can take that closing tag out of our index file. And our index right now is just responsible for rendering the body tag. To use the layout component that we imported, we are going to wrap the content here in open and close BaseLayout tags. Alright, so we can see the body, the main, the header (letā€™s just just format this out)ā€¦ this is what the index page is responsible for rendering, so letā€™s refresh and we get ā€¦an error: ā€œTitle is not defined.ā€

4:48
All right, well, letā€™s take a look at that because we have certainly defined a title here. The problem is that the index.astro file isnā€™t using that title. The title is being used in BaseLayout.astro. So what weā€™re going to have to do is pass that title information into our layout. And weā€™re just going to do that via props, title equals title. Excellent. Refresh.

5:21
And we still get the error, because although we have SENT the information, we havenā€™t properly RECEIVED the information in our layout component. So now weā€™re going to need a code fence. And weā€™re going to need to import that title property from Astro.props. Perfect. That is going to receive the title just fine. And then BaseLayout will be able to use that title to create the title tag in our head. So we refresh, and thereā€™s no errorā€¦ but thereā€™s also nothing else on the page. Okay, so whatā€™s going on here?

6:06
Well, if we look at what our BaseLayout is actually rendering, (and that is whatā€™s getting rendered to index, because weā€™ve wrapped everything in BaseLayout), all that weā€™re sending to index is the HTML tag and a head.

6:21
We need somewhere to SLOT IN the content thatā€™s actually being provided at index.astro. And in Astro, we do that via a self closing tag called slot. And now as soon as the layout knows where to slot in the information thatā€™s wrapped in the other page, we have our original page back up again, looks exactly the same.

6:36
Now Iā€™m just going to pop this out in Gitpod into a full tab browser preview because sometimes the simple browser in Gitpod might not have all the same interactivity as the full page preview does. So I just want to show you that those buttons, the counters are in fact working.

7:11
In fact, the page looks identical to the page we started with, because all we did was pull out the head and enclosed HTML tags. And weā€™re now rendering them instead via a layout. Alright, so then the whole point of having a layout is to be able to make another page thatā€™s going to use the same thing. So to create a second page in our project, letā€™s take a look at what index is rendering and figure out what weā€™re going to need to throw in page two to also render a full document.

8:01
The first thing we should do is make sure weā€™re importing the layout. Iā€™m going to start a code fence and Iā€™m going to put a layout, our BaseLayout in there. And letā€™s take one of the counters, letā€™s take the Svelte counter, and we will also import that into page two. So we can use that to get some test render. And we know that our layout expects a page title. So letā€™s give this page a title: ā€œPage Two.ā€

8:32
Now weā€™re ready to actually render some HTML. So weā€™re going to start again with BaseLayout component, passing the title information, open and close tags to wrap whatever now we decided to render on page two. And we said we wanted to render a counter on page two. So hereā€™s our Svelte counter. And framework components do need a client directive. Iā€™m just going to choose Load, weā€™re not going to wait till the page is visible on the page. This is just a very small page anyway.

9:14
Weā€™ll put a bit of text in here. So right now weā€™ve got a paragraph tag, and weā€™ve got a Svelte counter rendered. We go back to index and and look at what we wrapped here. Notice that we do need the body tag; the body was rendered in index. Our layout is not taking care of that. So we are going to put our body and weā€™re going to put our main tags on page two. Iā€™m pretty sure this default project, its CSS does make use of the main tag. So just to keep things consistent, letā€™s make sure weā€™ve also got main in here and then we need to close out main, close out body. Okay, structurally, we should have the same thing that we had for our index page. So Iā€™m going to go up and navigate manually to page two in my little preview here. And in fact, yes, so we have a paragraph rendered, and we have a counter rendered. Now you canā€™t see in this preview, but if you look at the top of the page, it does actually specify that the title is page two. So thatā€™s working as well. Excellent.

10:44
Now, if we go back and compare to the index site, though, our index had a header, and our second page does not. Now you might not want every page to say welcome to Astro. But you may very well want the same header on all your pages. So we can, again, refactor and we can pull the header into the layout. But by doing so this time, we have to make sure that weā€™re also bringing into layout the main and the body tags.

11:19
So letā€™s go into the layout and after our head, thatā€™s where weā€™re going to insert the body, main and header. And then after our slot, weā€™ll close off the main and close off the body. The slot can go wherever you want that wrapped content to be.

11:48
Now, if we go back to index, obviously, we donā€™t want those closing tags duplicated, so weā€™ll get rid of them. Now our index component is looking pretty minimal, quite easy to read. (Iā€™m not dealing with all the indentation and formatting right now.) But now when we go to page two, same thing, we donā€™t want our page rendering the body and main tags. Our layout is taking care of that. So refresh the index page, again, looks identical.

12:18
And thatā€™s what weā€™re going for: we are not designing, we are not creating anything new here. We are just exploring how to use refactoring to take out some stuff from the pages and have them instead rendered via an Astro layout component.

12:39
Now if we can have two pages, we can have three pages. So now letā€™s create page three. And letā€™s make it super minimal. Letā€™s see the bare minimum we need to create a new page and what it looks like when there is nothing on a page.

13:01
We will need the layout. And we will need to give it a title. But Iā€™m going to remove everything wrapped in the layout in the BaseLayout ta. Iā€™m going to remove the paragraph and the counter. Iā€™m going to manually navigate to page three. And what do we have? We have our header. But notice that we DO have our header and we DO have a page and it worksā€¦ even with nothing inside the BaseLayout open and close tags so your slot can be empty. But this gives you an idea of what your layout looks like with nothing there. This is what the layout is bringing to the table.

13:47
So we created a couple of new pages. But most importantly, we recreated that index page and didnā€™t really change anything. It looks exactly to the eye the way it did before. But now itā€™s being rendered using an Astro layout component.

Transcribed by https://otter.ai