Next.js + Contentful Preview Mode setup walkthrough

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone welcome to swashbuckling with code i'm jimmy cleveland and today we're going to be setting up nexjs's preview mode using contentful's preview api now i know this video might seem a little bit long to some of you for setting up a preview mode and that's fine there are already like examples like the next.js documentation and some other things to like kind of just quickly figure it out yourself if you wish for that but i'm really trying to go step by step through this and walk you through what it is how it works and kind of explain some like troubles i've had with other systems and stuff like that along the way i personally think that's really valuable and the stuff that i would want to know so that's why i'm taking the time to make this video but i want to be considerate of your time so you know i'm also going to have time stamps if you want to jump around to specific things that you might need and i'll also have the repo hosted which i'll have a link to in the description for the code at the end of it if you just want to glance at how my config is and figure it out yourself so before we get into the code let me give you a brief little summary of why something like this even exists this preview mode one challenge that i and many others have faced when working with statically generated content is that preview can be a little bit more challenging many traditional cmss like wordpress and such have their own preview mode like built in but when you're using a headless cms or you know a headless pattern like if you're using a headless wordpress and then you're doing statically generated content that actually becomes a little bit more difficult of a challenge to give them a responsive preview mode so each build system like uh such as gatsby has invented their own way to alleviate these panes through some really awesome engineering things to kind of speed up the process and make it more fluid but today i'm going to go over next js because i believe that they have one of the most elegant solutions if not the most elegant solution for this that i think is very simple and very effective hopefully by the end of this you'll have a pretty good mental model of how that all works all the problems and the solves in general and how next js preview works so that you can customize your own project to your particular needs [Music] okay picking up where we left off last time if you haven't watched those videos they're going to be in the description and in the playlist here it's the whole contentful plus next js playlist that i'm doing right now but for a quick recap for those who don't want to go back and watch that and just want to see preview in action here what we've got here is we have a contentful being hit which i'll go to that contempo space later when we need it but for now we are getting some a very simple model with a few fields we're hitting that client and then we are using get static paths to generate out all the different routes for every single slug that we find for a product review and then get static props here to generate out each individual page by fetching that one by id or slug or whatever you want to call it so now let's get into the preview functionality and to start there we want to understand how this like api structure works really briefly so there's this folder that it starts with whenever you make a next js project it's this api folder and they start out with this hello so let's see how that behaves you can see in the syntax here it might look a little bit express like to you and that is what next js also refers to it as they have an api it's not a one to one but it is very similar to express with this rec and res request and response object so you can do res.status set a 200 status return some json let's see that in action real quick so coming back over to here i'm going to start up my server i am now on a preview branch that's the branch we'll be on in the repo if you want to follow along or just compare your code or whatever if you have issues so when we do that we'll go back to the browser and we'll hit this route here and you can see it loading fine but let's go to slash api slash oops hello and then we get this response here right so that's pretty simple so in order to initiate preview mode you can go to the docs here i'll link this in the description but you could just search in xjs preview in google or wherever and they have some really nice documentation that kind of walks you through setting it up i'm going to distill a little bit of this they have some really good examples here for each database but i found them to be pretty involved when you're kind of first starting there's a lot of like abstraction and stuff like that which is good pattern wise but might be a little difficult to just get right into it so that's what i'm going to kind of do is keep it simple but walking down here you'll see that they recommend making a sort of route that has this code right here okay so that's what we're going to do essentially we're going to come back to our code we're going to make a new file and anything you make in this api one is going to use this format it's going to use this little express like server it's pretty cool we're going to name it preview.js and so whatever you export here needs to be the default export it's a common thing to call the function a handler you could call it whatever you like and then here you're gonna get a wreck and a res back call those whatever you like as well and let's just start by console logging that out when we hit that route let's just do um response okay we'll go back to our browser hit here and instead of slash hello we'll do slash preview and it's going to hang because we didn't end the response at all but that should be enough to at least go to our server and see this giant thing dumped out okay i'm not going to scroll all the way through that and put you through that misery but api resolved without sending a response to api preview so they gave you a little hint there you kind of need to resolve that somehow and in particular here conveniently right at the bottom there's this set preview data that's on the response thing and among some other things you can see dot end which we're going to use as well so let's do that all we need to do here is do res dot set preview data and that takes an object and a lot of the times you'll just leave this empty this is just to flag on preview mode with a cookie that i'll show you but you could do something like my key my val you know pass the key value and i'll show you where you get that later for now we'll just do res.end go over to the browser rehit this preview and you'll notice that why did it did it actually hit it or did my refresh not work i don't think it worked it'll do slash preview press enter and there you go we should get this white screen because we ended it but notice that we have this cookie over here and it's there's a lot of zoom going on here so it might be hard to see but in particular what's interesting is this next preview data is going to pop up here and it's this hash so you know for security reasons they aren't putting anything on there but this cookie is something that is going to be unique every time that the server runs which is pretty cool and so that will start over every single time so it'll have to be reflagged but what that does is it's going to make it to where when we go to let's say product product one we'll still have this cookie on our machine here and we will until we essentially restart the server in this case or if it were production you know we'd have to clear it ourselves or whatever when it expires let's go back to our code real quick and see something interesting if we go into this slug where we're processing all of our products in particular and we have some methods running if we were to log out this context object let's see what we get so we'll do console.log and we'll just do let's say context i don't know why i bothered to type that up but okay so we'll hit this again real quick to get that log triggered and then we come back down here and you'll see we get this context when we hit and notice that it says preview true preview data my key myval so this is how you would get those properties that you want to send yourself and you could do anything with those you want there's lots of options there we won't need it for the rest of this video so i'm going to kill it in a moment but just so you know if you want to kind of like send some data along and react to that that's a cool way to do that for preview mode only so we really care that the preview mode is true first of all that's one thing that we want to react to now i want to show you something interesting that happens here there's some pretty cool stuff that's happening that might not be obvious at first if we do npm run build sorry that'll build real quick here and then we'll do npm start so we're using like an actual production build here what we want to see is anytime we hit this i'm going to refresh this page and if we come back into here you'll notice that no nothing was logged here like the the server wasn't hit there isn't that log of the context object that we just saw so i'm just going to refresh it a couple times nothing happens go back to the terminal nothing happens but what happens if we go to notice we didn't have our our cookie anymore because we restarted the server so if i go to api preview i'm now going to get that cookie okay and when i go back to product now let's see if it does it again when i reload you'll see that this context was logged out this time that's kind of interesting huh it might be particularly interesting particularly can't speak because this get static props is not it's supposed to be static it's not supposed to run you know it's not get server-side props so it's like okay well how is it doing that well what's cool about nexjs is they've realized a pretty simple solution to this whole preview problem is that when you are trying to make drafts in your content editor you're not like the end client you know the user the typical person that's going to be using your website you're the person like editing it and so you don't need to do a full rebuild of all the pages every single time and and try to go through the problems if you've ever experienced a static site generation in preview mode you probably know what i'm talking about but if not just trust me it can be a real pain if you're just trying to do the whole build over and over again what they're opting to do is say you know what let's kind of switch back over to server side sort of behavior and let's do things on request whenever we see the preview flag sent because this particular person one probably already has the site you know cache to some degree because they're hitting it but two they don't really need the super duper efficiency of statically generated stuff you know server side is going to be good enough for them for this purposes this actually ends up being a really elegant solution i like it a lot it's cool that they've made this single function you don't have to do something special with it it just kind of opts in or opts out of re-running every single time and that's going to be crucial for us to be able to you know get things on demand as we're doing a preview mode okay so hopefully that ramp made a little bit of sense to you but if not i apologize hopefully it was useful so we'll come back to preview here and the next thing we're going to do we do not need these values we just need the empty object here and we want to start getting some params off of this query request so if we didn't need rec we could just do an underscore there but we are going to use it it's just a common thing just so you know if you're not using like the first argument of a function we're going to do we're going to pull product id that's what i'm going to name it when i pass it in off of rec dot query okay so now let's see what that is by console logging product id product id so now if i just go here and i hit i'm going to hit that same endpoint api preview again you know i didn't pass anything in so we should see an undefined for that what happened there api preview ended refresh oh silly me what am i doing um i need to rebuild i'm in uh production mode it's not updating to my changes i'm very sorry about that npm run dev restart that over i just had it in production because i want to show you the actual you know preview and production setup so let's re-hit this route here go back to here and there we go so we've got this product id product one and that's working great so you can see now we can pull some params off and start doing some stuff with that so the next thing we'll do is we'll head over to the contempo space and we'll get the preview access token and start to set up like preview and all that so for now we'll only need the access token so over here in my contempo space what you can do is you can go to settings if you're following along or doing your own thing you can go to we will do content preview in a moment but for now we need api keys so there's this next js key thing here and don't worry about any secrets i am going to regenerate them so normally don't show people this stuff but we already have the space and the content delivery now we're going to want this content preview access token so i'm going to copy that we'll go back over to our code and in our env.local here we're going to make a content full preview access token you could name it whatever you really want here i'll paste that token here and why we specifically need this token as this is how we're going to get contentful and many you know other cms's that i've worked with have this idea of a preview mode where they have a different api that you hit for like draft content and that's what we're meaning to get here so in order to do that if we go back up to our slug page you'll notice that we have this like contempo dot create client or whatever and we're doing this access token and this process.env is using or is pulling off contentful access token right now we're going to pull off the preview token to do that by that i mean you know getting preview data getting draft data so what will happen first though it's going to make sense at this point we were going to do it earlier in one of the previous videos but it was a little bit too early now it kind of makes sense to move this to somewhere else so i'm going to abstract this code to a sort of like utils folder or something like that and that's because we're going to need two different clients i'll make a utils got too many things going on in my brain sorry uh and then in this utils folder we'll just do a contentful.js file okay so for now um just to get things working we will cut actually we'll do both of those we will also want the import we'll move that over to here and oh i did folder oops lots of mistakes so we'll do contentful.js file not a folder and now we have this client which we want to export i don't know why it's a var uh let's see so we'll do export const client okay back here we're going to import that now and then say client and contentful and actually um rather than do it that way i'm going to do star as contentful so i have the whole thing and then down here we would change this wherever we use client we would change this to contentful.client you'll see why i'm doing that in a moment okay so it's just the two spots get static paths contemplate client and get static props contentful dot client okay so back over to here why we've done this is because we we really don't want to be creating these clients over and over and over again okay i probably should have loved that but when we go to um we want to use preview sometimes we're going to want to use regular data and sometimes we're going to use preview data but the problem with this is when we instantiate this client we have to give it the right access token and the host url and all that stuff to use the correct api right but if we want to switch back and forth between the two um what you know if you're a little more naive we might do is you know do some sort of like conditional here where we're like hey is it previewed mode because we saw we could get that off of context hey if you are preview mode you know use this client otherwise make this other client but the problem is anytime every little page runs it's going to be recreating these clients instead of using more of a singleton pattern where you just make them one time and then import them so now we're going to export const preview here let's actually call a preview client and then i'll do contentful dot create client same thing but i'm going to pass some different stuff here now so pretty much the same thing for these two i could have just copied this whole thing couldn't i and for contentful access token we'll say preview access token all and right last thing we have to do is you have to specify a host which is optional they'll default default to cdn.contentful.com that's what's being done up here but in this one we're going to do preview temple.com so now that we're exporting these two different clients they're just like pre-made the the first time that this file is imported and then we'll reuse that over and over again we imported it as contentful so i could access either one there we can keep this awake contentful.client because it gets static pass we're always going to get you know we can just hit the main api for that i guess you might want to switch this to be able to do uh preview or non depending on if you had like brand new urls that didn't exist yet brand new slugs but for now we'll keep this we'll just generate all of them based on the production urls and we'll do the switch here so in getstatic props we have this await contentful client actually i didn't want to do that because what i'm going to do is we'll keep this like client pattern and then we'll say const client equals and this is where we can say hey context.preview remember that was a true false boolean so we'll say if that's true use contentful.previewclient otherwise use contentful.client there's i'm going to format this i don't know why it's not formatting for me there are you know a multitude of ways that you could handle this um but i think this makes some sense so now when we hit this route it's essentially going to you know on production it's going to first build them with this contentful.client the regular mode the production mode whatever you want to call it as it generates out all the pages but then when someone comes here with that special preview cookie we're going to switch to the preview client and then everything else will be business as usual pretty nice huh so let's see that in action what we'll do is we'll go back to our contentful go to content and let's go to product one here now product one has the very first product if i were to um type draft stuff here in the heading uh you'll notice it's saving if you saw that i'm not going to publish though i'm going to leave it just changed for now and if i go back to my server let's go to just product product one again and we should see draft stuff right okay so that's because we have these cookies so let's clear those cookies real quick and let's refresh see it went away so that's how it's going to work so it's just we any time we hit this or the first time that we build all of our regular users if we're in production they're going to see this code no one's ever going to see the draft stuff unless they know how to activate this special little preview token cookie thing so let's flip that back on again just to see that go back to preview and um we really don't have to pass the slug we could just hit whatever because we'll get the tokens we haven't set up that measure yet and then if we go back to the page beautiful so we'll do redirecting all that stuff next so now let's set it up so that when we hit our preview whatever slug parameter we pass there it's going to redirect to this page so it's essentially what we're acting as is sort of a link that you could give someone that will give them a special parameter that's like hey activate preview mode and add a cookie to their browser and then redirect them to the page that they were kind of trying to go already and that's going to be especially useful in contentful when we add preview links to each page so when we come back here we'll go back to this preview and instead of res.end i'm going to use res.redirect some of you might be scared right now let me actually show you why if you go over to the documentation here um let's see oh they did that that's cool preview mode enabled um there should be a point here they have this like kind of full example we're gonna come close to uh as we step through it but right here you'll notice there's this res.redirect notice that they particularly say we don't redirect to rec.queryslug as that might lead to open redirect vulnerabilities okay so a lot of times you want to be really cautious with how you use res.redirect and let me just give you a real quick example of why so let's say that i redirect and i'm like hey you know what just redirect them to product id okay so let's say you know hey if they type in then they're query params or whatever we're going to send them all along on to the the product id so they type product one then we'll send them to product one or whatever pretend that that's how our url structure worked okay it's just like all everything slash at the root okay now what would happen here is now that that's working i'll go back to api preview we'll do product id equals so if i go to product one that's gonna take me to you know api product one and if i did slash it would take me to slash product one or whatever okay but let's let's go back here and do api slash and then maybe let's do something like preview and then product id equals https colon slash google.com all right let's type two letters there and if i hit enter here it's actually gonna full on redirect me to google.com because we just said redirect to whatever they type in there and that's really bad that's a really dangerous vulnerability to have because what would happen there is if someone else could you know give someone a link to your site um let's say that you were a bank or uh you know paypal or something like that you're using some sort of service you could fully redirect them with a query parameter to your site that looked just like the other site you could imitate it and you could like get them to type in their credit card data and that's pretty scary among a bunch of other attacks that could happen right so that's why the caution there okay so you know you just got to be careful with with how you do redirect here so what people will do commonly is some of the examples show like right head here and so you would do like right head with a 307 so it's temporary and not permanent so we tell the you know seo crawlers not to change their links and all that stuff but what we're trying to do here is you could just say like set location let me actually type it out just so you know and then we would be like okay let's set it to um slash uh product select go away and then like product id so you could do something like this which is a you know a pretty common solve here in this case i guess we wouldn't really even need it but let's say that you wanted to send them here you could just use right head as one alternative i've seen some people recommend to do that but we're going to stick with the res.redirect because i am not too worried about that just because i'm not going to be ever just sending them directly here you'll notice in the next js docs that we referred to they did like post dot slug so they have like a qualified link we'll kind of get into why that can matter in a moment but what i can do here is i can do the same thing i'd say product slash product id that i did before and so the thing about this is if you ever try to like do the whole thing that we did before i know i'm taking a little bit of time here it's just a pretty valuable thing to kind of have in your head um you know feel free to skip forward uh in the timeline uh if you're not interested in this i should have said it beforehand but it's a pretty useful thing to know so if you go to preview we're about done here and then we were to do product id and i did the same thing where i did that like um product id equals http s colon slash slash google.com and i hit that notice it's going to take me to slash product so it won't actually work if someone tries to spoof a url here because i've hard set it to go to that product here so because we have that url structure first i'm not as worried about that but you know just so you know be cautious do your own research and all that all right cool so now let's actually do it for real api preview and we'll do the the product id is equal to product one we hit that and it will redirect us here pretty cool huh so if we were to clear that we were to go there uh we have a regular production mode and then we go back to this route right here and we hit it again see it's like seamless it just kind of redirects us right here and it sets our cookie and we get the draft mode stuff i think you get it so let's move on to setting this up in contempo so in contempo here we can come over and what we want to do is go to settings and you do content preview and mine's a little bit zoomed in here just so you can see better but you should see this kind of like blank set up a content preview page if you haven't ever done it before you click it and then here you set a name i happen to have next.js preview as a name cool that works i don't think you need a description and then here the content preview urls you get to pick for every like content model what you want the link to be like if you want to turn them on and how you want them to go there and this is pretty neat if you want to do like some crazy component stuff where you're previewing like just a certain type of component and not like a whole page but for now we're just previewing the whole page so if we go to product review now notice they give you this cool example um right here yourwebsite.com product review entry field slug okay so the part that we really care about here is this entry field slug thing going on ah and looks i've already got it from when i was messing around with it okay i guess i'll just use that for now so we want to type http or for our case we're using localhost 3000 a note on that in a moment then we'll do slash api like we did before preview and then set a slug here we want to do product id equals and then this entry this is a contentful specific thing entry field product id let me show you what would happen if you were to put like slug or whatever they started out with it should give you a warning that tells you that id doesn't exist on this content type which is really cool of them so we'll say yeah we want to use product id and we want to save that perfect now the note about localhost 3000 is that i'm using this for preview mode you know just to kind of like demo it and showcase it because it's going to be faster to show it this way but commonly how i would do this is i would actually set this to the production url or possibly a separate server that specifically serves for preview purposes if you want to do that you know maybe you've got a really big enterprise setup going on but a production url actually will work just fine wherever our site is hosted we could point to that with https please with that we can go to the production site and the cool thing about that is that it's going to be reflective i love this about next.js and how they implemented preview it's going to be reflective of the real data the actual production data so someone who's a content editor and you're in here whether it's you or other people maybe on your team or whatever you know i don't know your purposes for what you're using this for but anyone who's using this as a content editor can see their preview data with the actual like production hosted site so they have pretty good assurances that it's going to work or what it's going to look like i just think that's a really cool elegant solution um i've played around with i've had a lot of fighting with for example gatsby cloud though it has improved quite a bit originally you know trying to redo these builds every single time that it previews and the delays and they've made a lot of cool engineering improvements to make that better and better and better but really i just love this elegant solution with next.js preview of like let's just use a cookie that gets flagged that you know only they're going to set somehow and that will show them the preview data and the regular users won't ever see it you would want to add a little secret for a little bit of extra security and we'll do that in just a moment but let's make sure that this works so now if we go back to content and we go to product one we'll see that there's this open preview button that used to be grayed out and is now here because we just enabled it for this content type the product review type if i click that it'll actually open a new tab and take me right there which is pretty freaking sweet so let me show that again by clearing my cookies so we don't have preview mode on right now right and then we go here and we click this and it opens it and it instantly went to that url we got redirected here to uh you know the actual product product one and we have draft mode on which is pretty sweet so now if we go back and we're a content editor we could um i don't know change some more stuff draft sub head here we do have to wait for it to save and this is the one gotcha that i haven't figured out quite yet i haven't spent a lot of time looking into it you do have to reload every time that that saves it's not a huge deal but it'd be cool if there was like a web hook or something that would auto reload again there might be a way to do that i haven't spent a lot of time looking into it because i just haven't really needed to but you do have to refresh but you know it's pretty fast like let's just kind of show that in regular time so let's you know delete that maybe do that thing it there's a little d bounce time waiter it saves as soon as it's saved we refresh and boom it's there cool so that's pretty sweet so we'll do that we'll get rid of we'll get rid of this for now i'll just leave that and let me also show you what's cool about this is this works for every page the way that we've set it up is really neat because now if i go to abc123s page and i click open preview i can do the same thing here it's opened this page and it's redirected to that and now i have my preview mode set which i already did but if i were to add some gibberish here and i were to wait for that to save i'll go back over here and i'll reload and there it is this is really neat it just makes it really easy let's publish that and go back i don't know why i did that i didn't need to but it makes it really nice and convenient for the editor to just kind of like pop over to that page okay so i mentioned a secret key that you could do and let's show that this is also recommended in the docs but if we were to go to content preview here let's reopen this and here let's add another parameter so we have this product id equals this but let's make it to where they have to pass a secret as well so we'll say secret equals and we'll do super secret you would want to probably create some sort of hash or something like that put that in here and then we use the and to set another parameter another query param and now that we've saved that what's going to happen is we are going to go back over to our api here and we're going to put a little condition so rather than making you wait for me to type it out i'll just copy paste this over just so you can see it so before we set preview data around here what we want to do is we're going to make a little if statement that's like let's check for secret so we're going to have to pull that off of query params right secret secret uh we're going to do a secret and we're going to say hey if that's not equal to some sort of secret environment variable here which we'll go make let's do that and we'll say super secret right that's what we set it to go back to preview and so we'll say hey if their secret that they passed in the query params you know if they don't have one or it doesn't equal it because this is an object so it will be undefined otherwise if it's not equal to this from our environment um or they didn't pass a slug at all so if either of the params aren't there let's give them a status 401 which is unauthorized and then give them the message invalid token let's see that in action oops i better save so let's go back here and we'll go to api preview let's just pass nothing see that we get an invalid token here and let's go back to the network tab and we'll see this 401 if we hover over that does it tell us yeah unauthorized cool so now if we did oh let's do product id again nope sorry we have some new credentials that you need and so what you do need is you need secret and let's try one more let's do woof instead nope that's invalid because it's checked it what about super secret i did secrete again what's wrong with me uh cool uh slug is not defined oh gosh i'm sorry in my last one uh i was using slug but i feel like that didn't make much sense so i change it to product id these are good little errors to see along the way though so i'm going to leave them in just because one you know that i can bleed but also it's really just you know it's the everyday life of a developer why try to hide it right and you get to kind of see like what happens along the way so cool now let's do it again um super secret hit this boom perfect so we've got that all working lovely so what we'll do just to finalize that just to be sure is we'll go to application we'll clear this cookie just to make sure that we're in regular mode and here now that we've set this up with our super secret and all that stuff let's go back to a content type and if we did this right we shouldn't get an unauthorized when we click this invalid token [Music] well i like i'm glad that we're really getting to see all of the the layers here because i made some new mistakes we did i don't know why i was so obsessed with typing secret but that's cool so you can see it wouldn't work if we didn't do it right we'll click this again and you know there you go it's like tdd you know let's take the unhappy path and then the happy path make sure that it actually breaks first good to have that assurance okay now as a regular user how am i gonna get out of this dang preview mode like we you know as developers might know to go to this application tab or whatever get rid of our cookies but one we don't want to have to do that all the time and two our users you know we shouldn't expect them to know that so what we're going to do is we're going to create a separate route to clear the preview data the cookie and then we'll make a little banner that lets you know that you're in preview mode which will be kind of cool and it'll also have a button to go to that route so let's do that real fast go back to here and in our api folder let's make a new one and let's call this like cancel preview maybe i guess we should probably do hyphens and i'll just paste this here so this is just a function handler we aren't using rec we are using res we're going to call clear preview data and then we're going to redirect to the home page because why not we could like figure out what page they are and all that stuff but let's make it simple for now so let's quickly test that that works we did cancel preview and so right now we go to this we should see our draft stuff but if we were to go to the route api cancel preview it should redirect them to the home page it cleared the cookie and then if we go back we can see that we're out of preview mode perfect all right so now i'm going to add a component here so i'm gonna since we don't really have a components i like to make a components folder at the root pretty common convention do everything in the root and xjs so i'll do components here and then let's make this like preview mode dot jsx or j are we just doing js we're doing js in this one it doesn't really matter and uh to save you time i'm gonna paste one that i've made and i know you'd love to watch me type out all these styles so you know it's gonna be a style thing you'll see how it's styled but really it's this preview banner let's actually call it preview banner i like that name better rename banner so we have this preview banner we're importing link from next link so that we're using it properly we have a span here that's just going to tell them that it's preview mode and in particular this is the part we care about we're using a link you this is important you have to set this prefetch false because this is a link to an api route it's in the documentation if you look in the like next preview docs or anything like that they have a little hint here but just so you know you want to set preview or prefetch to false that when it's loading and it's like pre-fetching all of the single page app links that it doesn't do this one in particular because it's not it's not an actual page it's a route and then um i had disable preview but let's i called it cancel preview in this one so let's do that so we're redirecting them to this cancel preview which will then clear their cookies and redirect them to home and that's pretty much it it's very simple as far as this component is concerned there's not a whole lot going on here and it'll be in the repo if you want to reference it now next what we want to do is we want to go to our slug page here we're only going to show this on the on the product slug here we essentially want to have like a prop stop preview or something like that so what we would do is we would go down to get static props and you'll notice that we had this like context.preview to determine this which of course you could destructure if you want to but we'll say hey props let's add a new prop called preview here to pass along and get static props and we'll say well that's going to be equal to context dot preview and so you might think that you could just do this um unfortunately i think this comes through as undefined let's just double check that come back here so if we're not in preview mode when we load this yeah we'll get an error because it's like error serializing dot preview return from get static props so what that's saying [Music] you always have to you can't just have undefined you can do null but whenever you have something that's going to be undefined you have to have another state of like if it's undefined we'll set it to false okay i wish that they like it's a boolean that comes in as true so i wish they would automatically flag it as false but whatever so we'll say or false so if we're in preview mode set it to true otherwise set it to false okay then up here in our props we're going to have access to that now so let's do something like this let's say when you return this you know this is the error version so we won't do it there but here we could do something like uh props dot preview if that's true and and load uh preview banner i think that should be it so we'll save that notice that auto imported that don't miss that you know if it didn't do that for you you need to import it then we'll come over to here let's see if i did that right so if you reload this we shouldn't see it because we are not in preview mode but if we were to let's actually just use our handy contentful link we'll click that boom boom boom this is what it would be for a regular content editor now they have preview mode enabled and it's got draft stuff pretty sick huh and then we could just click this exit preview mode and it will clear that for them and then of course they would have to go back to the page which is you know a minor inconvenience but if you want to figure out how you want to redirect them properly go ahead and do that okay so we're really just about done now um i think that the last thing we want to do is add one more little security measure i mentioned that in the docs we were going to kind of get to some some extra little security stuff that they're kind of doing here it's it's a minor thing but it is minor for us to implement and you know a good amount of extra security you can't too much so we have this thing right here we're just like hey you know if they don't have the correct secret key or the product id you know go ahead and bounce them otherwise set preview data but really what i would like to do is actually go and hit contentful and make sure that this record exists if someone's trying to get to the preview data of this thing for whatever reason let's go see if it's actually there and let's redirect them to that product id rather than use their query param this will make it even safer with the res.redirect so as an example we could go over to this like slug thing here and what we essentially want to do is something like this we would just take this like const product here we could this is from get static props in our slug we could just take that and we could say hey if they pass that first check let's go ahead and fetch this thing now we need to set our function to async so let's do that so that we can do that very easy and now we can await this product and so what we'll need to do though is we'll need to get client right so we'll import star as contempo just to keep the same convention from and this is from our utils folder oh is it just up one folder dot slash product dot dot slash i got lost utils slash contefl sorry now we've imported it as contentful and now this will do contentful dot client we don't really need to do preview mode for this unless of course you wanted to you know also get urls that haven't been published at all yet that's a whole separate thing that i'm not going to do in this video but what we can do now is we can check if this thing is here now what's interesting about this is we want to do if you know like there's no product right but what the contentful reply comes back as for this get entries is going to be an array and what we're really looking for is that array will have some metadata on it and we've seen that in the previous videos but in particular the shape is going to be product.items and in this case i'm going to use dot length because the items array will be empty if there are no records that match that so we're doing a limit of one we're getting a product review type we'll say hey it's equal to context.params.product oh actually we pulled that off though right can't we just do product id here because we copied it over from the other one right and so now we'll say okay the fields.product id is equal to the product id that they passed in go ahead and try to fetch that if that comes back as an empty array just bounce them again and we can give them a different message this time like instead of invalid token we'll do something like invalid product id whatever you know message you want to put there okay so finally uh what we'll do is now just to kind of make this a little shorter and more readable code as well um or not not to have so much down here let's go and get that field so we got we can assume that if they got past this we have a product all right and we'll say page fields is equal to and what we'll do is product dot items and then we'll do at position zero dot fields and so we'll say that's our our page fields or whatever you could do this multitude of ways and then we'll say page fields dot product id down here so what we've just done is instead of using the product id that they passed in and just kind of trusting it as um you know the actual link that we want to send them to we'll say you know what okay you pass the secret you've passed in a product id your secret's good okay well let me hit contentful let me make sure that that entry exists if that entry does not exist i'm going to bounce you again you're unauthorized but if it does exist i will go and i'll get the field of product id from that actual record not the one you passed me in and i will redirect you to that so now let's test that out and we'll be good so if we come over to here in our browser we'll go back and we'll say hey you know let's hit api preview and this whole thing again do i already have my stuff all saved cool whoops yeah i do want this one so we've got this long token here secret this might be hard for you to read i'm sorry i can't like zoom in the url preview equals secret uh secret equals super secret and product so let's do product like 37 right if we do that we should get bounced for invalid product id but if we change that back to product one it should be good and preview mode is now enabled pretty cool huh so let's make sure that still works with this link of course we'd open preview and you know our users are still good well i think that that will wrap this one up here as usual i hope that that was useful for you i really hope that stepping through this you know piece by piece and walking through and explaining everything was useful for you as opposed to just you know a lot of times just going through the docs and just kind of like speed running it you know might give you the answer quicker but not really tell you the whys and the particulars and might leave certain things out so you know please let me know if you appreciated that or not and i will do my best to improve upon that but regardless i hope to see you in the next video and good luck to you you
Info
Channel: Swashbuckling with Code
Views: 5,501
Rating: undefined out of 5
Keywords:
Id: HNDpkYJEjw4
Channel Id: undefined
Length: 47min 26sec (2846 seconds)
Published: Mon Apr 25 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.