Build a Next.js 14 Blog | React, Sanity.io, Tailwind.css, Shadcn/Ui

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so you want to create a block using NEX shares 14 incorporating the newest Technologies well you have come to the right video because that's exactly what we'll build today so in this video we'll build a block as I already said using NEX S14 and the app router not the pages router then we will store our content in sanity iio which is in headless CMS using the quo query language then of course we will style our application using TN CSS and shats in UI which offers accessible and styled components and of course we will also make dark Mode work because what is a modern website without dark mode and the nice thing is that the dark mode theme preference is stored in local storage so when the user refreshes the page the theme preference is still kept so that's very cool and now let's check out the demo behind me and I hope you enjoy this video and now let's go so now on my screen you see what we'll build today so this is the blog page as you see on the the top we have the Navar with the logo and the theme switcher I can right here choose for example the light theme and you see the background color changes and everything else also changes if I now reload the page you will see that the theme preference is kept persistent and we don't see any flash I can now click on a block article so let me click on this right here I click on the button and you see we get redirected to the block route so right here you see now the title a little heading the image and the content we also right here use the Teran CSS typography plugin that's why you see that it's styled very nicely and for example this bullet list has blue bullets so that's exactly what you bu today now you see right here that this page is very quick that's because this page is of course cached and we use revalidate TXS to revalidate our page our content comes from sanity and everything works and will also be deployed I hope now you enjoy this video you learn a lot and now let's go so to get started I will CD into my desktop directory CD into my YouTube directory and everyone npx cr- next- apppp at latest to install the latest package of next shars the CI will now ask me a few questions so first of all we will name our application um let's say nextjs block then we will use typescript we will use eant we will use tant we won't use the source directory but we will use the app router and we won't customize the default imp import Alias and now the installation will take a bit so let's wait for that so now the CLI has now finally installed NEX shs 14 successfully so now we can go to visual studio code and open the project so now you see I already opened the project in Visual Studio code and if you want to do the same you can go on top file and then click on open folder but now right here we have just the default template that the CLI installs for us and if you for example go inside of the app folder and inside of the patot TSX this is for now our default um index page we can actually test out and see how it looks by opening our terminal you can either use command J or go on top click on Terminal and new terminal but inside of here let me run npm1 def to start our def server on Locos 3000 so let me open that in Chrome so I have now opened Chrome on Locos 3000 let me zoom in a bit for you guys because that's probably a bit zoomed out for you but again what's that that's the default template that our CLI has installed for us and that's the default index page in that sense now of course we won't leave it like that we will showcase our block with the individual blog posts uh on which we'll click on later but for now what do we do there are two options that we can start with either we create the UI so what we see as a user on our screen or we create the backend logic using our CMS which in that case is sanity and I personally think we should start with the back end so that we can uh automatically connect our front end to the back end and with that it will be much easier to create the UI so for now let's head over to sanity our CMS so I'm now at sanity.io and sanity.io is actually an headless CMS where we will store our content and now you can use sanity for multiple of things for example as already said a blog post or and that's a Blog website a e-commerce store or actually anything where you want to store your content and now I will use sanity because I actually really like the query layer and there are multiple other Alternatives like for example build.io or I don't know strappy or um anything else but in my opinion sanity.io is very nice to use uh pretty cheap they have a generous free tier and that's why we'll use sanity but now to get started let me click on developers documentation and then right here we have the getting started tab let me again zoom in a bit now let's scroll down a bit right here create project first of all and now if we zo uh scroll down a bit the first step is to install sity studio and that's exactly what we'll do right now so let me copy this CI command let's go back let me stop my def server actually and then let me clear it and paste the command now what exactly do we do right here well we install a new sanity um Studio project in that sense or we create a new sanity studio so right here we choose a uh clean template you can of course use already a predefined template but then again what would we learn if we would use an a predefined template so let's use a clean template then we create a project we give it the name of Sanity project and we use a data set of production one thing I will change is the name I don't want it to name it um I don't want to name it sanity project but I want to name it let's say next shares 14 block I think that's a better name let me now click enter and now it will uh ask me to install the newest package let me actually do that this will take a second so now you see right here the C tells me I have already an account with sanity.io and it's also linked to my project right here or to visual studio code in that sense um if you get an error right here that probably means that you either a don't have an account with sanity or your account is not linked with um your uh I guess workspace in that sense uh if it's this case just follow the instructions it's very basic and you should be up and running in a few minutes but now for the first question if you would like to add configuration files in our nextjs folder no I don't want to do that so let me click on N then for our project path I will uh say sanity and then I will use typescript of course and then the last thing is what package manager do we want to use and that's of course npm so let me click enter and this will now take a bit so let's wait for that so so the CLI has now finally installed sanity so what does that mean we have now created a new folder which is the sanity folder right here with a lot of files they're not very important for now all we actually need is the schemas folder so for now let's actually go back to the doc right here let me click on create a schema and right here you will see what is the sanity Studio again I would highly suggest you guys to read through it uh if you don't really know what sanity is what sanity studio is and what the whole concept is but again for now let's skip that right here you see the file layout and that's also exactly what we have that's the file layout the only difference right here is that we use UMTS ending and not ajs ending and that's because we use a typescript um project right now then if we scroll down a bit further right here you will see how we create a schema and as you see it's quite simple you create a export default object and then you give it a name a type and a title now the important thing is the name is always lowercase why is that that's because you will actually query by this name so I would suggest you guys to make it as simple as you can and don't over complicate it then for the type it's always a document why because you create a new document a new schema then for the title you can actually do whatever you want right here they just uppercase pet but you could also say um this is the title for pet whatever you want because that's what will show up in your sanity Studio and then we'll have a Fields aray with multiple objects with the fields which you want to use so for us it would be for example a title a little slug a hero image or a title image however you want to name it then the content Etc so that's actually what you do as you see it's quite simple so now let's actually imitate that and do the same in our project so let's actually right here go inside of our schemas folder and let me create a new file called block TS now inside of this block. TS we will do the same as here so let's get started what we have to do is an export default this is an object and as I already said we have now to give it a name for the name I will just do a lowercase block then for the type this will be of course document since I want to create a new document and then for the title let me just say uppercased block so that looks good now we'll have to create a Fields array with individual objects or individual Fields so now let's first of all start with the title because each block of course has an title let's give it a name this will just be title then let's give it in type and the type of course will be string because a title is a string and not a number and then we'll have a title and for the title I will just say title of block article something like that now the next field I want to create is the slug why do we need the slug well that's because I will actually later on uh use this slck as a unique identifier that means later on our URL will actually uh host our Slug and that's actually better than to use the ID why is that well that's because of SEO purposes so now let me give it a name so the name will be slug then the type will actually also be a slug not a string and let's also give it an title and let's say slug uh of your block art icle and I think that's fine let's give it another field and let's say what else do we need we have an title we have an slug how about a title image because what I want to do is uh have inside of my block cards always a title image so let's give it a name now for the name let's just say title image and then let's give it in type the type will just be image and then for the title let's say um I don't know title image I think that's fine so now we have in title A SL a title image let's also create a small description so let's give it a name this will be small description then let's give it in type the type will now be not string but text so let's do text and for the title let's just say small description so now what's another important thing well of course the most important thing is the blog article itself so the cont content and for now we haven't created that so let's actually create a new field and now for this let's give it a name I will say content now the next property which we need is the type and now the type is interesting since I will actually give it in type of array and I will give it in title and for the title let's just say content uppercase now the interesting thing is I gave it a type of array and S sanity now assumes that this field content is an array that's of course not what I want I want to get in text editor and to make it work I will have to tell sanity what type of array we want to use so let's right here use a uh a new property which is off this is an array with one object and right here we'll have an type which will be block so now we actually created an type array for our field which has actually a type off block so our wi text editor should now actually work and to see it let's actually see our sanity Studio on the web to do that let's open our terminal again either command Jay or on top on Terminal and new terminal but uh inside of here let me first of all clear a and then let's do CD in our sanity folder so right here our sanity folder and now inside of here I can do npm 1 def to start our sanity def server as you will now see this will open a low close 3,333 so let me open that in Chrome so I'm now on locost 3333 the important thing things right here you should choose the lockin provider which you have used to create your sanity account at the sanity.io website so for me it was GitHub that's why I will use GitHub right here so now you see I'm in the sanity Studio dashboard and what's one thing that we currently see it tells me a warning right here no document types please define at least one document type in your schema so what's exactly the problem because at the end of the day what have we done right here we have created a schema but it doesn't not show up right here well the problem is right here inside of our index .ts file in our schemas we have to actually Define or uh actually import our block schema so right here we have exp so right here we export a empty array right now which is called schema types and inside of this array we have to Define each schema which we use so right here we can now Define actually our block schema so let me just say block and let me import that from do/ block if I now save that and go back you see it reloads automatically and now I get an error right here and it tells me unknown type document did you mean document so the error I made is I misspelled document pretty silly mistake of me so let me actually copy the actual name let's go back to the block schema and let me actually rename it to the correct uh spelling so if I now go back and actually click on block right here and create a new block right here with the plus icon you now see everything need we have an title we have an slug a title image a small description and our content which is a rich text editor so right here I can actually uh use the headings H2 H1 H3 I can do an underline or italic or bolt whatever I want so you see that works now there's one thing I don't like right here currently and that's our slug so the problem I have right here is actually that I have to man uh manually uh type my slug I don't want to do that I want the slug to actually um be generated automatically on the fly so how do you do that it's quite simple right here we have our SLU field and what we can do now is actually add an options property which is an object and give it in source and what's the source we want to use well we want to use the title so what I mean with that is I want to generate this lock based on my title if I now go back and save that actually you'll now see it reloads and in a second we should right here see a generate button so if I now create a title so let's say um hey from this video I hope you like it and if I now click on generate you actually see this slug right here automatically generated and the nice thing is for each space right here we use and dash so this works perfectly so now what I think we should do is actually create a few block articles and then later on we will fetch it from our font end and create the UI corresponding to our schema so let's now create a bit of content and for the content what I want you to do is go to my GitHub actually repository and there you will see all of the uh blog articles um actually markdown you can just copy them and paste them inside of here so you don't have to create anything by yourself but again if you want to create uh the blog articles by yourself with chat GPT or or whatever you want so now let me create about three or four uh block articles and then I will come back back so as you see now on my screen in total I have now created four block articles and as you see I've created right here the title the slack a title image the small description and the content with a bit of H2 text and then a bit of uh normal PEX and now there's one important thing you should uh do right now and that's check that everything is published if it's not published you will see right here on the right uh yellow I guess I don't know um uh icon for a pen and that means that your edit is not published so please make sure that everything is published with the screen icon and no yellow icon and then you should be uh good to go so now I think what we should do actually is create the UI and then actually cont uh connect to our backend to sanity fetch the content show the content and then we are finally done so let's head over to visual studio code so I'm now back at Visual Studio code and let's go in the app folder in inside of the page. ESX and as I already said that's now our default index page which was shipped with our default template so what I want to do now is first of all again start our def server for that right here in our terminal we have this plus icon to create a new terminal and then inside of here I can do npm run def to start a new def server this will open on local 3000 so let me go to Chrome and open that so now you see our def server is finally again running so what I want to do now is delete this default template I don't like it I don't need it I don't want it so let me delete everything inside of the return statement right here and what I will do is return a diff element and a H1 and let's say hello from the index page let's see if that works and we see right here a hello from the index page now there's currently one thing you see and that's the background is black and the foreground is white um that's fine but in Fury in a um normal application this wouldn't happen what would happen is that we would have a white background with a black foreground so with a black text and why does this happen right here that's because if you go to global. CSS so the CSS file you will see a bit of style right here again this was created while um downloading the um default template and we don't need it so I will delete everything but leave all of these at tent classes so just leave this at tent classes and delete everything else because we don't need it if I now save it and go back you now see we have the back uh white background with the black foreground that looks very nice in my opinion so now what's the first thing we do I think the first thing we should actually do is create the naft bar and then inside of the Naf bar we'll have two things first of all of course a logo because why not and the second thing which is more important is the theme switcher so the button with which we switch between the back uh the black background and the white black uh background so let's Implement that now to do that that's actually quite simple there are two uh ways you could do that either you would write uh just write the code right here inside of our page. TSX which is fine you can do that but what I will do actually is break it up into a component into a separate component because I just think it's a cleaner look so inside of the app folder let me create a new components folder and then inside of the components folder I will create a navb bar. TSX file now why do we use a TSX X not the jsx well that's because we have a typescript um project as you know so now let's actually start with an export default function let's give it a name of nav bar and then let me just open our uh function right here now let me create a return statement actually and then right here let's just uh for now say a nav element and then inside of here H1 and let's say hello from the Navar just to see if it works if I now go back you see see nothing why is that well that's because our component right here is currently not um imported anywhere right now it's just an file which is not um connected to anything so what I want to do is go back to my page. ESX which is the index page and then just import that right here so let me import Navar this is imported from our components and if I now save that and go back you now see hello from the Navar and hello from the index page so this works very nice let's now again go back and let's now actually style our nav bar let me first of all start right here with the nav element let's give it a class name of w full let's do a relative class let's do Flex items which will be Center and justify which will be between now why do you use justify between or uh what exactly actually means justify between well you can think it like that so our nav element is currently our um I guess parent element if I would now create two diff elements Childs so diff and diff and in each one let's say H1 um child one and then inside of here H1 Child 2 and if I now save that and actually go back what you would see now is right here child one and child two so what does exactly justify between mean it just pushes both Childs to the uh most outer screen so to the left corner and to the right corner as you see right here now there's one thing I don't like currently you you see that both Childs actually um I guess I don't know touch the uh end of the screen so they touch the screen B I don't like that I want to of course have some padding and also in a block I of course want to have a smaller width now how do I create that well it's actually quite simple I will have to give it a Max width so let's first of all give it a Max width and then now you can choose any value so you have 2 XL 3 XL etc etc you see right here also the corresponding pixel size and um let's actually see how 2XL looks like let's go back and yeah that looks fine but now one thing you see is that it's not centered so our child one touches the border of the screen but our child two does not so let's do an MX of Auto let's see yeah that looks better um let's also do a padding X of uh four I guess and a padding y of five and yeah I think that looks fine let's go back yeah that's uh looks quite nice uh let me now delete the the two uh diff child elements I don't need them anymore let's now create a link component and now what's exactly is the link component first of all it's imported from next SL link and it's actually quite uh the equivalent to the ACH so the normal ACH that you know from HTML the only difference is actually that it uses client side navigation and prefetching and a bit of other stuff um the tldr of that is we use the link component because we don't want to refresh our page and we want to have the bonus of prefetching with the AAG what we'll get is that we'll have a full page refresh and I see that as a not good ux practice and I actually like um client side navigation and that's why we'll use the link component so let's give it an hre and this will just be the normal slash and then let's name it Marshall um let's use a span and let's say block then let me style the link component so let's give it a class name this will be font of bold and text which will be 3 XL let's see how that looks yeah that looks quite all right let me also style the span right here and let me give it a class name of text blue 500 let's go back yeah I actually quite like that so this looks now quite good and what I want to do now is create the theme switcher as you know now for the theme switcher I will actually use a component library and to be exact shaten UI so let me head over to shaten so I'm now at shat UI and if you didn't know shetsen UI is a component Library which was built on RX UI RX UI is an accessible non- styled component Library so Shian UI takes all the benefits of RX UI combines them with styling and creates a beautiful component Library so that's why we will use shaten UI in this project I will now right here click on documentation installation for the framework will of course use nextjs then right here we have in quick start guide and the first step is to create a project we already created a project so the second step is to run the CLI so let me copy that we'll use npm of course let me open my terminal let me stop my def server let me clear everything and let me paste the C I command it will now ask me a few questions so do we want to use typescript sure and let's use the default style uh let's use slate as our base color uh our global. CSS file is in the correct directory then we'll use CSS variables why not now for the t. config.js that's a bit um wrong so if you check right here your Explorer you see we have a tonig dots and right here tells us .js and we use the typescript file so let me change that so let uh let me copy that and change the name to TS then our import Alias is correct and our import Alias for utils is also correct then it asks me right here if I use react server components of course because next sh is 14 and then let's write a configuration file and now this should actually Implement everything now you will see two things actually um first of all right here we have a components. Json file and if you go to package.json you will see that uh a few things have been installed so for example Tailwind CSS anime Tailwind uh merch C LSX and class variance Authority now that's just a few things that shats and you needs also an important thing is lucid react Lucid react is an um icon library and it's quite nice it's also what I use in my personal projects so it's quite nice that they use it right here but now let's go ahead go back actually and let's scroll down is there anything more interesting nope I don't think so one thing I could do now is actually install the button so let's search for a button and right here you will have a CLI command let me copy that actually let's go back back and let me paste it right here this will now just add our button or the component button and you can actually see that if you close everything go to the components folder you now have a button. TSX file so this looks quite nice in my opinion so now instead of using text blue 500 what I can actually use is text primary so that's the styling that comes from shaten UI and now instead of a red or I'm sorry instead of a blue color we now have a black color where does it come from well if you open global. CSS right here you have your CSS variables and we can actually change our theme so if I go back to shui click on themes right here I can use any theme so I will use right here this blue theme I can click on copy code let me click on copy let me go back let me delete everything right here everything inside of this layer base and paste what I've have copied and if I go back you now see I again see this blue color which is nice and the nice thing with shet and UI is that you now have actually a design system and you have a certain uh certain amount of equality in that sense so what do we do now we have now our H1 tag I think we should now actually create the dark mode switcher for that we going to have a nice actually um Doc Page right here so if you click on documentation click on dark mode and click on next shares it actually tells you how to implement uh Implement dark mode so first of all we have to install next themes and next themes is actually the package which helps you uh make dark Mode work so let me click right here on npm let's go back let me stop my def server right now let me clear everything and let me paste uh the installation Command right here so now you see next themes has been installed let's go back let's see what the next step is the next step is to create a theme provider so inside of your components let's create a new theme provider. TSX file so let me open my Explorer let's go inside of our app folder inside of our components folder and let me create this theme provider. TSX inside of here I can now just copy this code block right here paste that and this should actually look good now if I go back the next step is to wrap our uh root layout with our theme provider why is that well that's because our theme provider or in that sense our theme has to be passed to our children and uh be made I guess um Global um also one thing uh that is some important right here we use the use client uh directive why is that well if we wouldn't add that um next Shar would assume that this is in server component and with server components you can't use State why because state has to run on the client that's because uh that's why we have to mark this file as use client um so that next sh knows hey um this file needs client so let's hydrated on the client so now this looks good so let's go to our layout. TSX which is our layout and if I go back you now see that inside of our body element I have to wrap my children inside of the theme provider so let me first of all make a bit of space right here for uh our um theme provider and then let me copy this code right here so the theme provider code let me add it above the children and then let me uh close the theme provider right here and now we have to import that one important thing is don't import that from next- themes import that from your components if you import it from next themes you will get an error and you of course don't want that and now the last step that we have to do is actually add an mode to uh toggle so this button right here to switch between the themes and that's exactly what we'll do so let me open the code field right here and we will just copy this code actually so let me just copy that let's go back let's go to our Explorer inside of the app folder inside of the components and let's create emote toggle TSX now I can just paste this code actually now our Imports are uh incorrect so I will delete this uh import and then we'll need the drop down the drop- down menu trigger um so what we need is to install our drop down from shatan UI so let me go to documentation let's search for drop down menu right here that looks good I can now click on CLI to install it so let's click npm has open the terminal and install our drop- down menu so our drop- down menu has been now finally installed so now I can import all of the individual um items right here so the important thing now is it isn't imported from radex UI and because radex UI isn't styled so right here you should uh add the import from add components and do that for all of the items add components for drop down menu component also from our components then from our jum down menu item also from our components and and now everything has been imported and that looks nice what I can do now is go to our Navar component and then under the link component let me import our mode toggle. TSX so now let's go back let's go to our Local Host let me reload the page and we get an error why is that that's because our death server is not running so let me clear everything right now and let's do an npm one def to restart our def server on Locos 3000 so now my def server is finally running again and what do you see on the right side well you see the mode toggle button so I think we should test it out right let me click on it and now we have right here this options light uh light mode dark mode or system let me click on dark yes this works we now have dark mode let me click on system we still have dark mode because my system preference is set to dark mode let me again click on light mode and you as you see this works perfectly also if I click on dark mode now and reload the page you'll see that we still have dark mode so our preference is stored that's very nice let me go back to light mode so now what's the first thing I don't like well it's actually quite simple right here you see we have this padding on the left side on and on the right side but our hello from the index page so index page file is not uh does not have the same padding so what I can actually do is quite simple let's go to our layout. TSX and let me open also my Navar and the difference is that right here we we have a Max with 2XL with an MX of Auto and a padding X of four what I will just do now is copy The Styling so max with 2XL MX Auto and padding X4 go to my layout. TSX and then I will wrap my children inside of a main element give it in class name of what I've just copied let me wrap now my children inside of here and now if I save it and go back you now see we actually have the same padding um actually not quite the same because as you see we have here a bit more padding than here let me check what exactly the problem is I don't know right now so the problem is uh now where I check a bit about it um as you see if I open right now my death tools um right here we have our layout with a Max width of two XL and padding X of four now the problem is our Navar has again the same styling which also gives imp padding X of four I don't want that so the thing is what I will do now is actually instead of rendering my NAFA inside of this component right here uh inside of page. TSX I'm sorry I will delete it from here and instead of rending it inside of the page. TSX I will render it inside of the layout file so right above this main element I will now render my Navar component so let me import that again from my components and if I now go back um save everything we get an error um that looks now fine you still see everything works so now our padding is correct so now we can actually um fetch our content so let's go back to our page. TSX which is right here and I think the first thing we we should do now is instead of creating the UI let's fetch our data and for that I will create a new async function so let's do an async function uh let's call it get data and then let me just open the function inside of here now right here we'll have to write in query and then fetch the data now how do you query data from sanity and that's an interesting question let me zoom out a bit from here um that's an interesting question because actually sanity uses uh its own query language and the query language is called Gro and at first it could be a bit complicated for you guys but trust me once you use it a bit it's so simple and you don't really want to use anything else so how do you start the query and first of all again I WR here in the vision Tab and the vision tab is just um a file or a tab where you can actually test out your query now how do you uh start off well you always start with the Asterix symbol and an Mt or actually you don't even need the Mt if I right now click on fetch you'll see that we get everything from sanity so this um Aster symbol just tell sanity hey fetch everything you have like really everything you have just give it to me now this is not perfect because you fetch a lot of stuff that you don't really even need what you can do now is actually exclude a few things or in that sense actually tell sanity what you actually need so for that you can use these array brackets right here and now right here let's give it in type on underscore type I'm sorry and this should be now equal to a document that you have created so if you go back to our schema file to our block. TS you know that our name or our document is called block so what I can do right here is now if uh What We Want Is Everything where the type is equal to block if I now click fetch you see we only get four items back so we in total we get four block articles back that's perfect and that's exactly what I want now there's one thing actually um for our index page I don't need everything so for example I don't need the content right now um I don't need um what else do I not need I don't need the hero image for example um I don't need uh right here for the Stu this underscore type I don't need it uh I just need the most basic stuff to actually make it a bit more simple but also to reduce my bandwidth and for that again you can filter what you need with these um object brackets uh I don't even know how they are called but with this I can now actually tell sanity what I need from my block um document so what do we need let's start off with the title I of course need a title then what else do I need I need a small description right here so let me copy that paste that what else do I need um I think I of course need the slug now the interesting thing is with the slug as you see you have two things or the slug has actually two um children so first of all the current and that's our slug name and the type now I don't need a type and I only need the slack. current so how do you do that well you create a new um field let's name it um current Slug and this will just be equal to slug do current if I uh now click on fetch you now see title small description and the current slug which is equal to the actual slug value so this works nicely so now we have the title small description current slug what else do we need let me think about it I actually think for now we don't need anything else now there's one important thing currently our um items are fetched uh I guess randomly I don't even know how they are fetched now I want to actually order them by the created at timestamp so I want to order by the newest blog article so the newest article should be on the top and and the oldest article should be the last inside of the array and for that right here you have a query doc uh cheat sheet that you can search for and it will just be a cheat sheet of Gro queries um which you can actually check and see how they work and what I can do now is search for order or sorting no ordering was correct and if I scroll down a bit right here you can order your results so based by created at timestamp and then either ascending or descending so let me actually copy this right here you um actually paste that where our vision right here it's here you actually just paste it right here after the array brackets and right here you just tell it order created at ascending I don't want to do it ascending I want to do it descending if I now click fetch you now see that actually our items are fetched by the um created ad Tim stamp which is descending which means that we only fetch uh based on the newest timestamp or which is the newest uh created at Tim stamp and this looks good to me this is correct so this now also works so what I can do now is I should copy this query right here let me go back to our page. TSX and let's do const query this will be equal to Optics right here so not this but Optics and then let me just paste our query that I've just written so what we have right now is in static query what do I mean well currently the srey does nothing we don't fetch the data and to fetch data you actually have to create a client a sanity client because we have to somehow connect to our sanity backend we do that with a sanity client then we fetch the our data through this query and we get our data so what we'll do right now is actually create a sanity client with which we can then fretch our data using this query so what I want to do right now is actually go inside of my app folder create a new folder called lip and then inside of the lip folder I want to create a new file called san. TS now inside of this file I want to create the sanity client and for this we will actually need a package so open your terminal right now um this takes a bit for me and what I want to now install is npmi next- sanity this is the sanity package for next shares or the client package however you want to name it and with the help of this package we can then fetch our data so this takes now a bit so let's wait for that now one thing maybe if you don't want to spell the um the installation commands like I do right in the video or you want to make sure that you spell everything correctly you can go to my GitHub I will have the command for all the packages just an npmi with all packages you can click that install that and then you don't have to install everything manually as the video progresses so if you want to do that do that but I would just do it like that right now and now our package should be already installed in a second so our package is now installed so I can now use this next sanity package inside of this file right here so what I will do is now import something let me D structure create client and create client is imported from next- sanity as you see right here so what I will do now is create a export const let's name it um I think client is sufficient enough this will be equal to create client not create but create client and then inside of here we have to pass actually three values so first of all our project ID our data set and our API version so let's start off simple our API version this will just be encapsulated in a string and this will be a value of 20 23- 05-03 this is just the API version that we want to use then for the data set this is also very simple if you can remember from our installation command uh we created this um NP p m I don't know create sanity at latest we have a clean template and a name and at the end we had a data set and we named it production um so that's exactly what our data set is so right here we just write production and then the last value which we have is the um project ID the project ID for that we have to go to sanity.io manage our project and there we'll see the project ID so let me head over to sanity so I'm now at sanity.io as you see and I just clicked on manage projects uh search for my project and that's right here so right here you see your project ID and that's exactly the value we need so what I will just do is copy it and then paste it right here since that's what we need and also you don't have to store it in a um environment variable it's fine if you do it like that but you can do it under a nextore public and store it like that if you want to but I won't the last value which I was said is the UC CDN and UC CDN is the Boolean and this is just a question or s in that sense asks you if you want to use the CDN or the build-in CDN or not but since we use next 14 with um built-in caching I don't need it so I would set it to false and I would also encourage you to set it to false um since at the end of the day we use um ISR so that looks good and now we can actually use that to fetch our query and that's exactly what we'll do right now so let's go back to page. TSX we have our quer U here and what I can do now is create a constant data this will be equal to await client now client is imported from our lip file or lip folder with the sanity file let's do a do Fetch and let's pass our query as an argument so that looks nice the last thing we have to do is return our data so let me spell that and now our server component or in that sense our function to get our data works so what we can do now is inside of our export default function we can get our data so let's do constant data this will be equal to aate get data now you see we get an error right here and it tells me array expressions are only allowed with an async functions and since we are in a server component I can mark this function as async and this is totally safe since everything runs on the server now let's see if our query actually works so what I can use right here just in console.log and let me lock my data now let me again open my terminal clear everything start my death server since it's currently not running this will now open on local 3000 so let me uh head over to Chrome so I'm now on Locos 3000 let me zoom in again a bit and if I now reload this page let's get back to your project open the terminal what do you see well you see our data so we have in a way of in total I think four objects 1 2 3 4 yes correct four objects because we have four block posts you see this works perfectly just like I want it now there's one problem uh right now if I hover over data you see it tells me data is of type any now we use typescript and in typescript we always of course want to have types and if we don't get any types then the question arises why the hell do we even use typescript if we could just use JavaScript in that case so what we'll do is actually create a interface and then with the interface we will get all the types so what I want you to do right now is open your Explorer let's go inside of the app folder lip folder and let's create a new file called interface. TS now inside of this interface. TS I will create an interface with the types so right here you see our three types we have a title a small description and the current slck and that's all we need so right here what I do is an export interface let's name it um simple block cut and let me open that now again what do we get we get an title let me get that this right here is in string then what else do we get we get in small description this is also in string so let's set it to string and then the last value we have is the current slug so let me get that and set it to string so now what we can do is actually right here our data we can give it in type so let's do simple block card and now there's one problem data now assumes that um I guess the response is just an object this is of course not true because if you open your terminal you see we get an array and not an object so let me set simple block card to an array and now we know that data is in Array with multiple objects of our simple block card so this looks now very nice and what we can do now is actually show our data to the screen so let's do that now currently uh as I'm looking at the code maybe one thing we should also get is our main image so let me see how I named it so our interface is called block or schema I'm sorry and we named our image where is it small description here we named the title image so let me also get it actually right here so I can get my title image then let me put it also in our interface title image which will be of type any and yeah I think that's fine so now let me actually create the UI for our posts so let me first of all delete this stff and let me create a new div element since I want to start off fresh let me start off with styling it so let's give a class name of grid let's give it a grid calls of one so if we on a mobile device I only want to show one um card um vertically so always just one card and not horizontally for example two cards now if we of course on a bigger device I of course want to um also show My Block cards horizontally so what I can do is on a LG device so on a large device let me give it a grid calls of let's say four and let's also do margin top of five and now inside of this I can map over my data so let's do data. map let's get a post and then let me just return that so now inside of here I actually want to use a shat nuui component which is the card component and if you currently check our Explorer inside of the components folder you see we only have the button component and the drop- down menu component so if I now go to ui. chan.com what I want to get now is the card component so that's right here let me copy right here the CLI command and PM of course let me open my terminal I will stop my def server clear everything paste the command this will now install the card component let me restart my def server since we'll need it in a second and now our card is installed so I can now use this card component right here and as you see it's imported from our components um let me open that inside of here we get an error and it tells me I have to use the key prop this is needed to prevent hydration errors so let's give it in key and the key will actually right here let me just also get the idx and then the key will be the idx um the idx is just the iterator so um I guess data is just mapped and then every object gets an iterator so we can use that that's fine and we don't need any class names inside of here I can now use the image component from next image and now we have to give it in source and for the source this is again interesting because let me just delete this image for now um because what I want to do now is actually conso lock the data and I want to show you something so let's go back let me go to local 3000 reload the page let me open my terminal this compiled let's wait for that now it's compiled so what do you see right here our title image um does not give us back a um URL as you would think but what we get is actually an uh object as you see we have an underscore type and we have an asset now you can't really get the URL uh fast you could of course qu it's somehow like here it's uh fine so what do you do now you have an image and you don't have the URL well insanity or in the case of Sanity there's an actually nice helper Library which you can use which is sanity image URL and this is what we'll use so what I will do right now is um let me stop my death server again I know stopping and creating one is annoying but what I want to install is now the sanity image URL with the help of this package I can then actually transform the images and get the URL else so this is now installed let me go back to our sanity TS file so where we create our client and now inside of here I want to create the function to convert images to an URL so for that we have to create a constant Builder this will be equal to a function provided by sanity our image URL um Library so let me import image URL Builder um right here don't choose this default import Alias this incorrect so let me import it just manually so Builder and this will be equal or from at sanity imag so this is to correct import Alias be sure that you spell it correctly because the default import Alias is incorrect so this can now be set equal to image URL Builder and let's pass our client as an argument what we have to do now is create a function so let's do an export function this will uh be called that's name it URL 4 we have an uh parameter right here this will be the source let me set it to any and let's open that now inside of here we have to uh return our Builder now this is spelled incorrectly let me spell Builder correctly and what we can do now is return Builder do image and we can pass our source as an argument so now we have created the function to convert the image object to an image URL so what I can do now is go back to my page. TSX and now use the image component again so let me actually do that so let me get the image component um as you see it's already imported right here from next- image this is in self closing tag let me give it in Source The Source will be now the URL 4 function you import it from this um lip folder then we have to pass our post. title image and now the important thing is at the end you have to mark it as URL because if you don't do that you don't get the URL and you will get an error you don't want that now one important thing is also add an ALT tag to not get the errors right here let's just say I don't know image let's save that let's see how that looks let me reload the page again my Dev server is not running so let me restart that this will take a second so let's wait for that so my Dev server has restarted and now we get an error so image source la la la la la is missing required width property so if you use the image component provided by nexs you have to actually add a WID and a height property so that an image component knows to what size it should res size um now why do you use the image component and not the normal um HTML image tag well that's because the image component actually um just like the link component adds a few nice um actual benefits and that's why I use the image component if you want to know more about the image component you can head over to the docs learn more but I won't explain it any further but what I will do now is add in width which will be 500 00 a height which will be also 500 and let's save it let's see do we get an error yes invalid Source prop uh on next image host name CDN sanity.io is not configured so what's the error right here well if you didn't know with nextjs or with the image component you actually have to um tell it what host name um is used uh with that you actually prevent any attacks from any I don't know hackers because at the end of the day the image component has also in price after certain amount and with that you you just save hey only resize the images from this URL and then you're safe so what do we have to do let's go to next. config.js then right here what we have to do is get our images right here then we get our remote patterns this is an array with objects and then right here we have a few values first of all the protocol now the protocol is https not http our host name as you already saw right here is CDN do sanity.io so let me add that and the last thing is the port and I will just leave it as an empty string I can now save that if you open your terminal you will see that our def server will restart automatically for us this is a nice NE shares feature so if I now reload the page you'll see it takes a bit so let me wait for that so this is how it currently looks for me and it looks quite ugly as you see I don't like it so let me change a few things first of all LG grid calls 4 I don't want that again let me just delete it and let's leave it at MD grid calls 2 so now you see we have two grid calls that looks fine I think now right here object cover is spelled incorrectly for me so let me spell object cover again correctly let's see how that looks yeah that looks fine in my opinion actually I want to leave it like that let's see how it looks in dark mode right here yeah it's right here up to the top that's fine in my opinion and we of course also have to add a bit of Gap so let me do a gap of let's say five let's see how that looks yeah I can live with that actually I think so now you see we have on the top a little bit of rounding and on the bottom knot so what I want to do now is actually on the bottom is add a title our description and the button to uh read more so for that what I want to do is inside of the card component and under the image component I want to now import our card content this is imported from our components um let me also give it a class name which uh which will be margin top of five and then inside of here I will have an H3 and then uh render my post. tile let's see how that looks so now you see we have a title now one thing you see is the title is not big enough right now so let me make it a bit bigger let me give it actually in class name um let's test out what size looks good let's do in text of LG let's see yeah that's fine I think maybe XL how does that look yeah that's fine um if I zoom out on a normal device maybe the lines a bit too big actually let's leave it at LG let's see yeah I think that's fine one thing I want to do also is add a line clamp and with the line clamp I can tell um the code right here that the title should be maximum of two lines I think that looks better actually now the next thing I want to do is show our um small description so let's use a pag right here and let me render right here our post do small description let's see how that looks yeah that looks quite ugly yeah does not look good I'm sorry so let's change that um let me first of all actually do again a l a line clamp so let's do a line um clamp of let's say fre let's see how that looks yeah that's already a bit better um let's also change the sizing of maybe text small yeah I think that's fine and then also I don't really like the color right now so our title is white and our description is also white um let's see first of all how it looks again in light mode yeah let's change that first of all margin top of two or three n let's leave it at two let's do a text Gray of 600 let's see yeah that looks fine and on dark mode how how does it now look nope that does not look good so let's see on dark a text of gray 400 or 300 I think that's better actually let's see yeah I think that's quite all right I can live with that now the last thing I want to do is add a button and with the button then the user can click on the Block article and uh actually see the full block article so under the ptag let me import the button component again from our components um right here I can mark it as child and with that I just tell um shats and UI hey under this button or inside of this button I want to render another component or element whatever you want um right here let me also give it a class name of w full and margin top of seven and then inside of here I can now render a link the link component imported from next link um Let me give it an hre this will just be um let let's use this uptic right here so slash block slash a dynamic value which will be post. current slug now right here we can just render um read more I think that's fine let's see how that looks read more read more yeah that looks fine let's see how it looks on a um light device so on light mode yeah I think that looks quite nice actually so read more we have the title and then we have right here our description maybe we can make uh our title a bit more bold so let's why do uh right here do a font of yeah bolt let's see how that looks yeah I think that's fine actually I like that so now what happens if we click on the sweet more button let me do that and we get redirected to SL SL block SL mastering uh web development with knjs so our slug but we see no content we get a 44 that's not what we want so what I'll do right now is actually create a page where the user can then read more about our blog article you see we redirect to/ block SL our slug so we have to create a normal route and then inside of this route we'll have a child route which will be a dynamic route so how do we do that well you go in the app folder we create a block folder and then inside of here we can use these array brackets and give it any name so SLU with that we tell next sh hey I want to have a normal route so right here block and then inside of here I will have a child route which is dynamic uh as you see I tell it with these um array brackets and then I can query this Dynamic value using the slug now inside of the slug folder let me create a new file called page. X and now we have created our route for the block article so what we can do right now is uh right here a export default function let's name it um slug or let's name it a block article let me open that function let's do a return statement let's write here do an H1 statement and let's just say hello from the Block um article route something like that and now let's see if this works so if I now click on Read More We Get redirected to/ block SL disl let me again zoom in and then you see an H one right here with hello from the Block article route so now you see we don't get any errors anymore and now the nice thing with this um Dynamic route we can actually get these uh this slck right here so the value how do we do that well we get it through the params right here we can write here the structure params and now we have to give it of course in type so params will have in type of um slug which will be a string so what I can do now right here instead of rending H1 hello from whatever I can get my param and this will be params do slug if I save that go back and now you will see we get our slug right here spell could unleash transforming repb development with ease and this is the same slug which is also inside of our URL as you see right here so now we can actually query our data based on the slug and we also get it right here in our page so this looks good so what do we do now I think the time has now come to fetch our data or to fetch our block article based on the slug and then code the UI for the slug or for the article so what I will do right now on top is of course create a new function Let's do an async function let's call it get data and then let me open this function now inside of here we of course uh again have to write our query and for that we again have to use the gro query language provided by sanity and for that I think we should again go to sanity studio uh use the vision Tab and see everything again with an actual visual interface so let me open again my terminal let me open a new terminal tab let me CD into sanity let's to npm R def this will again open on lcross 3333 let's see right here so let me go there so I'm now on Locos 3333 you see our old query right here let me delete it I don't need it anymore and now we will start off fresh so how do we start again first of all we again start with an aster symbol if I click on fetch you'll see that with this itel sanity hey give me all the data you have everything you have now of course we don't need that we only want to get a specific block article so let me filter down what I need for that I use the um array brackets use the underscore type and this will be equal to block if I now click fetch you will see we only get four items this is good but still not perfect I don't want to get four items I only want to get one item so how do I get only one item well I have to use a multiple filter so if this multiple and filter I tell um sanity right here hey get me this and also this should be also true so right now hey I want to get typ block and I also want to get the article which is equal to the slug so right here we can do SLU do current and this should be equal to a slug so let's right here just pass in default slug so if I go back to our website we have this swel kit slug I will copy that paste it right here and if I now click fetch we should only get one item back and what do you see we only get one item back so again what have we done to summarize so we use the aster symbol and then the array brackets since I don't want to get everything but I want to filter what I get then I tell sanity hey give me the type block with that I get four articles but I only want to get one article and to specify what tic uh article I want to get I use the multiple FS uh filter and then tell sanity hey the SLU do current should be equal to the following slug so that's what I do right here now if you open right now our response you see we get everything from this response so the title image the small description the created at timestamp the um content uh what else do we have let me scroll down um we have the slack with an underscore type so again we get a lot of stuff and I don't need most of the stuff so what I want to do is actually filter a bit so let's again use these object brackets right here and now I can tell sanity what I need so first of all I need the slug and what I want to do is actually uh the exact same as we did in the uh previous example so we create a new t uh type called current Slug and this will be equal to SLU do current if I now fetch that you see we get current slug with the actual slug so this is nice now what's the next thing I want I want to get the title then I want to get the content and the last thing I want to get is the title image let's see if we get everything we get the current slug we get the title we get the content we get the title image and this looks great now there's still one thing I don't like even though we get only one item back and I know that we only get one item back because our SLU is a unique identifier our response is still an array and I don't know why or I know why but we don't need an array so what I can do and uh also that's what sanity actually recommends you to do is just to get the first item in the array so if an array symbol and a zero ital sanity give me the first item in the array and with that I now only get one object back and I don't have to map over and Away uh even though I know there's only one object inside of it so now we have written a successful query and now we can use that so let me copy this query again let's go back let me stop my uh or close my terminal and inside of here let's do now a const query which will be equal to Optics and now inside of this Optics I can paste my query now right here you see we have an static slug so even though if I maybe click on a different block than um this block right here I would still fetch the content for the same block if you understand what I mean what I want to do is get the um Dynamic slug right here which we get and then pass it right here so what we can do right here is through the params get a slug let me set it to string and what I can do now now inside of here instead of using this default value let me delete it let's still use these string columns and now I can get my Dynamic value with slug so this looks great and now this works let me now actually fetch our query so let's do cons data which will be equal to aate client client is imported from our lip folder do Fetch and let me pass my query now let's of course also return our data and this looks beautiful now we have to get our data in our component so what I have to do right here is say cons data and this will be equal to aate get data and yeah that looks good now we don't get one error anymore but we get two errors first of all the first error is the weight error so weight expressions are only allowed with an async functions we already know how to fix this error we uh just have to uh give it an async modifier so this looks good but now our get data um function also gives us an error and right here it expects one argument but get zero why does it expect an argument well because right here we gave it in param of slug so we have to pass our function now this um argument so right here what we can do is get our params do Slug and now we don't get any error anymore as you see so let's do a console.log and let's lock the data let's save that let's go back let me reload the page let me go back open the terminal let's go to the other terminal Tab and now you see we get the data so we only get one object as you see right here we only get one not a array anymore we get the current slug the title the content and at the end the title image so this looks beautiful and we actually get the data so now we again have one error or one problem not the error if I hover over data we don't have any types and as you know what we can do now is create an interface again so let me export a new interface this will be now called I don't Know full block and let me open that now what do uh what types do we get let me head back we get in current slug so let me get that this will be of type string then what else do we get we get a title let me get that this will be of type string then let's see what else we get we get content this is of type any so let me set that and then the last field or the last type is title image and this will be also type any so this looks very nice I can save that and now for data I can give it the type of full block now right here I don't have to add any array symbols that's because full block is just an object and our data that we get is also just an object so now let's actually show our data to the user so what do we do let me first of all uh delete this return let's create a new return statement so inside of here let me actually render a diff element and then inside of here let me do an H1 tag uh and then inside of here I want to now render two span elements so let's start with the first one and inside of here I want just to say J um Marshall and then let's say block let's see how that looks so J Marshall block looks fine not good so let's change that it's quite simple let me actually style the span element right here let's give in class name of block um text which will be base let's do a text which will be Center and then let's do a text which will be primary let's see first of all how that looks that looks already a bit better it's now in the middle and we have our brand color as you see right here let me now make it also a bit bigger so let's do right here a font which will be semi bold and then also tracking which will be white and then let's do uppercase let's see how that looks yeah that looks fine and I think I don't have to change anything more let me think about it and now I think that looks good so I don't have to change anything more now underneath this I want to actually render also the title of our block article icle so under the span let me create another span element let me right here render our data. title and let me also style it so let's give it in class name margin top of two since I want to create a bit of margin let's do a block element text which will be let's say free XL why not text which will be Center um let's also do a leading which will be eight uh font which will be let's say let's say bolt we will see how that looks um tracking which will be tight and then let's do an SM of text for Excel let's see how that looks SW Cil unleash transforming web development with ease I think that looks quite good the only thing I want to change right now is create a bit of margin between my Navar and my title right here I think it's a bit um too spaced in if you understand what I mean so what I'll do right here is give it in class name so our diff and let's do a margin top of let's say six let's see how it looks and we can give it a bit more more eight yeah I think that's fine let's see dark mode and that looks also quite good let me again zoom out a bit Yeah I think we can leave it like that so what I want to do now is render our image so our title image let me go under the H1 tag let me import our image component from next image inside of here we have we again have to pass our source this will be again the ur4 function um imported from our lip folder then inside of here we have to pass in uh as an argument our dat title image and at the end do URL now you'll see if I save that and go back we'll get an eror and it tells me that I'm missing a width property and if you can remember I have to add in width and height property so let's add that let's give it in width which will be 800 and let's do also in height which will be also 800 now the last thing I will do is add an all tag and let's just say I don't know um title image I think that's fine let's see how that looks yeah it's it looks all right it could be better so what I want to do is give it a class name and then let's do round it since I wanted to be rounded of LG and I think margin top of eight let's see how that looks yeah that looks all right let me uh reload the page just to be sure yeah I think that's good actually um let's see how it looks in uh light mode um what here you see the problem that our image has a white background and with that you don't really see I guess the contrast between the image and the title and it creates so much space so what I want to do right here is add in border so let's do in Border and then this should actually look better in white mode yes this looks better let's see how that looks in dark mode yeah that's fine and one thing I can also add a a priority tag right here or property and with priority I tell nexts to load the image with priority so if I again delete it right now let me open my um def tools right here let me go to next Network and let me reload the page right now so if you check it right now you will see that the image is loaded right here I think that's the right image let's see um preview yes that's the image and you see it's loaded only right here you see that all of this stuff is loaded and then only our image if I now add the priority tag right here so let's do that save that and um actually reload our page you will now see that this image is loaded right here at the third space or at the third place so the image is loaded now within priority before all of this stuff so now you see that this image is loaded within priority which is pretty cool in my opinion so this works nicely and now the last step has come and that's to show our actual content so let me actually do that and now how do we show our content because what I will do right now is again console lock our data so let's do that console um dolog data and let's open the terminal what you'll see right here is that our content is an array with a lot of objects as you see right here so content array with really a lot of objects and because of that you of course can just add a diff tag and then show the content because again it's an array with objects how would you do that so for that there's actually a cool um package which is portable text react and this is also what actually the sanity team recommends you to use and with that we can sanitize our content and show to the client right here so let me open my terminal right now and then again if you want to just go to my GitHub and copy um the installation command from there but let's do an npmi at portable text react with this I install this uh package right here and then we can sanitize the content from sanity so I've now installed that and now we can actually use that so now under my image component let me create a diff element and let's give it a class name of margin top 16 for now I will add more class names later but for now I want to show my content so I can now import our portable text component this is imported from at portable text react as you see this is in self closing tag now inside of here we have to add our value so right here there's a value property or I'm so we have to add our content so they have a value property and now we can do uh data. content and if I save that and go back let me reload the page real quick you see our death server is not running so let me restart that again let me go back and reload the page so now uh our content has loaded and here you see it and it looks ugly who would have fought so this really does not look nice I don't like it and that's actually a quite simple fix actually and let me show it to you now if you didn't know TN CSS has a very cool plug-in system and one plugin that they have and create themselves and also maintain is the tan CSS typography plugin with this it's very easy to style your text without creating I don't know hundreds of styles this is just a uh plugin you use it and your text is beautiful at an instant so what do we do right here you have an installation command so let me copy that right now so npm install development dependency ter CSS typography let me open my terminal let me actually just open a new terminal tab I think that's easier than just to restart our def server every time let me install that then you will see that the next step is just to add it at our plugins array so I will copy that let me go to T.C config.txt I can also give right here pros of blue and a pros of XL so the size of the text so now let me save it and let's see how that looks yeah that does not look good why is it so dark this is not good let's see how it looks in white mode um in white mode it looks quite nice actually I have to admit it's good but in dark mode you see that the styling is not nice so what you have to do is a quite easy fix right here we have our dark and then we can do a pros of invert not video I'm sorry but invert if I save that and go back you should now see in dark mode we have now actually white styling and this looks very nice in my opinion great I like that very much now since it works let's actually test a few things out let's see what we can do actually with this Pros class names so right here we have headings right let's say we want to give it an underline let's see how simple that is we again use our Pros class name and what I can do now is actually use in Pros headings and with that I can just say underline let's let's see how that looks yeah now you see all headings have an underline now I wouldn't say that looks good but I mean you see what you can do let me again change that let's not do it like that now maybe what's another thing that I want to change which will actually look good so right here we have this bullet list right let's say I want to change the color of the dots to my um right here color so my primary color this blue color let's say I want to change that how do I do that well it's again quite simple we again use our Pros class name and now I want to uh Target a specific value so what value is this right now as you know a bullet list is actually an unordered list with multiple Lis so we want to Target a li element then use the marker and give it a text of primary if I save that and go back you now see that the bullets have the color of this blue primary color if I change it to White mode right here you see it's still kept persistent this looks very nice what's another thing you could do let's say you would have links right here we currently don't have any links and I also won't add any links right now but let's just imagine you would have some let's let me show you how you would do that let's again use our prst class name and then you can again Target a specific value so for that this would be the a tag and then I can just give it a uh text of again primary if I would want to then if we would have links right here I don't have any you would see that the color would also be blue so very nice of course now I think actually we already done let me actually test out if everything works let me click on my logo right here we should get redirected to our homepage that's exactly what happens let me now click on this remix block article read more you see we it loads right here we have the image we have our text right here everything is loading that's great our bullet points have this blue color this is very nice now what's one thing maybe U for you maybe the this text is a bit too big so what you can do is instead of Pros XL let's do pros of LG so this is now a bit smaller and maybe also a bit better I think that looks even better right now let's see if the other block article works so let's click on I don't know KN right here the slows we have the image and we have the text very nice let me again uh click on dark mode Let's reloaded does it keep persisted yes it uh keeps persisted this is very nice now let's see how it looks on mobile so let me make it smaller yeah this looks very good let me actually go back to the homepage and yes this also looks very nice actually let me click on read more this loads great it works perfectly just like I wanted it so now I would actually say we are done and what do we do now we will actually now um deploy our application to Vel deploy our sanity studio and then once everything is deployed we will create another block article and see if it shows up spoiler alert it won't work but I will show you how you will actually fix that in a second once we deploy our application so right here I'm now at github.com slne and now I can create a new repository let me name it nextjs M14 block tutorial I think that's fine let me uh delete this I don't need that um I will leave it public and then let me click on create repository this takes second and now you see right here it gives me instructions how to connect my code to this repository so let me open my terminal let me clear everything and then let's say get in it this will initialize a new git repository then let's say git add everything within Dot and let's do a git commit DM and let's say finished project so let me click enter you see everything has been added if I now check right here the instructions the next step is to create a branch so let me copy that paste that then the next step is to add a remote origin I'll copy that and paste that and the last step is to push our code so I will copy that and paste that and now our code will be pushed to GitHub if I go now to GitHub and reload the page you'll see our code in a second right here and that's exactly what you see this looks very nice so now let's head over to Rasel and deploy this block so I'm now at ral.com slne as you see and now we have our project right here next shares 14 block tutorial I can click on import this will now import my project right here we don't have to change actually anything uh we don't have any environment varibles so that's fine we can now click on deploy and this will deploy our application to Vell let's wait for that this takes a few minutes and if there's any errors I will come back so we got an error I know exactly what we wanted no I'm joking what's the problem right here sanity or I'm sorry sell thingss that sanity is actually a file that we want to deploy I don't want to deploy sanity sanity is in Standalone project which does not need to be deployed to Vell so what I have to tell Vel is actually hey don't deploy the sanity folder I don't need it leave it there just deploy my code for that I will actually have to create a new file right here just in a root folder called Vell ignore and then add the sanity name so because our folder is called sanity and if I name it sanity I tell this verell hey ignore the sanity folder leave it right there don't touch it what I can do now is can open my terminal clear everything do a get add within dot to add everything get commit um-hm and let's say added uh verell ignore and then let's do get push to push our code to GitHub Vell will now automatically rebuild our project so let's head over to Vell and see that so as you see right here it now automatically rebuilds for us this will now again take a bit so let's wait for that so great news our project has been actually built successfully and it works as you see right here so let me actually click on the URL and let's see how it looks like so let me again zoom in a bit for you guys since I know it's a bit too small but here you have the code great everything loads I think uh light mode works dark Mode work system mode works great I can click on a block article so let me click on it this loads we have the content right here we have our bullet list which is blue we have the titles and the content which looks very nice now this is actually great you see we have deployed it and it works so now let's deploy sanity Studio it's again very simple I will open my terminal let me close all of these terminals for now let me just leave one terminal open let me clear everything let me now CD into the sanity folder because that's the folder we want to deploy and what I will do is one npm npm run deploy with this I will now deploy our code or our sanity Studio to sanity right here tells me I have to actually give it in studio host name so let's name it I don't know nextjs 14 block let's click enter and now it creates an output folder and everything should work so let's see let's see this should be quite fast actually and what do you see it has been actually deployed so our sanity studio is now deployed to the global web so let me now open this URL right here in Chrome this loads let's see and right here I'm already logged in this looks great you see I have four block articles and this works now I will actually show you now one thing that does not work so as you see I have four block articles right now right this is good let's say I want to create another block article I will show you one eror so I will right you click on this plus icon to create another block article let's give it an title of um hey does this um show up let's create this luck let me upload a image so I've have now uploaded an image right here let's give it in small description of hey how are you la la la la la some gibberish and the same for Content so I have now created some gibberish a title a slug and everything like that let me click on publish right now and now this has been published you see right here the screen icon now what do you think does this block article now show up on our website because you would assume hey we do an a fetch call an API call to sanity we retrieve our data and then we show it right here right well not quite if I now reload this page actually you don't see anything where's the fifth uh where's the fifth block article I don't see it well the problem is if your newon X is 14 and server components you probably don't know that right now if we don't add any revalidate txt nexts fetches the first fetch call um indefinitely so our fetch call or these four blog articles are now static in that sense so even though we have new items in sanity it isn't shown right here so what do we have we have stale data we don't want that we want to get fresh data so how do we do that well we have to actually revalidate our cash so that's again quite simple actually and for that let me actually open the docs whe quick so right here I'm now in the docs and one thing you see right here tells us by default next shares automatically caches to return values of fetch in the data cache on the server this means that uh data can be fetched at build time or request time cashed and reused on each data request so what that means is the first uh time we actually fetch so where the data is still still not there it will be in fresh request but each subsequent request will be forever cached you you will never get fresh data so what you can do now is actually quite simple and that's add and revalidate tag so right here they have a convention where they export a constant called revalidate and then you give it in value in seconds and it tells the next sh sayy after for example 30 seconds we validate my cash so you could for example also add zero with that you would tell um next shares hey don't cash the data at all each request I make should be actually freshh and don't do anything but for example you could also add 30 seconds with that actually you tell next shares hey if a request comes in um give it the fresh request then for 30 seconds uh give it the cached result and then again give it the fresh result after 30 seconds so that's exactly what I will do right now I will copy this export cons R validate then right here for our page SL slug I will add it right here above our asnc function so let me add that instead of 3,600 100 which is 1 hour I will do 30 which is 30 seconds and now I also want to do the same for our index page so let me copy that and let me also change it from at most every hour and let's do at most 30 seconds now let me copy that and paste it also to the index page so above our Asing function get data let me paste that and this should now work so now uh what you have to do is actually also push your code to GitHub so what I do now is I get at everything within dot let's do a good commit um- M and let's just say added we validate Tex then let's say get push and this will now push the code to GitHub now verell will automatically rebuild our application so let's head over to the cell so now you see it automatically rebuilds for me and this again will take a minute or two so let's again wait for that so it has been now successfully deployed let's see if this works so right here we have now our code and let me reload this page again and now you see we have this block article right here and it's also shown at the top left because we order our results if I click on read more we should also see the article right here and this works let me again test it out I will create another article so let me do that so I have now created another demo article I have published that as you see right here or it's not published right now let me click on publish again this is now published and in theory I hope it works I don't know we should see the article in about 30 seconds so I will now wait about 30 to 1 minute uh 30 seconds to 1 minute and then reload the page and then I will see if it works because maybe I have done something wrong we'll see so uh about 30 seconds have gone past maybe a bit less a bit more I'm not quite sure but what do you see we see a Blog article imagine that our page has now revalidate revalidated our cache it saw that we have new data and now we have our blog post right here I can click on Read More You See It loads we have the image and the data so now we have actually an very cool application which is cached and is also revalidated so when we write a new blog article it is being automatically revalidated after about 30 seconds and then we see it right here so now we have deployed our application to verel and we have also of course deployed our very very cool sanity Studio to the web so I hope you enjoyed this video we have now created everything everything is deployed everything works everything is great I hope you could learn a lot and I I hope you enjoyed it and I hope I can see you on the next video but now bye
Info
Channel: Jan Marshal
Views: 27,635
Rating: undefined out of 5
Keywords: nextjs 14, nextjs 14 tutorial, nextjs 14 blog, nextjs blog, learn nextjs, nextjs 14 beginner tutorial, Nextjs 14 typescript, typescript tutorial
Id: Lydgf-Hvla4
Channel Id: undefined
Length: 93min 37sec (5617 seconds)
Published: Sat Dec 23 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.