Build and Deploy BLOG with Tags - Next.js 14, Sanity CMS and Tailwind

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi dear friends it's Stefan from codebook Empire today we are going to build a Blog using next js14 with tail win for the CMS we are going to use sanity and embed it to our next application at the end we'll deploy everything to verell so without further Ado let's get started all right friends here is an overview of the blog which we're going to build today so on the main page we have all blog posts displayed we get these blog posts from our cmss sanity so if I go here you can see by the URL it's deployed on this version is Deploy on verell as it's our next JS application and it's available on the route Studio okay so you can see we get all the posts from here and also we get all the tags from here we have ability to add a new tag and also we have ability to add a new post okay now let's get back to our app if we click here you you can see all the content is displayed here it's a rich text element basically with image we have ability to go on the tag here and basically this is like a filtering system it will get us all the posts that include this tag all the posts also can have a multiple tags okay if I go back and click here I can see all the tags which we have which we get from our CMS and they have in the brackets here basically a number of posts which have that tag included all right besides that we also have a light mode which is nice but I prefer more this dark one okay now let's get back to our CMS and add a new blog post hi there YouTube okay we can build we have a possibility to generate automatically a slug also a publish date is basically set set for this current one but we can change it here okay let's now say something here is a great blog post okay for the body first I will add some heading heading so this is just some dummy text I will use Lowa mson for here paste it and at the end I'm going to upload an image okay so let's for example this one we have a possibility to add alt text for the image so let's say fire base loo all right and at the end we can add tags for this post I will add only fire base here so you can see when we type it recognizes that we all already have this tag in our base database so we are adding that that one and I think that's all we are now publishing the document okay now when I go back to the main page if I reload here yeah you will see we don't we won't see this post immediately because was next is doing a caching for us and in this project I set the cache to be in 60 seconds so basically when we publish and we go to our page after 60 seconds we'll get our post displayed so if I reload it here yep here we go we can see our post here you can see it has Firebase tag so if I go for tags and Firebase click here I need to reload the page because of the caching okay so we can see it here and if I click on the post there you go all right now let's jump into coding so we are here on the nextjs website and we are going to use a CLI to create a new Next app I just go here on get started and on installation so yeah we need to follow these steps I will copy this prompt and open my terminal I will paste this commands and press enter now nextjs will ask us some questions first first is the name of our project this will be blog CMS would you like to use typescript yes would you like to use eslint yes would you like to use Tailwind CSS yes we won't be using using Source directory we will be using App router uh we'll go here with no and yep that's it all right so we now have our nextjs application installed I can simply type here code and name of our app and that's blog CMS if you don't have enabled this command you can manually just go to your folder and paste it to your Visual Studio code okay I think we are now set up next step is to install a Tailwind plugin so I'll go back to my browser and type Tailwind CSS uh get started and if you scroll all the way down there you will see official plugin ins and the plugin which we'll be using it will be this uh Tailwind / typography so uh basically plugins let you register new styles for Tailwind to inject into user stylesheet using JavaScript instead of CSS and specifically uh this typography plug-in is usually used to style content blogs that come from sources like markdown or cms. database uh in our case we will use it for styling Rich text ments coming from sanity CMS so how to do this you just copy this command here and paste it to our terminal okay that's nice also we need to add one more dependency and that's npm I next teams so this is package that will help us with dark mode implementation it help us store theme preferences of the user so we don't get any blinking and screen flashing and so on when screen reloads basically takes a lot of heavy and repetitive work out of the developer heads okay so so now we are set up but first uh we need to go to tailin config dots and here we need to uh add some configuration specifically here in plugins I will put are we sorry for this require y this is the plug-in ta wi CSS and that's all okay now we can save this and run our [Music] app okay I'll go to our browser and type Local Host 3,000 okay here is our template now we need to clean up a bit a little of this code first things first I want to remove all this Tailwind configuration which we got from the next okay team is empty yep besides that I'm going to go to let me just check it yep we remov this background image okay now I want to go to app and Page folder and remove everything here because we will starting from scratch I'll just have a div with H1 saying hello world we're going to remove this image and that's all okay besides that I'm going to go to Global CSS and remove everything from here except Tailwind Imports okay if I now save we'll go back here and we can see a blank page okay now we are ready to go now next step is to create our layout first we are going to create an AB bar in our app folder right click new folder and I'm going to create the components folder okay inside our components I'm going to add a Navar do TSX now I'm going to use R AFC e which is a shortcut for creating component initial component if you don't have this extension I strongly recommend it this is this is the one es7 six Snippets okay now get back to this I will remove this and I will add some class names some table Tailwind classes basically around nvar it will have some sort of a container yeah so we need to center it with margin we need to add it uh Max width which will be five Exel it's Tailwind class I think it's yeah uh 1024 pixels that sounds perfect for a block container and we'll add some padding on left and right P6 I think that's 24 pixels yeah okay now let's create a d which would be a flex we have on left side Navar and on the right side I will add a button for team switch okay CL class name Flex justify between and align item Center which in Tailwind is a class items Center okay I will add height of uh 64 pixels which is h-16 and of course full width just in case okay as I said earlier on the left side we will have a link which will import from next slash link inside our link we'll have a logo which will basically be a div with a text Dev block okay we'll add some styles to it later and on the right side I for now I will add the div which will be like team something like that okay I will now save this and we'll get back to this nav bar later now we need to import this nav bar to every page luckily nextjs actually these newer versions provide us with a layout. DSX page in earlier versions We would need to create on our own layout component and then wrap it around every page so in this new version so next they do that for us so basically this layout is wrapping up our all whole application and we can use this to add a out bar since it will be present on every page okay to do so I will first cut children and add now bar yes and Below now bar we'll have our children so basically that's it let me check this uh okay I forgot to save this okay now now if I go back yeah so you can see we have successfully imported our nav bar here nav bar here okay now uh I see one problem here that's this hello world that's from our main page is out of the box basically out of the of the container so in order to fix that we need to go uh here to our layout and add some styling to our children prop okay so we'll first add main tag semantic HTML tag and wrap wrap our wrap our Trend learn with it then I'll add some classes and the class name here actually will be the same as this one because basically that's the container right I will paste here and voila that's it now maybe we can yeah I think we now need to consider our teams okay so if you remember earlier we installed this package called Next teams if you go to their documentation we'll see the detail instructions on how to to set this up but the problem is here in their documentation they are using this Pages yeah Pages folder structure and we are using app folder structure but yeah we can manage this with this way okay first if you go here we need we have this team provider that we need to wrap our app with so in our case it would go to the layout here and wrap everything this with this team provider and let me do so this will not work but let me do so just for you to see okay so I'm going to import this team Provider from next teams with this attribute class and uh we are here and I will close it okay so as you can see we WRA this and this should this should work out of the box but if I go here and reload the page you will see an error and why is that because if in their documentation they are they're referring to older versions of nextjs let's say the version that runs on the client but our component all this layout runs on the server so basically they don't know what is this and how to fix that we need to create our own custom provider okay how to do so in our up folder I will first create a new folder called called utils and in utils new file called provider. DSX in our provider first we are going to use this use client directive which basically tells nextjs this this component will run on client now I'm going to import react from react and also import team Provider from next teams now we are going to create a provider which will have children prop so now it needs to return yeah basically this team provider attribute class children and yeah so what's the purpose of this it's actually our own custom provider which runs on the client and then we import this here okay uh this is typescript error which says children is typ any so we don't want that we want to create interface for our props which will be yeah props that's okay okay for now children yeah that's true so children will be react node okay I will assign this prop type this type here and yeah that's it now what we need to do we need to go to our layout and import this provider here okay so instead of this one we want to import our provider sorry for this we'll remove this and type provider okay and paste it here uh yep we need to export this export yeah and now if I go back here and type provider we'll have this Auto completion and yeah that's it now if I save we should not have yeah as you can see we don't have any errors so yeah that's fine that's perfect actually okay now moving on next thing is to create a team switch but before that I want to say a few words about this provider so basically this will be something like a global provider where we going to put team provider as we did it yeah this team Provider from next teams if you would would use for example chakra UI chakra steam provider would go here also similar would be for context provider since you would probably use use state in your context and that used State needs to run on the client and not on the server also common misconception here is that because we imported this provider component which runs on the client this layout also runs on the client which is not true all right now I'm going to create team switch component and import it to naar so right click to the components folder and team switch. TSX great [Music] now we'll use our shortcut and for now I'm only going to add this here button says team switch now I'm going to the nav bar and down there I will delete this and import our team switch component okay let's check that out perfect here it is okay moving on now how to actually add functionality for switching teams we'll go back to our package next do next SL teams and you can see they provided us here with this documentation but also we have this warning here and this is actually our case because we we don't use it on the client we use it on servers so they give us a tips for that to avoid hydration mismatch it's a common error in this new next js14 version so how to to fix it basically we can import this and import this this is a custom Hook from their package which will we use and in easy way switch teams but in order to avoid this hydration error we need to implement it on in this way so let's get started first I want to import this use theme from next teams okay I will paste it here and then down below I will add this yeah thank you copilot okay next step if you can see this use effect only runs on the client so now we can safely show the UI so what they are suggesting to us is to first because us use effect runs only on the client to check when the client actually rendered our UI and then render our button in our case it's button in their case this select okay so how to do that we go here and we import use effect from react okay perfect and now we import this hook I will just copy paste it here copy and paste it here okay so we need to add also use State hook yeah that's that's true okay so what does this code do we are first checking in use effect so use effect only runs from the client if the page actually mounted let's say something like that because of that we are naming this this variable like like like like that so if component did not mounted we just return n so nothing and else if component mounted we return our team switch so now if I save it we go back here here whoops we see an error and why like it says here it only works on client component your important component that need US state so in order to fix this we need to go up and write our use client directive why do we need this because the team provider this used team runs on the server but the team provider is rendered on the client and that causes this mismatch in the initial initial team State like like their document documentation mention they don't know uh the where where I saw that yeah because we cannot know the team on the server many of the values returned from used team will be undefined until mount on the client so because of that we need to run it on the client yeah uh this is safe to do because because the team switch is only rendered on the client so we do not have to worry about anything else if I save this now and go back to our application everything is functional up and running okay now in our team switch here just to check if everything is working I will do something like uh okay something like this we can add on click event and fire call back function which will actually set the team so if the current team is dark and you click it needs to become light yeah else it is dark I think this is self-explanatory right and in order to actually show that on UI yeah I will use this recommendation from co-pilot so if the team is dark we'll have here light light switch and vice versa okay let me just refresh this click refresh dark light okay great perfect this is working one thing we forgot here is actually to add some base stylings in our layout here in our meain in our body actually if you remember this design we had this kind of purple color for the dark mode and for the light mode some sort of white color yeah okay what I want to do here I want to first start with the font I don't want this inter font I want um font called f if I remember correctly let me import it yeah F Cod so this this is a great thing about next GS4 and I think they implemented this in version 13 we can directly import fonts from Google fonts in our next application so how to do that I will say FEA code yeah exactly same thing we imported this inter font okay and now I don't want here to be enter I want it to be FEA code and guys just in case in case you don't know you can always click here I'm on my Mac I'm holding command and I click here and now you can see all the props this font has so it has uh font weight style display and so on and so on okay we are going to use this and yeah that's pretty much it moving on to styling I will just comment this and you see this we have another font perfect now I want to add classes to this body and to do so first I need to cut this and add back ticks paste the font and now I can continue adding class first height full background I want to use this Amber 50 which is some light yeah it's not actually white some yellowish white let's say it's something like that that's perfect for the text I want to use Indigo this dark version okay yeah perfect and now how to apply classes to dark mode actually very easy in Tailwind you need first to add dark okay and now apply styling whatever you like I will first start with background BG slate this dark version and when we have dark back when we have dark mode text I want it to be now number 50 this yellowish okay perfect okay moving on let's go back to our code and see what we can add here also okay I want when we have dark to add this selection BG purple 500 oop sorry yes so what did they do here this okay moving on next let me just apply prit here and I think we are all set up now I can add this instead of this text some icons actually and to do so I'm going to my browser and type SVG repo so this is a free repo of fvg icons where you can search and find icon you like so first I want to type Sun so feel free to choose whatever I will choose this one and also you can customize this icon I want to let's say have purple color here this this purple so to do so you can just go here and apply Styles I will cut the video here guys uh export all these images and I will get back to you also all these images will be on my GitHub GitHub repo so no worries all right friends here we are again and now as you can see I like this kind of purple for my icons so I downloaded they are on my desktop as you can see here yeah so these are svgs I can drag and drop them to my visual studio yeah uh sorry to my to my vs code okay I don't want to use them as images because in HTML we have support for svgs so I think the best practice here is to create in our components folder a new file called icons. TSX and then here we can use it as functions as components actually so so export const and this icon will be sun icon and then it needs to return a SVG okay and this SVG here it is I will just copy it command C and paste it here oops sorry for this my bad this is an aror function apply PR here and that's it I think I need I have I can close it now and now here I want to create export const yeah exactly Moon icon which will return us something similar okay here we need to return an SVG so this is my moon icon I will just drag and drop it here it will create a new temporary early file and I will copy it kill it and paste it here okay perfect next step is to First kill all these things we don't need page okay layout okay fine perfect now we go we can go back to our team switch and instead of displaying here a string in this button we can display our icons now so if the team is dark I want to use to to see Sun icon and else if the team is light I want to see a moon icon oops sorry for my spelling Moon yeah exactly that's the one if I save this now and go back to our application yes perfect and if I click here so we have an issue here and that's because we implemented our class to our layout let me just uh go there okay so here you can see we have class for white and Class for Dark and now have a we have a problem which we will solve easily we'll just need to go to tailin CSS dark mode yet that's the link and here okay so if you can see by default uh this uses prefers color scheme CSS media feature if you want to toggle dark mod mode manually so we don't want to use system color mode we need to add this preference this glass strategy in our tail with config JS now we're are going back to our code and Tailwind config yep and don't we need to to say dark mode class okay perfect let's see if now we have a working version go here reload the page all right looking good looking good final thing we need to fix this here this should be like something like logo so we are going back to our code to our Navar and first I want to import a custom font sorry from next font Google okay and the font name is this one little one okay now same stuff is in our layout font is L one weight 400 and subsets this seems like we have an error here oh yeah this is a string this is not a number okay perfect so let's add our font here to our div class name with back TI and they'll have font class name that's it and now some additional classes I want a bigger text here and on dark I want want this text Amber color this looks good now we only want to cut this and add it to some span we'll add class name purple text 500 and yep I think this looks good moving on okay last thing this team switcher uh want to go back to our team switch T TSX and add some basic stylings here in our button first I want border and the Border should be purple 500 yep that's the one I want to be rounded to Excel and of course some padding okay now some hover effects very easy actually in Tailwind we only have this hover class with background let's say purple 500 right and also I want it on Hover to be to have opacity of 10 which is basically a 0.1 yep and maybe maybe when it's dark Yep this yeah I think this looks good great okay I think we are finally ready to add sanity CMS to our project all right friends now we are here at the sanity I web page first we'll go here to Developers documentation and then getting started down below I'll click on create a project so here we can see a command which will paste into our terminal okay copy and go to our terminal now I'm going to open another terminal I will paste this command here and go here and rename our project this is a default name I don't want this one I will call it BL cm M for example okay and now press enter now just wait a few seconds okay so if you already have a sanity account will continue without this step but if you don't have it and you are logged out of your sanity account they will ask you to First log in or create it so in my case I'm going to create a new sanity account using Google just press here okay now it should open pop up in your web browser okay I will just Okay now click accept terms of service and continue okay we logged in successfully and created an account we can close this window and go back to our terminal now we need to answer some questions here in our terminal would you like to add the configuration file for a sanity project in this nextjs folder yes we want to embed our studio to our project do you want to use typescript yes of course would you like to embed sanity Studio yes I want to embed it would you like like to use nextjs app directory for routes yes I want to do that yeah Studio sounds perfect and we want a clean project with no predefined schemas uh would you like to okay so this is interesting would you like to add the project ID and data set for your to your EnV file yes we want to do that because they will automatically Ally assign those files into EnV folder EnV file so we don't need to do that by ourselves now just wait a couple of seconds and we should be ready to go great the installation has finished and we can now start with setting up our project first I want to show you the projects that sanity generated for us we have here sanity C.S and Sanity config.sys of course they added an EnV file for us but if you can see it here it is currently tracked in our uh git also they gave us warning here so we want to use env. loal for any secrets and I recommend you to do that so I will just rename this file tv. local so now it is not Source control so if when we push this folder to git we won't push our secrets our configuration from sanity moving on okay how we can now access our San sanity studio if you see here this folder structure in our app they created a sanity folder for us so inside this for sanity folder we have a client which is a configuration file basically for sanity image. TS it's file which we'll use a later for getting images from sanity EnV okay so this this is sanity Z envs and schemas we will type our schemas later in this file okay now if I go up you'll see in our app folder here we have a studio file with some subfolder and Page inside this actually provide us with possibility to access sanity studio right from our application so let me just do that if I go here slash Studio it should open up first time it will be a bit laggy but yeah it should open up our studio here which is currently embedded in our app we'll wait a few seconds okay great sanity gave us a warning so we need to go to our account to our project and add this URL as a course origin okay just press here continue we'll need to log out log in to your account I will use my Gmail account I created earlier and yeah that's it we are here to sanity uh okay they have this growth plan trial here for for us cool okay I will close this and yeah here you just need to press add course origin okay now we're going to go back to our sanity we can log in to our embedded sanity okay we need to authorize first great here we are for now we don't have any schemas so our sanity CMS is empty now the problem here is that sanity is embedded to our website and since in xjs we have our layout folder which wraps up every page we need basically to create a new separate layout specifically for our studio and thankfully nextjs give us that opportunity so I'm going just to my browser and going to type nextjs route groups okay here in their documentation you can see that we can use these route groups first to organize our routes into groups just for better readability and second if we have this nested layouts and here they give us a an an example so what we need to do is to create a folder new folder with this brackets and then insert our layout which is connected with this route and layout which is connected with this route and so on and so on so let me do that okay now I want to go here and create a new folder like documentation mentioned I'm going to create it in our in Brackets so first we'll have for example admin and another folder will be let's say client in our admin we'll have sanity Studio and the rest of the application goes into the client perfect now let's go here and just drag and drop this studio folder to our admin folder yes we want to move it here update Imports yes we want to do that okay perfect and now we need to drag and drop everything else into our client this page goes here yes and this layout goes here yes and I think this Global CSS file also we can put it here all right that's great now let me just save this here close it and let's see what we got here now as you can see it our studio is here and if we go back to our Local Host 3000 we'll have another separate layout which is great now I want to uh basically to utilize this new layout structure and add to our sanity studio also a custom nav bar uh but first let me just go through this quickly again yeah so as you can see see we are when we are accessing our studio we go like from Local Host SL Studio structure and if we go back we can access our main page only from Local Host so that's the point with these brackets basically we are eing this in url and just using using it as uh some kind of a structure for our web application it's more like organizational thing right okay so now let's create a new component which will called new file we'll call it for example CMS CMS now bar. TSX yeah CMS now bar perfect now we'll go here and create a new react component I want first to import link from next slash link right I want to import a new font r l one from next fonts perfect and I think that's it for now I also want want to add this font we'll call it just font yep that's perfect we only need to add weight font F here which is 400 and that's perfect now let's get back to styling down there I will add some classes here class names so Flex justify between and I items Center for centering it we'll add some padding on the top and the bottom and bit more padding on the left and the right px5 let's say something like that okay now I need my link withh okay and inside our link we want our logo so I can go back to our Navar and just copy and paste this copy and paste it here okay we need to close this div and yeah I think this is good for now let me just go back oh yeah sorry we need to embed our layout our naar CMS nowar to admin layout if I go back here I only want to go here and add CMS now bar perfect now if I go back Studio oops it seems like we have an error and this is hydration error so you I think you already know how to fix this if we go back to our client and lay out we'll see that we have this provider here so we need to do basically the same okay moving on sorry this should be inside our body I think this this was the thing that caused this hydration error yeah now as you can see now it's fixed but we also want to add this provider but maybe yeah we'll add it just in case in case we need it save and perfect we embedded a new nowar in to our sanity studio all right now I want to also add some icons we'll go to our SVG repo and add a back [Music] arrow I think we're going to use this one and as earlier I will pause my video here to edit this SVG and we'll paste it back to our site all right we are now back and here is our icon I will just drag and drop it here so I can access this SVG file copy and we'll go back to our no utils but component and go to icons and as usual create a new icon which will be something like back arrow icon yep exactly return and paste our SVG here okay I think this is perfect so now we can go back to our sanity CMS now bar go here on the yeah I think we can restructure this a bit so I will okay I will paste I will create a link here with hre Slash sorry now admin but only slash because this will be our back icon and inside of this link I will import our what was the name of this icon back arrow icon okay back arrow icon okay perfect and now we we won't need this link here down there here we'll copy cut it and yeah I think we are good to go okay perfect but now as you can see we although we added some stylings here we did we do not have that Styles and why is that well because our Global CSS file where we imported Tailwind is only on the client specifically in the client folder so now we only need to copy it and paste it inside our admin sub folder let me just do this so we need to so we need to copy it and paste it to our admin folder here I will just create a new file globals do CSS and copy everything from here and paste it here okay now if I save this and reload the page we don't get nothing and why is that well because we want to go to the layout and import our globals right yeah exactly with Slash yeah perfect so now when we go back we can see our styling is applied so we can now easily switch from our app to Studio perfect I think we are now ready to go and create our first sanity schema all right now let's go back to our code and go to our sanity folder here and create a new folder called schemas inside the folder first we can create a new file called post. DS inside the folder we'll start creating our schemas first thing let's create an object const post and start adding our Fields first we need to add name and that will be post after that we're going to add a title which will be post with capital P and type is document okay perfect now next step is to Define fields for our post schema so we're going to start start typing fields and first Feld we'll basically do the same so I will just copy here here copy here and paste it here first field first field will be title with the title here capital and that's type of string now let's just save here and test it to see if this actually is working but before that we need to import this post schema to this file schema. TS and how to import it well just go here and start typing post yep and we'll automatically import it save and now go back to our studio and yeah in our content tab we have our post and if we click here we are able to create post we don't only this first field which we defined and that is title field so now we are going back and we'll start defining other fields next thing is Slug so we'll name it slug with a title of slug the type will not be string the type will be slug so that's the type from the sanity and when it to add another field options and that's an object which has Source prop key and the value is actually based on what field we want to generate the slug so the common logic and sense is to generate the slug based on the title so we need here to add just title that that's the name of this field okay now if I save and go back here we'll see that we get got this generate automatically generated field uh button which will generate title for example if I go here hey YouTube and click this generate it will generate us automatically a slug based on this title perfect moving on next field we'll have a published date so the name is published at the title will be published at and the type will be date time save yep here we go now next thing we are going to add a new field I'll just copy and paste this object and just update the fields so name will be exerpt exerpt and the type will be text that's a short field for our blog post which will be displayed on the main page and now we need to add a action a rich text element which has I will copy this again paste it here the name would be a body and the title body with capital B and this is important part this is type of array in this new version of Sanity now we need to add off value which is basically an array okay and this we need to Define what what type of our a of array is this so if we want to use a rich text element this will be type block so basically this array will contain heading which is a block paragraph which is a block image which is a block and so on and so on okay I hope this makes sense okay let me just quick save this and go down down there okay so you can see we can type we can add headings so on and so on but we don't have an image possibility to add image and if we want to do so we need to add another key value pair here and that's type of image and this is optional field totally fields which will be an array of objects so the type here is text name is alt and title is alt so I think you already guessed what I did here when I add image you can see now we have possibility to add an image upload go to our images choose an image and when when the image is uploaded we can add an ALT tag so that's great okay moving on one final step is to add a field for our tags but before adding them we need to create a new schema specifically for them before that I want to add some validations to our field so we these all Fields needs to be required and we want here for example to have a default date which is today's date and so on and so on so let me just go back here and start adding some validations so in this object we'll need to add a validation key and for the value we have an call back function which receives a rule which is a type of role which we can import from sanity yeah that's right perfect okay and now we are taking this r which is basically a method that has its own method required and got error method inside which where we can specify our message we'll only type here required okay perfect now I want to add this line of code to every block here and except we want to add a new rule that it won't be only required but we need to specify the maximum number of characters we want we want to write to do that we need to go to delete here and say Max Define number of characters let's say 200 characters and then error with message Max to 100 characters all right that's good that's good and now I'm going back to the date we need to specify a prop property called initial value okay it's also call back function which will only return a new date sorry it's a new date to ISO string okay perfect now if we save this and go back to our page and and reload highlight the new post here try to save it for example blah blah blah okay so you see now we have this field required we need to generate it you have a default date here and so on and so on you can test it out okay Ming back to our project going to schema's folder and I want to create a new file called tag dots okay perfect like before we need to export const tag which is equal so we can this is another way of creating a schemas in sanity you can use Define type from sanity okay like this so and now we can create a name so if you see now now maybe this is a better approach because when we start typing it will give us an recommendation okay so this will be a tag so guys you can use whatever you like I just wanted to to show you all the possibilities you have with a sanity okay next is title this will be tag next is type and that's document okay and the next field is Fields that's an array of objects so first is name title would be tag name and the type of course string perfect and we want to create another object this will be a slug title also Slug and of course type is Slug Now options for the slug when we need to specify source and and the source will be name this here Prett here save and that's it now if I go back here we won't see anything because we did not import this tag to our schema. DS tag save reload and yeah great we now have a option to create a new tags okay now how to connect these tags with this posts here so we need to go back to our post and add a new field at the end this field will have name of tags title would be tags with a cap capital T and of course type is an array because we can have a multiple multiple tags for each post and array of what well array of type is reference so we are referencing tags to our posts here the next is to specify to what we want to reference this tags these posts so to basically the same type tag okay so we are referencing this field to what to this type tag and what is that type how how we know that because of this name type tag okay perfect okay now if we reload this we want to create tag for example JavaScript generate slug publish and we can add a new one flutter generate slug publish perfect now we are going back to our posts to our first post and we have now ability to add new Texs if I click add item and just start start typing for example this I can now have all that documents published perfect now I want to use a chat jpt to add a couple of blog posts I will I will post this video here and get back to you well thank you Chad GPT for providing us with a content for our blog post here we have tags couple of them and we have uh five blog posts you can see with we have this and text in some of them we have besides the text and image and tags and everything is set so just to remind you guys when you finish writing your posts you need to publish them here don't forget to do that okay now moving on to our application and start coding but first let me just go real quick here and type Gro so what is Gro gr is basically a query language which sanity uses under the hood very similar to graphql and I will show you here how does this language works okay so we have for example collection of our movies so that's the type movie in our case the type is post right and we want to return every movie which has a release year which is greater than 1979 so that's basic example so when we go back here to our sanity studio and go here to Vision we have this playground where we can play with our queries and test test them and so on and so on first if I type here ASX with here with this and just fetch I'll get all the documents from our from our sanity CMS but I don't want to do that I want to only to get all these posts how to do that well I need to type underscore type equal equal to post and why that because that's the name of our document here okay and when I hit fetch I'll get all the five documents perfect now we can query and get for example if I paste uh if I add this curly braces here like an object and I only type type for example no type title and now fetch I'll only get the these documents these blog posts and their titles and so on and so on let's Implement that to our application actually so we can type here we will need slug we will need published date just let me see yeah this publish that we also need a field X sert and I think we are good for now sorry I forgot to add Comas here fetch yeah perfect we have title published and excerpt okay I think this is fine for now so we can just copy this query to our application let's go back we don't need this we don't need this we don't need this we are going back to our app client and main page okay perfect now what we are going to do here first let me go up and import client from sanity lib client perfect so we want to use this San lab client here and this is a helper which we'll use to query our sanity CMS let's go now and write uh sorry ASN function function and we'll call that function get posts perfect so since we are using next js14 and newer versions with app folder structure basically all the pages by default are run on the server so we can run directly here and write our function for querying sanity CMS okay const query will be be equal to what well to this we'll need to copy this go back and pasted it between these back ticks cre here and okay I think this is okay for now now we need to store that into a variable called Data a wait and then we'll call this our client which has a fetch method and we only need to paste our query here so this variable query perfect okay where and where we done we only need to return our data okay perfect now so how to get these posts to our page well that's simple we just go here and type const posts we'll store all the posts to this variable and we'll just call await and await this get post function okay but now this is await and if you want to use a weight in this parent function in main function we need to make it to be a sync so we'll only just type async here and that's all so maybe you're wondering but why we don't use use effect here well because as I mentioned this component this whole page runs on the server so we don't need to use use effect here hook we can just conso log here directly and that will work out of the box so that's perfect console log post posts let me just yep these are post so yeah if I now save this and go back to our page let me just go back here okay if I inspect this you will we won't see nothing here we'll address this errors a bit later so I need to go back to our terminal and yeah here there are we are logging it into our console because this is a server site okay now we only need to look through the data and create a post first things first I want to create a base UI let me go to the components right click new file and create a haer component header. TSX okay I want to do this because I don't want to repeat myself with the same code in every page and I will create a header component here which will have basic basic title for the page and we'll pass that title as a prop I hope that makes sense okay so this will be a header it will return a header semantic HTML inside we'll have H2 which will return a title okay and the title will get that from props title okay and I want to create an interface here called props which will have a title and that will be a type of string okay I will assign this type here perfect okay that's good now let's add some class names here some padding maybe and okay let let me just first import this here so instead of this I want to import this header component header yep from components and we want to send a prop here title which will be let's say articles okay let's save and yeah here they are perfect now let's get back to our component header component and add some stylings here okay I want to add some padding four so pading left and right some margin bottom I want to text Center everything here I want to add a border bottom okay and in the dark mode this border I want to be border [Music] purple this one so darker shade okay now for the class name class names for the H2 for the title I want everything to be uppercase I want a bit bigger text so I think this is fine to Excel Center it with margin and I want to add some Maximum width so we don't have any overflow issues and so on let's say to excel and of course font bald okay I think I think we are good to go for now let's go back okay this looks good nice moving on going back to our main page and we'll add here an div which will hold all our posts so we need first to check if the PO post okay let me just fix this because I want recommendations here and we don't know what kind of post we are receiving from the server because we did not uh add type here and I want to go to my utils folder and create a new file which will be interface. DS inside our interface I want to create an interface for our post I'll export interface from here which will have a name post and we'll have Fields Title with a type of string we'll have a slug which will not be string and let me show you if I go back here to our vision you can see that slug has is actually an object with a current inside of it key which has a value which is actually a string so we're going back now sorry let me just hear okay so object with a current which is actually a type string perfect now we have published at which is a type string we'll have excerpt which is a type string also you'll have body for now we'll add any because that's basically an array of blocks so we don't need to waste our time here for creating a type for that currently uh after body we have Texs so so tags will be an array of type tag and we'll create this tag right now but before that only left field here is ID which is type string okay perfect now let's create type for interface actually for tag we'll have a name String we'll have a slug which is basically the same as here we'll have an ID which is type string okay I think this is good for now maybe we'll update these interfaces a bit later if we need to do that let's get back to our page and start creating now these posts can receive their type which will be a post and array array of posts exactly perfect now let let's go here and we'll first check if we have posts so posts. length is greater than zero so if that's true then let's map through our posts and return okay for now I will return only a P tag like something like that with a key post do ID okay and this P tag will only display title so let's see if this is working yeah okay here are the titles now the better approach here is I think to create a separate component for these posts because we are going to use these posts on on every page basically now I'm going to components creating a new file which is called post component TSX and let's start creating this component let me just delete here and first I want to import the link okay from next link and that link will lead us to the post pages but before that we need to add actually post data here and we'll receive that that data from our props so post I'll create an interface here which is called props for now it will only have a post and the type is post the post we just created now let's add it here let's add a type here and yeah perfect okay this link I will add HRA and this will link to slash posts Slash post. Slug do current okay we currently don't have this page but we'll create it a little bit later okay inside our link we want to add H2 which will be post dot title below that we want to add P tag which will be post dot let's go with publish that okay and below that I want to add ah post excerpt okay perfect let's get back to our code oh sorry we need to import this component okay we'll go here and import it okay we need to add a key here that is post. ID and we need to send the props so post is equal to post okay this this is good perfect now we here can see all our data excellent going back to our post and I now want to add some Styles I will add class name here and instead of traditional way of adding Tailwind classes here I want to create a separate variable for this because this will have quite a bit of classes so I will add here const this will be a card so I will name this constant card style and here I'll pass that card style this is something like similar like you would do in the react native okay and now we'll add some margin margin bottom we'll add padding P4 we'll add a border with a color of Border gray 900 border needs to be rounded okay Shadow small and Shadow color classes Shadow purple 950 now I want to add some hover effects First Shadow OMD then want to change the background color to purple if we have light mode also hover text white and hover dark BG gray 950 so when we hover when it's a light mode we'll have this purple background and when it's a dark mode we'll have this sorry this is gray gray color okay let's go back nice okay we are getting there I think almost now let's add some styles to other parts of our code for example let's go with H2 but this H2 will have a custom font so first they need to import fonts so import from next slash font SL Google nice okay let's go down there and store fonts to our variables we'll have a multiple fonts so the first one will be Lita one which used earlier and the second one for the dates will be this one VT 323 main one is this [Music] one we want to add width of 400s and of course subsets letter I will copy paste this and this variable will be called Date font and it will receive this font okay perfect now we are going back to our H2 and adding some class names in a back TI first so font. class name perfect and some other styles text to Excel and dark text slate 300 okay this is cool okay let's go to our date We'll add class name same like for the H2 but with a difference of another font so we don't want to use this one we want to use this one date font okay that's it and I'll add some other classes margin top and bottom 8 pixel so my2 and also text purple let's say 800 okay this looks good but I don't like this date formatting so I want to use this function from JavaScript so new date we pass our date dys function and only called method to date string okay now this looks good moving on to our last paragraph here we'll only add some basic class names here so on the dark mode I want this text to have that grayish color so gray 400 let's see margin bottom four yep I want to add some line clamp just in case that we receive a longer string here but I don't think we're going to do we'll receive a long string because we manage that on our sanity back end but just in case I think it's a good practice to also manage that on your front end okay I think we are all set now we have light mode great this looks really good in my opinion perfect now let's move on next thing we need to add Tex and I'll go back to our vision here to our playground and I want to add a field Texs okay if we now fetch this you will see something strange here we'll get this strange properties and we want see here name slug etc etc the things we need and why is that this is because this is a reference field and we need to resolve first that field in order to see the real data and how to do that because this is an array we need to add this brackets square brackets and this Arrow if I now again fetch this data you will see that now that the tag tags field which is a reference field is resolved and we are able to see all the data from here so this is great okay let's do this in our front end but one thing let's say we don't need this this and so on we need only a couple of fields so I can extend that I can create return an object with fields that we need so we need ID we need a slug and we need a name so let me fetch this again perfect current slug ID slug name excellent so I will only just copy this here and go back to our code go back to our page and I will add this here down below okay let's save it and now we should have access to our tags in our post so I'll go down there I'll add some comment here so this is where the tags go I'll create a div inside div we'll Loop through our tags so we first need to go to post then tags and then map this will be a tag which will return span actually yep and span will have tag do name and before this I want to add this sign and we need to add key for this so tag. ID nice let's check this out okay we're now seeing all our tags we need to address styling a bit but that's it let's go here and here and add some class names first I want some margin on the right some padding I want I want r rounded borders text small yep and everything should be lowercased we need to add some background here when it's a dark mode I want background to be gray this dark gray also I want to add a border here border and dark border should be this light bit lighter version okay let's see this now nice okay in light mode everything works perfectly so we can now start creating our single page in our application now before creating a new single page I want to go back to our main page and type down below export const PR validate and let's say 60 this is a very important step and naming is also very important it's crucial so what does this mean this means that nextjs automatically does the caching for us so if you do not do this and deploy your application when you for example add a new blog post in your sanity CMS and publish it it will need a long time to actually fetch again that post and for you to see it in your application because the cashing and that's perfect thing but with this here we are actually saying to our nextjs application sure let's do the caching but please revalidate I mean refetch again all the data in 60 seconds so for example we are on our main page and we are getting our blog posts we are moving around that's all everything happening with that initial fetch that cach date so we don't do not spend any more resources on fetching it again but when the 16 seconds have passed and we reload the page we will make initial fetch okay so I hope that uh makes sense now when I go back to our post component I told you earlier that our path here for that single page will be posts and then the slug so we need to create a a dynamic route and how to do that well in our client here let me just quickly yep that's okay now we need to create a new folder with the name of posts okay inside of it we need to create a new folder with this square brackets notation and we will call it slug I mean you could call it whatever you want I can write here test or whatever but it's important for now to be slug before because this page will be gener erated based upon our slack here so now enter but okay this is wrong this is not file this need to be a folder slug okay and inside our slug we need to create a file which is called page. TSX again this is very important naming convention is like this so you must name it like I did it here okay we'll create a basic structure here okay perfect so now we are ready to implement our page let me just quick go here and let us immediately import our header here header yeah now we need to pass Title Here which will be for now Dynamic page okay now if I go back to our post and I go here you'll see that this will link us to our Dynamic page now we need to find a way to fetch the data and display it here again so how to do that well you see we have these post posts and the here URL is actually a slug so all we need to do is go to our sanity here and update a bit this and how to do that well first we are going to add this one condition with and end and we need to check our slug if so give me back all the documents with a type of post and the document which has slug so slug do current is equal equal to actually a document name so I will only just copy here and paste it over here okay now Fetch and yeah here we got our desired item so that's the similar thing which we are going to do now we our application okay uh have in mind in order to test this you can in this playground you can add variables and this is the right way to do so I will add variable Slug and I will paste this here okay and now all I need to do is to remove this and add a dollar sign slug if I fetch this I will see this again so now what we need to do is to paste this copy this and paste into our code over here so let's create an as function like before Asing function the name will be get post okay uh we'll have receive slug with a type of string perfect now let's do the same thing we need to Define our query con query is equal to back TI and I will paste the code from our sanity okay but now we need this slug to actually be this variable and how to do that well it's quite simple we only need to remove this add strings here that's important part and dynamically insert this variable okay this should do the work now we'll store this query into a variable post it is equal to await client from sanity that's right sorry Fetch and pass pass here our query perfect last thing of course return our post nice okay now we are going to our compon component and we are going to call a function let's say post which is equal to await and get post from above this is await so this component it needs to be an async function so here async perfect now if we hover over yes we need to actually pass a slack and how we can get the slug well from the parameters in our nextjs application we can call here perams and this will need to have a type of perams okay and the pams I'll add a custom interface over there interface prams Okay so params will be an object with a slug of string and if you're wondering how do I know that well if you actually cons the log here this let me just show you perams perams yep oh sorry I misspelled this and if I conso here you will see all the params yeah it's actually an xjs thing so every route has its own params and params are basically an object which have slug inside of it so now all we have to do is to pass to our function these pams so perams do Slug and we we can now safely conso log the [Music] post and yep that's the one nice one thing this is an array so this here returns an array we are certain definitely that we'll have only one post by the slug so it is safe here to add return me first of array okay so now we'll get an object which is much easier to manipulate in our case here now let's start implementing some Styles here first this won't be Title Here will not be any more Dynamic P page but post again we don't use use effect because this is everything server component and we can directly manipulate the data here so post. title okay one thing if you noticed the code does not recognize recognize the type of the post and we need to assign that first so here I will import our post from utils interface and that's all now we can see a title here if I go back click here we'll get this perfect let's move on below the header I will add a [Music] div which will have only one class name and that is text Center then I want to add a span here yep which will be post publish that but we don't want to use it like this we want to to format this date immediately so like earlier we're going to use a JavaScript function new date paste it here and of course apply method to date string perfect now let's some some classes here let's go class name and if you remember correctly from our post component we imported this font here I will do the same here so whatever oops sorry for this paste now we only need to import this font yeah that's perfect going back here and some back ticks and we'll type date font right date font class name and of course this text purple 500 and if you now save yeah this is what we need great moving on we'll here add another div and that div we'll have a class name of margin mt5 so margin top five and we want to display all the tags from this post of course we are going to go to the to our post then tags have and map through tags okay now return a link I want user to be able to click on this and to go to our tag page which will be creating shortly okay this is a key so tag. ID and we need also a h which will go to page under the folder tag and of course our tag. slug do current same stuff as earlier now we are closing our link and inside link we can add span which will hold same way like before tag. name okay let's go back perfect We'll add some Styles here a bit just a reminder we are a we were able to look through all these tags because we resolved this field okay now let's add some classes I mean class names let's go with margin right actually you know guys you know what I'm going to go to the let me just see where yeah this one basically these are the same class classes we can later create the component for for the tag but for now on this is this is fine okay save yeah this looks very very good let's find some tag with a multiple some blog post with multiple tags yep that's the one perfect now I think we are ready to go and create actually a body of our blog post now before creating a re text element first need to go to our sanity and add a new library so just go to your browser and start typing sanity text to react okay so this is the one partable text to react and if we go down there we'll see sorry we'll see a documentation so just copy this command go to your code I will kill this terminal and paste this command okay now we can mpm runev again Perfect all right now I'll space this up and we can now import our component portable text right this is a self-closing component which needs to receive some props first is actually HTML that needs to be rendered so value and it will be a post do body if we save now here and go to our next application reload the page we should be able to see our data let me just go back click here and hard refresh it what's going on here oh yeah we need to yeah we have a we have a problem here we forgot to add a body here so if I go back here and type body and fetch it yeah you can see it so now I want only to add this here in our query our post already I think it knows that yeah it has body so if I now save and go back to our application here we can see our body okay this is perfect now first things first we need to do a bit of styling here and there are a couple ways to do that but in my opinion the easiest way is to wrap everything with a div like here and move it up and we want to add a class name here for this div which will be a variable called Rich Text Styles yeah I think this is this is okay and I'll go down below and create that variable let me just copy it and paste it here and same as earlier this will be the back TI with some Tailwind classes so margin top text justify Max width to excel then margin order save okay this looks better but now we need to use this Pros class so what does this do Pros like I mentioned to you earlier in the beginning of the video it help us with styling of a each text content so in the Tailwind you can add Pros Dash and then let's say heading we'll add MI5 okay then again Pros let's say sorry this is headings these are headings because we want to Target every heading and not specifically H1 two or five or so on so on so headings and this will be text to excel so we want the large text for this Pros I want all paragraphs to have a margin bottom of five and also I want to add a class of Pros P leading which is basically a line height class in Tailwind let's save okay looks good but if you remember this is all uh list item these are list items so we can do that in Tailwind also with this Pros class Pros list L item so Ali colon list dis yep that looks good also class for line height and lastly Pros last least item some margin left let's say four okay this looks very good now but now if you see some of our posts have images I think this one should have an image nope maybe this one yeah this one so mastering JavaScript let's check that out mastering mastering here here you are but as you can see we don't see any image here and why so because we need to add a bit of code to fix this okay first things first images are component so we have a possibility to add a prop here to our portable text let me just fix this a bit okay this looks good okay so we have components prop and we can pass our components which we can style so this is where the image needs to go I think we if we go back here to our documentation yep you can see this this is perfect example of what we need so I will just copy here this and I want to paste it down below so I don't need this marks I only need an image here okay uh for now for now we'll just to remove this type errors we'll add this here and yep I think this is this is okay yeah we don't need this call to action also I will remove it image is fine but we want to use an image from next did we import here nope let me just do that real quickly yeah from next image and for the source we need to remove this and if you remember when we started this video I showed you here in sanity lib image TS file so we need to use this function they gave us that that's basically a function that help us get images from sanity okay so here I'm going to type URL for image nice and I will pass a value here so that's source for our image do URL besides that we need to add alt tag let's say for now just post okay we need to add a width to next image and also a height let's say 700 pixels and I think we are good to go with here let me just prettier yep and in this components prop I'm going to pass this my portable text components so if you want to style anything else you can also add it here okay let's go back okay now we have this error that this is a common error in our nextjs applications because we need to add something to our next config files here we need to add basically a domains so the next application knows that they are our images so not any third party images and to help to fix that we need to go to copy this CDN sanity iio so this is where the images are hosted for sanity and go back to our next config file so in earlier versions you would have something you would have uh prop here called all think domains and that domains were an array and then you just paste all your uh domains where the images are hosted but in this new versions of nextjs specifically version 14 it's a bit different so we need to go here images and add remote patterns this is an array of objects and uh first and actually only our image provider is sanity IO so I will add a protocol and the protocol will be https okay and the host name is this thing I pasted I copied here from our error so CDN this is https CDN sanity iio is where our images are hosted so now our nextjs application knows that these images are safe it is recommended to kill the terminal restart server and run it over if we go back to our application and reload page we should see our image yep here is it okay I think we are all set up so our page our blog is already looking really really really good so now next step is to create a page for our tags now moving on to our code I will close all these tabs here put down this a bit remove this and okay perfect let's go to our client and create a new folder called tag okay inside of it we want to create two things first is new page new file called page TSX and the second thing is a new folder same like here in posts so in square brackets we are typing Slug and inside that slug folder we are creating a new page. TSX okay perfect now I will close this Slug and go to our page so tags tags page page let's go here RFC and this will be our tag page but I don't want here this to be a plural I want to be this one so we can access it by tag SL JavaScript tag SL react and so on and so on okay let me just go here command shift p and restart extension host okay this is good moving on this will be tags let's see if that is working so go here and tag perfect okay now what we need to do here well we can go to our sanity and quickly go to Vision remove this and quickly type another query so if it's similar like post but we need to fetch all type of tag if I fetch it we can see everything but of course I want to reduce this to only fields that we actually need so that's name that's a slug and that's the idid for now later on we will need one more field that we will create additionally but for now this is fine so now I can copy this and go to my code and create a new async function which will be called get all tags we do not need any parameters here and const query just as usual and inside our back tick we are pasting our query perfect below that just go and type const tags it's a variable for storing our actual data from CMS so client fetch query same thing as on posts then last thing return these tags perfect now if you remember we want to add a revalidate constant which will be also 60 don't forget to export it okay we are good to go now we'll go down there this will need to be an async component Asing function because we need to await our response here so tags it is equal to await get all Texs and and this we need to assign an interface sorry we need to assign a type here so that will be a tag from not here but this from utils interface which is an array of tags this is an interface we created uh earlier here this one okay moving on now I only want to console log it tag tags okay perfect we can see all the tags here now all we have to do is in our component import Navar which will have a title was this a title let me just check in quick components header title y that's the one so title will be tax I'm not sure what's going on here maybe it's in wrong input let me just do that over let's go back to our posts post page and see no it's not Navar it's heer yeah okay so we need to import our header here header that's right which has a title of TX perfect let's save and yep there we go all right now let's go down there create div and we only need to look through all these tags so tag if their length length is more than zero so basically we have tags then map through them so this will be a link from nextjs we need to assign a first key here that would be a tag do ID and we need to assign an H ra so the route route will be in back uh tag okay and our slug basically here so we can get our slug from tag tag slug current now we're going to create a div and inside this div we can actually place our tags so tag Dot name that's for now okay we can add some styling while we are here so I want to add this class name here some margin bottom some padding text small yep that's good everything lowercased in a dark mode we want BG Gray 950 yeah I think that's okay we also want a border on dark we want border to be let's say gray sorry B gray 950 or 900 yep and on Hover we want text to be purple 500 okay let's save this yep I think this looks all right just to see yeah this is not good I want this to be I misspelled this sorry border yeah now it's okay okay perfect so now when we click we have ability to go to the single page which we did not create still but okay we are working on it next thing we need to create this page so this is okay now this page will also have a header and with a title for now we'll hard code this title let's say that this will be posts per tag okay so idea behind this page is to when you go here for example on article and click AI it will lead us to the page where we'll have all the block posts with that tag inside of it so basically like a filtering system some something like that similar if if we go to all tags let's say tag and we click here we want the same thing let me just quick see if this is working yeah this is working okay now we need to query our CMS our sanity in order to get all the posts per TS all right now so this type of query is a bit more complex than a previous once and why so so let me just quickly demonstrate it here for you okay now you would maybe think that this is an okay option here so yeah we are getting all posts and what posts where well all the post that have tags. current SL JavaScript okay let's fetch it and unfortunately no that's not the case what we need to do is use something new now let me show you so I will delete here and I will type here references that's basically a function that can reference a type of field that is type of reference so this function it can receive a two parameters first one is the field that we want to reference and the second one would be ID of that field also we have an short way to do that simply we are best in ID of the reference field we want to actually reference right okay so how to do that well first we need to get the ID let me comment this out and we'll uncomment this and fetch it so we are now looking here for the searching for the JavaScript yes that's the one and we need to do all we need to do is take this ID okay now if I comment this again and comment this out I will only need to pass here this ID so fetch and yeah that's the one we have two posts with this ID with JavaScript tag in it okay excellent so now we have two options first option is to basically create a two queries and the second one which I'll go with is to do everything in one query so how to do that let me just go here and I'll type it like this so we first need a type that is equal to post so we need post okay what post do we need well we need a post that references and what does this post reference well this post reference tag with specific ID how we can write that well we can do another query here yep that's the one type equals to tag in that tag slug do current needs to be I will hard code this value for now for example JavaScript and all we need from this it's actually ID so do ID okay I think we can try this out okay I misspelled this reference okay let me try now again and yeah it's working now we need to do is actually instead of referencing this hard coded value we need to add a dynamic one so I will remove this from previous example and let's say this will be a tag with something like JavaScript okay and now all we need to do is reference it [Music] here okay F data sorry I again misspelled this and now F data everything works fine so I will now copy this let me just expand it a bit for you to see it better okay copy and they'll go back to our page so now let's create this function this will be an async function get post by tag all right inside we'll create query which will be equal to this one this one I copied earlier all okay now we need to do here this will be a tag of the type string exactly and only thing left to do is to pass dynamically this tag here so I will remove this I will add this and inside we need to pass our variable tag so this is it okay now if I save this I can return it to our variable let's say posts it is equal to await our client from sanity yes that's the one do Fetch and we are only passing our where here okay perfect and now we can return this posts okay this is great now we are down here here to our main page of course this needs to be async in order to process this this function here so const posts is equal to await get posts by T yeah perfect okay first things first this we need to to add a type for this and that will be array of our interface post perfect and now we need to pass an argument here so what are we going to do well we need to extract parameters from our URL how to do that well perams it will have a type of perams perfect now we can just copy paste this params from our previous component and this was post here exactly the same thing okay and now all we have to do is pass here params do slug perfect let's save and now we can conso log this okay now let's go to our page let's say JavaScript okay check our console yeah that's it we got it we got the post here okay this is perfect now of course I don't want to receive everything I want to receive only fields that I need so what we can do is just go to our main page when we got all the posts because basically this is the same query only with some filters and I will just copy this object here okay we don't need this here and just paste it let me now save this okay now we have a more I think a bit better optimized version of our query perfect now let's jump to coding and create our page here let me just pull this down okay first things first we we'll remove this title from this page and we'll need to add a dynamic one now I will only add back tis this and I will dynamically add perams do slug so we are aware on which page we are so is Javascript react or any any other slug actually a tag okay moving on below that one div and we will Loop through all the posts so posts if actually we have posts then go through [Music] them okay and now what we need to return well luckily we created our post component so we can return that this it needs to receive a post prop which is equal to post and of course since we are mapping it looping through it we need to add a key property that would be post. ID and yeah I think we are all good perfect the page is working let's go back let's go here perfect this everything looks perfect okay now I think something is missing I want to be able for example from this page to I want to be able to go to page where all tags are displayed so I want to add it here so let me just think through this okay this is a header component so maybe we can add another prop to this header component right let's say if we pass if this header component has tags let me just tags this will be an oppos optional parameter so by default it will be false okay tags so by default false ohop sorry this is false this is Boolean this is type okay and now we can go down there below this so if tags if this is true then we can render a div which will have a link inside of it which will go to slash T okay and inside of it we'll only add this string text so just let me apply a few classes here okay this is good hover let's say text purple okay save and if I go back let me reload the page no we did not add that prop so this header is imported here and we only need to pass a prop text which is true okay now we can see this and if I click it we'll go back to our page okay this is perfect I think we can also add it here for example but yeah you can do that all right this is good this is good okay now I want to have uh ability to see for example we I want to add brackets here and in brackets I want to display a number of posts per this tag so for example 1 two zero and so on so let's jump into it let's jump back to our code and as you can see we already have most mostly everything in this page what we need to do is somehow get here a number of tags of post per right so how to do that okay I will copy this this query and go back to our uh sanity vision and paste it here okay if I fetch I'll get all the text right let me remove this we don't need that fetch okay I think it's now more convenient for us now we can add a custom tag here let's say that will be post count right as you noticed it's under the strings so now we can here just type a number Fetch and yeah that's it but we don't want to hard code this of course we want to to somehow count posts so in gro we have keyword for that it is Count okay and what we want to count well we want to count type that is equal to post right so type equal post okay but now as you can see in every tag we are counting every post we have in our database so we we don't want to do that we want to use again field called reference okay actually function Cod reference so here I'll type and end references and what do we need to reference well we need to reference tags here right so these are the tags for this specific post and now we need to get if you remember ID from the tag but now we have a bit different situation so we are referencing we are direct directly in this specific tag right so there's a sign we can use here in Gro and that's the carrot sign roof sign so on my Mac is on shift plus 6 I'm not sure though on Windows machine probably the same and then this is actually this tag we are in so react flatter featured and so on and so on so we can now access their's ID by only typing dot ID if now fetch this I will see this so in Firebase we have one Post in JavaScript we have two posts and so on and so on okay that's perfect I think now we can paste this into our code actually we don't we yeah yeah we we only need this since we already have this query here okay so just paste it here and I think we're good to go okay maybe when one more thing we need to update our types or interfaces to be more precise let me just go there and this is under the tag so we can add post count and that's a number okay moving on if I now go back to our page we don't need need this anymore so here I'm able to access this here so how to do that well simply by adding it into brackets and just type tag. post count right let's see perfect everything works perfect all right and I think we are pretty much finished here with our project let me just do the final touchups as I mentioned earlier I I want this on main page to have a prop for the for tags yep so if you remember that's this here in our header component so I'll go to our main page which is here and all I have to do is say this so now the text will be visible from here that's perfect and the last thing I want to do is okay just imagine you're you have this post here and after some time you decide to delete it so I won't be deleting it now but I will just type here something which does not exist and I press enter and what we got is this what we want to render here is a 40 four page and let me now just show it quickly how to do that in next so now I'm back at my visual studio and I'll go quickly here to my client and post so not slug but post folder and create a new file which will be called not found. TSX so this is really important the naming convention so it must be named exactly like this okay now we're going to create a component let's say not found page okay this is export default and this here we need to return a div okay inside of it we'll only add n Bar sorry we'll inside of it we'll only add we'll only add a header component with a a title of something [Music] like 404 page not found okay and now down there another div with a link inside of it which will be something like return home okay and this link will lead us to homepage okay perfect so this is first step if you now go back and try to uh delete this it will still get us this page right because we need to do something else something more when do we want to trigger this function so this component when do we want to render it well when there's no post right so we need to go to our Slug and this page under the slug go up there and import something from next so [Music] from next navigation and that's it that's not found function now we go down there and right before returning this component this page we want to check if there is a post so if there is no post we then want to call this not found function so now if I go back and I remove some letters from here it will lead us back to not found page so we can go back home and that's it the important thing is that we invoke this function here in our page so if you want to do that for the tag you would you would need to do that also over there okay I think we are pretty much done with our project and we can now deploy it to our so but before that I almost forgot we did not add to every hour query here revalidation so we are here in our slug so I will I will add export const revalidate which will be equal to 60 let's go to our tag here check the slug here yep we also need to add it here let me just copy and paste this copy here from that and paste it here let me see here this is fine yep I think we are pretty much good to go all right let me go quickly here to my GitHub and create a new repository I think this name is fine it will be public no description for now okay create Repository okay now we need to go back to our code and follow these instructions so let me just check first what we got here okay we need to add everything now we can commit it let's say final project okay get status I think this is all fine now we'll follow the steps so get Branch it's main perfect now we need to connect our remote remote repository great and now just push to our main branch okay this is perfect now if I reload the page we can see everything here working perfect now let's go to our cell if you don't have an account it's easy to create now I need to go here just import down our repository and of course before deploying we need to add our uh environment variables just just let me go quickly here to envs no this but this local copy it and paste it over here okay I think this is perfect and we can deploy it we'll probably need to wait around a minute or so and I'll get back to you okay friends funny thing I forgot completely to push everything we did so let me go back to our code uh yeah so deployment is done but as you can see we have this basic nextjs template so now we need just to push everything here I'll just um say something like compete project and commit it okay so this will trigger uh our main brch for for GitHub and it will start to deploy it here so now we need to wait as you can see building you can follow this here in deployments and I'll get back to you as soon as possible and finally here we are okay let's visit our page we'll go here and perfect everything works fine okay we can visit page we can go tags we can visit all the tags here nice light mode yep dark mode perfect let's go to our studio okay final thing we need just to press here continue as we did same here and at the start of our project now we need to add our URL as a course origin also when you add your own domain for this project for example you would need to do the same thing so just go continue add course origin comeb back and finally we are all set and ready you can see here are our post you can add a new one and when you add you can just here publish it and that's it so thank you guys once again and see you again in my next video bye-bye
Info
Channel: Codewalk Empire
Views: 1,557
Rating: undefined out of 5
Keywords: Blog, Build Blog, Build blog with next js 14, Nextjs with app router, Blog with tags, Embed sanity to next js, Deploy sanity on vercel, Blog with CMS, Next js and sanity layout, Learn next js 14, Blog Tutorial, Next js 14 tutorial, Modern Blog with Next js, Blog with dark mode
Id: yAqgjSZ0PqY
Channel Id: undefined
Length: 151min 34sec (9094 seconds)
Published: Wed Dec 06 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.