Build and Deploy a Next.js Blog with Remote MDX Content Files and Nextjs 13

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello and welcome I'm Dave today we will build and deploy the final project for this next js13 series and I'll provide links to all resources in the description below I'll also provide a link for you to join my Discord server where you can discuss web development with other students and you can ask questions that I can answer and receive help from other viewers too I look forward to seeing you there earlier in this series we created a next JS blog that uses markdown files and the last time we touched this project was in lesson 10 so the completed code from lesson 10 is today's starter code that you see over here in the file tree you can find the code for lesson 10 and for all other lessons at the course resources Link in the description we were previously storing our markdown files on the server and you can see them here in our blog post directory and that works but it also means when you add or update a markdown file in your project you need to redeploy and that's it's not really ideal so today for the final project of this series we're going to make some major changes to this blog project and I'm going to move a little faster today because we really have a lot to cover if I'm moving too fast you can pause the video and the source code is available under Lesson 12 in the course resources I also want to note that next js13.4 was just released and also the beta docs I've referred to throughout this series are now being redirected to new docs pages that means no more beta docs now this was a bit challenging with the docs updating literally while I was making this tutorial but I've managed to put some new things in here as I've reviewed the docs while they have updated okay let's start by installing the latest version of next JS currently in the last lesson that we had this code in we used 13.2.4 but let's go ahead and get the latest now with npm I next at La latest and we'll install this latest version and we should see it update to 13.4 where it is next again here we are 13.4 so when it finishes yep we've got next 13.4 so the first big change we'll be using MDX files now instead of just regular markdown files so what is MDX well I'm going to put a link to this in the description of the video and in the course resources also scroll down here real quickly and we can just look that it says markdown for the component error so MDX allows you to use jsx in your markdown content essentially it's going to make our MDX content more flexible than just normal markdown files would be our next big change today will be pulling MDX files in from a separate remote GitHub repository using the GitHub API and this really solves our biggest problem by using a GitHub repo for the MDX files we'll be able to update or create new content and push it to the remote repository without needing to redeploy our next JS site and then by utilizing xjs revalidation that incremental static regeneration that we set up with three validation settings we'll be able to see the new content so hopefully you already know how to use git and GitHub and if not stop this tutorial now and go to my get tutorial for beginners otherwise you'll not understand the next part of this tutorial okay so going forward here you want to take the blog posts that you have in the current project and that was in the blog post folder and they had the extension dot MD for markdown files take those and either copy them or just drag them over into a new folder and a new repository like you see I have here this is a different folder a different git repository and I have changed the files to MDX as you see also previously we just had title and date meta tags up here you want to go ahead and add a tags also and notice it's an array and you can put in the topics like hashtags that this topic would be found under so we can just see that at the top of each one of these and then some other things you can add are code Snippets if you know how to write markdown already it certainly helps because you can put in a code snippet and this just shows an example of that let's look at this one here and you can see I've put in a typescript it's abbreviated with TS and we've got this code snippet right here now later on we're going to create a couple of components also so you can pull in a video like you see here and we'll update that later also another one's going to show maybe a image here's a custom image we're pulling in so you can see we can do things with MDX files that we really can't do with just markdown files so we'll tackle those extra components later but right now create create the MDX files and add the additional tags header up here with a few tags you think apply to your articles or just whatever you want to make up for now as an example okay after you have accomplished this you need to go ahead and initialize a git repository as you can see I have done here and then you want to go to GitHub and create a new repository there link the two up and push these files there so you're storing them on GitHub now you can see my GitHub repository here now we're going to use the GitHub API to request these files because if we do it when we're unauthorized they actually rate limit you to 60 requests per hour and you would quickly run out of those especially during development so much better to set it up with the GitHub API and just make sure you're making authorized requests then they give you more like 5 000 and that should be plenty okay so we'll go to the top right here where you see your icon in GitHub because we need to create a token to authenticate with the API so we're going to go here and then go to settings and then we're going to scroll all the way down on the left hand and go to developer settings and then we're going to go to personal access tokens and then tokens classic and once we're here we want to click generate new token and then click generate new token classic now GitHub may ask you for your password before you get to the screen and then of course you can put a note here what's the token for it you're essentially giving it a title so I'm just going to call this test token and of course I'm going to delete this token after this tutorial but it's for a public repository I'm not really hiding the information I'm just going to make authenticated requests with GitHub so I don't get rate limited and so the only scope we need to give it is the public repo here so just check that also for expiration you can choose no expiration again you don't have anything you're protecting here you're just making authenticated requests so no expiration public repo your name there scroll all the way down down and click generate token now after you've generated the token you'll get a screen like this where you can see the token it says make sure to make a copy of this now because you won't be able to see it again so you can just click copy right here and we're going to go back to the project and put it in our DOT env.local file right away we're back in our next JS project and we want to go ahead and put this GitHub token inside of our DOT env.local file so I'll call this GitHub underscore token and say it is equal to and I'll paste in the value and that's all we need here for now okay let's scroll up in the file tree now and let's go to our app directory and let's look at our root page TSX file here and just click allow there is it asks me that every time I think let's go ahead and do alt Z to wrap any code that we want to see there and we're going to make a few changes here as we go one thing we want to do here at the top is I'm going to change this main element to a div I want lowercase but I want to do that because I'm going going to just put the main element inside of the layout here in just a moment so I'm also going to get rid of the padding the psx-6 there so we'll go ahead and change that and now we also will need to add a typescript error comment just because this I don't believe has been addressed yet in an edition of next.js so we're going to need to put this in here just saying that the post component will need this when we change the post component after that I also want to import in the profile pic we're only going to use it on this home page now instead of every page and we previously had it over here in the layout so I'm just going to cut or yeah Ctrl X to cut that import here and paste the import here at the top and then we're going to use the profile pic just above the class name here so I'll say my profile pic and go ahead and add that component as well now one more change we're going to make and I know that this red squiggly May bother you temporarily but after we make the posts it will go away so one more change we want to make here right now we're using an HTML entity here because in a previous lesson we had a build error because of putting in the apostrophe that we would have just right there with the word I'm let's go ahead and remove one of those and now let's go ahead and use it because we might put in an apostrophe in one of our MDX files as we're writing an article that could easily happen and we'd rather just set up the es lint rule to skip that error so let's save this file as is and now let's go to our eslint rule file which is Dot eslintrc.json and I've pulled this directly from the docs so you could also look up eslint there but what you need to do is add a rules object and then inside of this you put react slash no unescaped entities and just choose off and that will of course ignore that rule that was preventing us from building when we had an apostrophe in there okay let's go to our layout page now and we're going to change a couple of things here too one is we already removed the import for my profile pics so we'll remove it there as well the next thing we'll do is after the navbar I guess I didn't need to delete that empty line let's scroll up here where you can see it but after the nav bar we're going to put in a main element here and I've got some Tailwind classes on it let me go ahead and press alt Z and I want to put this closing tag of course after the children here so put it right there and save and you can see I'm using some of the same classes that I had used in the nav bar and heading as well remember from a previous lesson if you looked at that one we use this Pros class here from Tailwind CSS and that goes ahead and applies some general Styles overall and we're using the same width on everything so I've applied that to a few and you can check those out in Tailwind if you're not familiar with those one other thing I would like to do that we didn't previously do here is just import The Meta type that is available so we will import and we'll go metadata and that comes from next so there we go and now we can use that type here let's see what the type is currently and we look at it and it says it's a metadata type but I guess we could just spell it out here by using it I have used that in the past after these changes we're ready to go to the components folder I need to just add one class here in the nav bar and it's going to go to this first div that we have here after the nav element itself and I'm just going to put in a medium so it has a break point here that's what that is in tailwind and then a padding of six just so it matches some of the rest of the page we could alt Z here to have all of this code show but we really haven't changed anything else it shows the icons and it has the heading for the navbar okay now it's time for a little cleanup so we'll go ahead and close up that components directory for now and the blog post hopefully you've moved those to a new repository because I'm just going to delete this folder now we do not need those in this project any longer after that we have a few dependencies that we will no longer need so let's look at the package Json and we're going to remove gray matter remark and remark HTML so these two right here and gray matter up here are no longer needed so let's go ahead and open a terminal window say npm uninstall and we'll say gray Dash matter and then we can say remark and then we'll say remark Dash HTML press enter and we should see those leave our project we can verify that up here now we no longer have remark and we no longer have gray matter so we have definitely got fewer dependencies right now but we will be adding more okay let's close the terminal window let's scroll back up now to our lib directory because if this red file here in the page TSX is bothering you as much as is me we want to change that function so when we call it in the posts that we no longer have this problem here so we'll come to the post.ts file and now inside of this file we're really just starting over so let's go ahead and Ctrl a to select all and just backspace and get rid of everything inside of post TS and we'll start over in this file I'm going to start by defining a function so it's export async function and it's going to be git posts meta and then this function inside of it is where we're going to request some GitHub data but we need to do something first we need to set up a type that we don't have so let's scroll down in the file tree all the way down to our types.d.ts file here and we previously had a blog post type let's just change this name to meta it's going to have an ID that's a string a title that's a string a date that's a string and let's add tags and if you remember from our MDX files that is going to be an array that holds strings so we'll just put in that type and now back in our post.ts file we can add the type here for this function so here I'm going to say promise or return type I should say and it's meta an array of metadata or it could be undefined as well and so we'll go with that and now just to save time I'm going to paste in the fetch request to GitHub I'll press alt Z here so it wraps down you might want to get this from the course source code or you could pause to see this full URL but we've got the api.github.com repos then I have my username and then another slash and then the repo name which for mine it's just test Dash blog post then you have get trees Main and then you also want to put the question mark and put in this one param that is recursive equals one and that will flatten out the repo so you can just get everything from it here as objects and then the other things and of course I looked at the GitHub API documentation you could go do that as well but the other things you need here in the header so you've got accept and this is a specific type of day data we're accepting then this is important here this is where we're passing in that GitHub token we created so the authorization header must start with Bearer and then it has a space and then you want to insert the GitHub token and so this is a template literal string and then here you need this GitHub API version and this is exactly what they have in the docs right now so that's why I have it there as well now we did say the return type could be undefined and that's what we'll put here underneath so if the response is not okay we're going to return undefined and then I'm going to add a type here at just above the function and I've named this type file tree this is essentially the file tree that we're getting from the get trees here in this URL when we send this request we're going to get this back it's going to have a tree and then inside of there it's got the path and the string and we're going to want to get that string out of there and I should add it this time if you want to copy this URL or make your own URL for your repo you could just paste this in a browser and it will make an unauthorized request but that's okay you get 60 of those per hour so no problem there just go ahead and put that in and you should be able to see what this will return okay let's scroll down and continue to complete this function let's look at the next couple of lines here so I'm defining a repo file tree this is what we're getting from GitHub it has the type file tree so we're just awaiting that Json data but here this is a little more important just a little more complicated I want a file array and so I'm using that repo file tree and we're mapping over each one of those and getting the path as a string from the object and that's important before we filter because if not if we just try to filter here without map we're going to have an object so I'm chaining map and filter together so after we get just an array of strings then we're filtering those to make sure they end with the dot MDX extension because later on and you saw in my repo already we have an images folder and some image files and we don't want to try to process those we just want the MDX files okay scrolling for a little more room we'll add the next couple of lines and review so now we have got posts and we're creating an empty array here that will hold metadata and that's fine we're going to go ahead and loop through that metadata and I'm using a 4 of loop because I want to await inside the loop and it's usually better to use something like four of in that case four each will not await just so you know I've got a separate video on that anyway we're going to each post then we're going to create another function here that processes each individual file because then we'll have the URL the path that we got up here for each file and then if we have the post we're going to get that metadata from there push it here into this post array and finally to return for this function we're going to sort the posts based on the date and that is from that metadata that we should receive okay let's scroll up and create this get post by name function and we want to create it above this get post meta function so here I will say export async function and it is get hosts by name and then it's going to accept a file name and that will be a string after that we need to add another type for the return type so let's go back to our types dot d dot TS file okay in this file we are going to have a blog post type so we'll call this blog post and set this equal to an object here that has meta and we'll set that as the type we defined Above So this meta type right here other than that we're also going to have content but I don't have that type ready yet so I'm going to temporarily put in any we're definitely going to come back and change this back in the posts.ts file now we are ready to put the return type here for this function so this is going to be a promise once again and it's going to be a blog post or undefined I'm going to scroll up just a little bit now just like before with our git Hub fetch here I'm going to paste in the GitHub fetch for this function you'll see it is very similar it's just not quite the same because we're getting the raw.githubusercontent.com URL here and then I've got my username the repo name Main and then the file name so we're getting the specific file and we're getting it from that raw data and you can view that in your GitHub repo as well I believe GitHub offers a button that says view raw data or something like that so you can see that as well once again you could put this request in your browser and put in the file name and you should be able to see it also now just like before we want to say if the response is not okay then we're going to return undefined okay scrolling for some more room again but underneath this return undefined line we'll look at the next two lines and essentially what we're getting now from this request is the raw MDX file and notice we're awaiting the response dot text here not Json this needs to be text but if the file doesn't exist what GitHub does it gives a 404 page and so what we'll get back as text is this 404 not found so we're checking for that as well and so you might have a 200 response in other words that gets by this if here so if we get a 404 page even though the response comes through is okay we're going to return undefined here as should have been caught here you'd think they would send a 404 with that but for some reason our response is getting through so we send it here okay now we're ready to work with our remote data we've pulled in our remote data and we need to process these MDX files and we're going to do that with a dependency that's recommended by nextjs I'm back in the next JS docs under remote MDX and you can see they say there are pop two Popular Community packages for fetching MDX content and of course using that MDX content the first one here is next MDX remote and that's what I'm using today so let's just click on that and then we should go to directly to the part of the repo that applies to next js13 with the app directory support and react server components now this goes into quite a few details basically we're going to use this bottom example and then add a few extra things into it so it says access front matter kind of like the gray matter we previously had for that metadata outside of the MDX so we can pull that front matter out here with parse front matter and we can access it like front matter dot title that you see right here and then we're still going to process the markdown that's in the file and be able to create content from that okay back here in our code let's scroll up to the top and let's import what we need actually we can't import it yet we need to install it so let's look at the pack is Json again and here let's open up a terminal and we're going to type npm I next Dash MDX remote and that should quickly install and once it's installed we'll confirm that here in our dependencies and now we have next MDX remote here in our dependencies so we can go back to the file so we will import and what we want is compile MDX and that's going to come from next Dash mdx-remote and this part's important we need to put the Slash and RSC and that supports what we're doing with react server components in next JS okay let's scroll down and complete our function so after this 404 where we return undefined I'm going to paste in how we use the compile MDX and then of course I need to close out the bottom of it here we're going to add more to it later but this is the basic we'll start out with the basic setup essentially so we're getting the front matter so we can use that as you saw in their example and we're also getting the content then I'm putting the type in here for the front matter itself and that has the title the date and the tags now remember in the type of blog post when I said we would come back that needs to be the content type and not any that we temporarily put in here so I'm just mousing over to get the intellisense I'm going to come up here and copy this part I still see some innies in there but I think this is better than just putting one plane any for everything and this is the type that's coming from the compile MDX so that's what I'm going with so I copied that let's go back to our types.d.ts and I'm going to paste that type in okay back to the post.ts and we'll finish out this function now that we have called the compile MDX function that we have from the remote dependency okay the last few lines here what I'm doing here is getting the ID without the MDX extension so I'm using a regex expression here to remove the MDX I'm calling replace on that string with the MDX regex and we're just putting in an empty string there so it removes it other than that we've got a blog post object and we gave this the type blog post that we just defined so it starts with meta and then meta is the type meta so it has to have everything that was in that type and you see that here we're using a lot of that front matter that we received up here from compile MDX so we get the title the date and the tags the ID we just got here when we removed the dot MDX from the file name so that's what the ID ideas and then here we have the content and then we just return that blog post so let's save this file now if we move down we should see where we were using that and here we do with the await get post by name and as we can get both meta and content from it here in this post meta function that's what this is get post meta we're just destructuring the meta after we get it and we're pushing it into that posts array now I'm not sure why we have the little red underline here it says cannot find this that's because we had it here first oh get post or get posts that could be a problem as well so get posts by name let me go ahead and put the S there typescript just saved me from a typo but now that I think about this this function is actually just to get one post so instead of adding the S here let's remove it up here where we Define the function and call this get post by name okay we're finished with the library functions in in this posts file for now but I just want to add that if I'm moving too fast for you if you want to go ahead and re-watch part of the video or go ahead and view the source code that I've provided at the link in the description for this lesson that's okay but for now we're going to move on to the components directory and then we're going to look at the post.tsx file for the posts component let's start by replacing our get sorted post data function and I'm going to press Ctrl D to just select both instances of that and we're going to bring in git hosts meta that we had already created in our posts library after that we need to make this an async function and now let's go ahead and put in a weight in front of get post meta as well now we still have posts but we might have undefined posts as we check the type here of post you can see it's an array of metadata or it's possibly undefined so let's just quickly handle that and I'm just checking to see if there are no posts and if that's the case we're going to return sorry no posts are available and now just a couple of quick classes to add here to our unordered list class name we're going to add a list none so there will be no bullets and then let's add a padding of zero here to our Tailwind classes and with that we're finished with this file and you can see typescript is underlining post here as we pass it into the list item so let's go to list item component now and let's just change our props type here so we have props post but instead of a blog post it's just going to be that meta type that we created and now you can see the problem is gone from our post component as well now we're ready to close the components directory for now and let's go to the Post directory and the page.tsx file inside of our Dynamic post ID directory here under posts let's start by changing out the functions we're importing so we're going to import get posts meta and then we're also going to import git host by name and after those two Imports I want to go ahead and add a type to this file for props so I'm going to say type props equals it's going to have params and then that object is going to contain a post ID which is a string one other thing I want to do is set a route segment config at the top for revalidate and during development it's easiest to set this to zero we can change it later and this will automatically make our Pages server side rendered because it will not cache anything this is like setting the cash to no cash and this is a good way to catch errors during development but then we'll come back and we'll add a longer duration here so we do use cache data and can create SSG pages and that those will be statically generated of course so we're just just going to put this here during development and we'll do this on a couple of other Pages as we go as well now let's scroll up and look at the generate static params function so we're going to get posts and so here we'll need to await but of course we need to set this as an async function as well so we'll put async function here and we're going to await our call but this is not the call it needs to be get posts meta and note I said deduped here in the notes from the previous code the previous lesson in 10 and this is still correct all of these fetches that our server side will be deduplicated during the build so we're not worried about using this essentially just request data wherever we need it and these will be deduplicated by next.js so that's good now we have a note here from typescript because posts could be undefined so let's go ahead and handle that as well and we'll just say if there are no posts we're going to return an empty array and we can see that generate static params should be returning an array that is an object inside with a post and ID but we could just return an empty array if we don't have any posts that's essentially what would happen if we didn't have any posts and we tried to map over it but since we could possibly be undefined we would have a problem if we tried to map over undefined so that is the complete function now I should note that while we have revalidate set to zero if we attempt to run a build or even I believe run in Dev we'll have a problem revalidate equals zero and having a generate static params function do not mix this would cause a problem so we just want to comment this out while we're using that revalidate equals zero now we're ready to scroll to the generate metadata function and I'm going to change what we have here for props so let's just start over with that and we'll have an object that has params and then we're going to destructure the post ID and then outside of these brackets we'll put our props and that should be good now the problem we have with post ID is that we were previously destructuring it here inside of the function so let's just remove that as well now we need to make this an async function and then we also need to await our function call and our function call is going to change this is going to be it post by name and we need to pass in a template literal string because we're going to pass in the post ID that the function is receiving and we also need to put the file extension.mdx right here at the end this will also be deduplicated now we're no longer trying to find a post we already have the individual post so we'll remove that but now we can say if there is no post we want to return host not found and I can see typescript is telling me I have missed something and I should have said post not posts up here so if there is no post we're returning post not found for the title this is very minimal metadata of course you could return more and there is much more metadata listed in the documentation I'm just doing something very simple here now post is going to have meta content in it from the blog post and so when we check that we actually now instead of just post.title it should be post dot meta dot title now I'm going to copy the props that we have up here and then scroll down to the next function which we already have as async and this is our post component so I'm just going to paste in the same props here so it's structured the same way of course get rid of where we're now destructuring or we previously were destructuring post ID inside of the function now here we want post once again so this is essentially the same line As Above also so we could just copy our post equals again being deduplicated and we'll paste it right in here and after that we're ready to move to the next line which should once again be simpler than what we had here before so we can just say if there is no post now we're going to call not found and we had already imported this not found function up here at the top from next navigation now in the past I may have used the return keyword with not found but it is not required and I noted that in the docs because not found uses a typescript type never so there is no reason to use the return keyword with not found now let's replace this line so instead of getting post data ID we've already got our posts so here we're just going to destructure our metadata and our content and that's going to come from the post and now our publication date is going to come from that meta object so we just need to have meta dot date there there's one more thing we want to add here and this is creating the tags now I just pasted this in but I will walk through this with you because we have our metadata if you remember it has a tags array of all the tags we relate to our articles and we can map over that array and then create these links because we're going to use these as related content at the bottom of the page so we're just creating related links to other hashtags and we're going to have a dynamic route for these tags where we can see a list of the related articles if we click on one of these we just haven't created that yet and now I'll scroll down to the jsx and I've made a few changes remember the main element is already in the layout so we're not going to need that what I'm going to do is just highlight this and replace and quickly break it down for you so we have our fragment here and if I save I think we're going to get better 4 formatting because the fragments the parent and then we have our heading here that's the meta dot title now there's our Pub date still and I may have changed some of these Tailwind classes now we have the article with the content that we previously had in a note I moved the link to back home outside of the article as it was previously inside and we also now have a section with related links and that's where our tags go now let's go to our not Dash found page just in case that not found function gets called now this is very basic right now so I'm just going to replace it with something that's not quite as basic but still fairly basic just says sorry the requested post does not exist and it gives a link back to home so I have imported link from next link and I also want to create an error.tsx file and we have done this in the past in this next JS Series this is nothing different this is essentially the Arid component the file error.tsx the example that was is in the docs so I haven't changed much of anything here error.tsx is always a client-side component and they must be we come down here I believe I may have put a link back to home that might not have been there before but I might have used this in the previous example as well I literally changed nothing from what I had previously had looks like I still need to save the not found file and we'll go back to the page.tsx file where we started here inside of the dynamic posts route with all of this complete I'd like to try out the app but remember when I said we would come back to that compile MDX function now's the time to do that so let's go back to post.ts and it was in our git post by name function let's scroll down to where we find it here we go it also accepts options so we want to add an options here and this is an object inside of this we're going to say parse form front matter I almost said formatter parse front matter and this is going to be set to true now there are some other options we're going to come back and add in the future as well but we'll just go with these for now so this is saved and I believe we're ready to go ahead and try out the application so let's open up a terminal window let's do npm run Dev start the application in Dev mode just to check it out now remember our revalidates are all set to zero so we should just be getting server-side rendered Pages let's go ahead and hold down control and click localhost 3000 and see what we get here inside of our Chrome browser and there is the blog so this is pulling in everything that I have for articles from GitHub in that other repository it looks like it says I have one error here already which is not totally unexpected because we're not finished yet but this is working so far let's go ahead and just check out a post and yep now we have an error there because of that let's see if I've got a post that doesn't have any other components in it possibly this one is okay because we didn't put a video component or an image component in it yet and of course we haven't handled those yet but look at this we've even got our code Block in here now it looks a little bit plain so we're going to do something to make this look a lot better as well I'm on npmj JS and we're going to use highlight.js to highlight our code and make it work better or at least look better it's going to work the same actually the code examples in the blog posts and in combination with highlight.js we're going to use this re-hype highlight extension and we're going to pass that to our compile MDX function through the MDX options a couple of other packages we're going to use so we'll install those while we're at it we're going to use re-hype slug this will add an ID to headings now when I talk about headings let me pull in a markdown file here from the other repository where we have our content this is a heading in markdown you can see it's got the two hashtags a larger heading would just have one hashtag I guess I don't have any up there for that but you can create different sizes of headings and you may or may not be familiar with creating markdown files but that's what a heading is in markdown okay so we're going to add IDs to the headings then in combination with that we can use this re-hype Auto Link headings and this is going to add links to these IDs so we can link to specific parts of the article as well and all we'll have to do is create a heading in our markdown file okay I'm back in vs code and I've got the package Json open if you have your Dev server running go ahead and stop that for now with Ctrl C we're going to install these new dependencies now I'm going to right click and paste them in but what you need is npmi and then you can install them all at once if you want to or you could do a separate install for each one but here we've got highlight JS then we have re-hype Dash highlight and we have rehype Dash Slug and finally re-hype Dash Auto Link Dash headings I'm going to install all of these dependencies at once here with this line so I'll just press enter and that should get started with the installation and then we'll see them added to our dependencies here in the package Json hello it looks like I had an error there with that let's try that again I don't know what happened but we can check it out let's see it says rehype Auto Link headings not found okay maybe I typed that one wrong let's go ahead and paste the others in and I'll just backspace over that and we'll go back to the npm page and double check that one so all of these will go ahead and install and that was fairly quick we can check here we've got rehype highlight rehype slug we've got highlight.js up here as well let's go back and check npmjs or this rehype Auto Link headings yes I put a dash between Auto and Link so let's just copy that go back to vs code and install this last dependency as well so now I can just right click and paste that in press enter and it should be good I had one extra Dash in there so all the dependencies are now added okay let's go back to our lib directory here with the post TS file and we need to pass all of these in to compile MDX and of course we're going to need to import those as well so I I guess we could start at the top with the Imports and we'll say import re-hype and that's all lower case and here we see them at the top so I'll just go through them Auto Link headings that looks good then we'll import re-hype and we'll get react highlight and finally we'll import re-hype and we'll get re-hype slug so we've got all three of those and now we're ready to scroll down to our compile MDX function and pass these in so scrolling down to where we see that I think I went past it there it is compile MDX and now we've already got the options object and they're going to go inside of here so after parse front matter set to true I'm going to paste this in and we'll look at this so inside of the options object we've got an MDX options and then we set rehype plugins now you can use other plugins with this compile MDX as well so you can look at the documentation I'm linking to for that I chose to use the re-hype ones we've got rehype highlight here we've got rehype Slug and then notice we've got an array and inside this array here or these brackets we've got rehype Auto Link headings with a comma and then we're passing in an options object and this is behavior set to wrap so a essentially we're creating the link with that there are some other settings you can check out as well but we're not quite finished we still haven't used highlight yet even though we have rehype highlight here okay so let's go back to the post directory and the page.tsx inside of the post directory and here we need to import highlight JS and then we say slash Styles and there are Styles we can choose from and the way to find these is to scroll down and go into your node modules and then scroll all the way down alphabetically to highlight JS which I'll be there in just a second once you get to highlight.js you can come down to the Styles directory and now you see all of these CSS files they are all themes that you can use for your code Snippets and so you can experiment with this and choose what you want I'm using GitHub Dash dark dot CSS so that's what I'm going to put Hub Dash dark dot CSS now I'm going to close up the node modules because it is huge and it just displays so many files it can get out of hand so it's best to keep those closed when you're not browsing those okay now with that complete we will save the changes and then press control on the back tick to open a terminal window type npm run Dev to start the server and then hold Ctrl and click on localhost 3000 to launch the blog in your browser and here it started so now let's go to a post that I know should have a code snippet in it but probably doesn't have one of the other components we haven't handled yet here we are look this looks much better than what we had before it is color coded with that theme GitHub dark now if we scroll further down on the page you can see our related area that gives us our tags but we haven't created those Dynamic Pages yet at the tags route where it goes tags and then it has the actual file name there or tag name if you will so let's go back to vs code and do that quickly we're back in vs code now we want to go to the app directory and inside of the app directory we want to create a new directory named tags and this is going to be a dynamic directory so inside of tags let's go create another directory that holds what we pass to it and that will be the tag inside of brackets so now inside of this Dynamic directory here actually in the tags path the one in Brackets is the dynamic directory let's create a new file name page.tsx our page inside of this Dynamic directory is going to display a list of matching blog posts that all have the same tag so a lot of it is going to be like the page we have inside of our post ID Dynamic directory but when it's displayed the display the jsx is going to be more like we saw inside of the components for the posts component so I'm I'm going to move quickly here because it's kind of a repeat of things you've seen before so what I put in first are the Imports where we bring in git post meta the list item component because we can use it for this list as well and the link from next link I'm going to set a revalidate and I don't want that set to 86 400 right now I want that set to zero here during Dev mode during development so it's easier to see any errors if we have those and we're not viewing cache data then I've got to type props it has params and then a tag instead of a post ID that is still a string now let's look at the generate static params function and here we're going to get all of the post metadata with get post meta and of course if that doesn't exist we're going to return an empty array because generate static params should return an array of objects and if those objects don't exist it will just be empty but then we're going to get all of the tags from all of the existing blog posts now this part is important here so we're going to map over all of the tags we're going to have an array of all the tags but then it would actually be an array of arrays because remember each tag itself is a collection of tags this tags here is an array to begin with so we need to call flat on this array that's created with maps we flatten all of that out and then we wrap it in a new set to remove all of the duplicates so at this point we should now have a new set of tags with no duplicates but we do have all of the existing tags but now we need an array of objects so we're going to use array Dot from on the tags and we're going to map over that array and then create the objects that we need and it would be a tag for the key and then of course the actual value is whatever the tag is so that's what we're returning from generate static params now we can't forget this we're going to comment this out for now while we have revalidate set to zero so control and the Slash and we still have revalidate set to zero again we'll come back and uncomment this this is just during development in case we have an error just much easier to find when we're not working with cache data next let's look at generate metadata so here I'll paste this in which is very small in my version I've got generate metadata we're getting those params that match the props and then we're just returning a basic title post about and then whatever the tag is however you could put something in here to say if there was not a tag maybe you would say No Tag provided or something like that I just kept it very simple here and again you could add much more metadata to this if you want to remember to reference that in the docs okay I will scroll for some more room and we're going to call this component tags post list and I'll start the component here and then I'll add the curly brace to end it now we're going to add more to this but I'll go over what we currently have and I'll wrap this down with alt Z as well so it's receiving the params with the tag and we're getting all of the post metadata once again remember this is deduplicated so just request data where you need it now if there's no posts we're just going to return sorry no posts available and of course that that also applies to our tags list it's going to display posts that match the tag and then we're going to get the tag post by filtering all of the posts to see which posts include the tag that is being passed and then if no tag posts exists we're going to return this sorry no post for that keyword or we could say for that tag and also provide a link back home but now if the tag posts do exist let's go ahead and return some jsx here and this is going to be basically what you saw with our post component so we have the heading here results for tag and then we're using that list item component as we map through the tag posts let's open a terminal again with control on the backtick we already have Dev mode running let's get out of that with Ctrl C and we'll start it once again with our new changes npm run Dev to start the blog application once again and I'll click on localhost 3000 and this should launch it in the browser I'll close the old version of the blog and now we should be able to test if our hashtags are working now this first post has a video component in it that we haven't handled yet so I'm going to click the second one so we don't get an error scroll down here and I'm going to look at the tags related here so I can click any one of these I'll just click the first one and here's a list of all the articles that have that tag now that's most of them so let's go back let's click the new tag which doesn't have as many and we see only three articles have that tag so our tags page our Dynamic list of articles that share tags is now working I'm back in vs code again let's go ahead and close the terminal window here after we close out of our app and now you'd think we'd have enough dependencies but no we need to add one more and it's specifically for Tailwind you can see what I'm adding here npmi then it's at Tailwind CSS slash aspect Dash ratio at latest and then here at the end it should just be a Dash D so I don't know why those other characters were there but we'll just have Dash D because this is a Dev dependency let's go ahead and add this and we're going to use the aspect ratio as we share videos in our MDX files so we can pull in some YouTube videos let's check our package Json to make sure we added that dependency as well so we should see that here in the dev dependencies and we do right alongside the typography dependency we have the aspect ratio dependency from tailwind and now in the Tailwind config file just like we required the typography here for plugin we're also going to require the aspect ratio as a plug-in for Tailwind now let's go to the components directory once again and we're going to create a video component so inside of here we'll create a component called video.tsx I'm just going to paste this in it's fairly short we see our props is an ID with a string use the props here and there's the ID then we're going to return this now this iframe is what you get from YouTube if you say you want to embed a video and YouTube provides that so a lot of what you see here is just from YouTube as far as the allow and here the title I'm just putting YouTube video player which I believe is the default from YouTube as well and they always provide this URL now what we need to do is pass in the ID of the video every video has an ID but also important to note that we're wrapping this iframe in a div and notice the class names here we've got aspect Dash w-16 aspect Dash H dash nine so that's that aspect ratio that we just installed as a Dev dependency for tailwind and it's allowing us to size this video responsibly to a 16 by 9 and that's the normal size for a video so that's important that makes it very easy to do for videos when you add that aspect ratio dependency now as I bring my blog post back over here and we look at this other repo you can see I've added a video component directly to my article that says post for today or my blog post that is post for today and actually that was yesterday today is May the 4th as far as I am of course you may be watching this in the future but anyway here is the video component we've got the ID that we're passing in and that's all you need to do in your MDX file so May the 4th be with you if you're a Star Wars fan now we're back here with the video component and we're not quite finished because we need to pass it in to our compile MDX function let's head back over here to the file tree into the lib directory post back to our compile MDX function there it is so at the top we're just going to import our video component there it is and then we can come down here and we're going to add something here to these options once again so we had the parse formatter or I said parse front matter there we go and MDX options we also have a source well this is outside of the options object so after Source I'm just going to put it right here and it is components and then it accepts an object and inside of here we can pass each component we want to pass and I don't know why it just set that to lowercase but I want that upper case and then we might pass another component here in just a few oh and I need a comma here which type script caught for me and now it should be good to go just to save a little time we will test out the video component and our Custom Image component at the same time so let's get started on that as well before we go anywhere else so let's go to the next dot config.js file because this is the first thing you need to do if you're bringing in images from a remote source so I'm going to paste in my config here you want to have images and remote patterns and then inside of this remote patterns array you need an object that provides the following so the protocol is going to be https you're really breaking down the URL that you have for your images then here the host name is raw.githubusercontent.com and the path name has your GitHub username and then it has your repo name here as I have test Dash blog post then your branch name which I had main which is probably yours is as well now I have mine in an images directory and then the two stars go where your actual file names would be that would be changing so that is your full path name and you need all of this in your next config.js now let's go back to the components directory and create that Custom Image component inside of components so here a new file and I'll call it custom image.tsx I'll just paste it in and review it with you here alt Z so everything shows which was just the curly brace I guess but here we need to import in image from next image first we've got some props we're going to have a source and an ALT that are required priority is not required at least the way I have set this up so this Custom Image component is going to receive a source an alt and possibly a priority so here I'm just checking to see if we received the priority because it's either set to true or false so if we did receive it we set this to true this variable here otherwise false and then we go ahead and set this up now what we want to notice here is I've gone ahead and used some Tailwind classes right inside of this component and that's part of why I wanted to create a custom component and then after that we're passing in the party here and here with the width and the height they're set to 650 but not every image is going to be 650 pixels height you know as a square height and width the same however these are just approximations for next JS next JS will take this into consideration but it will size your image to what you think is best so what I'm really setting here is my Max width but we'll see with a couple of images that I've put in my articles that next JS goes ahead and keeps their aspect ratio as it should be it doesn't turn a rectangle into a square for example so let's save this component and then we can go ahead and try everything out and I should highlight back in my blog here to show the Custom Image component and how we're passing everything in an MDX file so here it is passing in the source and you want to have that full URL for the image and you can get that at GitHub and then you can pass in your alt text as well and notice I did not set the other the priority I just didn't send one so that will be set to false but you do set priority to true if your image will be above the fold if you think it will load immediately that's when you want to set priority to True let's go ahead and drag this back out of the way and check everything out by opening up a terminal and once again doing npm run Dev and we'll start up the browser vocal host 3000 this is probably going to move on me right as I click there we go and we've got it open I'll close the previous one just so we get the fresh and it'll get this page going here Dev Mode's a little bit slower than if we of course had our static Pages already okay we've retrieved the data everything is probably going to look okay but let's find out this page has a video there it is right in line with the rest of the article it also has a code snippet that's good let's go ahead and scroll down to the page that I think I put oh you have an error here I think I put an image in this page let's go back and see if there is another one and it also has an error might have to check out what those errors are and I think I already know we probably got ahead of ourselves there as we started up this application because we needed to go back to posts and we needed to import Custom Image up here at the top and then pass it to our compile MDX so that's part of creating a long tutorial forget a few things along the way so here we go video now let's put in Custom Image and now we have both components being passed to the compile MDX let's go back and see if we still have an issue I may have to restart everything or if it's going to be okay let's try out post for today still has the video okay let's go here and we still have an error so probably going to have to restart that side of our terminal here so let's go ahead and Ctrl C to get out now we'll npm run Dev again so it passes the component to the compile MDX now with that going I'll click localhost 3000 come back close the previous browser window looking good got our video let's come down here and check this article now this article is working scroll down here and we have our image notice it's it doesn't really look like a square it's taller than it is wide now I've got another example where we're going to have one that is 16 by nine and I believe that's this one and as it loads there we go and this is actually a really large image so nextgs has to work with that a little bit and it also looks good here so it's keeping the aspect ratio of the original image even though we put in the height and width at 650. okay I'm back in vs code if you haven't stopped the dev server go ahead and do that there's one other thing we'd like to add that next JS recommends for production deployments and that is to install sharp so we'll say npm I sharp we don't have to do anything other than install it to our project next.js will use it automatically to help optimize our images so we went ahead and added that while we're talking about images back at npmjs.com one thing we can really do to help our blog project or any project with the search engines and SEO that is search engine optimization is create a site map and one dependency that will really help us do that is next Dash sitemaps so we're going to install that here you see in PMI next sitemap I'll just copy that and head back to vs code back in vs code I'll open the terminal once again and I'll just paste that in and we'll install next sitemap as a dependency and then we'll get that set up okay let's close the terminal window scroll down to our package Json just to make sure we've got next sitemap installed and you can see it right here so now that we know that's installed we need to create a config file for it so just in this area where we have package.json and next dot config.js let's create a new file and this will be next Dash sitemap.config.js okay inside of this file we've just got a few settings to put so I'll just put those in here and we can review so we have this line at the top that has at type and then has the import next sitemap.i config but after that what's important here is the module exports with the settings the site URL we're setting to a environment variable so this is one when we deploy we would want to find out what our URL is if you don't have your own domain like a.com if you do you'll already know of course and you'll want to put that in your environment variables and then we're just putting in the short circuit here or so if that's not the case when we're here in development it will set everything to localhost 3000 then generate robots text true and generate index sitemap false or that is for larger sites so if you had hundreds and hundreds of pages you could actually have a page that says okay here are the sitemap pages and it will create many site map Pages for you we don't really need that we're just going to create one sitemap page so we set that to false and just to be accurate let's go ahead and remove the S here from The Local Host because localhost runs on HTTP here in our Dev environment not https and then we have one other setting so we need to go to the package Json and in our scripts above we need to add a post build script to create the site map so we'll put a comma after lint and here at the bottom I'll put post build as all one word and after that we'll put next sorry next Dash site map right there and that is all we need as we near the Finish Line it's time to go ahead and check our revalidation settings and that will lead to our incremental static regeneration of our pages so let's go to the root page TSX inside of the app directory and we want to change our route config that has revalidate equal to zero to a small number like 10 seconds and then it will expire quickly and allow us to check the revalidation which was actually the ISR or incremental static regeneration okay now from there we also need to change this setting in our tags page TSX so we'll go ahead and make that a 10 as well and remember we commented out our generate static params function because that wouldn't work right if we had revalidate set to zero because we wouldn't have static pages so now let's go ahead and uncomment this function and save this file let's move on to the page TSX inside of our Dynamic host directory also and we'll do the same thing so set revalidate to 10 and let's uncomment the generate static params function as well okay we're ready to open a terminal now and make a build if you remember we can only check our ISR our revalidation essentially when we create a build we can't do that in Dev mode so I'll type npm run build while this is building I'll tell you the rest we'll go ahead and start the build after it completes now after we have it started that 10 seconds will expire and while it's expiring we're going to change one of those posts that we save in our other repository that has our MDX content and we're going to send that up to GitHub and then we will refresh our page and we should get that new data and also remember revalidation with ISR it's going to take two refreshes the first one will trigger the revalidation the second one will give us the new data okay the build completed and take a quick look at this it did generate a site map we have that notification here so that's working as expected we have SSG Pages now our server side render is probably our old revalidate route that we're still going to change yet and that's the on-demand revalidation that we'll check later but let's look at our Pages up here so the dot that is filled in with white indicates SSG and here's our Dynamic post ID directory here and here are the posts so we did generate those static params the same for the dynamic tag page as well so here's all of the tags from the different articles so everything's looking good there let's go ahead and start the project with npm start and we'll pull that up it's running on localhost 3000 so control click and we should launch that in the browser I'll close the old one we had running for Dev mode and now here's our project with the static generated Pages they should load fairly quickly it pulls in the video everything looks good there I'll scroll down here everything is loaded quickly as well we've got the image it's looking great so now let's change an article and send that to GitHub and then we'll check our revalidation I'm pulling my blog repository over and here's the blog post once again let's just change this file I'll change it from today.mdx to tomorrow.mdx I'll also make this say post for tomorrow we'll save this I'm going to push these changes to my GitHub repository and then we'll go back and check the revalidation in the browser back in the browser now I've pushed my changes to GitHub and it's been way past the 10 seconds for revalidation so we're going to go ahead and refresh once to trigger that revalidation and now the second refresh should get us the new data and it does this change from post for today to post for tomorrow let's go to the page and we have post for tomorrow in the page as well so our revalidation route segment configs are working as expected okay we're back in the next JS docs and we're at the revalidate path API reference now this wasn't available even yesterday so if I'd made this tutorial just a day ago we wouldn't be able to go over this new information but this was just released with the new docs and I wanted to make sure to add it so now we can go ahead and delete that old Pages directory that has the API folder that previously support ordered on-demand revalidation and now xjs has provided two different ways to do this and one is the revalidate path and that's what we're going to go ahead and use today okay we're back in vs code in the file tree find the app directory and in the app directory you should have an API directory if not you'll want to create one but there is this hello example here inside of my API directory if you started with the starter source code for this tutorial so I'm going to click on this API folder right here and then I'm going to create a new directory inside of it we're going to name this one revalidate and then inside of revalidate we're going to create a route TS file but before I forget we've now created a duplicate route because we had the older version of this route in the past and that was in the Pages directory and then there was an API in our revalidate.ts we can get rid of all of that so click on pages right click and choose delete and just remove it from the project and of course I'm getting some message about deleting permanently but now it is gone if you get a message of course just okay that as well now we want to go back of course to our revalidate route right here okay in our route TS file we're going to import next request and also next response and those are going to come from next slash server okay after those Imports we also want to import revalidate path and that's going to come from next slash hash okay with those Imports complete we can start our function export async function and this will be a get request so we can just pass in a URL we have a request here and this is a next request and then inside the function we're going to get our secret from the URL that we pass as a parameter so we'll say const secret and that's going to equal request dot next URL dot search params and then we'll say dot get so we get it from the URL and it will be the param that is titled Secret after that we can say if secret is not equal to our environment variable so process dot EnV dot my secret token is what we have named it we're going to go ahead and return a response or a new next response and the first thing we're going to do inside is json.stringify right here and we'll pass in a message or an invalid token well there we go a single quote invalid token and let's go ahead and wrap the code with alt Z so that comes down after that we need to go ahead and put a comma here at the end of that and oh not there at the end after the first parentheses then we're going to need to supply the next one and then we'll put in an object here and we'll have a status it is a 401 then we'll put in status text and that's going to be unauthorized and then we'll put another comma and add headers and inside the headers we're going to say content type is application slash Json there we go and now we're going to need to wrap this here at the end with that closing parentheses and all looks well as far as this response to where if the secret doesn't match now if it does match we'll make it down to here so let's go ahead and get the path param at that point so that's once again request dot next URL dot search params dot get and then we'll get the path and then we could actually add a short circuit here and say or just go ahead and revalidate the home page and that would work as well now after that we need to call our function revalidate path and we pass in path after that we're going to return the next response dot Json and here we'll just say revalidated and say that is true and that's the complete function for our on-demand revalidation route so we'll once again be sending it to the same route it goes to API slash revalidate and now this will just handle it and of course it is a get request at this route now that we've added this new route let's go ahead and delete the default hello route we no longer need that or want it there let's go to the root page TSX file once again and now let's set the revalidate time to something more like we would actually use let's go with like 86 400 which is one day in seconds now I'm going to copy this because we're going to use it in the other route segment configs as well so let's open up tags and go to that page TSX and we'll change this 10 to 86 400 make sure you save these changes as you go and then we'll go to the page TSX inside of the post route we'll also change this to 86 400. now that we've made these changes let's create another build and we will test our on-demand revalidation with that build so I'm going to quit with control C the build that was currently running now I'll do npm run build and when this completes of course we'll start the build again as well the build is complete let's go ahead and start the new build with npm start and now we have localhost 3000 control click get that open here in our browser I'll close the other one everything's running as it should be so let's go ahead and bring in the blog articles again here's my blog article repo that I'm pulling back over in another instance of vs code I'll go ahead and rename this file and I'm going to name it weekend.mdx now and I'll say post for the weekend and we could even add something else in the page even though that would probably be enough I'll just add a heading here that says hello okay we'll save those changes now I'm going to send this up to my GitHub repository and then we'll go ahead and test out our on-demand revalidation okay my file changes are now in the GitHub repository that we're pulling the data from those MDX files and now of course we have our revalidation time the route config set to 86 400 so it's one day so no matter how many times I refresh here we should not see a change and there's three times I'm still not seeing post for tomorrow change that's what we expect okay we're back in vs code I'm going to use thunderclient to test our on-demand revalidation route you can use Postman or you could even just paste the URL into your browser and it would probably work as on-demand revalidation as well because it's a get request so let's change this to its HTTP localhost 3000 slash API slash revalidate and then we're going to have a path and we'll set that equal to our slash just for the home now if you remember we could leave this out as well and it would default to home then we can put an ampersand and then say our secret and that's going to equal at least for my secret Dave Gray teaches code and now if we pull this down a little further I think thunderclient shows us our params here as well so we see those query parameters I'll close the terminal window just so we can see the response also and let's go ahead and send this request and we get revalidated true right away so now let's look at the browser and we'll refresh to see what we get and now it took two refreshes there I was thinking it was only going to take one so I don't know if that's something because I'm running it on localhost or if it's just the way it is but after I revalidate it it still took two refreshes I thought that first on-demand revalidation that I sent would trigger that already and it would just take one so that's an interesting thing but besides that everything worked as expected here's the new heading that I put in notice it has a link too because remember that rehype Slug and re-hype Auto Link heading that we added as well and then it's got post for the weekend up here so that also works as expected and now we're ready to deploy our project so if you haven't already you'll want to create another GitHub repository for your blog code not the other code that we had not the MDX files we've already got a repository for that so if you don't have a GitHub project for your blog code that we've been working on go ahead and create one of those and send that up to GitHub as well and then we're going to go ahead and deploy this project at versel.com okay I'm on GitHub and I have pushed my project here in a new project so if you go on my GitHub you can find this at my nextjs remote MDX blog so that's what we're going to look for when we log into versel and pull our project over for deployment let's go to versel.com okay I'm at versel.com and it automatically logged me in because I already have an account you can create an account and Link it to your GitHub account that shouldn't take you long if you don't already have a versal account and then you can go ahead and be at this dashboard which is where it will take you immediately when you come here when you're already logged in and you can see my GitHub username up here in the top left okay we want to add a new project now so I'm just going to click that and choose project and from here we can search our GitHub repositories so that's what I'm going to do right now and I may need to adjust my GitHub app permissions if I can't find what I'm looking for let me see if it will even bring in what I'm looking for here for repositories no results found so that means I haven't given it permission to view all of my repositories you can do that or you can do it on a repository basis so I'm going to go ahead and configure this in my GitHub and it pulls this up here to my GitHub account so let me bring this to full screen and I should be able to tell versel to be able to access essentially which repositories here so now I can select the repositories here because I've chosen only select repositories you could choose all repositories and that would be fine as well so I'm going to select repositories and I can search I'm going to search for my Dash next JS and it pulls up here immediate immediately so now I've got that project I'm going to save this setting here in GitHub and we're back at versel.com and it now has access to my next JS remote MDX blog and I'm going to import that now into Purcell okay we're now ready to configure our project and it's already filled in the project name directly from the repository and I'm going to leave it at that we're using xjs the root directory here basically the default build and output settings there's nothing here that I want to change either so I'll go ahead and let that slide back but let's go to environment variables which we have a few to add so if you remember we had in our environment or dot env.local file we had my underscore secret underscore token and then we want to bring that over from what we had inside of our code and I had Dave gray teaches code for my secret token so we'll click add for that now we want to add another one and we had a GitHub token so GitHub underscore token and we want to put that value in and of course I'll be changing these values after I publish this tutorial so no trying to use these essentially because they will not work you need to create your own and then there's one more environment variable and if you remember that was in our next sitemap config file and it refers to the site URL so we want to put site underscore URL but the problem here is we don't know what we're being deployed to yet what our URL will be now if you already know this information like you have a.com that you're going to use with your blog then you would know your site URL but at this point we'll have to add this later and then come back and redeploy essentially so let's just go ahead and leave it at these two for now and let's deploy our site so I'll click deploy this will take a little bit and I will come back when it's finished and of course we can see the progress here if we look at building we can see the logs and everything so you might want to do that as well just in case you encounter any errors and our build is complete so now we've got a congratulations page we got a little bit of confetti we can see the project here and now it gives us some next steps so instant previews add a domain that's one thing you might want to do uh enable some speed insights any of those things really we just want to go back to the dashboard now and then we can see where we're deployed so here's our domain which is my Dash next JS remote MDX blog.versel.app so that's a pattern there where we have the name first and then.versell Dot app where we would probably know where our project would be deployed now let's go ahead and use that the only thing that we needed an environment variable for that we didn't put in the value for right away was for the site map so the site map will be wrong and we'll need to update that but otherwise let's go ahead and launch this in a new browser window and there is our blog and everything is deployed let's check out out a post here able to pull in the video we have the big hello heading that I left in there so of course you can adjust this content the way you want it but everything seems to be working here as expected if we scroll down we have the static generation there is an image and so on okay back in the dashboard now let's go to settings for our site and if we scroll down here on the left we see environment variables so we want to add one more and that is going to be site underscore URL and we just paste in the URL for our site that we have deployed here at next and I'm not so sure we need the slash there actually let's just go without the Slash and let's save this URL and that looks good and now when we redeploy we're actually not going to have to pull the code since we haven't changed the code so that is one nice thing here let's find where we redeploy maybe under deployments or I bet there's three dots right here and now we have inspect deployment or role back at that point so I think it's going to be under deployments and now let's go ahead and choose something like redeploy there it is now it gives us this nice question here use existing build cache and really that's what we want to do it's the same build we've just put in the new project configuration and that's what it says but with the newest configurations from your project settings and that's exactly what we want so we'll click redeploy and it shouldn't take too long to go ahead and redeploy this we can see the duration right here and when this finishes I'll come back okay the redeploy is complete it took 32 seconds let's go ahead and visit the site once again everything still looks good here let's see if our site map built as we deploy to our site so at the end of our URL we just put slash sitemap.xml press enter and there is our site map so the next sitemap dependency is working as expected and you can see it created a map of all of our statically generated Pages those SSG pages that we created are all there so that's working as we want it to and now with our blog deployed let's check out our on-demand revalidation one more time so I'm going to pull over our blog post once again so you can see me make a change I'm going to change this weekend file and rename it to Saturday and now that I have a Saturday file instead I'll call this post for Saturday and I'm going to remove that big hello header that we had here as well so we've made a few changes now I'm going to push this back to GitHub and then we'll try out the revalidation okay I'm in thunderclient now all the new updates to the MDX file have been pushed to that GitHub remote repository and notice the address I now have up here for my revalidate my on-demand revalidation it has our new URL for our project at versel slash API slash revalidate and then you can see the params here thunderclient makes them easy to see down here so we've got a slash just for the home page and then of course the secret for our revalidation let's go ahead and send this and we should get a revalidated true and there it is now let's go check our site so here we're back at the blog project and I'm going to refresh once and let's see we've already got the update so previously on the computer when I did the build it took two refreshes but now that I've deployed to versel and we did an on-demand revalidation request that triggered the revalidation so then when we reloaded here it just took one reload and we have our new post for Saturday and we're seeing all of those updates here on the page as well so next JS 13.4 was just released here two days ago as I have been making this project video and it made that just a little bit more challenging but what I really want to highlight is the docs have been updated too and there's more things to learn about nexjs I'm going to post more things to my channel but it's hard to do these things as they're changing underneath your feet as you create a tutorial so this has definitely been a challenging series that started with next JS 13.1 about 12 weeks ago as I began the series and here we've finished with next JS 13.4 so there's always something new to learn just keep checking back to my channel and the playlist a couple of things I want to highlight here and one of those is the revalidate the on-demand revalidation so we can just search for that here in their new search entry and we have on-demand revalidation we used revalidate path but you can also use revalidate tag and they give an example of that as well and then something else that just came out in this new version is server actions and I really didn't get a chance to add those to this series and it didn't take me to the server actions page let me try that again here here's like server mutations so we previously covered mutations in another way and I think some of those things have been changed or at least we could use server actions to get involved with mutations so we'll see what all of that is about I don't really know yet as I haven't had a chance to explore those but more information coming from next.js and versel and of course you'll find more information on my channel in my next JS playlist as I continue to add to it remember to keep striving looking for Progress over Perfection and a little progress every day will go a very long way please give this video a like if it's helped you and thank you for watching and subscribing you're helping my channel grow have a great day and let's write more code together very soon
Info
Channel: Dave Gray
Views: 26,527
Rating: undefined out of 5
Keywords: build a next.js blog, nextjs, nextjs 13, next.js, nextjs blog, build a blog with nextjs, nextjs 13.4, nextjs v13.4, mdx files, remote mdx, remote mdx files, next mdx remote, compileMDX, how to build a blog with nextjs, build a blog with nextjs 13, what are mdx files, mdx blog content, nextjs remote mdx, nextjs revalidation, on-demand revalidation, nextjs on-demand revalidation, blog code snippets, rehype plugins, highlight.js, deploy next.js, deploy nextjs 13, nextjs project
Id: 6ih_3m_UPKg
Channel Id: undefined
Length: 88min 23sec (5303 seconds)
Published: Tue May 09 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.