Next.js for Beginners - Full Course

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
next js is a popular open source react front end and this is a great beginner's course cape does developer relations at sanity.io and she is an excellent teacher aloha everyone my name is kapehe and welcome to my intro to nxjs course so i've been super curious about next js and if you have as well then we're all in the right spot now together we are going to be learning enough next to be able to continue on and build out our own applications so if you've worked with react in the past then you know that server side rendering is a huge pain also have you ever tried to configure your webpack who has time for that i don't but let me tell you about next it'll take care of all that for us this next js course will cover a number of things so our front end will be all the cool features of next and what it has to offer we'll be looking at linking index and even api routes with serverless functions we are going to be using an external api to manage all of our content and we will have real-time previews we will accomplish all of this with my favorite app idea a recipe app so i picked a recipe app not only because i need a place for all of my recipes i really like to cook but also because next.js has a ton of great features that i feel we can cover with in a recipe app now people say that next is very intuitive it's a very intuitive way to build applications for the web it's a react framework that takes away a lot of the complexity like i was saying earlier that you would have to solve yourself if you built something from scratch i think you're going to really like it and to pair nicely with next we'll handle all of our content with sanity.io next doesn't come with a way to manage content so we'll bring that in ourselves but what sanity does for us is it gives us a content link so we can not only query for our content but we can interact with it sanity is free for projects like this we'll explore that by adding a heart button it'll be a little like button on our recipe page that uses an api route to patch the recipe document now once we have all of our next front end pulling and content from the sanity content link we will use versailles where with zero configuration we can deploy our next app you can of course deploy next js apps to pretty much any hosting platform that serves websites and finally we'll add real-time previews to our next front end which is super useful for editors who want to see their changes before they go live it's very nice to have now before we start there are a couple of things that you should have some knowledge on first a little bit of javascript knowledge is super helpful second having worked with react previously would benefit a ton if you want to brush up on your react knowledge you can follow a react course from free code camp now you can find me on twitter at copay hey underscore okay and with all that being said let's get started all right so next.js next.js is a react framework for sites and apps for the web so it comes with a lot of functionality and we will talk about that um in just a moment and also throughout the building of our recipe app but i just wanted to show you so next.js if we scroll down a little bit there are 12 tiles that are titled y next.js but there are a couple that i wanted to really point out one for example is the file system routing and we will show you exactly how that is done and how next does that there is a really cool thing that when you add a file it adds a route you don't have to do anything else um then there's like zero configuration to set it up there's image optimization with an image tag but all these great things come with next js and with next all of our pages will be pre-rendered which is generally better for performance your user isn't having to wait around while you're while your application loads and it generally is better for seo as well so you get in front of more users and we will talk much more about these in particular and i'll show you exactly how they're done and how it looks and more on that in a little bit all right so before diving in there are a couple tools that we will be working with throughout this course that i want to make sure you have up and ready or are prepared for them so the first one is going to be vs code that is going to be the text editor that i will be using throughout this course if there's a different text editor that you prefer to use by all means definitely use that but i will be using this and if you'd like to download it depending on your machine you can download it at code.visualstudio.com you will also need a command line i will be using item um it will look something like this um you could use the terminal you could use um any anything where you have a command line but we will be using a command line throughout this once we open up vs code i will be using the terminal in there and i will show you how to open that you will also need nodejs installed on your machine so if you know js.org you can find the download options for whatever machine you are on if you don't have this definitely get this installed and if you already do awesome so as i mentioned before you can pretty much use anything you want with nexjs local markdown files any external api and if you've built with react before you may have used use effect to pull in your external data and set it to state which also is something that happens client-side that is in your browser so that's all happening in the browser next does it slightly different and i think for uh good reasons but it's usually better to have all that content ready for your next visitor right they don't have to wait what next less you do is return a special function and from the page template file this handles the data fetching this means we can do a lot of the heavy data lifting when we deploy our site to a hosting provider so we save our visitors the time to wait for the code to fetch some external data before they can get the content that's a lot of waiting and we don't want that so by default next.js pre-renders every page meaning next.js generates html and the data files for each page in advance instead of having it done client-side javascript so there's two forms of pre-rendering that i want to talk about static generation and server-side rendering so static generation is pre-run is the pre-rendering method that generates the html at build time server-side rendering is the pre-rendering method that generates the html on each request so before it's served to the visitor's browser it's handled on the request and then serves it this is similar to what happens in systems like wordpress just think with javascript instead of php so we have our client set up and it's ready to go let's we're in the html file let's start pulling in some data we don't have any data to pull in from sanity but i just want to show you all what it looks like so next allows you to pull in data in different ways it does this by running the special functions that we export from the page template file these functions will be run when we build the site but sometimes also if we have instructed next.js to fetch fresh data depending on the circumstance but yeah so the first function we want to build out is get static props and we're going to come all the way to the very bottom of this page and we're going to export function get static props open that up and then in here we're going to do a return all right so as implied by the name this runs when you build and deploy your next site so it's getting the static props what this function does is that it can receive different parameters and return what becomes our page's properties props see what they did there the data you're returning will actually be saved to a static json file which means you have to return something that can be turned into json so next wants this object to have a key called props so we're going to do props and then you assign the data to and we're going to do recipes because we're going to be building out a recipes app and we'll do title pineapple smoothie so we're going to save that all right so now we have built out the get static props ours when we start building out the the application will look a little different but same idea we have the props passing through the data and the data is recipes and we've given it title pineapple smoothie so we're going to come up here to the top of this file and here we need to pass in our data so now it can be used we're going to do const recipes is equal to data dot recipes and then that's all we need here but let's use it within our template let's actually change out this to b recipes and we want to get the first instance of it dot title awesome so let's see what that looks like so we should now have a clickable link that takes us to the about page that's titled pineapple smoothie and we do awesome so pineapple smoothie is being pulled through the get static props and we click on it and it's doing what what we told it to do with the link but yeah that is what getstatic props will look like and we will be using that throughout this course so yeah so let's get started on setting up our sanity getting all our data set up so we can actually pull in our content all right so let's set up sanity sanity let's go to that website let's check it out and all right so sanity it will replace our need for markdown files or even a cms because it's a unified content platform meaning that it comes with a lot of apis tools capabilities that lets you work and build more freely with your content it also specializes on what we call structured content which means that your content is more readily available to be presented wherever you need it so today we're going to be building a web app but maybe you want to build a native app for your recipes too it can be used across both of those so what's neat with structured content is that you aren't locked to a platform or technology you can use the exact same content in all these places so we're going to build out one instance of our content and we can use it across many different platforms and technologies so in the long run this will save us time if we need to change it because we change it in one spot not in many so more specifically sanity.io gives you a real-time datastore where you put your content as json documents more specifically sanity.io gives you a real-time data store where you put your content as json documents and you can query it with a general purpose query language like grok which we will look at in a bit because we will be using grock today or you can use graphql so because sanity lets you treat content as data they call it the content link the content link is where you can pour pour all of your content and interact with it in any way you need to so sanity also lets you update and patch these documents and access them through an open source editing environment called the sanity studio which we will also be using it really lets you treat your content as data which unlocks a lot of possibilities and cool uses so if you know react like you have to when building next.js you can also customize the studio in all sorts of ways because it's build and react um you can make the content any editing experience make sense for you you make it what you need you customize it however you can also upload images and files to sanity and have them hosted on the global cdn for the images you can request custom sizes or formats from the one yes the one you it upload one and use it across many different sizes so you can query on the metadata on the dimensions or even the color palette of the image so you can use the color palette to see what would be like a good foreground color for accessibility which is really awesome so sanity's apis are hosted so you don't have to worry about uptime and availability and it's free to use for projects that don't have a lot of traffic or a lot of advanced needs so it'll be perfect for our application today you can create as many free projects as you want on sanity.io and pay as you go if you have overages or your business is growing that's great and you need more than the quota includes so let's set up our first sanity project together all right so there's many places we can go seated you can click on getting started or another spot sanity.ios starters so here you can find community and official starters that have been created awesome stuff angular next i see next 11t gatsby so there's plenty of starters that you can pick from here but because we are starting from scratch we don't need any of these starters we are going to click on get started this little button and here we have the official starters again those were in that list that we just looked at but i want to pay attention to this line right here let me zoom in so npm install globally the sanity cli because we need that and sanity init so sanity init is going to initialize a project for us so i'm going to copy that and i'm going to go back to my project let's add pull this up let's add a terminal because we need that and here i'm going to just paste in that command that we just copied and hit enter so it's going to install the sanity cli and it's going to ask us to log in so whatever you choose here google github email password combination remember it because it's going to ask us to ask us again and we need to choose the same one so i'm going to do github it's going to authorize me login is successful let's go back and right away we have create new project so the sanity init part of that command was just initialized so i'm going to hit enter because yes we want to create a new project let's name it studio and default data set yes we want that so y and then hit enter and then that is the correct path just double check and then here we can choose a schema that has sample data or just a schema but we want clean project with no predefined schemas because we are going to build out our schemas so it's going to be building that out for us all right so it's done so sanity init it initialized our new project for us it brought in a project id and the data set for all of our documents and it created a brand new folder for us called studio that was the name that we gave it so if we gave it a different name like my studio it would say my studio right here um so yeah it's gonna set up the studio and we are now able to customize and configure it locally so the first thing i want to do is i want to get our studio up and running so i'm going to cd into studio and then i'm going to run the command sanity start sanity start is going to run our studio locally at localhost 3333 let's run that and it might still be building it awesome so like i said whatever you picked before make sure you pick here so i did github so i'm going to click github otherwise it would have like an authentication error that an authorized yada yada all right so here's the name this is to create new document here is our desk and our vision i'm zoomed in a bunch but if i zoomed out those would pop up but because i'm zoomed in it creates that um my avatar would be over here as well there it is and yeah there's no schema so let's go create them so again we're not mapping this content to pages per se but structuring it after what it is and means so sanity lets us combine the content in any way that we want which means we can let next js take care of the web page building which is perfect because next.js is really good at doing that so we will get the content ready and let next.js do its magic so the way we want to structure our content in the studio is by making relatively simple javascript objects that describe the document types and the fields that we want to have available so there are plenty of fields that we can choose from but let me pull this down let me go back to the code so in studio this is our new folder in here we have config node modules plugin schemas all this great stuff now i wanted to point out sanity sanity.json and here we have our project id this project id is very important for us connecting our next app to our sanity app so we'll find that here and in a little bit we're going to be needing this so it's important to know where that is and we also need to know where this is but we chose that when we did the sanity init now in here we have schemas schema.js is where all of our schemas that we create will be imported into and used so we will visit this this file a good amount as well and then plugins we won't be using node modules make sure that this is get ignored and it is not so let's go to git ignore and all you need to do is remove that forward slash hit save come back here refresh that and now it's 19 because we don't want 5000. so that's what we need to do there okay so the schemas that we want to build out for this app there's three of them we want to do chef ingredient and recipe so chef and ingredient recipe will be referencing those individually so referencing is going to be happening a bunch in our schemas and referencing is fun because you don't have to rewrite content you don't have to rewrite anything you just reference it once and then the schema that you built out it takes all that data and it can use all of it so let's build out our first schema let's do a new file and we'll do chef.js okay so with schemas we're going to export default open that up and we'll do name chef title chef and type document so it's always going to have a name title type name is like the name of it title is the studio facing name of it and then type as document sanity has many different schema types this one is document let's go to schema types so here it's a little too big schema types here's a list of all the schema types so document was the one that we just used document is everything in the studio starts with a document so the document is created and then all the other types live inside the document type so the three schemas that i mentioned earlier are all going to be document types and then if you scroll down each one will have examples like type document and then the output of it some others that we're going to be using array block image string text so if you want to continue and you want to use other ones that we're not using today click into it and you'll find a little image of it what it's going to look like in the studio but then also the properties options and then code examples of it so definitely check that out if you want to add more to your studio one that i really want to point out is reference so reference because we are referencing our types our document types from recipe we're going to be referencing chef from recipe we're going to be referencing ingredient so relations between documents are modeled using the reference type so the model is a one-to-many relationship because it's one thing getting all the all the content in the one document type and there's different properties we can have on it weak hidden read-only but i want to show you down here what it's going to look like so we're going to have a type of reference and it's going to reference directly to so if we had recipe recipe would reference to ingredient so that's what it would look like then the output would be this there's many different ways to do it you can do multiple and then i wanted to show the grok way to grab it right here so when we write our grot query and we are using a reference this would de-reference it and pull out everything from that person so there are different ways we can do it we will be doing all of that in this so stay tuned all right so i'm going to get out of this let's go back here let's come out of that and so now we're going to have to do a fields array with all of our different types and i need to comment after this all right so i'm going to do name name title type name is going to be name title is chef's name and type is going to be string save that and come out of that we'll do name is image title image type is image and then we're going to do an options on this that is hot spot is true i will show you what hot spot is in one moment but it's very nice to have hot spot true on there so be sure to put that in now i'm going to come out of that and we're going to do another one we'll do name is bio title is bio and type is array so already we have three different four different schema types in this uh in this chef.js so open up that type and we're gonna do dove open that up and we'll do title is block we'll do type is block styles will have title is normal and the value is normal and then lists is an empty array so list will be a drop down of predefined values so we're gonna put that there all right so now that is all written out let's explain what's happening there's a lot going on right now so i'm gonna save this so document type everything starts with a document type insanity within that we have our fields array this is going to be an input where you can put in a string chef's name this is going to be an image now this this array with type block is type block is our portable text so this is creating for us a portable text editor so for the bio field we do want to have rich text that is text you can add things like emphasis lists headings and so on but we don't want people to go full overboard with text markup in the bio field it should be simple and neat so as i mentioned earlier sanity is all about treating content as data that goes for rich text as well so we will not store our rich text as markdown or html but it's a format called portable text this will actually make it simpler for us to use inside of our react templates too because we were able to render it directly to react components and we don't need to inject or parse html so without going too far into it portable text will store your rich text as json and if it's stored in json that means you can query it with grok and that's really cool so for example you can query all of your documents that has more than three emphasized spans if that's something you're interested in you can query for that or if you have added a custom recipe block as part of your blog content you can query for specific blog posts containing such and such reference to a certain recipe too so it makes everything even more queriable so to add a portable text editor in the studio you add an array like we did here and put a block field inside of it so with this what the studio sees is a block type inside of an array it will turn the array field or a field into a rich text editor so now this is our rich text editor and furthermore you can also customize the editor so if we want to simplify the out of the box editor we can add a bit of configuration to remove some of the options like what we've done here now let's see what this all looks like in the studio and then i want to show you what this really looks like in the studio so that's all saved something i need to do is i need to go to schema.js and i need to import chef from chef and then use it down here save that and if we go here it should have chef so we click on chef no document of this type found because we haven't added anything and here we have our and i'm going to collapse these by clicking on them here we have our entire schema for chef now we have chef's name it's just a string so i'm just going to write my name in let's bring in an image it is an image of me and my bunny bonnie and then bio here we're going to do is from is is a chef from las vegas nevada all right so then we're going to publish that and i want to show you what edit details does so this is the hot spot is true thing that we did so if we click on this this hotspot and crop comes up i'm going to just go a little bit so here is the crop and here is the here is the hotspot so because i'm the chef i want to make sure people know i'm the chef and not bonnie so i'm gonna put emphasis on me to make sure that everyone knows it's me just like that and that can be really zoomed in on me that's okay though let's make another chef and we'll do bonnie and this time we really want to emphasize bonnie so we're going to really cut me out and we're going to really emphasize bonnie the bunny so using one photo i'm able to across different aspect ratios use that same photo but always make sure that whatever my hot spot is on is always going to be in view so if i i mean if i changed this and i put on my face see how it changes so yeah it makes it really great for not having to upload many images for many different aspect ratios um but yeah that is hotspot and crop there's bonnie and then we'll say bonnie is a chef who loves to use carrots and then we're gonna do carrot emoji and i'm pulling this emoji thing up by hitting command control spacebar on mac hit publish and now we have two chefs bonnie and kapeh so uh yeah now i want to show you what it would look like if i got rid of this rich text editor so i wanted to talk just a little bit more on this array type so because i put block in here it is an array of blocks like with the rich text editor if i got rid of it this is what would happen so i'll do a type of um title is bio um name bio i should have capitalized that title and then type will do string so if i save that and i go back to the studio we had that block when okay so because it was blocked that we put in before it's kind of erroring out because it used to be block but if i wanted to add an item now it's just an array of a string so hi um add another item this is a string in my array so that's what it would look like but because we did block remove that changes back to block get rid of this string and now we should have our rich text editor pop back up and it's happy because it's now back to block but that is what's happening so it's an array and you can do an array of lots of different schema types but when you do block and then it creates this rich text editor where we can type in all of our content so here you can have your bio super long and you can just keep writing about all the chef awards that you've gotten over the past years so but yeah with that being said you add a block to the array and we have our rich text editor publish that i think this one yeah publish that all right so now that we have chef all set up and me and bonnie are chefs let's go and let's create our next schema so the next one we're going to create is ingredient so i'm gonna go to schemas new file ingredient.js and same thing export default open that up name ingredient name title ingredient and type is you guessed right document type we're going to do a fields array and open that up and our first one is going to be title or name is name title is ingredient name and type is string come out of that let's do another one we'll do name is image title is image and type is image and we're going to do again the option for hotspot is true great and then come out of that and one more we'll do name is notes title is notes and type is text save that and we need to come to our schema and bring in import ingredient from ingredient and then we have to use it down here save that let's come back an ingredient should pop up all right let's make some ingredients so let's add a new one for our first one let's do pineapple we will upload a picture of pineapple and i don't want to hotspot or crop this so i'm just going to keep it how it is but if i had a big picture and i wanted to crop it down to this that's what i would do notes now i wanted to put notes in here because this doesn't need all this content does not need to go on the front end and this is not going to go on the front end this is just notes for us as owners of the studio to always remember and when you cook sometimes it's great to have notes on ingredients where you get them what you like what you don't like if you like a certain brand that kind of stuff so this is just internal notes for us so i'm going to write um i like to get my pineapples at the local i can type local farmers market it happens every second saturday of the month so notes for me um so when i come into my studio it's kind of like a little diary of my of my recipes so we're going to publish that and let's let's make another ingredient when we will do mango we will drop in a pitcher of yummy mangoes and then we'll do notes um a notes about mangoes uh the seeds are really hard to get out and if you've ever tried to get out the seed of a mango i mean it's really hard so that is the truth all right so we have mango and we have pineapple so our last schema that we need to do is recipe and let's create new file recipe.js and this one remember is going to be referencing the other two that we just made so export default open that up and we'll do name recipe oops name recipe title recipe and type is document open up our fields array open that up and forgot a comma and there we go all right so the first fields object that we want is name so we're going to name title is recipe name and type is string then we're going to do a slug we're going to need slugs later on especially for our front end name is slug title slug type there's a type slug and then under that we're going to do options so the source is going to be the name whoops and then the max length is 96 so if you're if your slug is longer than 96 and then we're referencing this name cool let's come out of that and let's make another one and we'll do name chef we've seen this before somewhere do we want to reference it i think so title chef type ooh type is reference like we saw in the docs and we're going to reference two so we don't have to type out a whole nother schema we're just going to reuse type is chef so it's going to go right to chef and then next we're going to do name is main image and we'll do title is recipe main image type image and then we'll do options of course for hot spot is true and then we'll come out of that and all right so we're gonna do another array but this array is not going to be block so we're gonna open that up we're gonna do name is ingredient we'll do title ingredient i always want to do a colon after the that okay and then type is array and then type is array awesome okay and then we're going to do of open that up type is going to be object and fields open that up again here okay so what this is going to be is a modal we're going to click on like add to like add something and it's going to open up and it's going to be referencing something the ingredient it's going to be giving us option for a number an option for a string which we're going to create a list of an array of strings so there's going to be a lot going on in this little modal but i will walk through all of it with you so name ingredient title ingredient and type is a reference because we don't want to write it all again we're just going to reference straight to and you guessed it type ingredient awesome so let's come out of that the next part of the model so we're going to have an ingredient first item in the modal next is going to be whole number title whole number and type is going to be a number so if you can kind of guess what we're doing is an ingredient is put into a recipe and you can choose how much of something so whole number we're going to do next fraction and then unit so come out of this so the next one is name fraction title fraction type we will do a string string for this string and then we're going to do options because we want to create a list for these strings or a list drop down options list is going to be an array of strings half cup or half fraction one-third one-fourth three-fourths and you can put as many as you want i'm just gonna stop right here so that is my drop down so i've i've assigned what my strings are so it's like hard-coded um these are the only fractions that you can choose on the front end or the studio front end and yeah let's come out of that and let's create one more kind of just like that so name is unit title is unit type is string options same thing and we're going to do list an array of grams cup capital t for tablespoon and lowercase t for teaspoon i'm gonna save that let's go look at it i missed something oh ow we did not add it to schema so schema come in here you need to import recipe from recipe and use it down here awesome all right let's go look at it so recipe so if we click on this no documents here have been created we'll click on that and now we have i'm going to collapse these just so we can see all this our schema that we've created so recipe name uh pineapple smoothie generate the slug from that name chef we can type to search or we can choose one of them here um we'll give bonnie credit for this and then i have an image over here of a pineapple smoothie yeah and we can edit the details if we want to really make sure this pineapple is uh the hot spot we'll do that now ingredient add items we're going to click on this and it's going to bring up a modal for us this is the reference this is the number these are the two lists that we made so ingredient we can do drop down or we can just start typing we need pineapple we need two and a half cups of pineapple okay so we're going to exit out of that and look at this so notice how it says half we want this preview to look a little better we don't want to say half we want to have maybe a picture of the ingredient uh a title and and like a subtitle with like how many of the ingredient we want so we want to change this now sanity has a way to do that and i will show you how so come back to the code back to ingredient no recipe and down here below the array we're going to write preview open that up and we are going to select certain items that we want to use so title ingredient dot name name ingredient dot name um media will be ingredient dot image so we'll be using the image and then we'll do whole number is whole number and then fraction is fraction and unit is unit so we're pulling those out to be able to select them and use them so here we are dotting into the targeted thing so we wanted ingredient but we want the name for the title same thing so we're just grabbing the content that we want to be able to use now underneath select we want to run a prepare let me show you exactly what is going to be happening here so prepare we're going to pull out the title subtitle media whole number we're going to equal that to something because what if we don't have a whole number what if we're only using like half of something so if there's no whole number we'll say no whole number set then we'll do fraction same thing we might not have a fraction set so we want to write no fraction set and then last one is unit and we'll do no unit set okay and then there's one last section and after this we'll go we'll talk about this way more so we're going to open this up to a return and this return is going to be using what we just set in that prepare so title subtitle which we want the subtitle to be whole number and then fraction and then unit and then underneath this we want media so when it comes to preview prepare and return we're generally going to be using title subtitle media and i'll show you because it looks very nice so i'm going to save that and here now it looks nice now there's an image the pineapple is the title and two and a half cup is the subtitle if we wanted to add um more pineapple but we didn't want to do a whole number we just needed half a cup no whole number set half cup so that's what it would look like um and then just so you know you can move these around if needed now let's look at sanity preview so here sanity will often need to render a representation of a document or an object so what we're doing is we're previewing we're showing a representation of something we've already created it's called a preview so we decide what fields should be used again like i said generally title subtitle and media take the cake so here we have a schema laid out and the preview they selected title and subtitle as title here and release date here so here let's look at the prepare so above title and release date are selected but the result of the selection is past the prepare where you can transform the selection however you like so in this case split they're modifying it to be only the year so the whole year comes out but we just want just the first part of that so that's where you can tweak it however you need what we did is we set it like this and then it knows if there's nothing there to grab it will return no unit set or whatever and yeah there's a lot that you can do with this preview and prepare um what we're doing is a good start and it makes the studio side of this look very good i think um so yeah let's add something let's get rid of this pineapple and let's add mango because it's a pineapple smoothie we don't need tons of mango so we'll do a fourth cup of mango okay now when you have a recipe yeah you can have ingredients and a picture and a title and a chef but you need instructions so we need to add one more thing so we're going to come back here and under this after the array after the object right here we're going to do one more and it's going to be name instructions title instructions and type will be array of and i'm making a rich text editor by doing type block i'm gonna save that and let's go look we should have a rich text editor and sure enough we do so this is us being able to like fold it italicize it underline but here i'm going to write put all ingredients into a blender blend on high for one minute serve chilled nice okay so now all of our content is in here and now we can take this content and put it on our front end but i want to show you something real quick so here we have a string we have a slug we have a reference we have an image we have an array of these objects and we have an array of blocks let me show you what it looks like so if you click on these three little dots and you click on inspect this is what our data looks like parsed raw json either way you want to look at it but our data is returned as json so this can be used all over so ingredient unit whole number all of our information is here our slug what our current slug is instructions is going to be block and because we have multiple blocks because i created multiple blocks we have the children that has the text in them so put all ingredients to a blender next blocks next block blend on high for one minute next block surf chilled now see how all these don't have any mark defs and they're all style as normal let me show you what it looks like if i change one sort of chilled we really want to make sure you serve this chilled some italicize that don't forget don't serve it hot we're going to come back to inspect come to the bottom and serve chilled now has the em marks so emphasis and that's what it would look like if i did bold let's do this bold because we want to make sure people really know blend out high for one minute same thing and now it has strong so the marks for this strong marks for this is the italics that emphasized so yeah that's what our content looks like and we have all of our information here here's the parsed version of it main image all the content lives here and yeah now now that we have all that set up let's start pulling it to the front end let's start setting up our next app and let's get rolling with building our application all right so we do need to connect our sanity app to our next app so first we'll make a sanity.js file and we'll put it into a folder that's called lib we don't have to call it lib but just because of convention we're going to call that so we're going to create new folder we'll do lib and within lib we'll do a new file and we'll do sanity.js all right so the first thing we need to do is we need to install the next sanity toolkit so this will come with hooks and functions that are useful when we build with sanity so let's actually look at the next sanity um github repo so we'll do next sanity right here okay here we will see what it comes with some of the features so client-side live real-time preview for authenticated users um url helper for sanity's image pipeline we'll use that um rich text component for portable text again using that um but here we'll see how to install it we'll get the real-time preview which we will be doing that as well um but yeah here we'll just get more information on what comes with the next sanity toolkit we will also be bringing in our project id and our data set into this file and i'll show you how to do all that we'll import the things that we need and export the things that we need to use throughout the app so you can find out all the information here but let's go back to our code okay so the very first thing we do need to do is install the toolkit let's actually go back to this let's look at the command we need to do up up up right here so npm installed next sanity this is what we're going to use you can also use the yarn version but yeah you have both options okay let's go to one terminal that's not running anything and we will paste in that npm install next sanity so we will let that install and all right so now the package has been installed and we can just keep that down we'll just go back to yeah all right so now let's import it and let's import all the things that we need from this next sanity so like we showed in the github repo if you want to learn more about like the performance of the ones that we're going to be using definitely check out this github repo that will have all that that information um but let's just talk briefly about the things that we are going to be using and then once we do use them then we'll talk more about them and see how they actually work so we're going to do import open that up and we're going to do create client we're going to import create preview subscription hook create whoops create whoops image url builder and then create portable text component all right and then this is all going to be from next sanity all right so let's export these so we'll come down and the first one we're going to export will be export const sanity client and then equal that to create client and then in here we need to use our project id so rather than writing out the project id and the data set every time we want to export one of these let's actually do const config is equal to project id and we'll equal that to something in a little bit we'll do data set leave that blank for now api version for blank blank for now and then use cdn and we'll set that to true so let's talk about all these let's get that information so that um we don't have to write it over and over down in the exports so project id and data set if we go into studio and we go into sanity.json we will find our project id and our data set so i'm just going to copy this project id and then remember production for data set so let's go back paste that in and data set production so with a project id you can consider this public so it goes into the url of the apis that you're hitting you can find it again like in the senate sanity.json that we saw and you can also find it in your manage dashboard which i will show you in just a minute and then with our data data set name we picked production when we did the sanity init and again find that in the sanity.json so let's move on to the api version so api version is going to be 2021 03-25 so sanity's api is versioned so that sanity can push out new features and fixes without breaking anyone's stuff so we're going to put in this api version and let me show you where you can find out more information on that i'm gonna go here under api versioning in the docs so yeah and here we'll you'll learn everything about how to handle versioning with the sanity api uh if you want to learn more about that definitely check out this doc but we are going to put into our api version 2021 325. and lastly with our ucdn we're actually going to change this to false i put true just for the time being but we're going to have that be false so you can choose if you want to pull from the cdn that is the global cache network um or directly from the real-time content link we recommend using the cdn in a production environment but on local it can make sense for this to be set to false so you don't need to wait for those minutes for the latest changes so for now we're going to set it to false if you want to change it to true definitely go ahead and do that and now we can finally pull in our config here and it will be using all of that for us now let's work on the remaining of our exports so next we're going to export const we'll do use preview subscription equal that too we'll do the create preview subscription hook and we'll use the config the next one will be export const url four now in the url four we are going to be setting a source so the source let me put it in the source we'll be using create image let me just type this all out builder using the config and then chaining on image source all right so source in the url for is the asset data that we're clearing from the content link so this is the image asset data the asset data that we are querying for we need to make sure we pull that in so that is why we use source right there and then our last one is export whoops export const portable text and set that equal to create portable text no yeah portable text component and then open that up and we're going to do dot dot config to copy that and then serializers and then an empty object now we will be using all of these throughout this course so we just wanted to get it set up so that as we start using them across files it's already been exported and yeah so the last thing we need to do before we can start building out our next app is setting up course so coors controls from which domains a browser can do requests to your content like so enabling authentication will allow requests that uses your token information from your logged-in cookie so you really want to make sure you can only deploy code to the domain that you enabled this for so course isn't needed to do server-side requests it's only for browser so client-side because we typically don't use cookies on server side we use tokens which we will look at later we will be using a token now there are different ways we can set up cores um one of them to come down here we can go to a new terminal and we could do sanity cores add and we can do http and then type out whatever the url is but let me show you another way so we'll keep that down and if we go to our manage dashboard we will see how we can add cores and i'll also show you all the other things in the manage dashboard so if we come up here we go to manage sanity.io all right so here are all of our projects here's our dashboard now the last three studios i've named are all the same name i highly recommend not doing that and doing a unique name for each one because now which one do i pick no i do know which one it is it's my most recent one right here i click on it project id right here remember we found it insanity.json so here's our project id let's make sure it matches up h a j up here aj awesome now throughout here we see like the usage so we're on the free free version so everything's zero but uh if you added to this this is where you would see it you can invite project members members would also be under here but you can add people to this so they have like access to it data sets usage so what your usage looks like and then settings this is where we're trying to go so if we click on settings and here we'll just see general settings the name of it i could rename this um different things but here we're trying to find course origins so we're going to click on add course origins and we have our allowed one which is localhost 3333 and here we would add in the url um i've already typed it in before so that's why you see that drop down but pretend like we haven't so localhost 3000. so we want localhost 3000 to be able to have credentials so course origin settings is saying what control from which domains browsers can do requests to the content link so we're letting sanity know that localhost 3000 can make requests to our content link and we will be using that in a moment but we want to set it up now so we didn't have to worry about it something we have to remember is when we deploy this we have to bring that url that is our deployed url and bring it in here and add it to the course origins now the last thing we need to do is click allow credentials and hit save and we have now localhost 3000 and localhouse localhost 3333. both of these are under course origins and both can make requests and yeah now with all that being said this is all set up and the next thing we're going to work on is the app.js file so let's get rolling on that okay so now that we have next talking to sanity let's actually start building out our next files so we're going to come under pages and we're going to go to app.js so this file encompasses our entire app so we're going to keep it as is and just add to it so i know we are going to want link import link from next link and then we're going to come down here open this return up and bring it down here and then we're going to wrap this whole thing in a react fragment save that and i do know that we want to wrap this component in a main tag because this is going to be our main section of our app still because this is our page props and it's bringing all the information in and displaying it i do want to add an entire i do want to add a nav bar to our entire app that's why i'm going to build it here because i want it to show up on every page it's going to be just one thing that takes us home it's not going to be a very fancy navbar but i did want to make sure we added that in okay so underneath this we're going to add nav and then a div within that that has we're going to be using link that has an a tag inside now the a tag i'm going to do cap's kitchen and let's add a pineapple yeah and then in the link we need to add an href that is taking us back home and that is it so we should now have a yeah cap's kitchen takes us back to the home page if i'm i mean i guess i can click somewhere else and it's always going to be there takes it back awesome okay now all we want to do is add styling so i do know in this nav i do want to add a class name of header i'm going to save that and all of our css is going to live in this global css down here let's empty this out now when you have styling it is always good to normalize your css because when you send your app to um a browser sometimes there's applied styles from the browser so if we kind of cancel all those out we can make sure that that's not happening to us so i'm going to search for normalized css cloudflare and i want to copy this link yeah let's go back here and let's do at import url and we'll put the link right in there oh right like that so now all of our css styling will be correct and whatever browser someone's using won't be changing any of that so we just created the header in here we want to do max width width of 80 we'll do a margin of 0 and auto we'll do padding of 12 pixels and 10 pixels so on all sides and a font size of 25 pixels i also know that i want to style the a tag within header so we'll do header a open that up color okay i want to pick like a green color let's do green i like it i get darkish green yeah let's try that okay so that's my color um display we'll do inline block padding top we will do 10 pixels and text decoration we want none because we don't want that underline that comes with that and we have that main tag that was wrapped around our in app.js so let's do main so max width width is 80 so it matches that nav bar and margin 0 auto padding top of 30 pixels and padding bottom of 80 pixels save that okay so we do want to add a body so that a lot of this can be just encompassing all of our application so we'll do font family and we'll just do ariel yeah and you can choose any font you want i'm just going to go with that one for now and then we'll do a background color of yeah it's like a light gray i'm going to save that and we should have some nice styling but index.js is not like done so it's just kind of like background end of navbar let's get rid of this normalize there we go yeah so there's cap's kitchen and if i went and i navigated away it's always going to be there and it always takes me back so yeah that's what we have so far all right so now that we have our navbar our app.js file set up let's work on our slash page so our index.js file so i'm in it right now and we've done some stuff in it already let's clean out all of the content that was given to us when we did the next uh create next app command okay and then we'll get rid of this because we're going to update that so really we're just starting fresh from beginning we will need this um but we will change it a bunch so i'll just leave it there for now and we don't need this we will use link we don't need this cool okay so starting from the top we do need to import our sanity client stuff so we're going to do sanity client and we're going to pull in url for from and it's to yeah lib and insanity perfect save that all right so now we are going to be getting into grok so we are going to be pulling in our content using the query language grok let's go learn more about it together so grok sanity all right so it is a query language that was made by sanity and there's tons of different like examples there is a how-to section um this is a really awesome doc it starts off introduction basic sorting but yeah i definitely highly recommend looking through this and one that we will use a lot is this dereferencing because we are referencing and i kind of showed you that in that um referencing doc but yeah you will see that here and we have let me show you the cheat sheet i like the cheat sheet a lot of just like examples and what would come out of it so the asterisk gets you everything so it's everything in our content like of content so it pulls everything and then this we will start filtering through what we want to pull out and then you can modify greater than uh not equal to this or whatever but yeah there's definitely lots of ways you can use grock and we will be using a number of ways to get our content but yeah let's go back to our code so here we're going to set const recipes query two okay so here we're going to write our first graph query together um like we saw in the doc the asterisk pulls in all of our content so it is our content lake of data and we always start with asterisks then we're going to open up with square brackets and do underscore type is equal to recipe now this type is equal to recipe is going to pull all of the content here so this is our type that is recipe and if we wanted to where is it if we wanted to see what this returns we could you know continue coding or there is a spot where we can have a grok playground with our own content so let me show you that so i copied that if we come to our studio we have this is our desk view let me zoom out just a little bit so we can see so this is our desk view if we go to vision here is our grok playground for our content i'm going to zoom in just a little bit so this is where it will where you can play and put in grout queries for your content there is a place where you can go grok.dev where there's going to be content already for you you can play around with the queries and hit play and this is what's returned so this is just a generic bunch of content but for our local version this is what we use and here i'm going to actually change the api version to be what we put in our sanity.js file so we're going to do the this version right here and it ran for us all right so here is what we get when we run the query type equal to recipe we have one item and it is our pineapple smoothie here's the name let's say we wanted to pull the name out we would open that up and type in name run that query and we get just pineapple smoothie um if we take that away let's actually add another recipe so we can have two to kind of query up i'm going to go back to desk and let's add let's add a mango smoothie mango smoothie generate that slug and who was the chef for last one it was bonnie okay so i'm gonna take credit for this one and then let me pull in an image this is going to be pineapples or mango smoothie and then we come down here and we're going to add a mango of one cup awesome and then we'll say blend mango with ice serve chilled awesome so let's publish that and let's go back to our vision and remember if i just unzoomed a little bit those would be up here but because i'm zoomed in it creates that menu so click there i'm gonna zoom back in and now when we run this we should have two items exactly there we go so there's the mango smoothie and here is the pineapple smoothie and here's all the content that we are getting back with just the recipe so we are getting the id the type recipe uh the chef and this reference is the id of the chef reference so if we did so let's try and remember this reference but yeah four f e is it different than the other one yeah okay so 4fe should be the pineapple smoothie chef so if i did this chef and we get 2 4fe this reference is now the id of the chef which is bonnie so bonnie was the chef of that one so it's referencing this id and then pulling out all this chef information for us so let's go back to recipe and let's write out our entire query that we want for index.js so we want to pull out the id we want to pull out the name so here we see we want this id we want this name we also want the slug and the slug can be found right here pineapple.smoothie and then we want the main image and that is right here and again this is referencing the id of that image and it's a type reference so let's run this query and here we go here's all the content that we want for our index.js so i'm going to copy this and now that i know it's exactly what we need i'm going to take it back here and i will paste it in right there save that and now we have our query all ready for index.js okay so we're going to come down to the very bottom and remember when we when we did this get static props let's actually clean this out and put in the stuff that we do need so remember get static props is going to take in the fetch so instead of like using a use effect like with react we're going to use this we're going to fetch our data because we've written this recipes query up here we're going to use that so here i'm going to do const recipes equal to a weight and we're going to add async up here and then we'll do sanity client.fetch and we're going to fetch for that recipes query and then we're going to return props because we need props for all of this and it's going to be set to recipes so we have okay so let's go over this so the reason why we do the async await on this get static props is that next.js will pre-render this page at build time using the props returned by this getstatic props so that's why we add it here and then this line we're just assigning recipes to that fetch so all of our content that we are getting in that recipes query and then returning props as that content so now that we've assigned props or recipes to props we can use that up in our function so we're going to remove this and now it's not data now it's going to be recipes we'll get rid of that and let's write out our template and use our content so the reason why we have this in curly braces is it's called a destructuring assignment so what it does is it lets us pick out values inside of the object that is passed through the home function so instead of i mean we could do we could do this so we get rid of this pass through props and then we could do like const recipes is equal to props so we could do something like that but instead we can do the destructuring assignment and pass in recipes here and then we can continue on okay so the first thing i want to do is i want to update the tab so remember the head this title is this tab intro to next so let's update that to say caps kitchen and we will add a pineapple yay and then underneath the head we will start with an h1 h1 and we'll do welcome welcome to and we'll just do cap's kitchen here and that's it for h1 and then let's open this up and we are going to do an unordered list of all of our recipes so what it's going to what it's going to look like is we're going to have our home page we're going to have like caps kitchen and then like welcome to cap's kitchen and under that is going to be tiles that are clickable that has the main image and the title of the recipe and then you click into one it navigates you to another page that we have not built yet and that's going to have all of our recipe content like ingredients and instructions but this we just want to display the main image and the title so let's do that so we're going to do an unordered list within that we're going to do list items and within that we are going to link with an a tag that is set inside that has set inside of it image whoops i'll fix that and spam awesome so in the unordered list we are going to map over our content so i'm going to open this up and if we have recipes so that question mark is if there are recipes then continue on with this then we want the length the amount of the recipes to be greater than zero and once that is done then let's map over all of that so we'll pass in recipes a recipe and then come out of this and we need to take these three and put them underneath the li so now we have a map so we're doing an unordered list and mapping over the list items which is going to be images and names of the recipes so link right now we're going to do an href that is equal to home because what we do want it clicking to is not built yet so let's just leave it at that we'll come down to span and let's do recipe.name we'll save that and let's see okay so we have welcome to cap's kitchen but the content that we're pulling through because this was hard coded and so was this is pineapple smoothie if we click on it nothing will happen because remember it's being linked back to home now let's add in the image so because we were using the url4 we added that in our sanity.js file because we're using that we don't need to destructure the main image and we can use this to help us grab that url of that main image whoops so let's come down here and we're going to image source is equal to url4 and will be recipe.main image we'll come out of that and we'll do dot url now with this url4 we could continue chaining on so we could do it with we could set a height but the most useful part of it is this url we is this url for so we don't have to destructure up in our query we can just pull out the main image and this will take all of that url destructuring work and handle it for us so that's what is happening there let's save and we should have our main image displayed for each one of them and we do okay so we have pineapple smoothie and we have mango smoothie very big images but let's style that so it looks nicer so if we come here i think we have all of that in list items let's actually give a key to each of these so key will be whoops the recipe dot id and then let's just work from the top and let's style these out so an ordered list we'll have a class name that we're going to name um recipes dash list and then we have on the list item we have a class name that is equal to recipe card and that is it yeah okay so let's go style so all this will happen in globals.css come down here and let's write out our css okay so we have recipes dash list open that up and we'll do display is grid grid grid template template columns we're going to do 1 fr 1fr 1fr so that's giving three sections all equal space so one one one and then we'll do a gap between all those at 40 pixels we'll do list style is none and then padding is zero then let's go for recipe card and let's do recipe card and the a tag of that so we'll do display is block height is 100 percent text decoration is none now text decoration now will take off the underline for accessibility it's not always the best but make sure you make it obvious enough that it's clickable but if we kept this it would keep that underline and that underline helps people know that it is clickable so it's up to you if you want to keep that or not so color we'll do hash 444 and then font size will do 22 pixels and then recipe card the image part of it recipe card image we'll do height is 300 pixels object fit is cover we want to fill the entire space that is given margin bottom we want 12 pixels and then border 0.5 pixels solid and then hash 444. save that and let's go see what it looks like so the only thing i don't like about this is that this is wrapping so what we need to do is on image let's add display block and there we go okay so now we have two clickable areas takes us nowhere takes us home but all of this is our tile and if we added another one there'd be another one right here and then if we added a fourth one it would come down here so it's ready to be filled with content filled with recipes all right so with that being said all of that is what we need for index.js and index.js is done um and yeah now we can move on to the slug js file and this is where we are going to have when someone clicks on one of these where does it take them it takes them to the slug of where it takes them to the page of the recipe that we've clicked on so let's get to that okay so now that we have app.js and index built out let's build our dynamic route so the way next does dynamic routes is and remember all of our pages will live under pages and we're going to create a new folder called recipes to organize and within recipes we're going to do a new file and to do a dynamic route we do square brackets slug because that's what we want to replace that name is the slug of the recipe and this is our dynamic route so it means that whenever we go to slash recipes whatever so like slash pineapple dash smoothie then we can access the last segment of the url in our template file and use that data for something for example doing a query to fetch a specific recipe in our case so that's why we want a dynamic row here so we don't have to do a route for each recipe it will just know replace the slug and whenever we access this file we are diving into it with the slug that we want and we will write out all that code so it all makes sense so for dynamic page templates like this but we're going to be writing out we can access the data from the url inside of the get static props so we will do get static props with prams and we'll do that and then we will destructure the params uh within our get static props so then you can find the slug inside of params that will set and without talking about this let's just code it up and let's look at what it's all going to look like so i do know we are going to need to import a lot from that lib sanity file so we will need the sanity client of course we will need the url for we will be pulling in that use preview subscription and portable text so all those things that we made in the sandy uh file are now being used so we'll come out of here and right away we are going to have const recipe query here and this is where grock query is going to live and then we'll do export default function we'll call this one recipe and then in here we'll open that up this is going to be our template and all that good stuff and then very bottom we will have get we'll do export async function get static paths we have not seen that yet and we will talk about that and then below this we will do a export async function get static static props and there we go so here is how our slug.js or dynamic route is going to be set up and yeah let's get working on it so there are a couple things in this that are going to be happening so the use preview subscription we won't be worrying about the sanity preview till the end um and that so that's just kind of going to hang out for a bit the portable text is going to be within our template same with the url for and then the sanity client is going to be whenever we are fetching our content all right so where to begin uh let's start with writing out our grok query yeah let's do that so this query is going to be a little different because we are specifically looking for a slug because that is everything in this because we want to click on something and go to only that slug display the information there so we're going to do the same thing we're going to grab all of our content asterisks grabs our content like open up square brackets and we're going to do type is equal to still recipe and slug dot current is equal to the slug and we're going to grab the first item in that array so we are getting an array of recipes the first item the one that is clicked on the current slug is what we want displayed open that up and we want id we want name we want slug main image so this looks very similar to what we wrote in the last file and we're going to dereference that and get the id and the url now in addition to this so that's pretty much the same stuff as last time in addition to this we're going to also grab the ingredient in that and we want everything from it whole unit whole number fraction ingredient let me pull this up ingredient and dereference that because remember that is a reference to our ingredient and pull out from that the name otherwise we can't get the name if we don't dereference it because remember we didn't rewrite it in the recipe we rewrote we just referenced the ingredient and then come out of that and we will get instructions all right so that is our entire query getting the recipe the slug that is clicked on and all this content from it cool so let's leave the one recipe for a little bit and let's work on get static paths and get static props so because we have a dynamic route that uses getstatic props it needs to define a list of paths that has to be rendered by next so we want to tell next hey here are all the paths that could be clicked on when it's clicked on then props will get all of that content for us so get static paths will allow next to know all of the dynamic paths so next we'll take all the paths that we are giving it and pre-render all of them so getting it ready for the user so next.js is going to want params from this and we're going to tell it slug dot currents whatever slugs are made available those are parameters we're going to pass those parameters to our get static props and it will pull out the content so in here we want to open up get static paths and we'll do const paths is equal to await sanity client.fetch because we want to fetch all of and in here all of the slugs that could be potential paths so we're going to open up a grok query and we're going to do underscore type is equal to recipe and defined slug dot current so this is going to look for the slug dot current that is going to be clipped on open this up and we want to set params to slug that is slug.current so let's look at this for a second so it's very different than the grok query up here this is getting a type of recipe select the current but it's pulling out all the content that we want this is look is pulling out the path for that content now we're going to take this params and we're going to bring it down here but let me not move on from get static paths let's come out of this query and we now need to return the paths so we're fetching all this setting it to paths now we're returning it and that return is going to be able to be used now we need to also do fallback and set it to true so if we set fallback to false then any path not returned in the get static paths will just result in a 404. if fallback true then it won't result in a 404 if the page doesn't exist it will fall back to a version of the page on the first request of the path so fallback false we'll just be like i don't have it it's not in my list of static paths 404 fall back true it will say wait let me go look let me go see if it's there and then re-render it for us and then while it's getting that path it will add it to the get static paths because maybe you didn't build again or whatever it is but it will add it to your paths and put it up here so that is get static paths for us it is getting a collected list of all of the paths that this dynamic route can be so we will save that and let's work on get static props now the reason why we use grok right here is that you can shape the data structure that next wants for this right and grock so we don't have to do all these like well if it's not a slug if it is here just get that slug and set it two params all right so now with the get static props because we have set params to the the slug the current slug we are going to pass that into our get static props because we need those params and the slug that was clicked on in order to pull out the the correct content for whatever they've clicked on your user so we're going to destructure our params in here oops and then open this up and do const slug is equal to params okay so the params that we're sending in is now our slug so now we need to look at the recipe data from sanity and so we'll do const recipe away sanity client dot fetch because we've already written our query we're just going to pull in what we named it recipe query and then we want that slug so we want the slug but the content from that particular slug and then we will return props like we did in the last file and it will be set to data which is the recipe and that is it so we're going to save that now let's talk about this so now we can find the slug inside of pram so the const slug params if we had called our file instead of the destructuring slug if we did a destructuring recipe then the param would be const recipe is equal to params so that const slug is matching up with this right here the naming of the file so you can name that anything we just chose slug so we took this this grot query and pass it to our client like this okay the sanity client fetch and then in the studio the slug is stored as slug dot current because it wants to be able to store previous slugs in the future so the current one whatever it is is slug dot current and that's what is being saved as in the studio so our function get static pass works in a similar way to get static props only you want to export an array of the params that is slugs that you want next to build so we do the grot query for this as well and that that is next next is really great with like being able to build out really big applications but with two very very powerful functions um get static paths and get static props um we're getting our paths and we're getting those props out of those paths and then we're going to pull this up into one recipe and use it up here and send it to our template so from here you could take your next js application and grab any kind of data grab a large amount of paths and put in the temple however you need but this is a great starting point because it kind of covers a little bit of a lot i'm very excited to see what can be built on from this point especially from these two great powerful functions that next has given us okay so the way someone once described both of these to me get a static path and get static props is get static paths is like knowing the address of every house in a neighborhood the aesthetic props is knowing the people who live in those houses and what they ate for breakfast so the path to the house and all the houses and the data and content within those paths so i hope that makes sense um these are both really powerful and good to know now let's move on and let's get our content put into our one recipe okay now something that i realized that i did that we don't need to do is at the top in our query we actually don't need because remember from index.js we had the url4 that took care of pulling out that url from the main image so we can just do just main image but we will destructure the ingredient down here to get the name out and all this is good to go and one last thing i do want to mention is we are passing the grok params as an object as the second argument of the fetch function so we have our params coming in here setting the slug and using that here as the second argument that matches up with what's happening right here this slug so we have a lot of params going around but grock pram's second argument and it matches up to that slug that is trying it's trying to find and yeah so what we need to do next is we need to grab all of the props that we are getting out of this and put it up into our one recipe function so let's work on this part of the file so because it is set to data we are going to pull up here data and then open this up and we're going to do const recipe is equal to data and then down here we are going to be doing the return and let's build out our template so let's start with an article and within that we will have an h1 let's come out of that and we'll have our main section that will have an image and a div next we'll have an unordered list and then the list items we will put there and this unordered list will be the list of ingredients and like how many of each ingredient like a cup or a fourth cup a gram but that will all go in here and then outside of this unordered list we are going to have and i'll just say instructions here uh because we're not going to build that yet but that's where our instructions will go so yeah let's start on the h1 the h1 we're going to have be recipe.name so let's bring in recipe.name let's save that and let's see if that is being pulled out so if we click on that nothing happens because we haven't changed in index.js we have not changed this link so it still thinks it's supposed to be going home so let's fix that so let's delete all that and then we'll do curly braces with back ticks and we're going to do slash recipes because we are following this path so it's diving into this folder recipes and then we're going to do recipe dot slug dot current save that and let's see what happens so if we click on something 404 oh because if you look up here i miss a slash and so now it's just like that whole thing it's going correct but it's not fully correct because we need that slash now let's go try so let's go back home let's click on pineapple smoothie and now we get instructions here and pineapple smoothie so this is the part that is being pulled out and it's working our data is working and we have our list item but instructions here that is hard coded that's not our data yet but this is being pulled out if we go back and go to mango smoothie mango smoothie should pop up and it does all right so let's keep building out this template and let's get going on that so not index but here in slug so in the unordered list we do want to map over our ingredients and the amount of each ingredient so let's do recipe dot ingredient if it's there then map over it and we'll do ingredient we'll come out of that open that up and let's take these three and move it underneath this li perfect let's save that and then within our li we're going to give it a key that is equal to ingredient dot key so that will go there let's open this up and this is where we're going to pull in the amount of the ingredient so we have whole number unit fraction so we want to pull all that out it will be ingredient and if there's an ingredient pull out a whole number let me just copy all this and then we're going to do a break here paste that so we'll do whole number we'll do fraction we'll do unit and then we will do ingredient dot name so notice how this one is just well these three are ingredient whole number but this is ingredient ingredient name it's because we come up here it goes ingredient whole number unit fraction all that but we also have ingredient that is de referencing the ingredient and grabbing out the name and i just want to also point out i did update this to say key now so we're using the key now if we come back down here we're going to add just a space right there so everything's not so crammed and we have the name and let's pull in the main image so same as index we'll do source equal to and we're going to do url4 and it will be recipe if there's a recipe then get the main image and the url of that image now if we save that we should have a lot of content on the page we do okay so we have the image and we have one cup mango if we went to pineapple smoothie same thing and we have all of that so that is great it's looking good okay so then we can come back here and we have the name we have the image let's do the instructions part so like we pulled in from above portable text let's now use it so i'm going to come down here and i'm going to replace this h3 with portable text so portable text what it does is it maps over those blocks that we saw and transforms them into react components and that if we want to we can override and use our own customized components to replace any of the default behavior with that being said let's pull in our blocks let me again show you what our block content looks like so if i go back into the studio so pineapple smoothie if i come down here we have our instructions if i click on these three dots and do inspect we see in instructions type block and we have you just kind of collapse some of these so we have three items in the instructions that are block type okay this first one so see how it says type block if you go into children the marks the text is put all ingredients into a blender so that's our first block our second block is in children blend on high for one minute and our third block is serve chilled so it's grabbing all of those blocks and this is what we see here but the rich text editor this is where we edit all of that and we can do like bold italic and it will show up that way on our front end so it will take that styling with it now if we go back portable text takes in blocks and then it will take in recipe dot instructions save that and we should get all of the instructions blocks and that should be displayed so let's go back to cap's kitchen so at cap's kitchen we'll go click on pineapple smoothie and we should see our blocks and they're displayed just as we had in that rich text editor strong emphasis and yeah if i wanted to bold the chilled part bold publish that and then there it is sort of chilled with bold strong until and that is our template now what is left is styling because very large image and then that so what we're going to do is we're going to put them next to each other so let's do on main let's do an article we'll do class name is equal to recipe on main we'll do class name is equal to content and then this div we will do breakdown this unordered list will get a class name of ingredients and then this list item will get a class name of ingredient so singular and portable text we'll get a class name that is instructions save that and something that i forgot on our images is we want to have alt on our images so we'll do alt is equal to recipe dot name yeah and then we should do that on index.js right where's my image right here we'll do alt equal to whoops it's equal to recipe dot name save that and yeah let's go style and then we'll go look at it so we'll go to global css okay so we're going to come down here and we're going to start with recipe the h1 and we'll do font size is 48 pixels font weight bolder color we'll do hash 00 and margin bottom 15 pixels all right and then underneath this we will do content open that up and display grid grid let me pull this up we'll do that oops okay one fr and one fr so they're going to share the space and then we'll do a gap around them at 30 pixels coming out of that the recipe image will get border 0.5 pixels solid and then hash 444. then breakdown breakdown is going to have display grid grid template columns at 1 fr and three fr so like one and then three so like more space underneath here we'll give it a gap of 10 pixels and a border of 0.5 pixels solid hash 444. underneath breakdown we'll do the ingredient so not plural or ingredient so plural and then we'll do list style none so it takes away that that uh that bullet point that comes up we'll do padding at 25 pixels and 10 25 pixels and 10 pixels so all sides and then border right 0.5 pixels solid hash 444 and then we have ingredient so now we're at the singular one ingredient and we'll do margin bottom of 15 pixels and then the last one is instructions and we'll do padding at 15 pixels save that and it should look pretty nice let's go look and it does i like how that looks so we got our image we've got our ingredients and like how much and then the instructions let's go back to cap's kitchen let's click on mango smoothie and it should have the same stuff and it does and looks great um yeah so you can style however you'd like but this is just kind of like a good start to styling a recipe page there's one thing i do want to add that we haven't done yet you don't have to do this but i added it to mine so i definitely want to show you all if you go to hero patterns here you can pick fun backgrounds and let's say you pick this piano one you can change the color of the foreground change the color of the background and the opacity of it then you grab the url i already have one so i'm just gonna put it in but this is where you can grab it um you would just get background image this whole thing and use that so i'm just going to grab that that css styling i'm just going to put it in if you want to add it you definitely can it is my background image and it is little foods very fitting for a recipe app but that is just something that if you'd like to add you can i think it's really nice it's just like a very slight opacity and yeah so you can add that if you want all right so slug.js is built out we have pulled in all the things that we need we have our query and remember i updated this and the main image so be sure to do that and in here we're passing in our data using it throughout our template mapping over our ingredients and the whole number and the fraction all that we have our portable text and then we have get static paths and get static props so with all that being done we are really using the power of next js and this file can really be built on you can have a lot of content going in through these two functions and then passing it into your your template a lot can happen with the get sag paths and the get static props with that being said i do want to move on to api routes within next.js so how we're going to do that is we're going to add a like button so a user on the front end can click a like button and it will update a number on the front end and then it will save to the content link and we'll be able to see that in the studio an updated like number so somebody clicks on the button it says plus one or one more than what it was before and then it patches that to the content lake and then updates the sanity studio so the front end facing of it so let's get working on that and let's get our api route set up in next okay so let's build that like button we do want to have some interaction with our users and the like button i think would be a perfect addition to this application so that button will live right underneath the pineapple smoothie right underneath the name of the recipe in the slug.js version of that recipe all right so we need to add some things because every time someone hits the like button it will be like a little button with a heart on it and every time they hit it it will increase for them they'll see the number increase but then that will save to the content like and then that will update in our sanity studio so we need to add that to our studio so that it can update somewhere and show us the current live number of our likes so we're going to go into within studio schemas go into recipe and at the very bottom right under instructions we're going to add name is likes title likes and then type will be number awesome and then we're going to set an initial value so outside the fields array we'll do initial value and set that equal to likes is zero awesome okay so let's go look in our studio to see if there is a likes spot now so we'll come here and it should be in our recipe because that's where we put it and sure enough there's likes so every time it's clicked and it's saved to the content link it will reflect here and we'll be able to see that then the last thing we need to do is add it to slug.js into our query so save that so now we're going to be working with api routes within next.js so api routes will live still where all the other page routes are under pages so these are our other routes api is where all of our api routes will live so when we did create next app it gave us the hello.js1 we're going to create our own one so under api do new file and we'll do handle dash like js now api routes will because they are serverless functions they are node functions they will run on the server side so every time this is hit it's going to be running pages api it's running the api route of our application so we need to pull in a couple things we need to do a couple things in here but let's take it one step at a time and we'll do it together so we do need to import the sanity client from libsanity awesome and then right below this we need to do sanityclient.config open that up and token right here token here so right here we're going to have a write token so every time it's clicked saved to the content link it will write to our client and update the studio so we will get that token in just one moment but let's continue on with this serverless function so then we'll do export default async function like button handler and we'll do rec so request and res response open that up and we'll do const id we'll set the id to json.parse rack.body oh i forgot the equal equals great and then we'll do const data equal to await sanity client and then we're going to chain on a number of things that allow for us to do what we need this like button to do so the sanity client can do a number of things and as we chain on some of the different functionality of it we will be able to update our like count i'm going to pull up the sanity client information on the this package but we are using the next sanity one i just wanted to show that it also can be used in the sanity slash client now if we come down here i want to take us to the patch update document okay so some of these we will be using so let's talk about them we will be using patch so document id to patch we will be pulling out the id we will be using increment increment field by count so every time someone clicks on it it's incremented by one and then we will do commit because we want to commit that we'll do a catch so any errors we're also going to be using right here set if missing so set if missing we will set likes to zero if there is if it's missing if the information's missing and then yeah that's all i wanted to cover here now let's go write it out in our serverless function so right here we'll do dot patch and we'll do the id we'll do dot set if missing and this we will set likes to zero then we will do increment we want this to be likes is one so it will increment by one every time it's clicked and then we'll do commit because we want to commit everything and then we'll do catch error oops catch error and then console. log error awesome so that is our chain for making this work then we're going to do res.status will be 200 dot json and then likes will be data dot likes all right so i just wanted to also point out that we won't be doing any checks so we won't be doing a lot of security here um we will be keeping our token saved safe in an environment variable now to make this finally work we do need this token so remember when we were in manage and we went we saw our our project id we updated the course origins here is where that is where we're also going to get our token so let's go here and go to manage sanity.io switch to new version and then go back to our project so we're going to click on settings and then under api settings we're going to click on tokens and here we're going to add an api token so we can name it we'll do next recipe up like i have right here next recipe app and it will be read and write save that and here is the token by the time this goes live this token will be deleted but this is what it looks like i wanted to make sure you all saw this i'm going to copy this token and this is what we're going to use in our env file so we're going to come back here so let's collapse all of these and we're going to do new file we'll do dot env dot local and in here we're going to call it and here we're going to call it sanity write token equal that and paste that in save that and we're come to we're going to come to our get ignore and then here we're going to add env.local so when we push it to github this will not be pushed because we do want to keep this token safe but that's how it will look and again be sure to put it under your git ignore now with that being said let's go add that token so this will now be process dot env dot sanity write token save that okay so now our token is being used here and last thing we need to do is create that like button and get it to use all this functionality that we wrote that we wrote out so we'll go into slug so now that we are in the slug we need to add state because we are going to be using so import use state from react and then down here we are going to [Music] set our state for our likes so that our state can be updated as the user interacts with the like button so we'll do const likes and set likes and we'll set that equal to use state and if there's data and if there's a recipe get the likes likes okay and then underneath that we're going to write out a function that uses our serverless function that we just made so we're going to do const add like equal async open that up const res await and then we're gonna fetch that slash api slash handle like come out of that and then within that we'll do a method post because we're posting we're updating and then body will be json.stringify and we'll do underscore id is recipe dot id okay and then right outside of this we'll do a dot catch error and we'll do console.log error and then underneath that we will do const data is equal to await res.json and then we'll do set likes and set that to be data.lakes okay so now let's use this function and let's make a button out of it so underneath the h1 is where our button will live so we'll do button and then within here we will use the likes and we'll come out of here and we will add a heart save that and within our button let's give it a class name because we do want to style it class name is equal to like button and then we'll do an on click so whenever it's clicked use that function that we just wrote out the add like one up here all right so let's go style it and then let's go look at it so in styles as you guessed global.css let's add our like button styling so we'll do dot like button and then we'll do font size at 18 pixels display is flex align items center outline none we'll do background of none so we can see our fun background behind it and then we will do border radius so just giving it a little rounded edges edge five pixels border one pixel solid hash four four four padding we'll do six pixels and 12 pixels so all sides and then margin bottom 40 pixels and cursor pointer so people know that it's clickable okay oh and then i didn't save this let's save that and we should have a button let's restart our servers because we we did a lot so let's restart sanity to end it control c and then i'm gonna do sanity start and then for my next app same thing not sanity start uh npm run dev okay so that is now running now let's go back and we see a button um let's click on it and let's see what happens and we get a one okay now the big trick is was are was it saved to the content like and was our sanity studio updated and it was okay so everything's working and pineapple smoothie now has one like and if i click here again we should get two and we should have two okay so our serverless function our api route is all working and if we go to mango smoothie it should have nothing and then we should have let's go to mango smoothie click one and one okay so all of that is functioning correctly now our users are able to interact with our application and um yeah we have api api routes set up with our next application it's saving the the like every single time it's clicked to the content link sending that to our sanity studio and updating our likes field so it looks good now the last thing we want to do is we want to set up preview so for content editing it's a very quick live preview of edits happening in the studio onto the front end but let's get that all set up all right so the last thing we need to do before we push to github and deploy this is we are going to add preview so you might remember in top of this file the use preview subscription that came from the sanity.js file so now we are going to use it so we are going to be adding a couple of lines of code but those lines of code will do a bunch of stuff for us so the way we're going to use this hook this preview subscription is that if the preview is enabled we want to start listening to changes that's done in the content link and then replace whatever content you have on the page with that content and we can do that since next uses react so let's start with adding these lines to our slug.js file okay so we're going to come down here and we are going to pass in preview preview will come from down at the bottom of our page so in the get static props we are going to add in preview is true all right and then come back up here to at the top of the one recipe function and we're going to add const data and then set that to recipe is equal to and we're going to use preview subscription and then we're going to use the recipe query so that query that we wrote above open this up and we're going to set params to slug which is going to be data dot recipe if there's a recipe the slug dot current and we're going to do initial data set that to data and then enabled preview all right so let's talk about these so params here works the same as the client this is where we can dynamically add information to the query to find the correct recipe by its slug and then initial data is the data it should return before the real time updates start up so typically this is the data that comes through the props via get static props and then enabled here this controls if the preview should be activated or not so if you plan to put this to production you need to have a way for editors that are logged in to be able to activate the preview so that can happen through setting up an api route that redirects you to this page with preview enabled or some other way but next js does have a guide on how to set this up and you can of course join sanity slack community and ask there too we're just going to enable it from get static props for now and then we set up the index.js file to also be set up this way but we are only going to be focusing on the slug.js side of things so the clue here is to make sure that the shape of the object you pass to initial data is the same that you get out of use preview subscription and that's pretty much it so with all this setup behind the scenes this use preview subscription this hook knows if you're logged into your sanity project and if you are and preview is set to true then it goes and it fetches your whole content link in one request and then puts it into your browser's memory then it uses one additional request to set up a listener that creates a real-time connection to your hosted content link and updates the browser whenever there's been a change and we will see that live here in this course so then it re-renders the page component with the new content so that means it doesn't have to do a ton of api requests so since it uses this real-time connection you don't have to think about extra authentication for the preview as long as your editors are logged into their sanity studio so this is also why we needed to enable authenticated requests when we set up our course setting so you should only enable this for domains that you control the code on that's why we did here localhost 3000 and when we when we deploy it we'll add that deployed url it's also possible to add the preview experience to the sanity studio so that your editors can access it in a more seamless way okay and then the last thing we need to do is we need to remove right here this const recipe data because now that is being taken care of right here for us so we got rid of that line and now that's all here so be sure to delete that line that was down here okay now that that is all saved let's go check it out okay so i'm going to pull my studio tab out and then let's just bring this over and we'll just do half screen for each for the next side and the studio side okay so let's see this do live preview updates so we'll click into mango smoothie and here we have mango smoothie the like button is still working we have two if we click again it will be three and that is updating down here so that's all happening but watch this so if i click into recipe name and right away we see the update happening so like i explained all before what's happening behind the scenes now we can actually see what's happening so if i wanted to say yogurt and mango smoothie there we go we we do that and then we can do like let's add an item oh we'll just do pineapple um we'll do so see how pineapples showed up we'll do half of a cup of pineapple and as i'm working in the studio we're seeing that live update so then if we go to pineapple smoothie same thing we do recipe click on pineapple smoothie and we'll do maybe we don't want any mango so we'll delete that remove it and right away it is removed from our list so that is the preview that we have hooked up it was using or it is using the use preview subscription that we added to our sanity.js file and to recap what is happening here is it is saving the changes to our content link and replacing whatever content you have on the page with that content and because next is react we can do that so yeah using the use preview subscription creates this live preview update for us all right so now we have our entire application let's make this big again we have our entire application set up we have cap's kitchen taking us home we have two recipes and if we add it it would just keep tacking them on to this page we have pineapple smoothie and we have a like button that every time we hit it patches to our content link and that will then update our content in our sanity studio we have our pictures we have our ingredients we have our instructions now from here we go back we can go into mango smoothie and we have our information here as well and it's laid out all very nicely and if you joined me in adding this background image uh maybe you picked something else but i picked the popsicles and donuts and food so i thought it was very fitting for a recipe app and yeah it is all set up it's all good to go and this is a great starting point for any of your next applications we did uh dynamic routes we did regular routing index we did api routes we did styling we did a content back-end with sanity we saved everything to our content link and pushed it all to the sanity studio now what we need to do it needs to be pushed to github and it needs to be deployed so let's work on that and let's get that url so we can send our new next.js app to all of our family members so they can see all of our cool recipes and they can add likes to the ones that are their favorites so let's get working on that so before we move on from preview i did want to mention we haven't really dealt with draft documents in the code and how sanity currently works with draft documents so when you hit the like button when you're editing a document you won't see the number reflected in the studio it's of course possible for us to add a bit of code and logic to deal with this but the point here is to learn about next api routes so once we added preview because sanity created a draft document things might get a little off with the likes um you can remove the preview part of this if um you are not interested in learning further about this but if you are definitely keep it in and definitely go ask questions in the sanity slack community if you'd like to get get that all set up but um we wanted to cover next api routes and by keeping it simple we didn't dive too much into how draft documents are handled but just wanted to cover that and let you know that if you need further help definitely hit the sanity slot community and remove it if you just don't want it now the last thing we need to do is in slug.js and i wanted to point this out so we have fallback set to true so because fallback is set to true i wanted to point something out that next wants from us i want to paste this in we need to create so this is the document or the docs fallback pages because it's set to true because we have that in our code we do need to have a loading page so as it's getting the data if the first time it runs there is none let's have a loading page and then it can continue running and then put in our data so we're going to add a line kind of like this if the page is not yet generated it will display this loading page so we're going to go back to our slug.js so right here we're going to do const router is equal to use router and underneath we'll do if router dot is fall back open that up and return div that says loading dot dot and then we need to bring in the use router above come down here and we'll do import use router from next router and that is it that's all we need all right so to get this now pushed to github we are going to come into our terminal we're going to do get init all right and then we are going to go to our github so go to your github and click on new for new repository and here we are going to name our repository so that's where i'm at we're going to do next recipe app come down here i'll make it public so all of you can see this code and then come to the very bottom and click create repository so it's going to create it and we've already done the get in it we are just going to follow down these instructions so git commit dash m get commit dash m we'll do first commit and there's all of our file files and folders that need to be committed get branch dash m main git branch dash m main awesome and then back here we are going to copy this whole thing so that we can direct it to the correct repository hit enter so we're going to add all these so we're going to do git add space period to add all of them get status and we see all them that are added in so then let's do git commit dash m recipe app hit enter and we'll do git push origin main and that is going to push and now if we go back to this we should see recipe app so now we have all of our code saved into our next recipe app repository so let's go deploy it so let's do our back end first so to deploy our sanity back in we are going to i'll just add another one here i actually don't need to pull that down we will cd into studio and we are going to run the command sanity deploy it's going to ask us a series of questions so studio hostname this needs to be unique um we'll do uh caps kitchen for mine uh so make sure you choose one that's not cap's kitchen because that one is taken and it's available so lucky for me so it's building that out now if you wanted to undeploy this you could do sanity undeploy and that would refer all this but while that deploys we are going to have our studio now live at cap's kitchen dot sanity.studio and we will have a deployed version of our back end of our studio uh our content link is going to be living here and it is ready success so we could click on this but i want to go type it in caps kitchen.sanitylstudio capskitchen.sanity.studio enter and here is our deployed studio so we have all of our stuff chef ingredient recipe everything that we put in there is now deployed now whenever you need to like update something or you're working on a team if they have access to this studio if they have access to the content link that is cap's kitchen then they will have access here and then they can go in they can edit stuff you can see your team working there's the presence api up here um their avatars would show up if they're hanging out um but yeah that is our deployed back end now let's go deploy our front end so we're going to come to for sale i've already logged in and i already have searched for the repository so all you got to do is pick the organization and search for um your repository so i did the next recipe app because that's what we named it and i have found it now we are deploying to versailles it's a deployment platform for front-end developers so we are deploying our front end to versailles and let's see how this goes so we're going to click import now project name we can name this anything we want i'm going to keep it next recipe app you can change this here it is root directory now we don't want to change any of these these will just stay as is but environment variables we do need to bring in that right token so i'm gonna do sanity write token and let's go get that so it is underneath our env local let's copy this whole thing and then come back here and paste that in we're going to add it now it's encrypted and it's in there so now even though the dot unv was not pushed to github next is vercell is going to see it because we've added it here and yeah we're good to go so i'm going to hit deploy and fingers crossed everything goes well and we'll have a deployed app that we can send the url to all of our family members and they can see all of our recipes and they can like all of the recipes because they're going to like them no matter what they're going to be delicious and it's deploying fetching the source code building so we could be watching the build and it looks like it's going well okay so it's continuing to build and it should be not too much longer and we will have our deployed front end and back-end we already have the back-end and congratulations okay so our app is now deployed we can hit visit and it should open up a new tab and it has our whole application and we can click into things and we can see ah what do we need to do we need to tell manage.sanity.io that this is a trusted url so i'm going to copy this i'm going to go to manage and in here studio settings course origins and we need to add this one so notice how our sanity.studio was added um we don't need to worry about that but we need to add the versailles side so paste that in there allow credentials save and oh yeah there it is awesome we'll come back to cap's kitchen and if it all worked then we should be able to click in and there we go all right so now everything is working everything is deployed if i hit the like button and then i go to my deployed cap's kitchen what did i hit like on pineapple smoothie and i go to pineapple smoothie i should see four four likes awesome so everything is working and we have it to github we have it deployed to versailles for the front end sanity for the for the back end and you can use that url you can do with this app as you'd please but you do now have a good knowledge base on next js so you can take this however far you want or build another next.js application and take it however far you want and yeah i think it turned out pretty great first of all thank you thank you for sticking around thank you for going through all this with me and great work everyone on this amazing next js application that we've built we've looked at how to set up next and the overall structure we've looked at how next uses file based routing we've explored how we can do performant linking between views in next we have touched on styling and how to change the meta tags and how to deal with static assets now our recipe app wouldn't be much if we didn't use any recipes so we used next powerful data fetching functions get static props and get static paths to handle getting that recipe content for us and pre-render whatever recipes we had to give all of our visitors a faster and neater experience now we have also learned about how we can get up and running with structured content using sanity.io so we have configured sanity studio to make a custom way of entering the recipe info into a structured manner so that we can pull it from our content link and put it onto our next js app we have also learned about next.js api routes and that lets us quickly set up serverless functions to handle business logic for us without any configuration we use some business logic to make a like button remember and that patches an integer in the recipe document to our content link and we added that interactive feature to our app in about 10 minutes so really great and lastly we set up real-time preview in less than 10 lines of code which lets authenticated editors see how the content is presented before pushing it to production this was possible because sanity.io's content link is built to be real-time from the ground up and because next.js uses react that lets us trigger re-renders in the browser when something changes now next steps next next steps to advance so you should know enough to do useful stuff with nexjs there's still a lot that we haven't really touched too much on and although the people behind next.js spend a lot of time to make it performant there's still things that we can do to optimize it we haven't done too much with the seo of this app but there are many ways to leverage next.js and the structured content we get out of sanity to make that happen and we have barely touched on the surface of what we can do with the combination of serverless functions api routes and the content link both in terms of adding interactive functionality but also comes to making it secure and resilient in a production app so if you want me to make a more advanced course on next.js let me know in the comments below again thank you so much for hanging out thank you so much for building this app with me i think it turned out really good i like it but i'm excited to see where your applications go how you design it because my css doesn't have to be your css and where you take this recipe app to so if you'd like you can send it my way i am on the slack for sanity and you can also find me on twitter at copej underscore okay my dms are open and i would love to see your deployed recipe applications again thank you so much for hanging out and i will see you around
Info
Channel: freeCodeCamp.org
Views: 111,253
Rating: undefined out of 5
Keywords:
Id: 1WmNXEVia8I
Channel Id: undefined
Length: 158min 25sec (9505 seconds)
Published: Tue Jun 01 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.