Astro Quick Start Course | Build an SSR Blog

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's going on guys so I've been working on a course on the Astro web framework it's a quick start course so it's not as in-depth as some of my you know 12 20 hour courses it's available at traversy media.com for monthly or yearly members but I decided to release it as a free course on YouTube as well and it's been a while since I did a video so I figured that you know you guys might like this and if you've never heard of Astro it's actually one of my favorite newer Technologies it's a framework that can be used as both a static site generator or an SSR or server side rendering framework not only that but you can use any kind of components there's Astro components which is which are great that's what we'll be using but you can also use react components views felt and I believe some other framework components as well so in this course we'll be covering the fundamentals while building a practical project and the website that we'll build is an SSR or server side rendered Tech blog called tech people and we're going to be using typescript which comes out of the box with Astro we'll be using markdown files for articles and something called Astro collections which will allow us to create uh a schema for our data and query it from our pages and components all right so the blog will have a layout that I created with Tailwind the HTML theme files are available in the final repo and that link is in the description on the homepage will fetch and display the latest six articles as well as a search component and since it's an SSR website we can simply submit the form to a page and then on that page we'll fetch the articles that match that query so each article will also have a set of tags that will display in a tags component and if you click on one of those tags it'll show all of the articles that match that tag so that we can categorize them we're also going to add some pagination on the main articles page so that we can navigate and not have to have you know 100 articles loaded on on a single page so it's a fairly simple project but it will definitely get you up and running we'll learn about components and Pages filebase routing with slugs Collections and querying the image component and just overall project workflow and at the end we'll install the versel adapter so that we can deploy it as a serers side rendered website to the versel platform form you could also deploy to netlify you could install the node.js adapter and deploy to something like Len node or digital ocean it it can be deployed in many uh with many services again the final repo can be accessed in the link in the description and this video will include the entire course with timestamps but if you're interested you can become a traversy media member and you'll get the course in individual videos and of of course with the rest of my my work the rest of my my courses you'll also get the premium docs which will essentially give you the entire course in written form and you'll in addition to that you'll get access to the member's Discord server so I created a code traversy member and that will give you the first three months for just 15 bucks per month and of course you can cancel it any time so whether you're watching this on YouTube or on traversy media.com I hope you guys enjoy the course so let's get into it all right so before we jump in I just want to spend a couple minutes talking about what Astro is and I'll briefly go into how it works but if you really want to dive in and learn about all the mechanisms and the architecture check out the documentation they actually have extremely well-written docs and I would suggest using those as a supplement to this course so as I said before this is one of my favorite new web Technologies because it's pretty easy to use and it just does so much so Astro is an all-in-one web framework and you can use it to build static websites SSR websites apis and I'll talk more about what you can build in a few minutes but Astro Works in a different way compared to traditional front-end web Frameworks it actually outputs zero JavaScript by default and it does this with an architecture called islands and the idea is that it renders the HTML page on the server and then it injects placeholders around the the dynamic regions that can be hydrated on the client into self-containing widgets now most front-end Frameworks hydrate and render the entire UI or the entire application is one large JavaScript application and this is called a single page application or a spa and recently static websites as well as server side rendered websites have become more popular because Spas they have a a really high client side JavaScript usage which can have issues such as performance SEO accessibility so with Astro you kind of get the best of both worlds you get the speed and the SEO of uh a static website and you get the dynamic functionality of a spa now when it comes to components Astro has its own component syntax you just use the Astro extension for the for your files but in addition to Astro components you can use components from other Frameworks such as react view felt and I really like the Astro components personally so that's what we'll be using in this project I think they're really simple um really powerful and things just seem to work how you would expect so that's what we'll be using for this project however if you want you can use react view Etc now as far as what you can build these are the main things that Astro is used for so it it's a static site generator in fact that's what it was initially called and used for um so you can create really fast pre-rendered static websites um you can use just about anything for your data including markdown Json a custom API a headless content management system um like sanity.io or contentful in addition to that you can create server side rendered websites similar to what you would build with nextjs and that's what we'll be doing we're our blog is going to be serers side rendered and I chose that because I think that SSR is a little more interesting it's more powerful you don't have as many limitations um I also have uh an astro crash course where we built a St a small static project so I wanted to go SSR with this one now you can also create apis because you can create API endpoints that accept get post put delete requests um and even though we're not really using API endpoints in this project I'm still going to show you how to do it and uh we're actually going to create an article search API all right so you can basically use Astro to build both powerful front-end and full stack applications as well as simple and fast static websites so it's a it's an all-in-one solution for many types of projects and again you can use anything as your backend or your your data source it's often paired with content content Management Systems like sanity and it's very content driven so in the next lesson we're going to learn how to install and get set up with Astro okay so now we're going to get started with our project so navigate in your terminal or your command line to wherever you want to create this and I'm going to make a new directory for the project and I'm going to call it astro-h blog and then I'm going to CD into Astro blog and from here we want to run npm now you do have to have node.js installed in order to use the node package manager so if you don't have that on your system just go to nodejs.org download it and install it so we're going to say npm create Astro at latest and then it's going to go through and just ask us a couple questions so the first thing it's going to ask us is where we want to create our project I want it in this directory in the Astro blog directory so I'm just going to put dot enter and it's going to say how uh how would you like to start your new project you can include some sample files there's a Blog template I'm going to go with empty which for me is always the best choice because it's just less confusing I like to start you know as Bare Bones as possible and then install dependencies we're going to say yes so we don't have to run npm install then it's going to ask if we plan to write typescript I'm going to say yes to this but even if you don't know typescript that's fine because the typescript we're going to write is is pretty minimal and I'm going to choose strict for that okay so it's going to ask us if we want to initialize a new git repository we'll say yes to that and we should be okay so now I'm going to open up VSS code in that folder and right off the bat I want to tell you that you should install the Astro extension for vs code this will give you highlighting intellisense emit completions so definitely a must have if you're using vs code all right now to look at the the file structure real quick it's pretty simple pretty Bare Bones we have a config file for Astro so if you install like um Tailwind which we're actually going to do in this video that will get put in here if you install an adapter for like versel or netlify for deployment that will go in here as well um and then there's a typescript config file package.json pretty simple we just have Astro Astro JS check and typescript um and then the source folder obviously this is where all of our code will go including our pages so if we look in Pages there's an index. asro which has just uh pretty much nothing in it um but that's good I like when you know we don't have a bunch of boiler plate and we're going to wipe all this away anyway but yeah in the next video in the next section we're going to go into this Pages folder and how the filebase routing Works um our layouts our components our utilities all that stuff will go in source and then you also have a public folder which just has favicon in it you can put images in here as well um and I'll talk talk about images and the image component very soon but yeah that's pretty much it so pretty simple now we can run the dev server I'm going to open up my integrated terminal and run npm run Dev and by default it should open up on Port 4321 just make that a little bigger here yeah so 4321 so we'll go to that and since I didn't use any of the you know the pre made templates or anything like that it just says Astro there's no styling there's nothing um which I like so what I want to do before we end this video is install tailwind and that's really easy to do so I'm going to open up another tab another terminal I should say and all we have to do is run npx asro add Tailwind and that will not only install it but it'll actually set it up we don't have to include it in you know any files or anything like that and it's just asking if we want to generate a minimal Tailwind config file we'll say yes yes okay so now you can see that we have this Tailwind config file so basically it's going to look in any of these types of files for Tailwind classes and if we look at the the page now notice that the heading shrunk down because it what Tailwind does is it strips out all the default CSS so it's actually including Tailwind in fact we can test it out even further by going to our index. asro and this H1 let's add a class of text- 4XL if I do that you can see that that was applied so Tailwind is now integrated all right so like I said in the next video we're going to get into this Pages folder some more and talk about file based routing all right so now I want to talk about the pages folder and file based routing and if you've ever used nextjs or Gatsby or nujs then you're probably familiar with filebase routing so what we can do here is put anything any component in here and a comp a page is a component anything that ends with Astro is a component but again you can also use react components you can use view components but whatever you put in here is going to be a page and it's going to get an automatic route so the index . asro is what we're seeing on the homepage but let's go ahead and create a new file here called about. asro and for now we'll just put an H1 in here and we'll just say about and let's save that now I should be able to go to slab because that's what I named that file and that just works so unlike a a spa like if you build with react or view not using next or njs with a spa you have to create those routes manually using a router with this with Astro you don't have to do that uh you just put your your file in here and it just works and there's ways to make this Dynamic like for instance when we have our single article page it's going to be at a slug it'll be slash articles slash and then whatever the title is in in Slug format so that will be dynamic and I'll show you how to do that a little later all right so I also want to have a slash article page and that will be the page that shows all of the Articles along with the pagination now I could create an articles. astro right that would allow me to go to slash articles however we're going to have a few different pages that relate to articles so instead what I'm going to do is create a folder called articles and in that folder I'm going to create a file called index. asro and then in here we'll just have an H1 and we'll just say articles okay now if I go to SL articles you'll see that works so whether I create an articles. asro or an articles folder with an index. astro it's going to work at this route automatically okay so that that's filebase routing it's very very simple now in this video I do want to take care of the homepage so so basically I want to start to you know get our layout down and the navbar and all that stuff so you have in the the final repo is a folder called Blog theme and you have all the HTML files you also have the images we're going to get into images in the next video but what I want you to do is open this up in your editor whether it's the same you know VSS code or or whatever it might be um I'm going to open it up in Sublime Text just so you can tell the difference from what is my actual Astro code to my just regular HTML and I'm going to open the index HTML file and I'm just going to grab everything that's in here this is all just hardcoded you know every article card is hardcoded in here obviously we're going to make this all Dynamic but this is what we're going to start with so close everything up except for the homepage which is just pages and then index. asro this is what we have here by default and um we're just going to replace all of this with what we have in that index HTML and let's save the file so if I go back to the homepage now we see the layout because remember we have Tailwind all it's already set up in fact in this HTML file we're bringing in Tailwind by the CDN which we don't need to do anymore so we can actually get rid of that link this right here this flowy JS this is for the the response menu so I'm going to leave that but I can get rid of that Tailwind CDN and it still works if I make this smaller you'll see we have this this uh drop down here that's that's from flow bite so I'm going to keep that but uh yeah Tailwind is is all set up so we don't need the CDN now like I said this is all just hardcoded so we're going to work at it and slowly make this more Dynamic we'll have a a component for each of these articles for the search and so on for the navbar we're going to have a layout because obviously we don't want to put the dock type the HTML head tags all that in every single file that would be I mean why even use Astro at that point so we'll have a layout that will have all that stuff and then we'll insert the page content into that layout but what I want to do in the next video is take care of the images cuz right now we can't see them we didn't we didn't even bring them over yet so in the next video we'll do that and we'll talk about the image component all right so now I want to talk about image because right now we we have our layout we just basically dumped all the HTML in that index. asro file uh I I want to take care of these images before we start to make this more Dynamic now if we look at the documentation here it tells us that there's essentially two places we can put our images either the source folder where we can use the image component to optimize those images or the public folder where it'll just get treated like just the the image will just be as is right so just like if you had a regular HTML site and you used an image tag now the issue with using the source folder is when you do that and you use the image component which can optimize the images you have to import the image into the component or into the file and use that as the source all right when you use the public folder you don't have to do that you can just put in the path so what I'm going to do is put all of the site images like the logo the about images I'm going to put those into the source folder because we can just import those where they need to go and then the the article images right so these right here the images that'll go here I'm going to put that in public so that we can just use the path now we can still import the the blog images even though it they're going to be dynamic um we can do that however I did run into some issues when I tried to deploy to netlify and verel as an SSR site using um those Dynamic Imports for the article images so I'm going to stick to just keeping the article images in the public folder and then keeping the website images in the source folder all right so let's open up the Blog theme and that's where you'll find the images so all these right here so basically image 1 through 7 are the Articles the article images and then the rest are just images for the site like the logo the about um there's an extra team uh photo here that I'm going to get rid of okay so what I'm going to do is first create in the source folder a folder called images and again this these will be our site images so let's grab everything except the uh everything except the image one through 7 cuz these are all website images so we'll put those in there and then then when we use those we're going to import them into the page or into the component all right then in public I'm going to create a folder called images and I'm going to uh let's see let's go back here I'm going to grab image 1 through 7even and drag those over to public images now if you want you can put all of these in public but I I do want to show you how we can use the image component to optimize images in our source folder all right and you can read more about this in this this documentation right here so let's go to the homepage both in the browser and in the editor and we need to import the image component now when you import something it has to be done in What's called the component script up top and I'm going to talk more about this in the next video but just know that if you're going to have any serers side JavaScript any Imports anything like that it has to be wrapped in a code fence or a component script which is going to be three hyphens so we have three hyphens at the top and three at the bottom and then in here I can then say import and I'm going to bring in the image component from Astro colon assets all right and the way that this works is similar to just the regular image tag so if I come down here to the logo which is right here and replace IMG with image okay if I do that and then I save I'm going to get this error that says local images must be imported so I need to import that logo image so up top here I'm going to say import logo from and it's going to be dot do imageslogo PNG and then what we can do is just replace this Source value with that logo value so now it works okay now I'm going to add an image and a height I'm sorry an image and a height a width and a height to this so I'm going to set the width to can put a number in here so let's say 55 and the height I'm also going to set that to 55 so if we save that there we go so now we have our logo showing notice the other images are now showing as well because they're just using the regular image tag and it they're looking in the public folder okay now I can use this image component on the Articles so let me just SE search for the first one so IMG so right here image one that's this this laptop image right here so I can change this to image right and then add a width uh let's say with equals it doesn't really matter in this case because the CSS is making the image 100% of its container but let's just say 600 and we'll say 350 all right so if I do that we get this error again local images must be imported so if I don't want to import the image I could still use this I just need to add a slash here because if I add a slash then it's going to look in the public folder automatically and we have an images folder in there and we have an image 1.png so if I save that then it works right we're seeing the image we're using the component however it's not going to do the same optimizations that it's going to do with the logo because the logo we actually brought in at the top here and you know it's stored in our source folder so as far as I know it's pretty pointless to do this um if you if you have your images in public where is it if you have your images in public and you're using the image component I don't believe it does any optimization you can keep it like that if you want just if you want to just stay consistent or whatever but I'm just going to stick to using the IMG for the article images all right and later on all these article cards are going to be replaced with a single article component so we won't have like all these images in here um but just for now I'm going to add a slash to all of these just to specify that we're in the public folder so I'll search for the next one which is image 2 and I'm just going to add a slash here and then for this one for image three I'll add that and it's five six and I believe there's seven total okay so all the images on the homepage should be displayed at this point and then we have other images that we can bring in for the about page and the error page but we haven't got to that just yet so in the next video I want to talk a little bit more about this about the component script and and how this works all right guys so I want to look at component script a little further in this video so in the in the last video we on our homepage we imported the image component and also the logo itself and we did that within what's called a code fence okay so these hyphens right here and this Al together is called the component script so it uses a code fence to identify the component script in your in your Astro component so and if you've ever written mark down it's formatted similar to markdown front matter which is where you can add you know specific uh metadata or fields for your mackown files and we'll we'll get to that later on so as far as what you can do in here you can basically write any JavaScript you can import Astro components other components from react or whatever framework you want to use importing data fetching content from an API or database now it's important to know that um whatever you write in here is on the server it's not going to spill into your client so you can safely fetch data from a database using some kind of om um we'll be using collections Astro collections ultimately that data will come from markdown files but it could come from anywhere all right now um just to show you how this works a little a little more I'm going to create a new page just for this video we'll delete it after I'll just call it test Astro and let's just put an H1 in here we'll just say test and since we put it in the pages folder we should be able to just go to slash test all right now let's put a component script in here and I'm just going to put a variable let's call it name and we'll set that to I don't want to do test let's say John and then down in the H1 I should be able to use that we'll say hello and then in curly braces we'll say name and we get hello John okay now again this is not on running on the client if I were to do a console log of name you'll actually see It'll log it here in the terminal it's not going to log it in the the browser console because it's not being run on the client now if you do want to have some front-end JavaScript you can still add script tags all right so we'll say console log name let's do something else we'll do 1 2 3 and now you can see that is actually running on the client all right so you would use this for things like if you wanted to add a button event or something like that all right so yeah typically you would fetch from some kind of API or database let's just kind of mimic that by creating a hardcoded array of users and we'll just put in here uh a couple objects so we'll change this to let's say mik and Sarah all right so if I wanted to let's say Loop through these and output them as a list item I could do that the same way I wouldn't react but using map so let's say users. map and I'll say for each user then I want to show a list item with that user's name and you can see that now it's printing on the screen okay so I mean that's that's really all I wanted to to kind of go over here is just to show you what we what we can do in here and let you know that this is not going to spill into the client whatever you put in here but you still can use script tags if you want if you need client side JavaScript all right so let's delete the test file here we don't need that and and you can see we get this 404 page we're going to in a couple videos from now we're going to have a custom 404 page that uses our layout but first we have to create a layout which is what we're going to do in the next video all right so we're going to look at layouts now because at the moment we just have everything thrown into the index file which means if we want to create another page we would have to put the dock type the whole head tag the navbar in every single page which obviously we don't want to do so Astro gives us an easy way to create layouts and we can add a slot tag that will specify where the individual page content should be injected whether it's the about content the Articles page whatever it is will be injected into that layout all right so let's create in in the source folder a folder called layouts and then we're going to have a main layout is what I'm going to call it asro and that's a component anything with aastro extension is a component and you can have of course multiple layouts but this website you know we only need a single layout because there there's not that many pages so what I'm going to do is copy from or not copy but cut from the index page from the very top and we want to go down past the Navar because that's going to be part of our layout although we will put that in its own component later on but we want to go down to this opening section because that's where the container starts anything in between that section is relative to just the homepage so we don't want that so let's cut that and go into our layout paste that in right now let's go down to let's see So within this the homepage we have the top grid which is this these two columns and then the main grid which is are these so want to go down past the top grid and then the main grid which ends right before the section should end end so let's go down obviously we're going to change it so we don't have all these hard-coded articles but it ends at the section so let's grab the ending section tag and the footer so everything from there down we're going to cut that and then let's go to our layout and right after the opening section tag we're going to paste that in all right so we have the footer and then in between the section tags this is where we want that slot to go because any page content we want to Output here that way all this other stuff is wrapped around it okay and let's just change the the navigation links so instead of about HTML it should just be slab same thing with articles so that'll be just slash articles and then for home we just want that to be slash okay so right now if I were to save the index page as is I lose the layout so the the head body body tags the nav bar not it's not showing so I need to bring that in to the homepage or any page where I want to use it I'm just going to tab these back real quick I don't know why prettier didn't do that all right now at the very top we're going to import the layout and remember we need to use our component script here so we want our three hyphens let's say import main layout and that's going to be from Dot do/ layouts SL main layout Astro and then we just want to wrap this in our main layout component because again this is a component so the ending tag obviously that's going to go down at the bottom like that and now if I save we go back you can see our homepage is now using that layout if I go to the about page it's not because we need to again bring it in so here let's go go up and let's say import main layout and then just wrap that in our main layout and now if we come back over here now about is using the layout let's do the same thing with the Articles so Pages articles index we'll do the same thing here so we want to import main layout and then wrap it in main layout okay so now for articles so now all three pages are using that layout now I think this is a good time to just get the content for both the about and the Articles page even though it's all just you know hardcoded HTML we'll go through and change that as we move along but let's at least get that initial content so in the about. HTML obviously we don't want the layout stuff we just want everything that's within that section container so that H1 down to this div here and then let's go to about. asro and replace this H1 with that stuff and if I save we see the content but there's no images now remember the website images are in the source folder which means we want to use the image component and we need to import those images so up at the top here about let's grab the image component and then the images themselves so I'm going to say import about from dot do/ images about we also want Team 1 team two and team three okay and then down here where we have the first image we're going to change that from the image tag to the image component and then change the source to about because that's what I brought the image in as and then do the same thing with the team images so this will be image and then for Source that's just going to be team one and then what I'll do is just copy that image component add that to the second one here just change it to team two can also change the alt to team two and then same thing here paste that in that'll be team three we can also change that to three and then we should see the images okay now for the all articles page let's grab that so back in Sublime Text if I can get it open so here let's go to articles not article make sure it's the plural and then we want to grab again everything within the section so section ends uh uh where is it right here so after the pagination just going to grab that and let's go to so it's going to be Pages articles index Astro paste that in save it see what that looks like okay so this is articles good we have our pagination obviously none of this is going to work but we have the the UI all right so now that we have our layout let's see in the next video I want to talk a little bit about props um and props work pretty much like they do in any other front-end framework you pass them in basically like HTML attributes and then you can use them within the component so we'll look at that next now we're going to take a look at component props and how those work so this is the documentation page basically we just pass in props as uh like an HTML attribute just just like you would with react view spelt and to get them we can destructure from this Astro doprs object so what I want to do is our layout is a component right so I want to be able to pass in a custom page title so that we don't have to have the same page title on every page which we do right now okay so let's go to our homepage so pages index. asro and on the main layout component let's pass in a tile and I'm going to set this to we'll say articles articles stories and tutorials say for tech people all right so I want to use this as the page title now obviously that doesn't do anything right because I'm just passing it in so let's go to our main layout and we basically need to catch that that prop that's being passed in and again we have this Astro do props and we can destructure from that so let's say we want to get the title from Astro doprs and then wherever we want to use it we can so I'm going to go in the title tag and just open up some curly braces pass in title and now we have a custom page title all right and it's only for the homepage as you can see so you're probably going to want to have some kind of default page title and to set a default prop is very simple we just go ahead and set this equal to whatever we want and I'm actually going to use this for the default so I'll copy that and paste that in and now no matter what page I go to it's going to have that title in fact on the homepage I'm not even going to pass it in because I don't have to because that's the default now let's say on the about page I want something different so if I go to the about and then pass in title let's say about uh about the tech people blog and then you'll see that we now have a custom title for the about page all right so it's as simple as that you just pass in the prop and then you destructure and you just get it from Astro doprs and then you can use it where you want all right so in the next video I want to have some constants for things that are unlikely to change like the site title the site description and so on so I want to have some sitewide constants that we can use like the site title the description also like the number of articles on the homepage just an an area where we can have those those global constants so in the source folder I'm going to create a file called constants dots and in here we're going to export const and let's call this site title and I'm going to set that to tech people blog and then we'll also do a site description so for that I'll say articles stories and tutorials from tech people okay and then um site URL I don't want to do that I want to do the homepage article limit so let's say const homepage pcore article limit and I'm going to set that to seven all right and then let's set the Articles per page when it comes to pagination and obviously we're not doing anything with these now we'll we'll use these later on down the road so we'll say article or articles per page and I want to do six for that all right so let's save that um we do want to use these two now the title and description so that's going to actually go in the layout so we're going to go into main layout and we're going to import those constants so let's say uh that's going to be from dot dot slash you want to go up one level into constants and let's bring in site title and site description okay and then what I'm going to do is the site title I want to put that before the page title like we'll have the site title and then a dash and then whatever the page title is so let's do that we'll say sitecore title and then a dash and then the the page title so now if we check it out you'll see tech people blog which is the site title and then we have a dash and then whatever the the page title is okay now for the description I want to add a metatext tag for that so I'm going to go right here and say meta um let's do name [Music] equals description and content is going to be site description we don't want quotes here though like that okay so if we check it out now and we view the source we should see do line wrap meta name description content equals and then we have our site description all right so yeah that's really all I wanted to do in this video so now in the next one we're going to start to separate our layout a bit by taking the navbar making that a component and also the footer and making that its own component so now I want to clean up the layout a little bit and we're we're going to create a a Navar component so let's cut everything the nav the nav tag and everything in it so down to here we're going to cut that and then let's create in Source a new folder called components and these are just you know basic just UI components the navbar the search footer things like that so let's create a new file here called navb bar. asro and I'm going to paste that code in now it's looking for the image um the image component as well as the the logo itself so what we'll do is just take this we can just cut this because we're no longer going to need this here and then put that into the navbar just make sure you put it into uh a component script like that and then we'll save the navbar and then come in here and then let's import that actually I'm going to go above here and let's say import navbar and that's going to be from dot dot SL components SL navbar all right uh actually we need to go up two levels I believe right no no that's fine all right so now where we cut the Navar from which is right here we're going to put in the Navar component we're going to embed it so now we should see the same thing right but if I were to not have that navbar then it's gone so that cleans up this file a bit now the footer this footer I I want to put that in its own component so let's grab all this okay make sure you don't take the body and HTML tags let's just cut the footer and then in components again we're going to create a file called footer. asro paste that in save it and then let's bring it into our layout so we want to import footer from the components folder and then we're going to just embed that right here oops it should be uppercase save it and we still see the footer all right so our layout is much cleaner than it was at the start now another thing I'd like to do is set up typescript for props for our components and we have a title prop in our layout so I'm going to come down here and just add an interface of called props with an uppercase p and we're saying that this should have a title prop that is a string now I do want this to be optional so what we can do is add a question mark here and in order for this to work we do have to make sure that we set up the as Astro types and there's a command that we can run to do that so if we go to our terminal we can just run npx Astro and then sync all right so if we do that that should set up our types so for instance if I were to remove this question mark right and then we go to our homepage which doesn't pass in a title we should now see at least if you're in vs code you should see this red line so it's telling us property title is missing so makes your code more verbose and just more helpful and you can spot errors better if you forget to pass a prop in or it's the wrong type so it's just good to good to have um but I'm going to put that question mark there because title is optional all right so what I want to do in the next video before we move on to our markdown files and collections I just want to create a custom 44 page so what I want to do now is create a custom 404 page and Astro makes that really really really easy all we have to do is create a page in the pages folder called 44. asro and whatever I put in here I'll just say test and now if I go to slash whatever we see that page so let's first import our layout because obviously we want to have it within our layout so let's say import main layout and then I'm also we're going to have an image here here as well so I'm going to import the image component and I'm going to import the image itself as error so we'll say from and that's not right we want it to be Images slash and then it's this error 404 PNG so now we're going to use our main layout and I'm going to add a custom title as well so we'll pass in a title prop of four 404 page not found okay now in the main layout I'm going to have a div with a few classes we're going to do a flex call I basically just want to push everything everything to the middle so item Center let's say justify um item Center and then Gap we'll do seven and then inside that we'll have our image component and that's going to have source of the error image that we brought in alt we'll just say 404 and let's add a height so for the height I'm going to do 250 and for the width also 250 and then a class of let's say margin top 10 so that's our image so if I save it so so far you can see we have our image all right now underneath it I'm going to have an H1 let's do a class of text- 5xl and we'll say page not found underneath that I'll do a paragraph with let's say text text Dash we'll do 2XL and let's say margin bottom 10 oops so margin bottom 10 and in the paragraph I'm just going to say sorry we couldn't find the page you were looking for and then underneath that we'll have a link let's give it a class of inline block and BG - gr-100 so it'll be really light and then padding to margin bottom six and then on Hover I want the background to be Indigo Indigo 500 and also on Hover I want the text to be white actually I forgot we can't do that with EMT the the hovers here so we'll have to just do these first oops a I forgot sorry guys P2 and what was it margin uh margin bottom six and then I'll add the those hovers like that and the link is going to just go to slash actually yeah we'll have it go to just the homepage and we'll say go back home all right so let's take a look there we go I think that looks pretty good so anytime we go to a page that doesn't exist we'll see that all right cool so I think that that's going to be it for this section basically we you know learned about components layouts uh filebase routing so in the next video or in the next section rather we're going to start to work with our data which are going to it's ultimately they're going to come from markdown files but we're using something called Astro collections so we can actually create a schema we can fetch our data and display it how we want so we'll get into that in the next section all right guys so now we're going to get into collections and collections are a way to manage your content within Astro and you can use different types of of files you can use markdown Json yaml we're going to be using markdown files which will include front matter front matter is a way to add uh metadata or fields to your content so and I'll show you uh what our markdown files will look like in a second um but any collections we have the the content the actual files are going to go in a folder in our s Source folder called content and then you can have subfolders for each collection so in our case we're going to have a Blog subfolder so let's create that now we'll go into Source create a new folder called content and then inside content we're going to have a new folder called blog and that's where our markdown will go so if you go to the final repository you'll see the content and the blog folder and you'll see all these markdown files okay which has a bunch of content that I generated using chat GPT so we're going to grab those and bring those over to the content blog folder okay and we'll take a look at one of them so they all have the same fields in the front matter okay everything in between these hyphens here is called front matter and it's essentially Fields like you would have if this were an article in a database we have a title A publish date an author an image which is just the image name and then then tags which is an array of just tags for the article and then a slug which ultimately will end up being the URL to that specific article and then any anything under the front matter is just marked down it's just the content okay and you can use um for instance if you want headings you can use number signs if you want uh lists you can use hyphens like item item one item two Etc and if you want to view this you can either do um I forget how to do it with just normal vs code I use a plugin called markdown preview enhanced so if I use that you can see what it would look like formatted okay on your website and it will actually get converted to HTML all right so let's get rid of that and what we're going to do next is ADD our config because you do have to Define your your collections in a config file so in the content folder we're going to create a file called config.txt colon content okay now if you have a red line under this it's because you didn't set up your types so you just want to go in your terminal and just run npx Astro sync okay so run that if you see a red line here that should set up your types and and that should fix it all right so now I'm going to create a variable here called blog collection and set that to Define collection and we actually don't have to pass anything in here except an empty object okay now we're going to export and say const collections set that to an object that has all of our collections which in our case is just one and we're going to say blog and set that to the blog collection so this will allow us to from our our Pages our components we'll be able to call a a function called get collection and we'll be able to pass in blog because that's what we called it right here now in the next video we're going to create something called a schema and that allows us to Define all of our fields and we can do that with this object right here here so we'll get into that next okay so now we're going to create a schema for our blog collection and I'm sure most of you know what a schema is if you don't it's it's kind of like a blueprint of what your your collection or whatever it is should look like so it enforces in this case front matter so if we look at our article here we have front matter fields of title pubdate author image and tag slug is looked at differently it's not really part of our data so these we want to enforce using uh using a schema and with collections we use something called Zod so where is it data types with Zod Zod is uh a validation library and we need to bring that in as Z and then when we create our schema with the specific types we use z. string z. number. dat whatever all right so let's go ahead and let's bring actually we don't need this get collection I think that was Auto inut orted by mistake but we need to bring in Z and then the schema goes inside of this object that we have in the Define collection and I turned off co-pilot because it was starting to annoy me it's probably annoying some of you too um now the first thing we're going to add here is the type and that's going to be content and then after that we can add our schema and we're going to set that schema to Z so Zod doob and in inside that is where we're going to put the rest of our Fields or the rest of the front matter that we want to validate so we have a title we're going to set that to Z string and these are functions so put your um parentheses then we have pubdate and I'm going to set that to the date type so z.e then we have what else author so that's going to be string then we have the image name or image that's going to be a string as well and then we have tags tags is going to be an array so z. array and then you can also say well what types should be in this array and those those are going to be strings so z. string we go in here okay and that's really it so very simple um obviously you can have you know multiple collections that have multiple schemas you could put this object into a separate file if you wanted to like if you had a bunch of collections maybe you'd have a file called schemas and then you could import that and just you know throw that in there but uh we don't have that much so we might as well just leave it how it is all right so now that we have the schema in the next video I'll show you how the how we can actually query from our collection and actually bring it into our blog so now that we have a schema we have all of our markdown files we're going to query our collection and bring it into our blog and we can do that with a couple functions that are available such as get collection get entry so if you want to read more about it you can do it here um access the reference data and so on so let's jump over to the I want to start with the Articles page so not the homage but this slash articles which is pages and then in the Articles folder there's this index. asro so we're going to start here and I'm going to bring in so let's import from here get collection which does just that we'll get a collection so we can Loop through it we can display each you know whatever we want from the markdown files from our collection so that's going to be from Astro content Astro colon content and then we're also using types script so we're going to import the type of collection entry okay so collection entry that's also from Astro content just make sure you put the type before it all right so now still within the component script let's create a variable I'll call it all blog articles and we're going to type this to the collection entry that we brought in and then in angle brackets and in quotes we're going to put the name of our collection which is blog and this is going to be an array that we get back so we want to put brackets here all right then we want to await on get collection make sure that you do add that away cuz it does return a promise and inside get collection we want to pass in the name of our collection which is blog so that should give us all of our blog articles so now what I want to do is instead of having these hardcoded article cards like there's one there's two we have seven of them here I want to take the HTML from just one of them which is this div with the class of Max wmd so this one ends right here I'm going to grab that okay so I'm just going to copy this just one of these article cards then we want to just delete all of everything that's in this grid class which is just seven of these article cards so this grid class ends down here way down here okay ends right here so everything within it I want to get rid of so we're going to just take all of this all seven articles and we're just going to delete those okay so now we just have this div with the grid the class of grid and in here is where I want to open up some curly braces and say all blog articles and we can just Loop through with map okay so inside map we're going to get the article and then set that to some parentheses and in those parentheses is where I'm going to paste that article card HTML all right so if I save that and we take a look you can see we have we're getting all seven articles however many markdown files you have in that blog folder are going to show here it's just showing um hardcoded HTML that's why it's all the same image all the same title but we have access to all the data through this it's actually article. dat Dot and then whatever title image so let's start with the title so this hard-coded title will get rid of that and instead let's say article. data. tile and now if we take a look we have all different titles based on the the markdown files all right um let's do the image so since we're using just the regular image tag we can just pass in a path we don't need to to import it or anything like that so we can say article. dat. image now remember it's just the image name so we do have to add on to this the path we're going to concatenate slash Images slash and then whatever that article image name is so now we can see our images all right next we have the let's see the date so right here let's get rid of that and let's say article. data do uh what is it pubdate so if we do that you can see the date doesn't look very good I'm we're going to format that in the next video but that's good for now and then for let's see for the the links here where's the link so it goes to article HTML both the image and the title links I don't want that so let's just change that now so I'll actually select both of these and then we're going to have um it's actually going to go to slash articles slash and then we want to concatenate onto that the article. slug it's not article. dat do slug it's just article slug so now if I come over here and I click on one of these obviously we get a 404 but you can see it's going to the right place it's going to article slash and then whatever the slug is we'll handle that single P single article page later so next we have the tags right so if we come down here the tags is an array so what we're going to want to do is Loop through those tags now notice that I have different colors for each one basically I want want to alternate the color classes for for the ones that are you know even and odd um so first of all let's just Loop through and show the tag so I'm going to copy one of these spans because that's what we want in the loop let's just fix this so I'm going to copy this span and then I'm going to delete both spans okay and then we have access to article. dat. tags but we're going to map we're going to Loop through with map I'm going to open another set of parentheses because in addition to the tag I want to get the index so that we can tell if it's even or odd and let's just type that to string and this to number all right now this is going to be pointing to parentheses and in here is where I can paste that span except I'm going to replace the hardcoded text here with the tag if I do that now we're actually we're seeing the tags from the article now now they're all blue at the moment I'd like to alternate the colors so what I'm going to do is copy all the classes and actually the quotes too so everything that's in this class I'm going to just copy that actually I'm going to cut it and then we're going to put in curly braces and we want to test to see if the index right if the index um modulus 2 is equal to zero that means it's even so in that case let's paste in the class is here and then else we'll paste it in again except I'm going to change the first one actually I'm going to change the second one to Indigo Indigo 500 and I'm going to use green for that so basically if it's even it'll be green if it's odd it'll be Indigo so let's save that take a look and now you can see we have alternating colors so let's see when we click on these we're going to want them to show a list of articles that have that tag obviously we don't have that page yet but we can at least put the link in here the correct URL so we're going to say slash articles slashtag and then we're going to actually do another slash and then concatenate the tag onto it so if I click on one of these now it takes me to tag slash and then whatever the the tag is so now our content at least on this page is dynamic right if I were to change something in let's say um let's say change the title of this to 20 best laptops in 2025 soon as I save that it changes here as well all right um the homepage isn't going to change yet because it's still all hardcoded but before we move on to that I want to just I want to format this date to look better and I also want to sort it by date because right now we have like the 19th the 14th 13th 16 18 I want it to be in order descending so we'll have the most recent first so in the next video we'll do those two things we'll sort it and we'll format the date so now we're going to format these dates and we're also going to sort the articles by date so let's go in back into the Articles index. asro and let's create a function here and we'll call it format let's say format date and it's going to take in a date and it's going to return a string so here I'm going to set some options and the type for this is going to be intl. dat uh let's see datetime format options and we're going to set that to an object with the year and I want that to be numeric um then we're going to have the month and we're going to use the long format for the month instead of the abbreviation and then day that's going to be numeric as well and you can format this however you want all right now that options variable is going to get passed into uh a new date object and we're going to use the two local date string method which is used to format dates to human readable formats so let's say return new date and then we want to pass in the date whatever date is passed in and then we're going to call to uh local date string now the first argument is the local that I want to use and I'm going to pass in undefined because I want to use the run the um the local of the the user if possible the the whatever that the JavaScript environment that they're using is and then let's say options so we'll pass in our options and that should give us the formatted date string so now if we come down here where we have the date right here and let's surround that with format date and let's see what that looks like and now we just have January 19th 2024 so if you want to format it in a different way you can do that I think that looks pretty good now I don't want to keep this function here I want to have a separate utility file for things like this because we are going to use this in other places as well so let's go ahead and cut that and we're going to create a new file in Source called utils dots and then we'll paste that function in there and then let's export an object with the format date function and then that way we can bring it in so let's see we're going to bring it in up here let's say import format data date and that's going to be from Let's see we want to go up two levels into utils and yeah that should do it so if I save that we still get the same same result now I want to sort the articles by date having the most recent first so the way we can do this is we can add on to this so we're going to actually wrap this in parentheses so we put another parenthesis at the end here and then we can add on a do sort in fact I'm going to put that on the next line so do sort which is going to take in another set of parentheses and in here is going to be the comparison parameters of A and B now as far as the type goes these are going to be collection entries and we want to put our collection blog okay no no um brackets because it's not an array it's just a single entry and then same thing with B that'll be collection entry and then in angle brackets we'll have blog all right and then here all we're going to do is take B we want it to be descending so B will be first so it'll be b. data. pubdate do value of minus a. dat. pubdate do value of all right so if I save that take a look now we have the 19th as the first one and the um or I should say the last one and the first one is the 13th so 13 14 15 so you can see that it's now in order if you wanted it to be in the opposite order like you wanted the earliest first you could just change a to B and you can change B to a and now it goes the other way but I want the the most recent to be first so I'm going to put it back to uh B minus a okay now I think we're pretty much we're good for for now as far as fetching data so I want to make each one of these its own uh its own component instead of just hardcoding it here because we're going to have the same the same thing on the homepage so we want to be able to use the article component here as well as well as the when we do the tags because if we click on a tag that will also show post when we search right when we search through this form that will also show post so we're going to we're going to want to use these article cards in quite a few places so we'll create that component in the next one okay so now we want to have a component for the article card basically it's going to take in a prop of the actual article and then it will display it like it is here so let's cut basically the the whole article card so everything that's in this right here not this itself but everything within it so this div with the the max with medium so we're going to take that all the way down to where it ends so right here and we're going to cut that right and then let's create in components a new file called uh article card. asro and then I'm going to paste that in here so it has no clue what article is that's going to be taken in as a prop so up top here let's add our component script and we are going to need the format date as well so we might as well bring that in so format date from utils and we're going to we're going to get the article from the props so let's say const and we'll destructure article say equals Astro doprs just like we did with the the title and the layout and let's see we're also going to add an interface let's say interface props now the article is going to have the type of a collection entry so we're going to bring that in as well let's say import type and we want collection entry from Astro content and then we want to type the article Pro top to collection entry and then in angle brackets we want the name of the collection which is blog all right so yeah that should be good um now down here this article pertains to the prop that's passed in so let's save this and then let's go back to our homepage and we're going to want to bring the the article card component in and then down here where we had it before we're going to use that article card article card and we want to pass in the article so we want to set that to article just like that let's save and we get the same result which is what we want all right I'm just going to get rid of this Main comment yeah so anywhere we want to put these cards we can now just use this component we can pass in the article as a prop oh and we can also get rid of the format date here because we're no longer using it here so in the next video I want to start to work on the homepage because this this page is looking pretty good I know the pagination we're going to do that later but I want to take care of the homepage which right now is just all hard-coded HTML so now we want to start to work on the homepage so we have a couple elements to to look at here we have the search right so this this should go in its own component we have this here which is separate than the rest of these articles this is going to be the most recent article and it's just formatted a little different so the image takes up the whole thing and then we have the text overlay or we have kind of a doc overlay over the image and then we have our six uh six articles in the same format as the as the article page all right so the first thing I want to do is just clean it up a little by moving the search to its own component so let's create a new component here a new file and we'll call this search form. asro we're not going to do anything with the search yet I just want to move it out of the homepage so we don't want to go to the Articles page now we're going to go to Just index the index that's directly in pages and we're just going to take the entire form and we're going to cut it and then in search form let's paste that in and we shouldn't need to do anything else right now like that we don't need to bring anything in so just save that and then we'll import search form whoops search form and then we'll just put that right here so search form save and we should get the same result all right so now I want to fetch the articles that we want for the homepage now it's going to be a little different here because we have to do a couple more things one we don't want this is going to be a separate component so we don't want to have this article down here as well cuz then it will be there twice so we want to make sure we we show from the second article on also we want to limit this to whatever we have in our constants which I believe is what seven we might want to change that to six because I don't think the yeah I don't think the this is going to is going to count so we might change that to six um but yeah so we want to do that and yeah I think that's really it so let's jump back into the homepage and at the top here let's bring in uh we're going to bring in get collection just like we did in the Articles page so get collection from Astro content and we could probably just copy from uh from the Block the Articles index yeah I guess we could just copy this because we do want to get all the blog articles so right here we'll paste that in but and we do need this type so let's also bring that in we'll say import type and collection entry and then down here let's create a variable called most recent article and we can get that very easily and that's going to have a type of collection entry uh collection entry and in angle brackets blog okay and then we're going to set that to all blog articles but we just want the first one so zero zero index that'll give us the first article the most recent then we want to basically get the rest of the Articles so I'll create a variable called other articles which is also going to be collection entry blog and we're going to set that to actually that's going to be an array so we want to add some brackets there so that's going to be all blog articles and then we just want to slice out the first one so just pass in that so that'll give us the rest of them outside of the most recent all right now let's come down here and uh let's see we want to go under the first grid into the main grid and then let's get basically get rid of everything in this div not the div itself but all the cards inside so this div ends let's see it ends right here so everything inside of that article card yep so right here so the main grid should now have nothing in it and then what we're going to do is take not the all blog articles but the other cuz that doesn't include the first one so we want to say other articles and we're going to slice we're going to say slice from zero because remember we only want whatever is in that homepage article limit constant which we actually have to bring in so we might as well do that so let's say import and homepage article limit so now let's say slice zero to homepage article limit and then from that is when we want to use map and say for each article then we want to show the article component so article card and we're going to pass in as the prop we're going to pass in article which is coming from here now we do have to import that article card component so let's do that okay so that should work let's save it let's go to the homepage all right so it looks like it's working now let's see what happens if I go to the constants and I change this to three okay nothing happened um oh I'm sorry that's the wrong thing that's articles per page we want to change this there we go so now it's showing three now I'm going to change that to six instead of seven and the reason it only showed six even though I put seven is because there is only there's only six in there not counting the first one and remember we're not counting that in this um this other articles so this only includes six so make sure that you put well I mean you could put what you want but if you put seven it's going to have one down here so I would put either Three 6 9 just so you have them going all the way across so yeah six is good all right and they're they're in there by date so 18th is at the top here and then 13th at the bottom all right so that looks good now just to kind of reiterate cuz I know that that we did that kind of fast so we created our article card component we're bringing that in we're bringing in the homepage article limit constant which is six and then we're getting all of the blog articles so this gets all of them and then here we're putting just the most recent article into this variable because we're just getting the one from the zero index and then here we're slicing off the first one so we're taking off the first one and putting putting the rest of them in other articles and that's what We're looping through down here right so we're not looping through all of them We're looping through other articles which doesn't include the first one now without this slice right here it would just get from the second one on no matter how many there are but we don't want our homepage filled you know what if there's 50 articles we don't want all those on our homepage so we're saying slice from zero to whatever the article limit is is in the constants which is six and then we're showing an article component for each of those so hopefully that makes sense now for the for this right here the most recent article which is this we're going to make that its own component we're not going to use an article card here because it's just formatted much differently right it doesn't have the image at top and then the the text down here uh it has different looking tags so you could manipulate the article card and put some conditionals in there and say like I don't know you could pass a prop in to say if most recent or something like that but I think it's easier just to create a separate component for this so that's what we'll do in the next video so now we're going to create a component for this most recent article uh this area right here so in the homepage in the index. asro we have this most recent article comment with the div so we want to get this whole div and everything in it so we'll grab that and cut that and let's see we're going to create a new component and we'll call it most recent article. asro and I'm going to paste in that HTML that I just copied I'll get rid of the comment here and then up at the top let's create our component script and what are we going to need here so we're going to need the format date so let's import that so format date from utils and we're also going to need the collection wait do we need that yeah because we're going to pass in an article which yeah so we're going to say import type and say collection entry all right and and we might as well create our interface so interface props it's going to take in an article and that article will be of type collection entry and blog and of course we need the props so we'll say or the prop which is the article get that from Astro doprs all right so let's um I know that this is all still hard-coded HTML but let's bring it into our homepage so up at the top here let's say import most recent article actually you know what well we can keep this name because this one is lowercase but if you want you can change this to something else but yeah I think that this is fine and then that's going to go let's see where does that go right after this div right so let's say most recent article and we're going to pass in an article prop which is going to be the most recent article so let's save that and we should still just see you know the same thing here so now let's make this data Dynamic so first of all the link here let's get rid of that we want this to go to slash articles slash and then we want the slug which we can get from article. Slug and then let's change the title here so for that we're going to do article. dat. tile now it still has the same title because that actually is the latest article so let's change that just to make sure that this is working so I'll go into um let's say this one here elevate your mobile experience I'm going to set that to what's the latest now the 20th so we'll set this to the 22nd and now you can see that the title has changed elevate your mobile experience if I click on it it goes to the correct slug as well now for the image let's do that uh and and also since I Chang that date if I go to all articles that's going to be the first one because now that's the latest so let's change the image right here get rid of that and that's going to be slash Images slash and then we'll concatenate onto that article. dat. image and now you can see it has that the mobile phone you can barely see it cuz it's really dark but it is back there and then what else do we have the date so we want to change that and we want to use that format date as well so let's say format date and then pass in article. dat. pubdate so now it should say January 21st and then the tags so the tags are a little different here they don't have the colors or anything I'm not even going to put links on these I just I'm just going to display them as they are there but we do have to you know Loop through and show them so I'm going to copy one of these spans and then get rid of both of them and we want to go let's say article do tags dot um actually it's data. tags. map and then let's see in here we're going to pass in the tag and then we can paste that Span in and we can replace that with the tag so now we have our three tags here all right so we're getting there I'd say the homepage display is good and the Articles display is good the about page so now in the next section we want to start to get into the individual article Pages which has a little bit more you know there's a little bit more to do there because we don't have uh you know a hard-coded route we have a parameter here of a slug so we have to get that we have to match that um and then after we get that single article page we can move on to these tags so we can click those and we can categorize them and then of course we also have our search so we'll start to to work on that stuff next okay so now we want to create the page for the single article so if I click on one of these right now it's a 404 but it is going to the right place now this slug right here is obviously Dynamic so to create our page we're going to go into the pages folder and then into articles because I do want it to be slash articles and then the slug and in here we'll create a file and the the convention for this is a little weird we're going to use brackets and then inside that we do dot dot dot Slug and then outside of the brackets we do Astro okay so it's just this represents that Dynamic slug now this is where it starts to get different if you're doing a static website versus an SSR website if it's a static website you're going to need to generate your paths because they're they're created at build time and you need to create this function to do that get static paths if you're building an SSR you don't have to do this however this is configured as a static website a static website generator unless we go into the config and specify that we want it to be server rendered which we are going to do in the next video but I do want to show you how to do this in case you you want your site to be static I want this to be a complete course so I want you guys to know how to do that so that's what we'll do in this video but we're not going to keep that code because in the next video we're going to configure it as an SSR all right so first off let's create our component script we'll import the main layout because I do want to show you how we can display the data after we generate the paths and to generate the paths we're going to need our data because we need those slugs so let's say get collection and then we'll get the type let's say import type collection entry and then we're going to create our function so let's say export and it's going to be async function get static paths whoops I don't want that it's static paths all right so in here we're going to get our data using uh using that get collection so let's say all blog articles just like we did in the other files and we'll give it the type of collection entry and blog and we'll set that to await get collection and we're going to pass in here the collection name which is blog all right so that will get our data now in order to generate our our paths we need to return a specific object and that object is going to have a params object and then any props that we want to pass to the to this particular page so we want the data so we're going to return all blog articles and then we're going to map through that or Loop through that that and say for each entry we want to return an object okay and that object is going to have a params object and we want the slug which is going to come from that entry. slug all right so that will allow us to create these paths uh now what is going on here map does not exist on type ID oh I need to put brackets here because this is an array all right so we're we're going through all of our articles and then this is going to generate the paths using the slug now any data you want to pass and use in the article we can just go ahead and add props and inside that I'm going to put entry because I want access to all of the data in the entry object okay so now what we can do is underneath all that we can destructure from Astro doprs we can get that entry for that particular page and then down here I'm not going to do the whole article I'll just do an H1 and we should have access to entry. dat. tile so now let's save that and if we come over here oh we didn't use the layout say main layout okay so now now we have the the slug and we have the title showing so we were able to generate the paths using this function here returning it in the correct format so if I go back to another one let's say this guardian of the digital realm you can see now we have the path to that so it's generating these paths for a static website but like I said we're going to make this an SSR so we actually aren't going to do it this way um so we can actually get rid of this and I mean it depends on what you want to do if you want to keep it static you can but I'm going to make it uh server side rendered so I'm just going to get rid of let's see I'll change this just back to article for now because we're not going to have any of this I am going to bring in the get collection and stuff like that so actually no I'm not we're going to use get entry because we're just getting a single post we don't have to to get all of them and loop through and click and create the paths because they're the paths are created automatically because it's server rendered so we can actually get rid of all that so just for now this isn't going to work because it's set up as a static site but in the next video we're going to set it up as a server side rendered website in the last video I showed you how to generate your static paths if you're building a static website but this is going to be server side rendered so we have to change a configur or add a configuration value so let's go into our Astro config file and we're going to go in the defined config object here and we want to just set the output which has a couple different options as you can see here there's static which is what it is by default then there's um server which is what we're going to use there's also hybrid so you can have some parts of your website static and some of it server server rendered so we're going to choose server now remember before I save this remember if I go and I click on one of these it tells us we have to create get static paths but if I save this and when you do save this file you can see down here that it restarts and then we come back over here and I click on one of these you'll see that it actually works because we don't need that get static paths function because it's server rendered okay it doesn't have to generate everything uh at build time so now that we've done that we can go back into our slug page here and we're just getting a single article now we don't have to get all of them and loop through and create a path for each one using the slug it just it'll do it automatically um so instead of importing get collection we're actually going to import get entry which is used for getting a single uh single object or single article in our case so that's going to be from uh that's going to be from Astro content all right so now that we've done that um we can get the slug we can get it through the params so let's say const and we want to get Slug and we can get this from the Astro object there's this param that we can use okay in fact I'll do a console log of Slug and you'll see if I go ahead and reload this page and we look down here you can see this is the slug right here and we can do something like this we can say if let's say if slug is undefined then let's throw new error and we'll say slug is required then we're going to create our entry variable and we can set that to await get entry and that takes in two things it takes in the collection which is blog and it takes in the slug all right and we can do a console log of entry and if we look down here you should see you can see the data all right so now let's just make sure that the entry is not undefined so we'll say if entry is equal to undefined then we're going to just redirect so we can do that with return Astro do redirect and then we'll redirect to just sl44 which will show the 404 page and we can use entry to get the like the title all the uh front matter stuff but we can also get a Content component that will that will give us the actual markdown the formatted markdown so down here let's say const and we want to get content uppercase C and we can get that from entry there's a a method actually we need to await that so there's a a method called render and that will render the content and we can use it down here so the next step is to get the the single article HTML which we can get from the uh the the Blog theme so I'm going to open that up so if you go to article. HTML we want to go under the nav here and let's see what do we what do we actually want here so everything within the section all right so I'm going to grab this this a tag down to Let's see we have an article here yeah so here down to where the article ends I'm going to grab that and I'm going to put that within the layout and all these these paragraphs here under the image I'm going to get rid of those I'm going to replace that with the content component so we'll get rid of that and then let's put content like that okay so we'll save it now it's not it's actually not styled because it's just like paragraphs there's no Tailwind classes since we're using Tailwind I mean everything is stripped until you put Tailwind classes on it so what we can do to to make to style this is we can add a style tag so let's go down here and let's say style and I'm going to put this is global okay otherwise it it doesn't work for some reason if I don't add the is global so I'm just going to take the paragraphs and just say margin 20 pixel 0 so if I do that you can see now the paragraphs have separated and then these are H2S and you can look at the you can look at the HTML here so these are H2S so I'm going to say for all the H2S let's do margin 20 pixel 0 and let's make the font bigger so we'll say font size let's do 1.8 REM so now it's formatted all right so that's just the content the stuff up here like the title and all that we can we can get that stuff with the entry itself so for the title this right here let's replace that with entry Dot data. tile so now the title should match the actual articles and the back button isn't working because it's right now it's going to articles HTML we want it to go to slash articles so if I click that it brings us back if I go to this imense in the virtual world you can see we get that title we also have the content so the other things we need to add here are the author the date the tags and the image so for the author right here let's replace John Doe with entry. data. author and then let's replace the date now we want to format the date so let's say format date and then pass in uh I'm sorry we have to wrap this in curly braces obviously and then entry . dat. pubdate now we have to bring the format date in so up here let's import format date from utils and then I'm also going to bring in the image component so actually we don't yeah we don't need the image component we'll just use the image tag because it's in public so let's see the image where is the image right here so let's change that path uh Source set that to let's say slash Images slash and then we'll add on to that art uh entry. dat. image all right cool so now we have the tags and we're going to create a separate tags component we're actually going to do that in the next video but just for now um I'll I'll just copy what we have in the let's see in the article card component right here We're looping through the tags and outputting them I'm just going to grab that code block and I'm going to replace these two spans with it except I'm going to change article to entry so that should work there we go now these go to 404 because they don't exist uh which is fine all right so yeah I think I think we're good so we have our single page so if I go back go to a different article uh why is there a back tick there tag is that in the file let's see content so right here um yeah we we're missing a there we go okay so yeah that's it for for the the article page and it doesn't matter if we go from the Articles or from the homepage should work either way so what I what we'll do next is create a tags component cuz we're we are using these in in a few places um so I think it would be nice to just separate that out from uh from the page so now I want to create a tags component for these tags here as well as on the the actual article page so let's go into components let's create a new one called tags. asro and we're going to have some props pass in here well a prop of tags which will be an array so let's add our component script and we're going to say const let's say tags and set that let's say Astro doprs and then we'll add our interface props it's going to take in tags which is going to be an array of string so we'll say string with some brackets all right and then let's copy from article card I'm going to grab this div here with flex and flex wrap and I'm just going to cut that and then that's going to go down here under the component script except we're not going to use this article data tags we're going to use the the tags that are passed in so just tags. map okay and then yeah let's just do that for now so we'll save that and then in article card we'll bring in that component let's say import we don't need that import tags and then where we had them we're just going to add tags and we want to pass in a prop of tags which is going to be article. dat. tags so if we save that we go back to the homepage we should still see the tags in the article card so let's do the same thing in um in the slug page or the the single article page which is this bracket Slug and we're going to import up here let's say import tags and we'll replace the div here the flex and flex wrap replace that with tags pass in the tags prop which is going to be in this case entry. dat. tags and then if we go to the single article page we should see it here we should have a we should add a little space there though so let's see on the image I'll add a class of let's make this my6 that will give it some on the top as well all right now what I'd like to do is the tags I'd like them to start with an uppercase or a capital letter so let's create another utility function we'll go into tills and I'm going to create a function called capitalize so let's say function capitalize and that's going to take in a string which will be a string this will also return a string and let's do we'll say if okay so I'm just going to check the type I'll say if the uh type of STI R is not equal to string oops it should be quotes string or let's say if the string. length is equal to zero then we're going to return string okay else then we're going to return string and we want to make the want to make it upper the first letter uppercase so we want to get the first character we can use Char at zero and then do two uppercase and then we can catenate onto that the string the basically the rest of the string by saying string Str Str slice and then pass in one so it's basically going to take off the first character because we're outputting the first character here as uppercase okay and let's just put some some comments here we'll just say capitalize uh capitalize the first letter and then this one here format the date to a string okay and we just need to export that capitalize and then we'll bring that into our tags so let's see we'll go up top here let's say import capitalize and then I'm going to use that down here let's see so we have the tag right here so let's wrap that in capitalize and then I'm also going to put just put a number sign in front of it so outside of the curly brace right here I'll just put a number sign or a hashtag and there we go so now we have the little hash and we have the the first letter capitalized all right so I think that that should do it as far as the tags component now we want to have these obviously want this to go to a page where it shows all of the the articles for Hardware or for Tech or whatever the tag is so we're going to work on that next now we want to make these tag TS work when we click on them so we're going to create inside the Pages directory and In Articles I'm going to create a new folder called tag okay singular just tag because I want it to go to and if you hover over it you can see in the bottom left it goes to article SL tag slh Hardware or whatever that tag is now that tag is dynamic so we're going to do the same thing we did with the slug we're going to create a new file and call it brackets do do do tag. asro and basically we can we can pretty much copy from the the article's index so this right here yeah we'll just grab that paste that in now we're not going to actually have the pagination here so we can get rid of this last div here and then let's see we're going to have to just change these paths up a little bit we're one level deeper so for the main layout we're going to add another dot dot slash same thing with the article card uh let's see get collection I don't know why what's going on here make sure to run Astro generate the types yeah we've already done that npx Astro sync that's strange I don't know why it's I don't know why for in this directory that's giving us an issue huh well let's just see if it works so I'll save this if I click on one of these okay it does work it's fetching all articles but that's because we haven't narrowed it down yet I'm not sure why it's saying the corresponding why it can't find the module that's weird uh anyway we're getting all blog articles and we're outputting those but we want to narrow it down by the tag so what we can do is come down here and create another variable called tag articles and then we can basically filter through all blog articles so we'll say all blog articles. filter and and let's pass in here article oops what is going on article and then we'll say article. dat. tags and we can use the includes method and say where it includes that specific tag all right what's this doing can't find name tag that's because uh uh data includes tags okay so this tag is actually coming in from the Pam right so it's coming in up here which you can get with Astro do params so let's go here and let's say const tag set that to Astro do params and then we'll just make sure that the tag is there not undefined so if we'll say if the tag is equal to undefined then let's throw new error it should be uppercase so we'll throw new error and we'll say tag excuse me is required all right so yeah that should work now instead of looping through all blog articles we're going to Loop through tag articles so now you can see we're only getting this one article if I go back and let's see so Tech has quite a few so I'll click on Tech and we get all the tech articles now I'd like to show what tag it is up here in the heading so instead of saying all articles which isn't true we want to get rid of that I'm going to put the tag name here and I'm going to put uh I'll put a a number sign before it and I'm also going to capitalize it so I'm going to bring in that utility function that we created so uh capitalize and then we'll pass let's see right here capitalize pass in the tag to that and now we get Tech okay now you might be saying well that's that is unsafe I mean you can put anything here like we could put script alert one script however that's not going to work okay cuz Astro has safeguards for that stuff so we don't even have to worry about sanitizing it or escaping it it does it automatically all right so don't worry about that that's what's great about these Frameworks is you have things like that in place all right so we have that working we should probably put a a back button here though like a back to articles so let's go to where do we have that in the slug page yeah I'm just going to grab this a tag and we'll put that above the H1 there we go all right cool so what I want to do next is in the footer notice we have some tags here but the this is just coded HTML I want to actually fetch the tags that we have the unique tags we don't want them to repeat and then show them here and Link them to you know the the tag page like this so we'll do that in the next video all right guys so now we want to do the tags in the footer cuz right now it's just HTML so let's go into components and then go into our footer and we're going to want to first of all fetch the Articles and then extract the the tags from the Articles and also make sure that they're unique so that we don't have these repeating cuz it's going to get all of them at first which you know it'll have Tech from this one Tech from this one this one so we want to make sure they're unique and we can do that by creating a set there's I mean there's a bunch of ways we could do it but that's what I'm going to do so let's create our component script and we're going to import get collection and then let's import The Collection type or collection entry type and then let's also import the capitalize utility function because I'm going to use that here as well so capitalize from utils and then we'll just fetch the blog articles so let's say all blog articles collection entry and block and it's going to be an array so we want our brackets and then we want to await on get collection from our blog collection all right so that'll get all the Articles now we want to get the tags so let's say cons tags which will be uh an array of strings and we're going to set that to all blog articles and I'm going to use the flat map method for this so flat map and then we'll pass in here let's say article and I'm going to use the any type here because I was getting some weird errors um and then let's say we want to get article. dat. tags so that will give us all the tags in fact we can check that out so if uh let's see it doesn't matter what page we go to you can see that it's giving us all the tags but notice that there's there's some that repeat there's Tech right here Tech right here so we want to make these unique so what I'll do is say const unique tags which will be a an array of strings and we can do that by creating a new set so in this array we're going to use the spread operator and say new set and then pass in those tags so that this will make them unique so if I do a console log now of unique tags now you can see that none of them are repeating so now we just want to Output that in the footer so let's go down here where we have them hardcoded let's get rid of everything within the UL so all these Lis and then we want to say unique tags and then we'll just Loop through that using map and uh let's see I want to get actually yeah we can just we'll say for each tag then we want to have an Li and I'm going to give it a class of margin bottom two okay and then inside here we're going to have a link because I want to be able to click on it and take us to the tag page so let's create an a tag and this is going to go to let's say slash articles slashtag slash and then we're going to add on the tag okay and as far as what we want in here I'm going to put the number sign and then I want to have the capitalize function and I'm going to pass in the tag all right so let's save that check it out and now you can see we have all the tags none of them are repeating if I click on Tech takes me to the page with all the tech Tablets Samsung all right so that's working good so I think we're we're pretty much all set with the tags so in the next section what we're going to start to work on is the search okay that's the the big part of the next section also the pagination cuz on the all articles page if there's like a 100 articles I don't want to list all 100 I want to be able to just cycle through next and previous so we'll do that in the next section all right so we're going to start on our search we have the search component here but obviously it doesn't do anything so let's first go into that search component so search form and if we look at the form tag what I'm going to do since since this is an SSR website we can actually just just put an action here and it will submit to that page unlike If This Were a static site we would have to go through you know we would add some script tags frontend JavaScript and probably submit to an API endpoint which I am actually going to show you in the next video I'm I'm going to show you how to set up an endpoint where you know you can get Jason data back from a search term but we won't actually need that for the application it's just for learning purposes but what we're going to do ultimately is just submit to a page so let's say action and for the action we're going to go slash articles SL search okay so we we can just create a search. asro in the Articles folder and then we can basically just get the data from there and we can get it from our collection all right so let's save that and then let's create that page so in Pages articles I'm going to create a new file called search. asro and just for now I'll just put in hello and I just want to make sure that this submits to it so if I say test and there we go so it it submits to that page and it has test in the query and we can get that using Astro um I think it's Astro url. search prams so let's go into the search page well we're already in the search page but let's bring in the layout first of all so let's add our component script import main layout and then down here we'll have main layout and I'll just add a title here of search results okay so uh what else do we want to put here um we we'll take care of this after let's just focus on actually getting the the articles for the search term or the search query we are going to need the article cards so might as well get the Imports taken care of uh let's see I'm also going to put the search form on this page as well because they might want to search for something else and I don't want them to have to go back to the homepage so let's say import search form and then we're going to import get collection and that should do it for the Imports now let's get the query that's sent so I'm going to say const query which will be a string um or let's say string or null and then from Astro we can there's a URL object and then there's this search params and then we can call a get method on that and we want to get the query okay okay so let's just test that out in fact we'll just put it down here for now so we'll say query and now if I were to put something in here like test there we go so it's just going to output on the page because it's in this query variable so next thing I want to do is fetch all blog articles like we have been doing so let's say all blog articles collection and wh collection entry and blog and it's going to be an array all right so we can just await get collection blog all right uh what's going on here oh I didn't import that type okay so now we have all the blog articles but we want to filter let's say filter articles based on query okay so I'm going to create a new variable called search results and we'll take our all blog articles and let's filter okay so we're going to do filter and then say for each article then we're going to do a couple more things here we want to match a couple different fields of a couple different front matter Fields like title um the body obviously I want to search the entire markdown body as well as um as well as the slug so to do that let's create title match and that's going to be a Boolean okay and then we can take the article do data. tile and let's make it all lowercase I'm just going to go on to the next line here and say two uh to lowercase and then on the next line we're going to use includes and we want to pass in our query and let's make that to lowercase as well okay so that will do the title um and this question mark actually let's make that an exclamation mark that should make that go away all right um yeah I think that that should match the title now for the body we can kind of do the same thing so I'll just grab that and let's call this body match and the only thing we're going to do is change it from article data title to article data body okay um body does not exist oh I'm sorry it's not data body it's dot b just there's no data for the body okay so that's body match now let's do the slug match so slug match and we'll change this to article. Slug and if you want to match other fields you can you just got to add it here so now what we'll do at the bottom of this function is return let's say title match or body match or slug match okay and then we should get that so down here what we want to do is just Loop over those those results but let's add a couple other things here I'm going to have a a back button so we'll have um an a tag let's do inline Dash block let's do BG Das gray 100 padding two margin bottom six and I'm also going to add a hover in here so hover colon and we'll do BG Indigo let's do Indigo 500 and also hover uh text white okay and in here we'll say all articles all right now I'm going to put the search form at the top so if they want to search for something else they can so we'll throw that in there then we'll have our H1 let's do text uh H1 text- 2XL we'll do padding bottom three and margin top six and let's say results for and then in strong Tags I'm going to put the query okay and and all the the sanitation and stuff is is done for us so we have to worry about that then we basically just want to have our our main grid just like we do with all the other uh article P pages so let's say grid and grid Das calls D1 let's do a gap of four and then I want to do on small screens and up we want grid calls to be two okay grid calls two and on large screens it'll be grid calls 3 all right now in here is where we can take our search results and loop through those with map and say for each article then we're going to want to show an article card pass in the article prop which is going to be that article all right cool so let's save that so we come back here we get results for test which means that the word test must be in either the title the slug or the body so let's go to one of these and let's search for test and you can see right here a testament so it doesn't have to be the word test it just has to be in there somewhere which is what you want all right so if we uh why is this not working so this article button I'm sorry this uh a tag here yeah we just want this to go to slash articles okay um yeah so if we search for let's say Samsung we get that I'm just going to add a line break after the search form here yeah so that looks better and I think we should put a search form on the all articles page as well so let's do that let's uh so articles index let's import I want to import uh search form and let's see underneath the H1 here I'm going to grab from this the search page yeah I guess we just we'll just grab that yeah so now we can easily search here if I say web cool so what what we're going to do next is I'm going to show you how to create an API endpoint using Astro and again this isn't part of the project but it's a pretty big part of Astro and I want this to be a semicomplete course um so we're going to do that in the next video okay so our search is working well but I think this is a good opportunity to show you API endpoints it's a good use case so we're actually going to have an endpoint where we can send a query and it will return a a Json document with all of the the articles that match that search query so you can check the documentation out here basically what we do is in the pages folder we can create a file that looks like this something. json. TS or .js and the the TS or JS will be removed during the build process and you can create these get end points for static files but if you're doing SSR we can do something like where is it like this we can have get requests post delete all all right so that's what we're going to do is just well we're just going to set up the get but um again you could make it a post request uh Delete Etc so in the pages folder what I would do is create a new folder called API and put any endpoints in here so let's create a file called search. json. TS again that TS will be stripped off um so that it'll just be a Json file now from here we don't need to put our content script or anything because this is not an astro component so let's go ahead and we're going to import the type of API route from Astro and then I'm going to create a function let's say export const get and this is going to be of the type API route and let's set that to an arrow function and what we're going to pass in here is we're going to destructure URL and this will be the type of response and then let's create uh or let's get a quer the query Pam that's attached to it so basically we want to be able to call something like this um let's go over here so we want to be able to do like slash API slash search. Json yeah something like that and then put a query on it and search for whatever in this case we searching boundless which is a word that I believe is in this article right here so we want to be able to do that and get Jason back with those results so to get that query let's say const query um and we're going to say string or null and then we can get that with that URL object and then search pams and then call the get method and we want to get the param of query okay and then just to show you that let's do a console log of query and then I'm going to actually make this right here and it'll give me an error because I'm not returning what I'm supposed to but you can see boundless is now printing in my terminal so I'm able to get that query so next thing let's handle the qu the case where query is not in the URL so let's say handle if query is not is not there or is not present okay so we'll say if query is equal to null then I'm going to return because we need to return a response so return new response and we're going to pass in here I'm going to run this through Jon do stringify and let's pass in an object with an error and we'll just say query query Pam is missing and then after that stringify so let's go after this first parentheses we're going to open up some curly braces here and we want to have the status so so in this case the status will be 400 which is a a bad request so we'll just say bad request and then we also want to send headers and add the content type so we're going to say content-type and set that to application SL Json all right so that's if it's not there now let's go underneath that if now if it is there we're going to return a response so I'm just going to copy uh let's see this ends here so I'm just going to grab this return put that here except we're going to change this get rid of the error and we're going to return the query and it's not going to be a 400 it's going to be a 200 because it's successful and yeah that should do it um so right now all it's going to do is give me back whatever the query I pass in is we're not fetching any any articles at this point I just want to make sure that this actually works which it does it just reloaded and you can see what I'm passing in is boundless and I'm getting that back okay if I change this to test then I'm getting query test so our our API endpoint is working now we want to actually fetch the data and we're going to do that the same way we have been by using colle CS so let's import get collection and let's import the type collection entry and this time we're not going to return for for the return it's going to be a promise with the response so let's say promise and then in angle brackets put the response okay and same thing we're going to get the query we're going to check if it's null um this is going to stay the same if there's no query down here though we want to change this so before we return the response we're going to get all the blog articles so all blog articles collection entry blog wait get collection you guys can probably write this in your sleep now we've done it so much all right so once we have those then we're going to get the search results and I'm going to do that the same way we did on with the regular page so let's go to Pages articles search and can basically just just grab this right and then put that in here um sorry we need brackets right here okay so that's the search results now all I'm going to do is when we return this let's pass in instead of query we're going to get rid of that and pass in the search results uh yeah I think that's correct response is not is not for promise um what am I missing here we got a wait oh we need to make the function asynchronous so up here we need to just say equals async like that all right so this should work let's say come back over here if we reload that I'm searching for test and I'm getting back an array of Json objects that match that test right again if I search for boundless which is it's in the body of one of the this article right here then I get that so what I could have done is in my search form I could have used JavaScript to catch the query you know create an event to get the query that's in the the input and then send a fetch request to this with B with whatever in the query get the Json back and then I could use that to put it on the page all right so I I mean and I could I could use something totally different a completely different um front-end application that hits this this API endpoint and gets the Articles all right so again we're not using it here but I wanted to show you how to do this how to create these endpoints so next we're going to move on to pagination all right guys so we have these pagination buttons or links on the article page and we want to make these function we also want to put them into their own component so let's go to pages and then articles and then index and we're going to come down to where we have our pagination which is this div right here and we're going just cut that and then let's create a new component in the components folder called pagination do asro and then we're just going to paste that in going to get rid of that comment and then we'll add a component script here and there's a couple props that will get passed into the pagination component so let's define those so that's going to be from Astro doprs and the two that we want are going to be the current page as well as total Pages all right and then down here where we have the links for previous and next let's change this and we want this to go to slash articles but we want to add on a a page query string so we want to say question mark page equals and then we're going to add on the whatever the current page is minus one because it's this is the previous so we want to go back one page all right then we'll copy this and for this one this is the next button so we want to say current Page plus one for that and then let's embed this into the Articles page so I'm going to bring in let's say import pagination and then let's let's see down here we're going to add pagination and for now let's say current page and I'm just going to hardcode it to one for now and then for total Pages we'll set that to two Okay and then let's add the the typescript interface as well for our props so we'll say interface props and current page oops current page is going to be a number and total pages also a number all right so we should still see these here if I click it you can see it goes to page two right if I click it again it stays at page two so that's what I want to do next is make sure that when we click next it goes to page three and four and so on so to do that let's go back to our article index and here we're going to uh let's see we're going to get the current page which is going to come from the URL so to do that let's say const current page which is going to be we'll say number or null and then that's going to come from Astro DOL remember to get and to get any search prams or query prams we do URL and then search Rams and then we call the get method and then whatever the the pram we want which in this case is page now if it's not there so we're going to say or if it's not there then the page is going to be one now this is giving us an error because this comes in as a string so I'm going to convert it to a number simply by putting a plus sign in front of it and this could be null so let's put a a exclamation here as well all right so that will get us the current page from the URL so we then we then want to pass that in here like that now for the total Pages we're going to basically have to get uh all the blog articles get the length or or the the count and then uh divide that by our constant of Articles per page which we have in uh where is it right here this articles per page so let's bring that in to our articles index so we'll say import articles per page bring that in from constants and then we are we're already fetching all the articles with this we have we have it in this variable so what we can do is then create total pages and we'll set that let's see that's going to be number and we'll set that to math. seal so we'll write round this up and then in here we're going to take our all of our blog articles and get the length with DOT length and then we're going to divide that by articles per page that should give us the total Pages all right in fact let's check that out so total pages and let's see and you can see right here three now the reason it's three is because we have what seven articles and I have articles per page set to three so it would be these three on page one these three on page two and this one on page three so we'd have three total pages so now we want to pass that in get rid of this hardcoded two and let's pass in total pages so now at this point we should be able to click on next and you can see it goes to page three click it again goes to page four now we haven't it's not limited yet we can just keep going and going but at least that's working and if I click previous it goes back to page four now the articles are the same on every page so let's let's address that next so what we can do is go back to our articles index and we can get rid of this console log and I'm going to create a variable here called articles for page okay cuz this contains all the articles now I I just want to get the ones for the particular page or the current page that we're on as far as a type goes this is going to be a collection entry um it's going to be an array of collection entries so let's say blog and put our brackets here and then we're going to set that to all blog articles and then use slice and we're going to say for slice I'm going to pass in another set of parentheses and say say the current page minus one and then outside of those parentheses we're going to multiply by articles per page okay so that's the first argument we want to pass into slice then we want to pass in the current page multiplied by the Articles per page okay so that's how we can get just the page I'm sorry just the articles for whatever page we're on so down here instead of looping through all blog articles we're going to Loop through articles per page or articles four page so let's save that and we're on page four so there's nothing here let's go to page one well let's just get rid of page completely which should should default to one and we see our first three articles right if I click next it goes to page two we see our next three if I click next again we see our last one all right so that this is working the only thing we have to fix is I can keep going all right and I can also oops I can also keep going back it'll actually go to page zero which obviously we don't want so in the next video we're going to make sure we disable these buttons if we're on either the first or the last page okay so we have our pagination working we just need to make the buttons disable if we can't go any further either way so in the articles in index where we're passing in the uh the P the props here we're going to add two more so one is going to be disable previous and I'm going to set that to an expression of current page so we'll say if current page is equal to one right so because that means we're on the first page so obviously we don't want a previous button or we don't want it enabled then we'll pass in disable abled uh or disabled not disabled next and for that we're going to say if the uh wait a minute this shouldn't have these shouldn't have uh quotes around them all right so for for disable next we'll say if the current page is equal to Total Pages then we don't want to show next because that means it's the last page and we can put these on different lines too just to kind of make this a little more clear uh number Z okay so we just we need to add these to our interface so in the pagination let's take in um we're going to take in disable previous and disable next and then we're going to add those down here disable previous and we're going to set that to Boolean and same thing with disable next okay now we just have to implement those and we're we're not using a button so we can't use the disabled attribute so we're just going to use CSS and we're going to set pointer events none and Tailwind which makes it so we so it's not clickable okay we'll also change the color as well so where we have the class right I'm going to just for now I'm just going to cut the whole class along with the quotes and I'm going to set the class to some curly braces and in here let's say disabled or disable previous so if that's true we'll use a Turner here we'll say if that's true then let's paste that in what we just copied or cut except I'm going to change up a few things here I'm going to change the text uh let's see what do we want the background to be let's change the background from Indigo 100 to gray 100 and let's see we're going to we'll get rid of the hovers so hover text white we can get rid of that and then hover Indigo we'll get rid of that and let's just add text- gray- 400 all right and then after that quote we're going to do an else and then I'm going to paste in what I copied again which is the default which which I want if um if it's not disabled so if I save that and then I come back here and we go to page one you can see that previous is disabled it's still showing the pointer so I I also want to add onto this class right here pointer events none so then we don't even have that that um pointer all right now let's do the same with the next so I'll actually just copy what we have here for the class and I'll replace this okay except this time we want to say disable next and now if we click next we go to page two page three now I can't go any further because there's no more and that's it so our pagination is now complete so I'm going to just go back to the constants file uh let's see where is constants I'm just going to change this back to six so if we go back to page one we just have two pages because there's there's seven articles all right cool so that's yeah I think that's it guys so I do want to deploy this to versel um so in the next video we're going to install the versel adapter and we'll push this to GitHub and we'll deploy to versel so now we're ready to deploy our website you have a lot of different options you can deploy to versel which is what we're going to do or netlify or there's a a nodejs adapter so if you want to use like digital Ocean or Len note or AWS so there's a lot of options versel and netfi are extremely easy and you can do both static and server side rendered all right now if you're going with SSR then you need to install the adapter okay so let's see this is the documentation here you see if you if you wish to install or if you wish to use server side rendering Astro requires an adapter that matches your deployment runtime so if we come down here we can install that adapter with this npx Astro ad versel so let's go ahead and run that I'm going to come down here and say npx Astro ad versel and that is going to add um a new entry to the config file let me just make this a little bigger here so say yes so it's going to ask us if we want to make the changes to the config file so it's basically just going to import versel and it's going to add it as an adapter so we're going to say yes to that and if you look at the Astro doc config you can see that that has been added now I need to update my GitHub repository so you should you should push your project to GitHub you can see I have it right here at Astro blog and I'm not going to go over you know pushing the GitHub if you need help with that I do have a git and GitHub crash course on my channel it is a couple years old but it's still same thing same commands so I'm just going to push this change to it so I'll say get add all and let's say get commit M and we'll say added versel adapter and then I'm going to push to my repo and if I reload should see right here added versel adapter I'm going to go to my versel dashboard and you can just log in with GitHub um and then we're going to click add new project and since I'm logged in with GitHub it's going to automatically pull up my repositories and you'll see Astro blog at the top that's what I want to import and then this stuff here you can leave all this as as is just leave the defaults and then click deploy and this might take a minute or two okay so that took about a minute maybe a little bit more and you can see it get this congratulations message and we have a a screenshot of the page so let's click on that and that should open up your project and it's going to have some weird versel doapp domain of course you can move on and add your own domain if you want you can start right here uh I'm not going to do that I'm just going to keep this one but let's just make sure we can go to the inner pages so here's our single article page if I click on a tag that shows me the article for that tag let's go back we'll search for um let's say laptop go to the all articles page that works about page that works so looks like we're in good shape if I click on one of the fooo tags okay so everything is working as as we would expect click on the most recent good so now when I want to add a post all I have to do is go in and add a new markdown file in my blog folder here and then push it to GitHub and it will automatically deploy to versel so it's a it's a nice little workflow for like a personal blog or even a company blog if you only have a couple people obviously if it's a large a really large website large application you probably going to want to have some kind of content management system or API or build your own custom back end um but I think that this is good for especially personal projects all right guys so I hope you learned a lot here um I know this this wasn't an in-depth course I mean there's more we could do but this is a quick start it's meant to do just that get you up and running really quickly and now you have the knowledge to build your own Astro project all right thanks for watching guys and I will see you in the next course
Info
Channel: Traversy Media
Views: 31,894
Rating: undefined out of 5
Keywords: astro, ssr, ssr website, astro js, astro web framework, build a blog, blog, react, typescript, markdown
Id: XoIHKO6AkoM
Channel Id: undefined
Length: 164min 4sec (9844 seconds)
Published: Mon Dec 18 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.