Build a full stack web application. Next.JS and Django Project.

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome to this new tutorial series where we're going to be building a full stack application with django and nexgs so we're going to be building out a marketing manager application or website that will be powered by a rest api that will create using the january framework and with that api we can be able to put in that data onto a next year's front end and we display it on a landing page so we'll also be able to capture a user's email and save that to our django backend so over here we have the django admin where we can add new campaigns and those campaigns can be seen on the next year's front end so over here i'm gonna come in here and add a new campaign so i'm gonna choose an image so let me choose this one edge right here and i'm just gonna say new and latest so we'll have a field called slug and also something about the images these images are gonna be uploaded to cloudinary which is a media service so if you want to store images videos from our application so cloud9 provides us with the resources and also they enable us to do different transformations on that media directly from our application so it's a pretty cool service so you're going to be seeing how to integrate it to django and they have a specific python module that we can use so down here we have a slag so every time we create a campaign it's going to have a next slag now you notice that this is basically the title here but it's separated by the dashes so we're going to be looking at the jungle slug field and how we can create slugs so notice that the slag has to be created from a title meaning that the user has to supply title and then the site can be created so over here i'm going to put a test description i'm just going to go to the next year's sites and copy some of their marketing stuff so we also can track page visits and how many successful submissions we got but we won't be getting much into this instead i will show you how to set up google analytics to track which people visit the site after we launch it so i'm going to go ahead and save here so when we save we can see that a new one was added and when we click on it you can see that it got a slag assigned and now on our next year's front end so on our next yes site you can see that the campaign was added and if you come back over here you can and you can see that now we have it here and the slug was assigned so on the jungle restaurant we're going to be seeing how to override the model save method to be able to generate the slag based on the title and then we are going to build out a rest api that can be consumed from nexus you might be wondering why next yes why not just build this with the templating with the templates that django provides so i'm here on the nexus features now what stands out mostly is the static site generation feature and this allows us to generate all the html pages at build time with its data so whenever we deploy and the user is trying to request for the website the html with the data will already be generated and it gives us a fast and better experience in general so next year's is actually a react framework so you're going to need to know a bit of react to get started here so if you have any experience building applications using create react app whenever you build the application for production the whole application is bundled into one javascript file and that makes it very terrible for search engine optimization as it is not easy for search engine quoras to crawl sites that are powered by javascript so nexus solves that issue up front and yeah so we're going to be exploring the framework we'll cover most of these features here so if you're excited about building this application be sure to subscribe and i'll talk to you in the next video hey guys welcome back so let's go ahead and get started building our project so we are going to need to have python installed on our computer and also we are going to need to have node.js so python enables us to work with our jungle backend since django is a python framework and node.js gives us access to npm so we'll be using npm to manage our project dependencies including next and all the libraries that we need to have our front our nexus front end to work so be sure to have node.js installed and also have python installed so in this one i'm going to be working on windows but if you're working on your mac the process is going to be similar you might have to do things a bit differently if there's something that is specific to mac os or linux i will be mentioning it before we continue so i have a folder on my computer called projects so over here i'm going to create a new a new folder so this is going to contain all our project code so i'm going to call this campaign so i'm going to call this campaign manager so inside here remember we're going to be having django on the back end and next year's on the front end so we are going to have to maintain two different projects the next year's front end and the django backend so i'm going to create a folder for the front end so new folder called this front end and also the one for the back end so we're going to be working in the back end for all the jungle stuff and we're going to be working on the front end for all the next year's stuff so i'm going to open the whole folder the one that's containing all these projects in vs code so i'm going to be using vs code as a text editor for the project i recommend to use vs code but if you're already familiar with another text editor or ide and you know how to navigate your way around it then be sure to stick with that but if you get problems with the environment you can switch to vs code and it's pretty simple to use it so i'm going to open this in vs code so on windows once you store vs code you're going to have the open with vs code added to your menu when you right click and this is what i'm going to click so it's going to go ahead and open up in vs code it should open up here so here we go all right so vs code comes with an integrated terminal so we're going to pull that one up because we're going to need to run some commands to install some things okay so i'm going to cd into the back end so we will start working with django right away and here what we want is we want to create a virtual environment inside the back end so to create a virtual environment you're going to be using the virtual env module so you should be able to get that by typing in pip install virtual env so that's going to go ahead and make sure we have it on map or linux if you have python 2 still installed you might have to run this using pip in pip3 install virtually nv and once we have that we can use virtually nv to create our our batch environment where our project where our back-end project will live so here you can see that we're in the backend folder and i'm going to create a virtual virtual environment by writing virtual env then the name of the batch environment in our case is gonna use in our case i'm gonna use vamp this is an arbitrary name so you can call it anything just something you can remember so event and when i run that we have a vm folder added to our backend and in there we can go ahead and now activate it so to activate it on windows i'm going to expand it just so we see what is there so we have the lib and the script so the script is what contains what we care about so we care about the activate script for us to activate a virtual environment we want to execute the activate script so this activate.bat so what you can do here is we can run the vm and then we want to run activate so i'm going to put this slash like this so i'm going to click enter there and once once we run that you can see that the virtual environment is now activated and we can tell that by looking at the name here you'll notice that when we create a virtual environment to get peep installed we get pip set up for us and python setup so on if you're on mac or linux then you don't want to run that but you want to run source then the name of the environment you don't have the scripts folder but you have you have been and then there is activate so i'm gonna leave the the command on the screen so now assuming we have the first environment set up we can go ahead and install django and create a jungle back end so let's install jungle by using pip so pip install [Music] django i'm also going to get the jungle rest framework just because we are already here so let's get the jungle restrainment and by the way if you're new to the jungle rest framework this is a very powerful python module that we use to build rest apis for django so it's like an add-on to django that makes you make any kind of rest api so let's go ahead and get jungler's framework also on the jungle swimming sites they're going to get markdown and django filter so django estimate comes with the browseable api and for it to work well we need to have macadam installed for django filters this can be used if you want to have filtering or searching so let's also bring it in we might use it i'm not sure but we'll find out so let's go ahead and install this okay so now that the installation is done we can now create our django project so whenever we install django we get access to the tool called django admin and that can enable us to bootstrap the django project so let's run django admin to django admin we want to run stat project like this so then we give it the project name so in this case i'm going to call the project cm backend since it's going to be the backend and then i'm going to want it to create all the bread of it files just inside the backend folder so i don't want it to create another extra folder so i'm going to put a dot at the end and then i'm going to run that and by the way we need to change how we are naming it so it shouldn't have these special characters so let's run that and once we run that and we go back to our back end you can see that to now we have manage.py and also we have them our main project for project files so let's start our django server now by running python manage.py run server all right so once we run that you're going to quickly see that our server has started so let me open it up in chrome which is pretty cool it actually opened in another browser anyway so now that we have django we are going to focus on just putting it off putting off all the jungle functionalities we need but first we need to address framework to our installed app section so i'm going to copy this from the documentation and in settings by we want to make sure we add it and that's how django knows about all its functionalities so right here after we include all the pre prior jungle apps we add a restrain for our application it's going to be pretty simple we are going to have only one app that's going to be managing the campaigns so here i'm going to stop the server and we create an app so i'll do control c so one around python manage.py start app and then the name of the app so for this one i'm going to create campaigns and once we run that then we get the campaigns app created it has all the django app files so inside the campaigns we're going to start by working in the models so we'll have two models one of those models is going to be managing the campaigns themselves so if maybe have a conference coming up that's going to be a a campaign and also we are going to have another model that's going to manage the subscribers and those would be the people who opt in for updates about specific campaigns so let's create a model for our campaigns so class campaign so with python we want to make sure that our class names are singular and they start with a capital letter so one import from models.model because that's how we get the jungle model stuff okay so here we're gonna now describe the fields that we're gonna need on our modem each campaign is gonna have a title a slug a description and they created that and updated fields and also a logo so let's start by setting up the title and we are not using translations this underscore that you saw autocomplete you can use it if you want to translate the messages but we're not going to be doing that let's keep things let's keep things simple and we only set the max thing so max length for the title we rotate those can actually be big so let's set it to 200 and and let's also have a description so the description is going to be a text field so that way we don't have a specific limit on the description that uh that the campaign can have and i think we're going to have is the slack so this is going to be a human readable unique identifier of our campaign now there is a slag field built into jungle so models slag filled and since it's going to be created from the titles that means that its max length is going to be slightly above this so we will be like adding so we'll be like replacing spaces with dashes so let's make it like 255 all right so now that we have our slag let's go ahead and also have created that and updated that field so for the creator that we need auto now add to be true so whenever we create so whenever we create a new campaign this should be inserted automatically using the using the current time on our server so this is going to be created at and also let's have updated that whenever we update it we are going to set the updated date to the current time on our server when it gets updated so in addition we set auto now add to true and on update then we set auto now to true so that's going to do it for our our normal field so our other field is going to be managing our logo which we are going to be saving in crowdenary so crowdnerry already has a model field that it ships with and whenever we use that we can pretty much get all the upload functionality directly from the django admin so i'm going to go here just so i can show you the module for cloudinary if you need to do any if you need to do future references so in clonary we need to set up an account and then we can get credentials to access our account from our applications actually i'm just going to log in with my existing account don't worry so i'm just gonna log in here with my existing account so whenever you log in you're gonna have your credentials here so you guys can see these credentials here and here this is the python sdk i was talking about so you can quickly see that they don't only allow storage but they also allow transformations you can add runtime requests like different variations of an image and the crowdnet apis would go ahead and work on that for you right here we have the an example of how to upload from python using the ordinary module which you're gonna install but we want to be doing it like this like i said since we're gonna be uploading from the django admin the model we set up with and will allow everything to work out of the box so i'm going to go to our terminal and we're going to install cloud nary so peep out dinner like this and when we have cloud dinner in our project we need to configure it so we need to set up cloudinary settings so the settings are going to be like this cloud name of ours and also the api keys and the api secret so when you sign up you're going to have this now to set it to set grabnary app once we install it you can see it installed you want to go to our settings.py so in our cm backend we want to go to settings and up here we need to import cloud dnr all right and anywhere in settings so i'm just going to go even just after we import it then you can secure binary then we want to call config so config and you want to pass the cloud name the api key and then the api secret so the values for this will will be the what will be what you have here so you have the cloud name the api key and then the api secret you can toggle this you can reveal to see what the the secret is or you can click the clip copy to clipboard and then make sure this so the cloud name api key and the secret you can use those here okay so one thing that you will probably notice up front is that this is very crucial information in fact even in cloud narrative they don't even show it to people that are around you especially the api key so you don't really want to expose this to your version control if you push it to github or gate so what you want to do is you want to use environment variables to get these so inside so inside our backend i'm going to create a dot env so the env and i'm also going to create a dot envy sample file and i'm gonna talk about this in a minute this is gonna contain all your secrets that you don't that you don't want to push the version control now whenever you're pulling some things from your own environment and someone is trying to run this uppercase and someone is trying to run this application maybe they clone it from git and they are trying to run it the application is going is not going to run because it the application will be depending on this environment config configs that will not be in the code so what we always want to do is we want to set up a sample file where we can dictate the things they are going to need to set up for their project to work well that's why you see this now i'm going to set the secret so here let's set this inside the environment so i'm going to copy this and here so when you define it with f that's going to run in linux you can define your variables as by prefixing them with the export keyword so you want to make them constants so let's do cloud name or let's also have cloud api key so and also just have the api secret exported to and why you want to prefix everything with cloud is because in your regular application you might have other api circuits so you can just prefix this to differentiate them from your other api keys that may have a similar name so let's go ahead and save this make sure whenever you do this you insert your correct values that you get from the dashboard in crowdenary and once you have everything set up then inside then inside settings.py now we can use the os module to get access to those environment variables so i'm going to import os and down here what you want to do is gonna do os to environment when i do dot gets then the keys so the key for the cloud name is cloud name very creative so i'm gonna get this so so do the same thing for the api key and also the api secret so in dot m this could be the keys make sure they are matching copy the secrets make sure it's matching so once we have this then we need to update our time you know to know about our environment file so for example if we went and printed this so i'm gonna copy and print up here so i can do print then i'll just do this so that's what we want to print so at the end i'm going to try to print the cloud name so let me set it to some values so we can see what's going on so now if we try to run backup application so i'm gonna do run server and notice that it's none and it actually tries to get it twice so you if it does get the first time it retries so what we want is to make sure that we can pick it so we can pick a d here so for us to be able to make it work so if you're in linux or mac you can use the source keyword and then you type dot env like this and then that's going to be able to work but notice when i run it on windows so if i type in windows you can set it doesn't really understand it so what we want is in windows we can't really use export but rather we use set so what i'm going to do here is i'm going to duplicate this file and i'm going to rename this to be env dots b18 so brt is an executable file that we can execute from the that you can execute it with the content from the terminal from the command line so instead of us using export then we are going to be using set instead so this is what works on windows so we can do set and you can see vs code actually understands the syntax so now that we have that then what you can do is we need to bring it in just like when mark you do source something but here what you can do is you're gonna need you're gonna use the keyword call and then you call env dot but like this so so when we run that you can see that we didn't get any error and what we can do now is run back our server and now when it comes back you can see that now we have the you can see that now we have the environment variables being grayed here which is pretty cool so now that we are done reading from our watch environment on both windows and linux and by the way guys if you guys get any issue any specific issues relating to this feel free to ask in the comments i'm sure people are going to help you out so whenever we do this what you want is you want to update your dot in dot env sample so you can come over here and make sure that someone is going to need to have this so here this is just an example file so we just need to make it able for someone to quickly tell what we need here but we can expand more on this from the like a readme just so people get to know what exactly they need to do but for now this is gonna do so let's have just some placeholders here and here okay so now what you can do is in our model dot py so models dot py then we can set up the logo or the image so the logo it's going to be a cloudiness field so when you when we install cloud binary we need to import it so we can do from cloud generate dot modules import so we want to import cloud in our field so when we have cloud and refuel that's one i set for the logo so over here we can set up some configurations so we can have a name then we can have other config so the configures i'm going to pass in is overwrite so overwrite it goes true so overall it's true means that whenever we had uploaded let's say a similar file with the same with the same path and we are now trying to upload as a file with a similar path then we should go ahead and repress the previous one but we can also set the formats like jpeg because jpegs so jpgs are actually more lightweight so we can be transforming every every image we upload to a jpeg but feel free to examine the documentation i know sometimes this can be very daunting to read this documentation but this is going to be your friend because on our side we're only covering like a very small fraction of what cloud dinner it does now that we have our model field set up then we can set up the the class meter so let's have class meter and the in the class meter we can specify how we want our model to behave so we're going to specify an ordering so the ordering and we want to order the dates one order by the create it but in us in descending order so we can say created that but then in descending order so we want to put a minus at the start so the items that are created later are the ones that are going to be shown first when we do the first query and this is also very useful if you want to like add pagination so let's also set the data str so this is used in the django admin and we'll get there we'll actually expand on this and improve what we see in the jungle admin so let's just return the title here okay so another thing we are going to have to specify is notice how we have this lag field and the slug field is not provided by the user but rather it's created from the title so what we want is we want to override the model save method so whenever we are creating the campaign we want to create a method that generates the slug depending on the title that it's going to be saved at that point in time so down here we are going to overwrite save so def save so every modal you create implements this method now we can override it which means that we can customize how it behaves when it is being executed so it takes in self ads and quarks is we want to create the slack depending on the title so i'm just going to create a simple variables here step by step so we can see what's going on so i'm gonna say to assign then we want to selectify we want first slagify so in django so we have a function called slackify and we're gonna import it in a minute so we're gonna slagify the title that's being saved at this point in time so if you use our suspended data like the story of my startup it's going to replace all the spaces in that with minus signs and also transform everything to lowercase so that's what it does behind the scenes so let's import it actually just go here and put logify and it should be templates so from django template default filters import laggify and then we can use slidify here i wonder why my quags is complaining we're going to find out about that now that we've created our slag from the title so one thing you should notice is on our front end we use the slags to make the query to the server so they the slugs have to be unique so in this case the title doesn't have to be unique but the strike has to be unique what we need to do is we need to make sure we need to first check if this if the slack we just got already exist in the db and then if it already exists then we are going to try to regenerate it using another function so here we can check if campaign wanna call objects on a filter when a filter by the slide so when i say if this lag equals the one to want to assign we can check exists actually so that exists so if it exists the risk we are going to use here is we are going to be appending at the end the number of the items in the db because we are sure that the number of items in the db will always increment once we add one so now we can query for the number of items and then we append maybe a a number at the end and that's going to make it unique so to do that we want to reassign to assign reassign to assign so now to assign will be to assign and then we want to add there the count of objects in the db so i'm actually going to get this plus so that returns uh our query is going to return a number so we want to transform that into a string and we are going to just query by for we oh we're gonna query for all all right and then we wanna add the count at the end so that counts so that means that if we had like 15 then our slack is going to be something like my event 15. my event 51 if the the titles are the same so now that we have the slack we can set it to the value of our slide on the model instance and then we can let the jungle handle continue to handle the save so what you can do here is you can do self dot slag equals stick to assign and we are saying equals for you putting dash okay so now that we have set the value of the of the slag then we can let django to continue and handle the sub the save so we can just send it back to the super class in this case it's a jungle models model okay so now that we are done with assigning this then let's go ahead and create the model for for our subscriptions so whenever someone opts in to be notified about these campaigns so basically what that happens is they say it's an event and an event has tickets coming up if there are some discounts running those can be notified to the subscribers so for us to do something like that we need to have the subscribers or people opted in so here let's have another class to have to handle the subscriptions so class subscriber remember there's no objections to how we name the classes the model classes so it has to be a valid python class name so models then we want to call that model so we are going to associate each subscriber to a campaign so we're going to set up the foreign key so let's have the campaign already so campaign echoes models foreign to equals campaign and if the parent campaign is deleted we also want to delete out the subscribers for that campaign so if for some reason this is something we may not want so if we wanted it to work in a way that whenever a campaign got deleted we should keep the subscribers maybe for the related events then you can run models do it do nothing so do nothing there's also set now that just notifies all the records for the corresponding one that was deleted but usually that's not what you want to do you maybe want to keep them or remove them let's also take the user's email so email equals modules.email field then you can also have created that updated that so let's get this i'm actually going to take the class meter too let's have the create that update that we ever need those usually we will let's have the ordering let's also have this let's also have the tostring just live with the mess the user's email so if you don't customize how the django admin looks so the value in the tostring of this model is the one that is used as like the identifier the human reader by identifier in the django admin but we'll get there so we'll see how that works so now that we have our model set up now we can create our migrations and run them so down here and basically what that means is we want to prepare our db to now start start to accept connections and and work so what we have here is an sq rate that jungle ships with that python ships with and django uses that at the start so that's what we want to work with now whenever we are deploying this of course we will have to change it to to postgres so sure this is just going to be useful in development so here let's run our migration so python manage.py make my questions so if we run that you can see oh so one thing you notice is nothing green that's because whenever we create an app we need to add it in our in our installed apps in the settings.pi section so what we want is we want to go to we want to go to abstract py and then we have the name so this is what we want to copy and then in the main project folder settings we want to go to install apps and also add all our installed apps there so that allows django to know where to collect things like migrations from so let's rerun again so when we run again you can see we have an error somehow i thought there was something wrong here i couldn't really tell i couldn't read it here but the thing is axe is the star is just one star so let's correct that so now models by save okay okay looks good so let's run again then we don't have models from django.tb.modules how are we importing this it should be modes.slag field okay you guys already noticed this stuff i believe so when we run you can see that our models get created so now if we migrate this if we migrate and now that we have all our database tables created we can go ahead and start to make our api endpoints so we don't need many we only need one that's going to be retrieving all our campaign list and that one is going to be of course used by the front end the nexus front end because the nexus 200 will need to display a list in html and also we're going to have an endpoint that retrieves one just so when they go to the detail page they make a request to get more details about that specific campaign that the user will be viewing and also we are going to have an endpoint that can allow the front end to subscribe a user to a campaign so we're going to go to our views.py so views py in our modules app i always prefer to use the django generic views they give us a very clean api and we just need to in our code implement specific things let's say if we wanted to implement pagination we only need to add like a pagination class property to our class if we wanted to like handle permissions authentication for that very view it's just a matter of adding one line of code and things work and that's why i always prefer them makes you write this code and keeps your code elegant and something maybe i can say is whenever you add code to the code base usually what happens for us as developers is whenever we add code to a code base we don't think about the cost of maintaining that code so whenever you have code just remember you have to maintain it so the less code you have the less bugs you have the better your life will be anyway so here let's go ahead and import generics so from rest framework so let's first work on the endpoint that's gonna be retrieving all our it's gonna be retrieving all our campaigns so class campaign list api view this one is going to be since we want to show a list then we are going to be inheriting from list view so we're going to inherit from genetics dot list api view and here we want to specify the serializer class and also the get curry set so let's first implement the get query set so def so this is a function that is used to query for the records that are going to be returned in this list and pass to the serializer so you need to implement this and here for the return what you want is you want to return a query set so a query set is a set of records it's not a query but it's a result of a query so you want to make sure you make a query here and you return the results back to the class so we need to import our model so from dot modules i'm just going to use relative inputs here let's import we need to put campaign so here when i want to query all of them so campaign objects are and that's it so the next thing i'm going to need to do is set the serializer whenever you're working with dress framework this erasers are everything what do i mean by everything so seriously are used to validate incoming input from the user and to also to specify outputs for the different responses for the user so it's very important you really understand what serializer fields are available just so you can create key serializers so if i can show you here if i go to api guide serializers serializers specifically serializer fields you're going to see all these fields so these fields have built-in validations they like built-in transformations on how responses should be so you want to take time to whenever you're working on a project come here and see okay what could i use for this specific field so something i felt i would mention i was thinking about this and i think when i get time i might make specific videos just to illustrate how this can be used like shots or something like that but it's a very important concept there is a very important concept so you want to make sure you invest time to learn about them so going back to here just create a sterilizer for the campaign so class campaign serializer we are going to inherit from serializers this imports the risers from jungler's framework so then we want to inherit from sterilizers thoughts modest eraser and you might be asking why why am i inheriting from modest eraser why not just import from serializers.serializer so that's because when you look at our model the model specifies criteria on what we need so we need maybe this to not exceed this so the model already enforces specific validations so right now if we wanted to only rely on the validations from the model then what we can do is instead of us specifying the series of fields we can just rely on the modern one so whenever you specify that you want to use a modus eraser you want to provide a class method to describe which fields you want included in your responses and checked on requests so we want society model so the module is going to be the campaign and also the fields so the fields if you want is only exposed title description and maybe the slab and not send this we would only create a list and we specify this but at this point we don't we don't really have anything we don't want to send back so we can specify that's be sure to send us everything okay so then that all will make sure all the fields are included so we don't have to type them one by one just import the model so from that models import the campaign and once we have that we have the class meter let's also have the serializer for the subscript subscriptions because for that we need to make sure the emails are validated and all that stuff so it's going to be a modest eraser now this is going to be a subscriber model so subscriber then we can based on that right here and if we take a look at our models then you'll notice that for the subscriber we only have the campaign and then the email and these ones are auto created so they have default values so we also don't have to worry about specifying different fields so now that we have our serializers set up then we can import we can import our series in our views so from dot serializers imports subscriber and also the campaign subscribers eraser you need to rename this i believe oh it should be subscribers eraser so this should be subscribers eraser this is what you want to import in the views so import subscribers eraser and also we want to import the campaign series so once we import those we want to specify serializer class as a class property so serializer underscore class we'll set that one to our series and that's gonna handle serializations for this ap this view so this is gonna be serializer so i'm gonna save this and that's pretty much it we don't have to handle any authentication we don't have to handle pagination what we can do now is we need to set up our urls url buttons and then hook hook up the routing for our app with our routing for the main application so let's go ahead and set up our url.py you and we want to import path so from django urls then what we want to do is we want to set url patterns and then we specify path we want to say that every time the user goes to slash campaigns on our api then we can instruct django to handle that using our campaign list api view so in the urls.buy we specify the path so path wanna say if someone goes to campaigns then we want to handle that using the view so let's import views from that views import we need campaign list api view so since it's a class based view we want to do as view so as you then we can set a name this name can give us an easy way to get the details of the url without having to know the url so you will see what i'm talking about but i'm going to give it the name of campaigns so whenever we are testing we are going to be using the reverse utility to know more about the url without having to go to slash campaigns slash anything so now that we have our url buttons for now we have one we're going to be adding more here we need to hook this one up with our main application routing so we can go to our main urls.py here and right now we're going to have the admin we also want to have another path so for this one we're going to say every time you go to api we are going to be sending you to other apps so for now let's import include so include allows us to combine to combine url patterns so what you can do is here you can have include and inside there then we can we can specify the path to the urls so just the way we specified the app name and settings as py because that we set it up as campaigns so whatever you have here sometimes you might have a path or an import like backend.campaigns so to include the urls in that app we put the name which should match in the settings then dot euros and we have an issue importing subscribers eraser in the views i believe so i need to save this and now once you run back the application you can see that it's running so i'm gonna click there the page has changed and now we can see some other urls added here so i'm gonna go to slash api slash campaigns since that's the path we specified in our app now when we come here you can see that we have no campaigns now and so i'm going to create a super user since we already set up our models so i'm going to stop a server real quick and run manage poi create super user so python manage py create super user so we can specify the username and the email then the password can be anything so let's run back our server and now if we went back to our application so if we went to local export 8000 so when i go to slash admin you can go to the django admin and then i'm going to log in as the user just created in the terminal so that user was chris i believe hopefully i remember the password you can see that we don't have our model added here so what we want to do is we want to go to our app so whenever we have an app we have the admin.2i file and we need to register the model here so we want to do from modules imports so when i import the campaign let's also import the subscriber because we're also gonna need to register them so here what you can do is we can use admin dot site dot register then we want to register them one by one let's start with the campaign one then let's also register the subscribers subscriber all right so once we have that and save and come back to the site i'm gonna refresh okay so here if i click on campaigns you can see that there's nothing so i'm gonna try to add a campaign so when i click add you can see that we need to add a title so for the title the mega let's say the mega markets okay so for the description this can be anything i'm just going to pick a random picture so notice how the slag required us to enter it and it didn't allow us to save so that the save method gets caught so what you can do is we can tell django to not accept this at request time so a scan so what you can do here on the slack field we can circle that's the max length but it can be blank but it can be now so now it goes true and blank equals true so if you're confused about these properties so for null means that we can pretty much not certify so set a value at all and blank means that we can set the value that is empty like an empty value something like an empty string so that's the blank one then now it's just you don't set it at all so that's how it works now whenever we change the models we need to update our our migrations so let's do that so make migrations migrate then my grid let's run back the server so i'm going to try again so i'm going to click and then click save so here we need cloudinerry.config and then we passed the cloud name so notice how we say crowd name so it should be cloud name okay so let's save that and try again so we're gonna need to retry this so this is the mega conf then description can be anything just so i'm going to save now when we save you can see that this was now created and we have our event here and right here you can see we also have the file that was set notice how it has this name here so if i open this in a new tab you can set it points to cloudnary so all all cloud narrow resources are prefixed with this and then down here we have like other things and the name at the end and you can see that it was transformed to jpeg because we set the transformations on our model so that's how that works and now if you go to our api endpoint so if you go to slash api slash campaigns we got the list you should be able to see that we have one one item and the slack was automatically generated so let's go ahead and now add an endpoint that can retrieve one of these that the details will use it's pretty much going to look like the object is going to look like this because there's not really much but oftentimes you want to send the little amount of information especially on the list endpoints so the detailed endpoint is always going to be needed but for now this is okay we don't really have a lot of properties but let's also have the details endpoints so we're gonna go to the views and also we need to have the details so to create the details endpoint we are going to have a class based view also so we can call this campaign detail to campaign detail in-house from generics so there is one called a retrieve api view and that can be used for the details but also i want to talk about the generic api view so let's just get generic so guys whenever you find that what you want to do does not easily fit the case like you're not really maybe you may not be sure about which one to use and you want to implement them the http method yourself so let's say you want to implement the put the patch or the they put the patch they get the post and you don't want to use this so like that would be like reimplementing them but if you want to take that route then you want to inherit from generic api views and then you can handle any kind of method here so since it's generic then can handle anything so you can handle put patch i can handle i guess it's called post and post and get so all those so in our case let's use this to handle the gate so when you're trying to get one so get will be in self request and then the slug so we're gonna be since our slides are gonna be unique and the front end is gonna be sending the slug since that will be what the front is the front end will be using so in here what we want to do is we want to query for the item with this slug we can say query set let's save that one to campaign object filter then we want to filter by the one with this slack so what you can do here is you can do campaign [Music] objects filter so we want to filter by this lag because where the slag it goes to this slack so there's no the reason why i'm using the filter is because it doesn't it doesn't throw an error so we can do first on it so it's always going to return one and we can handle the case where this didn't match like the you the front-end didn't send something that matched in our db so we can say if we have the query set then we want to return that data to the user so we can say return so now you're going to be handling resources ourselves and that's the drawback why you don't want to use generic page views but use like retrieve api view in this case so you guys can try retrieve api view to implement the same thing so let's import responses so whenever we want to send a response to the front end we have a response class that you can call on this response so if we have that query set so if we matched then we can return response dot response then we can send back json now we are going to have to select the the query set because this is a model a python object this is a model object so one up series it's to json and send it back so we can pass it to our serializer so i'm going to set the serializer class even on the even on the detail view allow me to change this to a behavior so what we can do is so to use this array that serious this object you can just pass it by calling the serializer class so by the way instead of the serial class is equivalent to you just calling this okay so we're just referring to it just to keep things a bit more organized so there is a class then takes in the instance it's gonna say rise so by default whenever you pass something there it is it's expected to be one instance which in our case should be one instance so query set so if you want a series more than this in any case you want to pass another another option for many equals june so if you're if you're still raising more than one instance you're going to pass them an equals true but in our case it's one and then we're gonna call the data in it so the server of course has different fields but the dot data is the one that gives you the release the serious version of what you passed in here okay so now that we have that response we can handle a case where we didn't find it so if we don't have it we can just return it for so again it's a response response we have statuses from risk framework so that's so let's go ahead and import them okay so down here we can just return http 4 for not found and we need to add this in our urls so i'm going to copy duplicate this let's also input the detail so that's what we want to use for the second one let's keep a comma and this one is going to be handling the campaign not campaigns so here we are gonna we are going to be handling when a user goes to the slot to the campaign slash the stack so we can specify it here so you need to have a slash here and now if we come back and refresh because it gets the one and now we have on the object and not the array or the we only have one object and not the array so that's it if we put something that doesn't exist you should get the 404 sc you can see we get the note found meaning that those two are working so the last endpoint you're going to need to work on now is going to be the endpoint to allow a user to subscribe to a campaign okay so let's go to our views and in our views we need to set up another class based view that will handle the creation of a new subscriber to come it to a campaign so what we want is to want to set up a class so i'm going to call it subscribe a behavior subscribe to campaign hey what's up long name api view and then we wanna inherit from so this one we're gonna use the generics create api view and yeah just easier to work with so generics dots create api view so that one is used to handle it knows that you're gonna need to create so it it goes ahead to handle the post for us so the things we did here underneath the gate for it it's going to do whatever needs to be done to handle the post so it's going to be create api view what we need to do is handle the get query set so whenever we create it needs to use a get query set to know which one to send back so here we can actually say like subscriber objects with latest that's going to send this one we added but using latest actually needs us to update our model so right now i'm just gonna get all of them because like i said it doesn't really matter so much so let's import subscriber from the model so also we need to specify this eraser class let's use it to sterilize the incoming request to make sure the email and the campaign exists on the in the request the substantia underscore class and you can set that one to our subscribers eraser class so that's gonna be this so ctrl a then let's have it here okay so now that we are done setting up our api view then we can end we can also add it to our urls so here you can have campaigns subscribe so let's have subscribe let's let's also import our view so subscribe api view that's the one we want to use here let's say subscribe here so for us to test out our subscribe i'm going to copy our url so and then i'm going to open up postman so postman is a tool that allows us to test api endpoints so since we're going to be making a post request we're going to come here and you say want to go to let's see localhost put 8000 slash api so i'm going to copy that bring it here all right slash when i make a post request so we want to go to the body and we want to specify the data i want to send so we need the email and also the campaign so those are the required fields from the from the model so let's set an email and now say email let's also set the the campaign so the campaign since it's a foreign key then we need to use its id so at this point in time we already have created one so that means that's the id that was assigned this one because what one i use so let's send here i see post note allowed so let's take a look at what's going on so what's happening is the subscribe is being passed as this slag so what's happening our request is being handled on this point so when we send the request it is only handled up to here because now the slug here is looked at as the subscribe one so what you can do in this case is move this one down or or we could use a completely different one here we could use a completely different url here so i'm gonna do subscribers and uh i'm just gonna remove campaigns from the start so that means that now the request you're gonna make is gonna go to slash subscribers and it's gonna be a post request and we are sending the campaign and the email so i'm gonna send this and notes that we get one created here and now if you go to our django admin so i'm gonna go to the jungle admin so that's found at slash admin so once we get in and click the subscribers list you can set we have one subscriber and when we click on them you can see which which campaign they subscribe to so that's it in the next one i'm going to be showing you other things we can do in the back end hopefully we'll finish the back end in the next one so thanks guys for watching and i'll talk to you in the next video hey guys welcome back so in this one we're going to go ahead and customize a few things in our admin and also set up documentation for our api just so it can be easy to use for both the front-end developers of which it's still going to be us today and also for the admin users so to get started we want to be able to add we want to be able to add other fields here like when this was created on the list we want to enable a way to search for these if there are many and also i'm going to show you how you can add pagination if there are like many records in the in the admin so let's start with the campaign so let me bring up the code so if we go to our app or campaigns app we have the admin.py file what we did was simply register our modules to be able to show in the admin we can be able to customize this one better using the model admin so so the way that works is we create a class so i'm going to go ahead and create a class or it's going to be a model admin class so it's going to do so let's do class let's start with the campaign so it's going to be campaign module admin and we we have to inherit from model admin and we get that from admin dot model admin so what we want is to be able to to set up fields that should show here and we do that by specifying a list display property and we set that to an a table so we so we're going to want to see the title let's also make a table that you can see the created ad so we can see the time that it was created also i'm going to add updated that so once you create a custom model admin for the model what you always want to do is still register it on the admins admin with the model itself so the way we do that is first we pass the the model itself and then we pass the admin class as the second one and you can see from this signature here that the second has to be an admin class and it should be of title mode admin so let me save this and now if you go to the to our server and refresh you can be able to see that now we have created that and updated it so i'm also going to show you how to add a search field just so a user can be able to search so still on the properties you have to specify such underscore fields so that also is going to be an entry box so let's enable the search by the title also let's enable the search by the description okay so let's check that so i'm going to come and refresh i notice that now we have a field that can enable us to search and i can pretty much search by anything so i can pretty much enter anything and it's gonna try to match titles and the descriptions so here you can see that in the description we have test so if you came back to our list and put in tests let's put in tes and do a search because that will still match the this very campaign so let me change this to something that wouldn't exist like yolo hopefully this doesn't and such because this doesn't exist and the search is working so another thing i want to show you is how to add pagination so let's remove this search because it's kind of limiting so let's say we had two campaigns so i'm gonna click add and let's add another one so let's save this so let's say we had very many of these let's say like a hundred or more and we wanted to enable pagination on them what you can do is on the model admin so right here you can specify a property called list per page so list per page and you can see all the properties that are available here through the editor autocomplete so what you want is list per page and we can set that to a number so if we set it to one in our case since we don't have many and uh come back to our or our admin i'm going to refresh here and you can see that we have the pagination added so that's how you add it so if you click on page 2 should be able to see that we see page 2 if we go on page 1 you can see page 1 and you can enable all of them so that's how you add pagination if you had very many records here that's when it would be useful but that's how you go about it so moving on we are going to go to our subscribers and on the subscribers we want to do the same thing but we also want to be able to search subscribers by the campaign they subscribe to so that's gonna raise this situation where we need to work with the the foreign keys so let's go ahead and see how that one works so i'm going to go here and create another mod admin for the subscriber modem so i'm just going to copy and repress this since we pretty much know what this is about and just copy this then this rename campaign to modern so we want to be able to show the email and uh when someone subscribed okay so we can say we can say we want to show the email and then the campaign that someone subscribed to so let me just change this one to campaign and also they maybe when they they signed they signed up or they subscribed so let's change this one to create that okay and we're gonna keep this as the same fields in the search just so we can i can illustrate the problem better so i'm gonna do this so after we specify the module admin we also want this we want to send it to the register through the register function so let's bring it here and save and now if you go back here and refresh we have the creator that we have the search fields but one thing i want to show you here is let's say we try to search but for something like conf so i'm going to put conf here and click enter notice that we get an area that says that related field got an invalid lookup and that's typically because by default whenever we by default whenever we use a foreign key if we don't specify a related field it goes ahead to use the id and here basically what we need to do is specify the field it should search by in the related model so in the campaign we need to specify a field it should search by when we are defining the search fields so here where we have search fields and we have campaigns we want to be able to search by the campaign's title but the campaigns is a model and the title is an attribute on that so what we need to do is we can use this syntax here and at the end we put the the field we want to search by in the related model so if we save this and come back around i'm gonna i'm gonna search again you should be able to see that now we match and we don't really get an error so this touch and the search is working okay so that's okay that's good so the next thing you're gonna need to do now is uh to set up documentation for our api and since we are using django rest framework the easiest way to get documentation up and running is to use drf yes now i've used this in several of my videos it's really a good one and we are just going to stick with that and add our documentation so to use drf yeah document our api we're going to go to drift yes it's good it's documentation and take a look at what we need to do so i'm going to open it up so we need to install the arrayvia 6 i'm going to copy this and go to the terminal i'll stop the server and run pip install their fiasc and as it installs i'm going to come back around here so what you need to do is add it to our installed apps so just django knows about it so gonna go to our settings py and scroll to where we have installed apps so right here i'm actually going to put it on top of our custom app so if you go to the documentation basically what you need to do is to specify a schema view and then we can hook in the urls where we want our documentation to be so it's going to be we're just going to use the boilerplate that we give in the documentation so i'm going to copy this and go to urls.py so here we can define the url buttons we are just going to keep on the one path the one that serves the soccer documentation we want to listen for when a user goes to the home page and then we want to serve the documentation to them so let me remove this so right now what we have is we have a url buttons with the path so we're going to copy this path here and take it to our main url buttons so over here we can press there the path for the documentation and save that so let's look at the schema view so basically the schema view it enables us to specify some meta information for our api so we're just going to change this to be not snippets but campaign manager yeah so now if you go back to our application i'm gonna go to here and go to the home route oh our server is actually off so let me bring it back up so the server is now on so if you go back to here and refresh you can see that we have the documentation being served and everything is good uh yeah so we now have the documentation that our front end will use so we'll be using this endpoint here to get the list of campaigns that we'll show on our nexus front end then the detail endpoints that we will make a call to that will give us the details of the campaign and the subscribe so we're going to be making a post request from our phone from the front end so now our api is done we have everything on our jungle setup so what's left here is to maybe do set up some some cores to enable to enable access from different domains so hopefully later i can show how to deploy this to app platform so you guys can put it in a live environment so in the next one we're gonna start working on our next year's front end so if it helped you give it a thumbs up don't forget to sub and i'll talk to you in the next video hey guys welcome back so in this one we're going to go ahead and set up our next year's project and explore the basics of how routing works in nexus and also customize the way our folders are going to be so to get started right here you can see that we have the front-end folder and that's where we want to work from now since we want to separate the back end and the front end so i'm going to go ahead and create a new terminal window and i'm sticking to command prompt i want to make sure we are on the same page so i don't want to be using git bash when someone doesn't have git bash installed so if you're on mac you just want to have a new window and the commands are just going to be the same so to create an xds project we use a tool called create next app so i'm gonna cd into the front end so here we want to run create next app so we could go ahead and install create next app as a global package in our on our computer but we don't wanna do that because we have npx so npx allows us to use emoji without actually installing it create next app included so wanna do npx create dash next dash app and then want to give it a name so so let's say our register is going to be called maybe campaign manager would put the name here but for now we are going to keep it as front end so we could go ahead and add front end here and what that would do is it would go ahead and create a folder inside our front end called front end and add there all the boilerplate for next yes inside but that's not what we want we don't want to nest a front end folder inside front in fact we but what we want is want to create all the nexus files inside our front end so if you want to create the app directly where we are you can go ahead and add a dot at the end and click enter and you can see that now it's putting in node here so we have node and python so it's gonna it's going to go ahead and create a node project so you can see we have the package.json so we have the let's call it the simple starter let's wait for it to go ahead and scaffold the whole project and then we pick up from there okay so now the command is done so what it wanted to do it created us the next year's boilerplate inside front end so we have the pages folder so inside the pages folder this is where our pages would go you can think of a page in nexus as a representation of each webpage so by default we have the index.js and this is the home page so if we had like the about page we would add about.js here if we if if we add like the contact us page we would have contact us.js here and the styles here we can write our styles for the components we'll write and also the the pages will draw it so if we wanted to style those we would put them here so by default nextgs supports css modules and css modules is just a way that you can write css that gets assigned random classes at compile time and that helps us to scope our styles to specific components and not having and not having different styles override the other ones in other components so we have the essence json this is for linting and we have the config so in the config this is where we would put different settings regarding how we want next years to handle different things so in the packet json here usually we have three scripts set up for us so we have the dev script this we use in development we have the build if we wanted to deploy this the server would run build so have the start so the start is used on the server so if we build the project this this stat is the one that basically runs the app in production so we also have the links this is for linting and yeah so for the dependencies we have next year we have next we have react and react down so these use webpack and people under the hood just so we can get a good experience developing so down here we have the dev dependencies we just have eslint stuff so to run the project to take a look at what we have we run the dev script because that is the one we use in development so what we want to do is we want to put yandev and that's going to go ahead and open up on port 3000 so i'm going to go to the browser so it's compiling here so it's done compiling so if you go back here you can set we have the next yes welcome page and our nexus project is up and running so nexus uses file based routing so the routes we put here in the browser are immediately mapped to the files on our in our project so in the pages folder this is where you put your routes for example let's say wanted to have like the about route so if we would we would have to write about dot js like this and here what we can have is just a react component so let's just have a react component there so we have function about the convention for the file is use a small letter for everything and then of course um of course we can still use our regular components but we're gonna see how to set up like a components folder so here this can be named anything and since it's a react component this one we can now name it using a capture data so i'm just gonna so i'm just gonna change this one from about to about so even this i'm going to change it to about and now when i save and go back to the browser and go to slash about notice that we get the page rendered our page doesn't contain anything for now but let's say we returned an h1 that said about us like this so if we save this you can see that the compiling happens so we still have hot rear enabled and uh if we come back here everything updates and we have the about us so let's say we wanted to have another page that maybe had uh our contact information so do that by creating a page we would call it something like contact.js like this and in here we can just have a react component the common convention is react components are named using so react components are named using capital letters and that's what you want to make sure you are using so let's return contact us so now if we go back here we should be able to go to slash contacts and we should have the contact page being rendered so those are the basics of just routing using this now we also have dynamic routing so let's say we wanted to go to a dynamic item we pick from the server so we're going to be looking at that in the later videos when we are fetching from our server but this is how we basically route now what i want to do now is to show you how else we would organize this so of course with the react kind of project we want to have a way to have our components in one place so you could go ahead and you create components here a component folder here so let's create it and this is where we put all our reusable pieces of the ui so also to keep organizing our project we also want to have a constant folder where we can keep all our constants and you'll be seeing how we'll use these in our simple projects we're going to create so let's have constants here so we might have cases where we need to maybe isolate some specific functions that we use in different places so we can also have a folder for that so i'm going to create a folder called uh utils so also when we are doing like data fetching we want to have like the data fetching setup logic in one place and uh usually this is done in a folder called services but sometimes you would see one called especially especially with next year's projects so we'll have lib here and this is where we'll put like all our setup for like our feature function that will set up the like axios or something like that so now one thing you'll notice here is when we keep adding folders here this keeps getting uh a lot like we get more files added here and it's usually hard to look at so next yes supports us creating an src folder and then we can have all our major project source code in the src folder so what we're going to do here is we're going to create an src folder and then we are going to move everything here so i'm going to move pages inside the sr scene i'm also going to move components inside src i'm going to move constants in inside src and also i'm gonna take the styles so let's bring them there and also the youtubes in there okay so let's see what's up with the folder the pages because we need them to come down here okay so so after we move everything inside the src you can see that now our folders are still a minimal and we can add all our like mains main source code inside src so in the root we have like config files and then all our major project code can go in src so if you go back to our application so i'm going to go back to chrome and refresh this i'm actually going to go to the home page you can see that everything is still working out of the box and you didn't have to reconfigure anything so something to take over here is next yes supports putting everything inside the src folder by default and uh yeah so that's gonna do it for this introduction video so in the next one we're gonna be looking at how to add a custom font how to use css modules how to route to a dynamic page so it's going to be interesting if you enjoyed the video give it a thumbs up don't forget to subscribe i'll talk to you in the next one hey guys welcome back last time we're able to set up our next js project so in this one we're going to go ahead and fetch a list of campaigns from our server and display them using nexus on the front end so i'm here on the next year's website so they have three unique ways to fetch data from the server we can implement get static props basically we we use this when we want to fetch data at build time and we have good static paths so this works hand in hand with get static props to be able to generate routes based on the data so we're going to be working with these two git server side props is specific for server rendering so if you wanted to be fetching data on every request we'd be using this in our case you're going to be using the static generation approach such that the data is prefetched at build time and the pages are pre-rendered aside from that we are also going to be able to set up custom fonts with our nexus projects and also write some styles to make it look like this so we'll also look at how to use environment variables and use them in the browser and we'll talk a little bit about what the difference is and how next years works with them okay so this is where we stopped up from now i'm going to go back to our vs code project so in the source folder we have the pages folder and this is where our and this is where our index.js is and this is where we want to work so i'm going to go ahead and remove everything so for now i'm just going to create an h1 all right so if we check here again we should have available campaigns and you can see we have just a typical h1 so right now let's work on create let's work on configuring our application to use a custom font so we'll be using a font called merrywear the sun's so let me go ahead and bring it up and uh we can get it on google phones so what we want to do is we want to come to fonts.google.com you're also going to use another font called no nato so over here let's say we want to get the regular 400 and maybe a 700 one we're just going to get the port so we have these two here and if you wanted to use them if you wanted to link to them we would go ahead and copy this link here so i'm going to copy this and now that we have our font the question is where do we put them so we would want all our websites to use these fonts so it would not be ideal to add these fonts on every page like in the pages folder but what you can do is uh if you come over here in the docks if we come here on the next year's docks we have something called a document we have some information that tell us about what it's about and how we can use that so you can see that we could create a document that augments our application's html and body tags and the way it works is it uses all this next year's stuff what you have to know about this is we can use this to set up things like fonts to load any other extra javascript you would want to load so what you can do is we're gonna need to create something similar so i'm gonna copy this whole document here and in our application in the pages folder we want to create an underscore document.js file so over here then we can go ahead and paste in what we got from what what we got from the documentation and we can go ahead and export it to export default it's called my document so we are not going to be working with get initial props so we are only going to be worrying about how our html is rendered and we are going to need to work inside the head if we think about our regular html page or structure we usually have the html and then the head and then the body now here in the head is where we would add things like links to external css links to fonts so over here i'm going to open this one up and we're going to add our links to the fonts okay so now let's go ahead and get our font so we're gonna go back to the browser so on the myweathersense you're gonna go ahead and select the 400 so 400 is the font weight so let's select this let's also grab the 700 all right let's also go and grab the nunito font so what you can do is here we can go ahead and refresh this so let's refresh here so that's going to go ahead and see that we've selected some other fonts before so what you can do is also select the nitto font so i'm going to select the regular 400 and yeah so that's gonna do it now what we need to do is go ahead and copy these links here so i'm gonna copy this go back to vs code so in our document dot so you know i do so in our underscore document yes since you are not using it in re in an in a regular js project but a jsx project here we can go ahead and fix these errors by closing these tags so let's also close this and save and that's gonna go ahead and include our fonts now now since we want our font to be used on every webpage we have a file where we can put our global styles and in styles that file is called global.css so what you can do here is uh we can change which font we use in the body to use our own and also we're going to change the fonts that our paragraphs are going to use so to use the nonito one so i'm going to come here and down here we have a way we can specify them so i'm just going to copy the first one and where we have and here on the front family just going to replace the default ones to use our merry weather so once we save that we also want you to change paragraphs to use our nato font so you can say all paragraphs should use an anita font now let's go ahead and copy the style for that should be chop so here we can include our font and save so if i go back to index.js i'm going to create a paragraph so p let's make sure these are in one parent element and this is just the same way react works like this is this is just react there's nothing new here so we always want to make sure that all our elements have one parent element so now if you go back to this site we should be able to see that these changes so to verify i'm gonna go ahead and remove the styles and we'll see if this changes at all i'm going to go ahead and comment this so i'm going to comment this and this now i've not really saved so things are still good but notice when i save so i'm going to come and save that come back over here you can see that we lost the font so that means that our font is integrated and things should be okay so we can move on to now creating our page so now let's go ahead and do our data fetching and display campaigns in our ui and then we can go ahead and save them after so back here so whenever you're fetching data for the page you want to face that data in the page that helps out making sure that data is only fetched in the pages that it's needed from i'm going to come over here and whenever we want to fetch data and we want to make sure that next year's fetch exit at build time we want to export an async function called get static props so what you can do here is want to say export async it has to be async because inside there we need to do an asynchronous operations so let's call it get static props and this is how you have to call this anything else will not work ready and this is how nexus understands that this should be fetching data at build time so you want to make sure you call it this so inside here we can go ahead and fetch our data so what we can do here is we can use fetch to get this data so i'm going to go ahead and say const response equals a weight so since we are in a nesting function and we can use a weight so it's a way to fetch inside here we need to put the url that we're going to fetch data from so if we go back to our documentation we need to call this endpoint for get campaigns and by the way let's first try it here in in the docs and it's going to send us this so this is what we want to call just like we called it here but now i want to call it using fetch so i'm going to copy this and bring it in in the code so that's what we want to put here and later i'm going to be showing you how to put this in an environment variable so that's going to give us a response but then with fetch the actual data is in another promise so here we can do cost data equals a weight so one await response then we want to transform that into json and that's going to be our data so from here we need to return props so we need to return an object that has props all right and this is how it should be this is the the way it should be you want to make sure you return something called props here and then down here you can return any prop so since we want to return the data we can say data we can say data will be data and also we can return anything else here and that should be available as props to our page so to test it out let's return something called done we're going to under send that as june so now once we create our async function and return props here these probes are going to be available in the in the page itself so here we can destructure them we can say data and also done all right so let's go ahead and and consolidate this so we're going to consolidate data so i'm also going to console.log down there i'm getting this console log you can see i'm able to type clo and click enter and things work and that's because i have an extension called es7 react redux graphql react native snippets this this is the one that gives us this functionality and it's the one that we can use to generate the the react components so now if you go back to our application so i'm going to go i'm going to open up the chrome console chrome javascript console and we come here so you can see down here that we got data and the data is an array with the items from our server so that means we're able to fix the data from the server so let's go ahead and just do something simple to display it on the page so what you can do here since data is going to be an array we can go ahead and map over it and display it in a list so here let's use a div so in here i'm going to create a main so now here that's where we can put our available campaigns and for now i'm just gonna map over them so we're gonna do data dot map so map takes in a callback function and that callback function can access each element in that array so let's have element and we want to return a div so let's return a div it's going to represent a list item on our ui and since this is react remember we need to pass keys so react knows how to handle rendering of our list so let's pass elements we need to use a unique property here and we know that our stacks are always unique so that's what we want to use here so inside here we need to show an image and to also show the title and then the description so i'm going to have a div that's going to contain both of those and i'm going to have it the first div that's going to contain the image so i want to display them as effects like left to right so here i'm going to use the regular image and then we're going to talk about the next year's image component and how that's different from this so for the source so the source of this is going to be element. so let's take a look at our response from the api so if we take a look our image is dot logo so that's what we want to use so let's go here i'm gonna do dot logo so let's close it yes so let's apply some hate and we did so hate let's send like 120 let's apply some with it so we can specify an earth so if it doesn't load the user should know what's going on so we can say campaign maybe banner or something like that so on the right we want to have another div that's going to have a title and then the what else the description and also we're going to show some and and we're also going to show this date here when it was created so let's have an h1 there and here we can show the title so let's just put element title so let's also have the description so we're just gonna have a p and for the p we show that the description the element the description and we can use we can use typescript to get autocomplete for these things but that's that we are not gonna cover we probably are gonna cover that in the future so down here let's also show the date when it was posted so let's have elements created at like this and save now if you go back to our ui so we're gonna go here and come back here you can see that we have you can see that we have we are able to display this on a page one thing that's not working really well is the the the images they're not being loaded and the reason for that is because on the server we are getting a relative path and not the absolute path so every time we upload to crowdenarry we only get the relative path and to get the absolute path we're going to go to our admin so i'm just going to slash admin here then i'm going to click on the image from here so if i click on this you can set it renders the image but notice that it prefixes everything with up to here so we're going to copy this and we're going to copy the prefix so already viewers starts at image upload so now what we can do is in our project so here we can do what we got as the prefix and we want to stop before slash image because slash image is provided from the api so if you come back here and check you can see we have image so when i'm gonna add a slash make sure it's matching so this is now gonna be the prefix slash our relative url so now if we go back to our application and go to the home page you can start now we're able to render the images so let's talk a little bit about the image component that we get in next years so i'm gonna come here and search for image so this is a component that's built into nexus and it's built to enable optimizations so the things that it gives us out of the box are loading the images only when we need to see them so let's say a page had like very many images it would go ahead and load only the images that the user is seeing so whenever we scroll like down then it can load those images dynamically also if we went ahead and so if we went ahead and put this in a mobile view you can see that we are still seeing the same image with the image size as we would see on the web but when we're using the nexus image component it goes ahead and does the resizing for us depending on the device viewport looking at the examples you guys can come come over here and see what else you could do so looking at these examples here you can see that we can import it from next image so i'm going to copy the input and here let's go ahead and import it it's actually imported here so that's the only one i use so instead of us using this regular html image that's the one we want to use so let's check now so it crashes and then it tells us the hostname rescalenera.com is not configured under images in your next.js so nexus needs us to tell it about where we are loading our assets from such that it can be able to do the optimizations so i'm going to come here and we take a look at where they talk about that so here they say to enable image optimizations for images hosted on an external website in our case they are hosted on culinary use an absolute area for the src and specify domains so the domains are like the prefixes so we need to do something like this so what we can do is we're going to copy this and we have the the next conf file so down here the next config file here is where we want to put the config so let's bring this one in and uh let's cut this one out cut this one out so we satisfy images and then the domains so the remains have to be an array so in our case what we need to do is let's take a look at our error again so what we need to do is specify rest.ordinary.com as our host name so where we are getting the images from so let's go here and repress example.com and this so cloud9 has built in optimization itself so that makes it a good fit for the nextgs component and we're going to be seeing what kind of request next yes makes to cloud dnr so once we change things in the config file we always have to restart the server so i'm going to stop it so i'm going to stop this and restart it so i'm going to run yandev again so let's go ahead and restart it and now if we come back to our site let's refresh it notice that the images are being shown properly using the nextgs image component okay so for the props that we can send we have to send the src which we are doing the width and the height there are some optional props so there is layout it does the resizing when the device with this changes but if you set fixed then it's not going to change so you take away the responsiveness bit of the component so for now this is gonna do so the next thing we're gonna need to do is uh let's talk a little bit about error handling so let's say we were fetching something that didn't exist or we got an error fetching this what you want to do is since we are using a weight here you can wrap everything in try and try catch block so we're going to do try catch and i'm going to copy this whole code and take it in a try so so this is something we would expect to work but now when we put it in the tray we can't access the data down here so what you can do is define as a data here so that data let's set that one to empty and then we assign it when we get it so now that's gonna mean we have the data but how do we send the errors so what happens when we get an error and we couldn't get and we couldn't get the campaigns so down here before we return the props we so let's say we don't have any data so let's say if no data length so we can return something called a note found so we can return an object that has a not found key you can say return not found so if we return not found true so for example here i'm going to go ahead and make an error here i'm going to remove this slash here meaning that this should not work and save and that's going to make it that the data array is always going to be empty and this is going to catch and this is going to throw and this is going to be returned so if we return this here and go back to our application and refresh it notice that we get a 404 page here so optimally this might be something you want to do for some cases this is not what you want to do in our scenario in fact what you want to do is tell the user that there was an error and possibly show that error to the to the user so what you can do here is i'm gonna come here and instead of using this in the catch so we can go up here and create an error property so we can say let's error let's set it to now okay so down here when we get an error from fetch so let's say we couldn't fetch we can go ahead and assign it to our our error so we can just set it to we can set error equals the error we just got and in the props then we can return the error so inside instead of us returning done we are not using it for anything we can return the error and set that one to the error to errors so let me go ahead and do this and this should also be accessible in the in the page as error so here you can expect it so let's go ahead and console log it to and here so if you have any errors you're going to do a simple check so we're going to say if we have errors then let's go ahead and show them in a paragraph as error like this so down here we have this as error so that's what we want to return here and by the way when we are using es6 and above we don't have to set the prop the the values when the value when the value is the same as the key so we can just abbreviate it by doing it like this you can see we get that error so we can't show that this in we can't we can't show an object in a div so what you can do so for now to be able to see what's going on i'm just going to wrap everything in json.stringify so let's have json.stringify and put the error in there so something to point out here whenever we are returning things in get static props it has to be obviously erasable type so wanna make sure that our error the error we are getting from fetch is something we can work with so let me consolidate it just so we might need to transform it so here i'm just going to say something went wrong instead and then we see how to inspect the error and send a very serious type to the to the page in the props so for now let's just say something went wrong so something to mention here get static props runs only on the server so that means that whenever we do a console log inside here it's not going to log in the browser at all so if we go here and try to look for it here we won't be able to find it so what so what happens is whenever the code is being run on the server the console logs the prints they all go inside the the development server log so down here this is where we can find our console log for the error okay so you can see we get fetch error inverted json response body at http this unexpected token so if we wanted to send this we would go ahead and string fight and then send it as a string so json stringify the error like this so now if you go back to the site if you go ahead and refresh it you can see that we get we get something being shown on the screen so you can see if we have error.message then you can go ahead and send that to error.message then we can say otherwise so otherwise that would mean that the error didn't come from the server it's not a server generated error it might be because we couldn't make the request then here we can say something went wrong okay like this or any message you would want to send so if you come back here and refresh now this should catch that message so let's reload it and you can start to get the the string so i'm gonna go ahead and turn off my internet so meaning we couldn't we shouldn't be able to connect to the server in fact i should turn the server off so if we come here and i go to my python and cut it out and go ahead and stop it so i'm just going to ctrl c and come back to our nexus front end and try to rewrite we couldn't really make the request and now this is being sent out there and let's correct our error because we don't want to be closing the errors ourselves and save just refresh and you can see that our things are back so the last thing i'm going to be showing you guys is how to use environment variables so if you go back to the application you can see that we are setting the because that we are setting the base url inside the code so what we can do here is we can cut this one away and set this to an environment variable use backticks here so we can embed a dynamic variable and we can do something like and to access an environment variable we can get it from process dot env dot the name of the environment variable so we have some environment variables that are built in you can see all these now the one we want to access is going to be a base url so we are trying to reference a an environment variable called the best url now for us to be able to set it we need to create a file called dot m dot local so this gives us environment variables that we can work with in in development and you can see that by default it gets grayed out and removed from git so you can go ahead and set our best url so i can do this url and set it to a value like this and restart it okay so you can see it's going to pick up the environment variables and now if you go back to the site so i'm going to come back the site and refresh it and you can see that now we are getting things and we are using an environment variable for our api one thing that i want to show you is all the environment variables we set are only accessible on the server it makes sense that we're able to access it like this because getstatic props runs only on the server so what if we wanted to use this in the browser so let's say here we add the use effect in fact i'm just going to demonstrate that now so this is a regular react hook and it runs on the browser like you would think so here i still wanted to to console.log this so i'm just going to come and copy this up to here and go to the use effect and console.log and this should of course show in the browser now so if you come here in the browser so the best url is undefined inside in the browser so that means that environment variables and are not really accessible when you're in the browser environment they are only accessible on the server side so what you can do here to be able to access to be able to access let's say this environment variable inside inside the browser is to prefix it with next underscore public so i'm going to go to our mv.local and prefix this with next underscore public underscore so when we set it like this and go back to our and go back here so i'm going to change whatever we have this so whenever we change something so whenever we change something in the environment we are going to go ahead and restart our server we are going to go ahead and restart our server so i'm just going to stop it systemnet then restart so yandev so we have next public underscore base url and uh if we come back here make sure that's the one we are trying to access in the use effect so it's going to refresh here and if you go back to the browser and reload this so when we change that you can see that now here we are getting the best url in the use effect so in the browser we're able to access it now but notice that of our our fetch our feature failed we're going to get from the server again so want to go ahead and update that let's come back here and instead of using this we can now use next public url and save that and now if we refresh so using next underscore public enables it to be accessible both on the browser and also on the server side but when we don't prefix with next underscore public we can only access these only in the server side so i'm going to be pausing here now in the next one we're gonna be talking about we're gonna be talking about the head component and we're also gonna style our page better to make it look great so i hope this was helpful if it was give it a thumbs up don't forget to subscribe i will talk to you in the next video hey guys welcome back so in this one let's go ahead and design our page better give it some modern look and feel and also fix a few things that are obviously going wrong right now so first of all if we take a look at our title right here our title shouldn't really be this at least it should be like available campaigns or marketing campaigns or campaign website something like that so to be able to change the meta information of an html document we use the head component that nextgs provides so here we can import the head component and in any page so let's say here in any page we can use that head component and then inside there we can specify things like the title things like the description if we have specified let's say favicon we can specify it there if we had other things let's say specifying like the og properties if you're not familiar with what og is let me see if i can bring it up rg is open graph protocol yeah if you have some metadata for the og we can specify them there so this can be audited or d type so these basically are for social media so if you wanted to specify some of these we would do it in the head company by the way i love the url odp dot me oh that's cool anyway so let's go ahead and set our title since we are still basic then here let's say here we want to say campaign manager we would put that in the head component and now if we come back to the site and go here let's refresh it you can see it has changed already so now we can change the title let's also change the description and then the value for that is specified in the content then let's say site a site for campaigns so this can be anything now the details you put here are very useful for search engines so you want to make sure that your titles are not so long they are not too short they make meaning and also your description they shouldn't be so long and they should be related to your site so stacking optimization is a whole block of itself and i would recommend you take a look at what next year's provides on that and also read up mostly on searching operation techniques because you might have to handle it differently regarding the needs of your site but nexus does pretty much a good job out of the box with that but feel free to explore around learn some theory about searching optimization it's going to be useful for you even on other projects so this is how we set up the meta information for that page using the head component so now let's go ahead and style this so i probably have mentioned this but nexus supports different ways to style elements so by default we can use css modules and just like regular css css modules allow us to import like a css module or a css file as one name and then we can access the individual style declarations using a dot and then we use the name of the style the style object so let's say here i wanted to have a container here so what you could do is instead of saying class name equals container like this what we can do is we can go in our style file in this case you're going to be in the home.module.css and what makes it a css module is having a dot module in the naming so what you can do is we can go to that file so we're going to go to styleshom.mojin i'm actually going to remove everything so let's define the the container so for this container we still want it to have background color equals green something like this and of course you're going to be changing that no worries so here we import the styles so if you're already familiar with styling direct applications whenever you add a style here and that file is being imported anywhere that style starts to work across the application so wherever there is a container if wherever there is a style referencing the container it can go ahead and start to work but notice that right now nothing is working here i'm actually i can actually refresh here but you can't get that style so instead of us doing this we can we can access it by this style and then we styles then we can call that container on it and then we can go ahead and close here now if you come back to the site gonna refresh here you can see it picks up the style so one thing here i want to show you is let's inspect this notice that the style object is called container but if you take a look here you can see that next just went ahead and added some random stuff so next just takes care of making sure that our styles are unique and are scoped to different pages and different components so that is the instance of css modules kind of helps us to scope different styles and they do that by adding random text to our styles so that's how that works so obviously i'm going to remove this here we want to be working with it similarly it's not really useful so let's go ahead and restructure html document and go ahead and style things better so for the main we are going to reference a class called main so i'm going to have a class name that's going to be styles dot main and obviously and this is what is like our container now so let's go to our module style file create a container class and then what we want to do in this one so here we want to change the background color and when i use a dac create like a dark mode kind of theme so set that one to this and now if we take a look you can see that we have a dark one so one thing that i don't like is you can see that our main is not really taking off the whole screen so we're gonna set the height for it so let's set the h to 100 viewport height so height 100 vh and that should be able to take off the whole screen let's go ahead and set our color to be white so let's set an overflow so we can say overflow let's say overflow scroll now if we come back to our page you can see that now this is taking off the whole page which is what we want and everything everything's good so now what you're gonna need to do is take everything here let's say leave some paddings here on the left under the and the right make it look a little bit neater so inside our contents here i'm just gonna have another div so i can say dave class name let's set this one to styles so it's inner content so that will contain everything so i'm gonna cut this make sure we can close so it's inside the main so make sure you can close it here and here let's style the inner contents we can do dot so let's go ahead and reduce the whole width to 70 percent since the since our background is taking off the whole body we will we won't see that it has changed so what you can do is we are going to display everything in the main aspects and then center everything so let's do display flex and say justify content center and now if we come back again refresh it you can see things are in the center which is great which is what we want okay so the next thing we're gonna need to do is to style the individual items make them look a little bit better so gonna go to our html here and uh inside in the map so inside the map we're gonna create a style here for the items so we can have a class name because it says styles dot item okay let's go ahead and create the styles for this so inside here you can have the item so for the item let's change the background a little bit so it can stick out so background color okay so now if we check again you can see that this one now sticks out we have the separation here so let's go ahead and give it some paddings so inside inside the items we can have padding let's set let's set that one to 24 pixels we need to separate them somehow so we need to take a margin for each of them actually let's have a margin top let's check that you can see that separates them out so we need to create a grid or flex this for the item so the image goes on the right and then this goes on the left so we can do that by using grid so let's have display grid so when you say display grid nothing should happen let's see and that's because we have entries provided the variations of how the children should be laid out in the grid so we need one we need the image to take off the smallest amount of space possible and this other content to be on the right and takes off and take off the rest so we can specify grid template columns grid template currents and we want the first parent to or the first child to be just small and then want the last one to take off the hole with it so i'm just assuming a 12 column grid and i'm setting the second child to take off a lot of space or remove the space that means that the first child is going to be this image and the second one is going to be this content so this is which is what we want so if we check again you can see that it's working the way we want so the next thing we're going to need to do is to put a margin here and to also maybe style the dates better and format them better and maybe make this one round and we're going to be good to go so let's go ahead and create a padding left for the second item so let's go ahead and create a class here so class name and we're gonna do a styles dot write items so for this and just copy this inside home then down here you can have rate items and basically what we need is to specify imagine left so let's set that to 24 pixels so if we check that you can see that we got the space so going forward we need to style the image to be in the center so we're going to be giving it the imaging autos and also make it round so let's go ahead and add the class for it so let's do here.img so we want it to have a border radius of 100 and vs code kind of generates for me these are the browser specific for the radius space specs so let's come here and set this to the image so we can say class name equals take a look does that help and that makes it round which is what we want so putting it in the center we need to position auto the parent so this here let's give it a class so class name equals thous img container so let's set that so we can do imagine auto and you can see that it goes to the center so we can use date format we want from updates so this is a lightweight module that gives us a function that can form update so you can see it gets six million downloads a week oh my goodness which is a lot for a reason i believe so down here let's go ahead and install it so we can do npm install so we can just come here and install it so we can just do let me bring up the console actually going to create a new terminal window cd into our front end so now that's going to give us the date format utility so to use that we want to go to our file which is index and this imported date formats okay so now where we are displaying the dates we can just come in and say so when i get our date pass it into the new date object and then we want to format it so to format it so it format it we want to pass this to the format dates function so the first parameter is the date and then the second one is the format so here let's put a comma so for the format we can go ahead and specify the format you're gonna get the day just put a comma let's get the math let me just bring it up then we're gonna see how it formats it so the yeah survey comma let's have the hour the minutes seconds so now if we come back to our application let's go back to campaign manager you can see that it's changes really you can see that it changes to the way we want so we have so the formats here we can get more we can learn more about the formats here on the library you can see this on the library page you can see the formats here and you should be able to almost do any any format you want to do with it so feel free to take a look here if you want to use this in the future so this style this one let's make this one small because it shouldn't look like the paragraph and coming back and coming back you can see that now it is yeah pretty cool actually so that's gonna do it for now in the next one we're gonna start talking about routing how we can route using the link component how we can use the hooks the routing hooks and how we can work with dynamic routes so it's gonna be interesting if you enjoyed this one give it a thumbs up don't forget to subscribe i'll talk to you later hey guys what's up so let's go ahead and explore the details of navigation in next.js so the primary way to navigate on the web of course is using the a tag so we usually have the a and then the href that goes where we want a user to go and in labor is like react router dom we have a link component so in next years we have this similar one but of course this time we put it from next slash link and this gives us contact routing and we can use this instead of the regular a so one of the best features for this link here is that whenever your page renders next just goes through the page and picks out all the referenced links and it does a prefetch of those pages so by the time a user clicks on it then it has already prefetched the data for the corresponding page and that's why things happen very fast so scrolling down here you can see the props you can pass now you can see there is a prefetch prop that is true and that makes the functionality we're talking about possible so also we have the router so the router gives us some hooks that we can use to handle navigation related tasks so in this one let's go ahead and see how to navigate to the detail page and how to pick the parameters on the detail page so we can fetch again for the detail of the campaign earlier we saw that we can navigate using the href and the link to these ones but in this case we want to be going to a dynamic page so whenever i click next yes conf we want to go to something like slash desktop and that's going to be different depending on what the user clicks so what we want to do is we want to define a dynamic url so at this point in time in the pages we are going to create a slack.js and we are going to put it inside this syntax here so this means that this is going to be the press order for whatever the page will be viewing and that's going to be based on the slide so whenever we go to slash certain slack the page is going to be generated here dynamically so we want to use js sorry so now if we come here we can create a component and it should work as a page so down here i'm just going to say campaign and to be able to link to this page like normal we want to go to our listing index and where we have the title so where we are displaying the title which is here we are going to turn that into an a and like we saw we need to wrap everything inside the link component so this is going to enable us to achieve client-side routing and pretty much get all the benefits that the link component provides so we're going to move that inside and then specify where we're going to navigate to we specify the href prop so let's set the href probe to be we want to do slash and then let's go ahead and concatenate the slack so element dot slack so now we can come back to the browser you can set we get next year's conf when i hover above you can sit down it goes to slash slash nexus conf this one goes to slash date fetching class so when i click on it you can see that it's navigate so now one thing i want to show you is is how to use the router to navigate programmatically so let's say we want to navigate when a user maybe clicks on the parent element so let's say a user clicks on the this div here so let's go ahead and add an unclick so we're going to do on click so whenever a user clicks this we we're going to call a function that's going to handle the navigation so i'm going to call it handle navigation and whenever we call this function we're going to be passing in the item that was clicked on so let's go ahead and pass the element so let's go ahead and so we're going to need to wait for the user to click so let's go ahead and call this on a on click so down up here let's create that function so gonna have const handle navigation obviously it takes in the element so we're gonna go ahead and destruct the slack from it and what we need to do is navigate to the item with this slack so the way we can do that is by is by using the use use router hook so here what you can do is we can get throughout the router by defining it so cause router then we want to call use router so use router comes from next slash router so here it's imported so import since it's a named export we can just pick it by use router then we want to do from next slash router so with this we can be able to navigate by calling push on it so you can think of this as the history object that's available in the browser and let's go to the documentation just so you guys know where to find extra information so this is the user router hook we can be able to navigate by writing push and uh let's take a look on details we can pick the path names or query to be able to do it like a fetch for the detail or something like that so we have router push this is what we want to do to be able to navigate to the page with this item you can just do router dot push so we want to go to slash [Music] then we want to go to slash and dislike so just slug like this all right so now if you come here i'm just going to go here and refresh it now i won't click on the title but i will click anywhere around here so i'm going to click here notice that it navigates the same way it would navigate when we click here the navigation that is triggered by the by the click on the on the link is the same as is the same as the one that is triggered when we click somewhere in the component so it is also clear inside so which is also pretty fast so now i'm going to show you how to pick which one was clicked on on the detail page so to be able to know which one we navigated to is here where we have the slag we can just do use router again so here let's do const router equals use router i'm going to console the router just so we see what we are working with and like we said it is a client it runs client side so since it runs client side we should be able to see it in the browser so now if we go back here i'm going to bring up our i'm going to bring up our browser tools so in the console and inside there we have all these properties so the path you're going to need to get is in the query so what you can do here is you can just restructure query from use router so we can just say query like this and we need to get this log from that so we can just do slack like that and if we now console log this log just switch this for the slug and come back to the browser refresh it inside here you should be able to see that it's undefined at first but then when it loads we get the the stack so if we go to a different one let's say we go to one that's not next conf just go to data fetching class you can see that we get a data fetching class here so in the next one we're going to be looking at how to use get static parts and get static props to prefetch the details pages at bureau time so if this one helps you out give it a thumbs up don't forget to subscribe and i'll talk to you in the next video hey guys welcome back so last time we're able to fetch a list of campaigns from our backend and we can display them here on our front end and we used a method called get static props so like we said the reason why we used get static props is we would want this to be called as bureau time such that we can fetch all the data for this page at build time now when we go to the detail page we would want to do the same thing so we would want this page to be fetched at build time and the html pre-rendered already with the data so normally with this kind of detail routing on the web we would have to let's say come on this page when this page has rendered pick the slag and then make a call to get the data but with the kind of approach we want we want all the data to be fetched at build time that approach will not work because there won't be any user to click any buttons now next year supports us at being able to achieve prerendering of all the detailed pages for all our items on this list by giving us an implementation for a method called get static paths so what git static path does is it goes ahead and makes a call to our server and then returns all the slacks that are on the server and then nextgs can use each of those slides to generate the individual pages for that campaign so to implement this you're going to go to the slag now first you're going to first implement the get static path function and that should be the one that returns for us all the slags on our server that would want to fetch data for and pre-render so here we need to export it has to be an async function so export async function it's you have to call it get static path like this so inside this function we're going to go ahead and make the same call we did here so we're going to make this call here to fetch the data so what i'm going to do is actually copy this and bring it to here because it's going to be the same call but the difference is now we want to only get these lags we don't care about the images everything because this function should return the slugs which will be a substitute for the page itself so here we're going to fetch now when we first you get the data so i'm going to do a cons and also get static parts runs on the server so here i'm going to console.log this and i'm going to construct the data so this is going to give us a list like this so it's going to be an array with each of these objects but what we want is to only get the array of slugs so the way we can do that is here since this is going to be containing all of these we're just going to strip out everything we don't need and only use this lag so we can use the map function for that to manipulate the contents of a an array so here let's have const all slugs so this is going to be the data then we're going to call map so map gives us each item in a callback function and we can now just return the slug so for each of the items you're only going to pick the the slug and map gives us the array of all the objects that gets enumerated from this map function this should be able to give us the slugs so something like slag a strike b slug c so now the return from the get static path should follow a format that has a params key and then the slag itself so something like this so you should be able to in get static path we should able to return an array and that array should contain objects like this and each of those objects should have a key called params and that's going to be an object also and then in the object there can be the slugs so something like this so slug is going to be a slug now since we already have the slugs what we can do is we can still map over these and inside each of these we embed there the k for params and set the value to the slug itself so here we can just have return we're just going to do all slides then we want a map so this is now going to give us its lag so what we want to return params params and the value is going to be the slot like this okay so this is going to give us now our parts so what we need to return from the function will be the parts so we're going to say across these parts so would be the parts so here we can return an object that has path in them and we can specify another property here called fallback so i'm going to say fallback equals posts so right here we could be able to supply false true and broken and the difference between these options here are that whenever you supply false nexus is only going to update the data when you rebuild again but you could be able to supply but you could be able to supply true or blocking and that would enable nexus to create fallback pages for when a user tries to access a campaign that was not generated at the bureau time and also there is a feature called incremental static site generation but won't be getting much into that so for now we will only expect next years to work with the data that it builds at build time and not having to expect it to to prefetch other pages that don't exist so let's keep this now whenever we implement get static path that means that next yes is going to know about all our slabs and right now what we need to do is we need to fetch data for each of those parts this time we saw that if we want fetch data at bureau time we can implement get static props and this is what we want to implement now so i'm going to copy get static props and down here we will have get static props and basically what happens is whenever we're on a dynamic route or a dynamic page like this next yes it's going to check if we have get static parts now when we have get static path this function is going to be called for each of those parts and the data is going to be fetched for each of them and whenever we have get static path each of those path is available in the get static props function and it's available as a probe so we can get it here so the path is is passed in here as params now with this we can be able to access each individual slug so you can here we are we can be able to do params.slack and it's going to be called for each of the items that are returned in the path so here we can now do a call to our backend to this endpoint here for the detail and get this data and get static props we pass it to our page and the page can get it as props so let's go ahead and make a call so i'm going to come here and make a call like this so this time we are going to be fetching the detail so we're going to be using here params dot slag since our path has the params key and then the slug inside so it's going to be accessed like this and this is going to go ahead and make the the http call so we expect to get the data here so you can say cos data equals this now we can return props like we said in get static props we need to return props like this so we can return props and for now we're just going to send the data to our page so now if we go to our page here we can expect to get that data and down here if we can select the data we should be able to get it so if we go to our website and refresh and open up the chrome console which you're gonna minimize this and go to the console so if we refresh you can start to get the data being logged inside here meaning that we're able to fetch the data we're using these functions here if we open up our chrome console and click on one of these so notice when i click on one of these we didn't go ahead to make a call to the server we didn't so if you take a look here you can see all the requests go to post 3000 so the data is gotten and then it's cached inside the underscore next underscore data but this is in development but this kind of shows you that the data is going to be prefetched and we're not going to be making like calls to the server when we use this approach so now that we have the data we can go ahead and display it in the ui so for now we will show the image so i'm going to go here so i'm just going to copy our item so i'm going to copy the whole div and bring it in here so we'll go here we have campaign we're gonna remove this expand this so we'll have the container then we'll have the the description and the title so let's remove one of these divs and save so now the data is the object so here where we were using element we're going to change that to use data and uh of course we don't want to route here so we can remove that on click we need to import styles so for now i'm going to use the styles that we were using for the for the home and then in the next one we are going to be starting the next page we are going to be starting the detail page better so now if you come back to the site i'm going to refresh it i'm going to import image from image link just copy this make sure we are inputting image image image so now let's also import link we might have to use it to go back so let's get it down here save come back date format says import date format also since we are formatting the data in the detail let's come back here and you can see that our data is being displayed so this is how we set up the ability to fetch data for dynamic routes using get static past and also get static props so that's gonna do it for this one if it helps you give it a thumbs up don't forget to subscribe and i'll talk to you in the next video hey guys welcome back so in this one i'm going to go ahead and continue building our next year's front end so this time we stopped off when we had created a detailed page and it's looking like this so what we'll be doing now is transform this page here to look like this so this is going to be the ultimate css tutorial so we're going to be covering some advanced concepts in css things like creating different layers on a page if you take a look at the background you'll see that it's an image but that image is browned so we're going to have to create a background layer and then we're going to create this layer on top that has the content so it's going to be an interesting one if you're someone who's passionate about css and you want to know how to build a ui like this then stick around so to start we won't first fix our title the head metadata information so just up here let's just have a head so wanna do head and then let's pass the and then this pass the title so yeah i'm gonna do title so for the title we are going to use the title of our campaign so that's going to be in data.title so here we can just display dynamic stream so it's going to be later the title so let's make sure the head is being imported so i'm going to go up here and input head so import head from next head okay so now if we come back here you can see that our title is being used up here let's set the meta description for the page so we want to do meta name equals description then accepted content so content we're just going to use the dynamic description that we have on this very campaign it's going to be data description now we are going to go ahead and start creating the background layer the one that has that darkish and then the image as a background so here i'm just going to have a div called wrapper so you're going to have a div so this div is gonna have a class name so it's gonna be class so we're gonna do stylus dot wrapper and to style this last time we included the style that was coming in from the home.module.css but now we are going to be including one that is going to be detail with module.css just go ahead and create it in styles so over here just going to do a new file it's going to be detail.module dot css let's start studying the wrapper so like we said we are now creating the background layer that will have the darkish and then the image so the first thing you're going to need to do is set its heights to be full screen and also disable the scroll so we're going to do 8 we're going to do 100 viewport 8 so you can see that now just creating this and giving it a state of 100 over 100 vh it takes off all the all the visible rate of the page so let's go ahead and give it a background color so i'm just gonna do background color and i'm gonna use zero zero one one zero one zero zero one one zero one and save now if you come back you can see it takes off the screen but notice that we can scroll down so what we want is to prevent the scroll so how do we prevent the scroll there are different ways we can do it but but we're just going to position this fixed so we're going to do position fixed like this when we set position fixed then we want to give constraints like the wedith so over here i'm going to specify with it a hundred percent so i'll do it a hundred percent and save that and when you come here you can see now it's taking off a hundred percent so the next thing i'm going to want to do is give it a z index because like i said we are going to be creating two layers this one we are creating now and the other one that we have content that's going to be directed in front of the user so let's give it a z index so if you're not familiar with the z index what it does is it enables us to position things on top of each other on a web page so let's give this one one and the one with a higher z index is the one that is close to the user so now that we have this one done let's go ahead and see how we can add the the background image so what i'm going to do here is inside the wrapper i'm going to have another div so this d we are going to give it a class of mine so styles dot main so for now it's going to be empty and let's go ahead and style it and position our image in there so we're gonna go here and do dot main so here what we want is to just of course give a background image and make sure that this is taking off the whole head i'm gonna do background image and then i'm gonna bring in this pixels image here so when i click on it you can see it opens here now i'm going to to leave this link in the description just so you guys can copy it so now once we set it as a background image and go back here and refresh you can see that nothing is happening that's because we need to to specify other things so one of the things we are going to need to specify is the position so one is position it absolute so we're just going to do position absolute and then position absolutely let's specify exactly where we want it to go so we want it to be slight on the top so we're gonna do top zero let's give this a height and then and the width so for the height we're gonna need to take we're going to need it to take 100 of the appearance then for the width we're also going to need to take 100 of the parent so let's save that and now when we come here you can see that we have our background it's already looking great okay so one thing we don't want is we don't we want it to be just one we don't want it to repeat so here we can just do background repeat so we don't want it to repeat so we can do no repeat save that and now you can see it's one so one thing you will see here is this is not taking off the whole screen and it is getting stuck on the top left so if you want it to be in the center and taking off the whole screen you're going to specify the background position and also the background size so let's specify background size first so we're going to make it cover everything the container so we're just going to do that also let's specify the background position so background position so want it to be center vertically center horizontally and save that so now we come here you can see it goes in the center it's not covering let's check over here this should be size so background size cover save that coming here you can see it takes off the whole page so at this point we have not achieved the effect we would want so you can see this effect is dimmed it's calm so on the image let's go ahead and set the background color and also set some opacity so you're gonna have background color so for this it's gonna be dimmed one so it's gonna be zero zero one one zero one i believe we use that somewhere so also let's set the opacity so we can do opacity then let's set the opacity to zero point zero eight save that now and when we come back then you can see that now we have the dim effect and things are now looking calm okay so to get started building out the upper layer let's actually start with the footer here because it's going to be tricky to also position it down so because it's also going to need some work to position it down so we're going to go in our j6 and we we will go at the bottom so at the bottom we are going to have the footer so i'm going to have footage here so for this footer we're just going to have a link that goes to the previous page so we can have href equals the the default route and then inside here you know we need to find a and then the a has to have a text so you can say go back to list but since we are positioning everything absolute we need to also handle its positioning so let's give it a style here so we're gonna have class name equals styles dots footer so we want it to be positioned absolute because we want to control where it's it goes so position absolute we want it to be at the bottom so we're just going to do bottom zero all right let's do left zero let's also do right zero just so we know it has to go on the bottom so let's give it a width of a hundred percent just so it takes off the whole width so and also let's make the content there white so it's not showing up because our background layer still has the z index of one so when you specify a specific set index that is higher than its background layer just so it can appear on the top so we have z index so z index let's give it a two and now if we come back here you can see it's appearing down here so we actually want it in the center and also want to give it some border top so here this so here let's give it a border top so the border is going to be one pixel solid white or white and now you can see that gives this that gives it the border so we want everything to actually go in the center so we can just position we can just fix everything so display flex and then center everything just try content center so that puts things in the center which is what we want now we are going to need to give this some paddings but the easiest way can do this is give it giving it a specific case we're going to do 100 pixels for the height and since we wanted to go to the center we want to align items also so align items center okay so it is centered both vertically and horizontally now we can move on to creating our left and right content now to create this the image is going to be on its own line and then we're going to have this content on the left and this on the right so we can flex everything and also control their responsiveness and after the main so the main was used to control the image layer so here we can have another div for the content so we're gonna do div class name because styles dots content so i'm just going to do contents and then inside here then we can have an image first so we're just going to copy this so i'm just going to cut it out so now we are creating a new design and put it there when i come back you can see it appears there so we are going to need to style the contents first so i'm going to get the contents class and bring it here so contents so for the contents let's make sure everything is 100 so we can just do with it hundred percent so let's give it some paddings both horizontally and also vertically so we can just have padding here so top and bottom we can have like a seven ram then left and right we have like a 10 ram save that and that's going to push things that's going to push things in the middle a bit so let's style the image very quick because i don't like the way it's looking now so let's give it a border radius of 100 so put the radius 100 percent let's go here give it a class it actually has a class so that's good that's already taken care of okay so the next thing we're going to need to do is after the image then we are going to have like a grid that's going to have content this content on the left and this content on the right so after the image then we are going to have a div class name so this one is going to be a great so we're going to create the grid so stay with grid let's also have left and right so here we can have div class name equals thous left so i'm gonna duplicate this to get the right one so this is gonna be that right so the title and the description are gonna go on the left so i'm just gonna come here copy the title and description i'm just to cut this so in the left i will move the title there but this time the title is not going to be inside the a so it's going to be an h1 just going to have h1 there let's get rid of this then the description can keep in the p so let's give the title a class of title then the description the similar one of description so here we're going to do styles dot's title then here we'll have description so in the right one we're gonna have a form so here let's have a div i'm just gonna list another one here called write contents so inside here now we can have like a dummy form which we can later style so i'm going to have a form here we are going to have a div that contains this this input here and also the one that will contain the button the button details and also this will respect your privacy so here let's have a div class name so for this one we can just set the class name to form group and we're going to style this as you as we go then here let's have the input so input the type is going to be email we want it to have some variations built in but they are going to be validating for dating gits even using javascript so let's give it a name so name can be email we are not going to be handling things i can change right now we are going to handle those in a separate video so let's have a press order so press order here will be enter and email all right so let's give it a class name because you're gonna need to style it so class name equals styles dot input so we're gonna have a button submit here it's gonna look quite similar it's gonna be an input but for this class we can set this one to submit and here it's gonna be an input type so the input type is gonna be submit and then and then we want to find the values so here we can say vario and then the value can be something like subscribe so for the classes we'll have a specific one called button all right and also let's have this text here and you see this text for we respect your privacy and subscribe anytime let's also have it here so i'm gonna do p i'm gonna do a p then we have respect your privacy okay i guess that's pretty much it let's take a look at what we have so when we come here you can see that we have things but they are not quite visible properly we can start styling this and maybe changing the colors to be white and positioning things from left to right so you know we have the left and then the right so let's go ahead and style the left here so i'm going to do dot left and we're just going to want it to take off 50 percent of its parents so we did 50 percent also they set the color for the contents here so color white let's also style the the right to take off fifty percent so one thing here is we want to fix everything we want to fix the left and right to be aside each other so we want to get its parent and style that so here we have the right so this is the right and this is the left so the parent is the grid so here we're gonna have a grid so that grid now we can set we can make this flex so display flex so if i save this and come here you can set now this is on the right so now let's focus on the right content here we want to give it some margin on the left so inside the right we have another div that is called write contents so we can start from this one so here we can just have we can have right contents let's have a margin left so let's have six ram units here and that's going to give it some space so now let's start making this input a bit better so what we want is let's first grab the phone group which is the div that holds it let's give it a margin on the bottom just gonna do 15 pixels and you can see we have some space there so for the input so we are just giving it a font size we are giving it a font size and this goes ahead to affect the press order and the text that the user enters so we also change the color of the text that the user enters so we give it a background of height we give it some paddings we give it a border of a whitish border so let me remove the flex and most importantly we give it the height that goes ahead to give it this height so if we made it big actually wanted to make it look bigger we give it like 85 and then look like episode there so this looks good now let's type the button so the styles for the button actually going to be simple remember we gave it a button i believe so i'm going to do a button here then i'm going to put in these glasses here i'm going to type them because it's the same thing so we give it a color of white we give it a background of we give it this background so it stands out now this is how it's going to look so this so we are getting there now let's go ahead and style the we respect your privacy to make it look smaller so if we check the class we gave it here we need to give it a class so class name styles let's call it consent so for this we can go ahead and um a font size of 11 pixels let's give it a color like a grayish color so let's have 7 8 7 eight seven eight save that and we need to save this one too and you can see that now it looks like this yeah looks good to me so we are done actually what we need to do is make sure it's responsive so for the responsiveness i'm just going to bring in this media query so down here in the styles i'm just going to press these stills here so whenever the screen reads it goes below 1024 we go ahead and change the flex direction of this build an uber clone and this form here to become column meaning that this is going to get stuck this is going to be moved to the bottom we also go ahead and reduce the paddings here by like a half then we go ahead and make this one to take off 100 percent the left so in this case the left is the left was build an overclone and then this description so we make it take off a hundred percent and we also make the right take off a hundred percent and then and then down whenever the user goes on the smallest devices these are like the smallest we go ahead and we go ahead and hide away the description just so we can keep the the hundred percent viewport and we don't enable the scroll and that's just something you can change depending on how you want to do it but now if i save this and come here and open this and i'm just going to come down you can see what happens here is whenever we leave 10 24 we go ahead and make the flex direction column and we change the width from 50 to 100 both for the right and the left and then when we go down and then when you go maximum return we go ahead and hide with the description so you can switch this to the way you want but one thing i wanted you guys to take over is how you can create different layers so you can create some designs that kind of look unique so one thing here is i'm not able to focus on the input or even click the button and that's because the background layer still has the the z index of one and since our contents don't have a z index that is higher then we can't go ahead and do interactions because it is behind the this background layer so what you can do here is on the back on the contents so for the contents we can just have a z-index of two since the background has the index of one so we're going to set the z-index and also we need to position it absolute just so it goes in front so position absolute and now if you come you can see we can focus it one thing i don't like about this input is when we focus it it gets that highlight so we can remove that by by targeting the focus pseudo selector so we can have input then focus so when focused we so when focus we can remove the outline so we can do outline none all right another thing is when we hover above the submission button we can change like we can change the the color a bit so we can also target the the button you can also target the button hover sudo class so dot button hover then you can change the background color a bit we're going to change it to this and now you can see when i hover we get that effect which i think looks pretty cool last time we started our detail page a little bit better so in this one we're going to go ahead and and submit an email and create a subscriber in our database so we're going to be hitting this end point here called subscribe buzz so we're going to be making a post request to this subscribers route or subscriber's endpoint and we are going to need to try the email that the user provides and also the campaign that they are subscribing to so whenever we click on a campaign so here when i click on build an uber clone this campaign details or the id also is available in the detail page and we're going to be using that so now let's go ahead and see how we can pick the email whenever a user enters it and also we can handle the submission so our submission we are going to keep it simple we actually are going to use html5 validation so so here we have the input for the email the type is already email but now you can see that if we come here i'm just going to remove this go afresh and submit you can see that it doesn't check it just submits so what we want is to actually prevent it if the user hasn't entered the email so you can specify a required attribute so now if you come and try to submit you can see it it doesn't rate us and it wants us to fill the field obviously on the back end we have the validation to make sure that the email is going to be there and it's going to be valid so here if we enter the text you see we still have to enter a valid one and we can't submit before we enter everyone so that's just gonna do the validation for us so no worries let's handle how to pick the email whenever a user enters it so we're gonna we are going to have to keep some local state to be able to to persist what the user is entering so here i'm just going to have a const so we're going to have email set email so we're going to use the use state hook to keep track of our email state and we're going to start out as a we're going to set out our email as empty so whenever a user changes something so whenever a user enters something in the email we're going to have an unchanged so on change so don't change you're going to have a function to handle they won't change so we'll have an event here now whenever a user enters something there we can pick the newest value from event target value and we want to update our email like this so we're gonna say set email to event target variable okay so now i'm going to go here and consolidate the email just to see if our own change is working so let's load it so it's we need to import use it so we're going to go here and import use it it's a named export so so now if you come here let's get the console i'm going to expand this one a little bit so here i'm going to start typing there's something so i'm gonna do tests at gmail dot com and you can see that our email is being logged here so many we are able to capture it so now let's go ahead and handle when a user submits so we're gonna have a function so whenever a user submits the phone calls and on submit and we need to provide a handler for it so here we're going to have one submit and we are just going to have a function code on submit i'm just going to call it handle and submit and let's create this function so i'm gonna go top here and have cost and submit equals so this gets the event so whenever the user the form is being submitted by default it is going to be making a get request so you can see it's going to do something like this so we don't want it to behave that way so we can give use this event to prevent the default behavior for when this form is submitted so once that happens then we can go ahead and handle this our way so what we want is to basically make a request and save this email to our backend so the end point you're gonna hit is this it's called uh so here i'm just gonna try to submit this so the endpoint is called api slash subscribers so i'm just going to get subscribers because we already have we already have this in an environment the base url in an environment variable so here what you can do is since you're using fetch you can first define our options so these are gonna are going to be request options so we're gonna have have a method of post so method post so here now we can have a fetch so first text in the url so we're gonna use this syntax here to bring in a dynamic url from the environment and to also concatenate there the subscribers so we can do process dot env dots next public base url i hope that's how we called it to check and then we want to concatenate there so we can put this put their subscribers like this okay so the first one is where i want to make the request to then we can specify the options so we can specify our options there now since we are going to be making a post request we need to send some data to the server of course so you can satisfy the body so since our backend accepts json we need to create a json string and send that instead of our javascript object that's going to have an email list of the campaign so here we'll have json stringify so what do you want to string file we want to incline the email and also the campaign so at this point in time our campaign is going to be data dot id data dot id and for the email we would have to try it like this but since the the key and the value have the same names then we can just keep one of them it's gonna behave similarly another thing we can specify is the headers so things like the content type but let's first try this so whenever we make a fetch we'll get a promise so we can do the thing so the first dot then is sent from an initial request that is not actually the one that has what the the server responded to so what we want to do with the first response is to actually transform it to json and then the data is going to be in another thing so you can change another then so here we can expect to have a response from the server and we're just going to consolidate it for now so let's consider response and also if there are any errors let's go ahead and handle them so you can do dot catch so let's do error let's console them for now and now if you come back to our web page so i'm just going to enter an email and click notice that by default we are not able to make the request we are not able to make the post request and we get the error saying fail to fetch they are telling us that the the request has been broke by cause policy we didn't satisfy the access control origin so what you can do here is specify some species it specifies some headers so i'm gonna go here and have headers so for these headers we'll specify the content type to be application json so what we can do here is we're going to go to server and enable requests coming from this local port 3000 so we're going to be using a module called django for headers so django cores headers and install it so we're just going to do pip install jungle core headers so go to our back end so this is our python server i'm going to stop it and install this so let's go ahead and include this in our installed apps and we're going to be seeing how to use it as we go so let's include it here then the next thing i'm going to need to do is add its middleware so we are encouraged to add the middleware before the command middleware so just going to come here and get it right here now the next thing i'm going to need to do is specify allowed origins so i'm going to copy this and anywhere around here i will say cycle as around origins so we want about 3000 to connect our server so also we can just use the domain instead of the ip and once we deploy the front end we're going to have to update this to also accept the front end but for now let's remove this so let's go back to our our front end and try again so here i'm going to try making the same request notice that we we update this notice that our record is saved on the server so we get it sent back to us so since both these servers are on localhost you can see it's pretty fast but sometimes we may have a delay so we want to disable the button when we are loading and also show a success message once we submit successfully so how do we do that so in the front end we are going to have to maintain some state for the form submission so we're going to have const i'm going to have one called submitted set is submitted it's going to start out as false as you may imagine let's also have the loading state so when we are submitting set so const submitting set is submitting we also start out as false so now here once we start to save we so once we start to make the call so before the fetch itself we can set is submitting to true and whenever we finish submitting or we get an error we can update it to we can update the is submitting by the way there is a finery so we can call we can also catch finally so this is called regardless of if things are successful or not so you can see here this is called when the promise is settled by being rejected of a field so whatever happens this gets called after so here we can just set his submitting where is that how do you call it set is submit gun so here we set we set is submitting to false again and also we want to handle we also want to handle is submitted so once so you can see that by default it's going to be false now whenever we submit we'll change that to true so we're going to go here and they do it then so we don't want to log here we are sure it's going to work i'm just going to get a block here and write some code there so we're gonna set it submitted here to true so once we submit successfully then we wanna give the user a thank you message so where we have the form right here we're only gonna show the right contents only when the user has not submitted so here we're just gonna have if not is submitted so if we have not submitted then we're gonna go ahead and you and show the form but if we have submitted so here you can have an or so let's have a div here so here we can just have a thank you message so right now i'm gonna so here i'm gonna have a class name this is gonna be stos thank you and inside here we basically want to show an icon so here i have react icons up so wanna show a check icon just so a user sees the green so we're gonna have to install react icons so npm install react icons so i'm going to be using yarn of course so you guys i'll switch to my front-end server and do a yarn add react icons inside thank you div we're just going to have an icon and also the text that says thank you so div class name ecos styles dots icon and icon is gonna go there then let's also have another div that's gonna have the text the success text or the thank you text so here is have thank you for your subscription so now that we have this then we can spin up our server again but we need to import the icons and also use the icons so react icons comes with a very many icon sets so you can choose from very many so it's likely that you're always going to find the icon you want from this so what we want to do is we want to import the check one so we're going to import it from font awesome so whenever you're importing icons you want to input from a specific icon set so you can see there's font awesome anti-design game icons hero icons aquamoon ionic icons material i can name but a few so here let's get the the import so we want to import from font font awesome so react icons fa and the one we want is going to be the fha circle so if a check that one all right and we can use it as a regular react component so down here we can just render the component all right so we can specify props like size so size let's set that one to 17 and we're gonna see how that would look let's also give it a color so the color is gonna be a green one so green so let's go ahead and see what we have gonna go back here it's gonna refresh so we have some typos i believe so it's submitted oh god it's submitted i'm gonna change that you submitted and also whenever you're submitting we want to disable the the button so we want to disable the submit submit button so if you are submitting then we want to say please wait and also disable the button so we can say disabled equals when we are submitting all right so coming back here it's gonna refresh let's try to submit this click submit you can see it submits and we get a thank you message so let's type the thank you a little bit better we want to flex it left and right give it a background of white and maybe make some things a little bit bigger but you can see you can get where we are going right now so let's see how we group this so we have a div thank you so gonna go to a detail mode due before the before the the media queries let's have thank you let's make it bigger and fix this so we're gonna so let's give it a head let's do something like 400 pixels we did a hundred percent of the container then let's have display flex just so they are left and right let's center everything just try content center align item center i love doing that anyway so you just goes in the center we don't we don't want it to be so big so let's make it 200 all right looks good so for the for the message if we check here you can see the message let's change this one to message want to give it some padding left so dot message padding left 12 pixels and let's save here you can see we get that so let's give the background so the whole layout let's give it a background so background color to white and you can see that so for the message let's give it a get that color so color i believe it's quite i believe it's it's the height is a bit is a bit large but you get the gist let's give it some border radius and yeah so also let's give it some margin on the right because it's kind of stuck there so imagine actually imagine on the left 24 pixels let's see what one does and yeah anyway so this is how it looks i'm going to refresh here just so we get a new flow so come here choose an email click subscribe to get the subscription success so that's gonna do it for now so in the next video i'm gonna be showing you guys how to deploy the applications so thanks guys for watching if you enjoyed it give it a thumbs up don't forget to subscribe and i'll talk to you in the next video so we have our rest api here we also have our admin where we can go and manage campaigns and also subscriptions so now let's go ahead and deploy our jungle back into heroku and then we are going to be deploying the the front end in the next one so heroku is a managed service so they give us the infrastructure they also give us other add-ons or other resources like a database so so they do heavy lifting for our deployment for us so to deploy our django application to heroku we are going to be using a module called django heroku we also are going to have to use g unicorn so that's gonna be our server so let me bring it up also we are gonna work with something called white noise so white noise will be responsible to serve our static assets we also are going to use something called dj database url so this makes it easy to configure our database using one connection string and in our development process we've been using sqlite but we're going to be switching that one up for postgres because heroku doesn't actually work well with sq rights so since sqright is file based heroku's infrastructure doesn't really support that so what we're going to do is set it up to use postgres now let's start here so we need to install django heroku so whenever install jungle error it's going to install white noise it's also going to go ahead and install cycle pg2 which is a database connector for postgres and and python django heroku just run that command so then the next thing we're going to need to do is in our settings.py we want to go to settings ui so we need to import it so right here we can import it then the next thing you're going to need to do is add this line here to configure it to pick up the settings so we're gonna go at the end of this file and just add that line from the documentation it goes ahead to set up white noise so this is gonna be useful if we are going to be seeing like this css that that is used to render this page here so what we'll do is on the white noise documentation we basically need to do another step and that is to add the whites noise middleware in our list of middlewares so i'm going to copy that line there and go to the list of middlewares so they suggest to put it after security middleware so we can just bring it here let's have a comma there so now that we have that then we can install g unicorn and that's going to be ours our server the terrace is going to be used to server is going to be using server application so whenever we are running python managed with py run server we have a local development server that django sets up for us but that's not suitable for production and we just need to use another server so basically whenever we install g what we need to do is we need to tell it where our application would be and tell heroku how it should run g unicorn so heroku is a special file called profile so i'm gonna go in our backend folder and i'm gonna create a file called proc file so in the proc file we're going to add this piece of code here so the deployment goes through different phases so here we are saying that whenever we are in the release phase we should go ahead and run and make migrations and also my great if we are if we have any other new migrations that are not yet synced to the db and then we go ahead and add a command that heroku should use to be able to serve our application so for the web process we want to run g unicorn then we have to point to where our wsga file is so if you look in our folders here we have this folder for cm backend which is like the entry point to our project and that's where our wsga file is that's what we want to put here in front of g unicorn so now that we have this one out of the way then we need to tell heroku about where our our project dependencies would be such that it knows how to run the project you know so what we need to do is we need to create the requirements.txt file and in there put in all the requirements that we are using in our project now since we are using an environment now since we are using a virtual environment like we're using here then we can be able to get all our dependencies by doing pip freeze so we want to do pip-freeze and we are going to freeze into a third code requirements.txt so requirements txt like this so when we run that you can see we have a recommended txt file created and that's going to contain everything we uh every dependency that we're using in the project so one other thing we're going to need to do before we go is uh we're gonna switch though we are using the secret key here so we're gonna move it with an environment variable and then we are gonna be using an environment variable to pull it in so we don't wanna expose it since it's used for many things by jungle on our application so here what we want to do is we want to do os environment so i want to pick it from an environment variable and hero actually does this by default so you just need to reference it so heroku actually pulls it from an environment variable by default so we also want to make sure we are doing that so whenever we add any so we need to update our env file so since i'm on linux since i'm on mac now then we can use export secret key because secrets key equals the secret key so i'm just going to put something here just something right now so if you're in windows you want to have it.envy.file and that's what you want to contain our your stuff so it's going to look something like this so in windows you're going to have something that looks like this on mac whenever you update your version whenever you update your environment file or dnv file you want to update your terminal to be able to pick up those new values by running source then the name of the file which is the tnv but on windows you want to call call then in your case it's going to be env dot env dot but like that but that's not going to work on one mark anyway so we need to also update our our our m sample file since those those env files are not going to be in uh and it's going to be in in version control we want to make sure that we want to make sure we want to make sure that next time we are checking out these projects we are going to need to know what we need to set up as environment variables by looking at the example file for dot tmv so the next thing you're going to need to do is create a git repository and push our code to git and then heroku can deploy it from there so go to github so github.com so here what i want to do is create a new repository so i'm going to call this i'm going to call it this cm backend api we're going to copy the example commands they give us here i'm just going to replace them i'm just going to paste them here in back end and that's going to create a git repository for our back end so the next thing we're going to need to do is create a git ignore file because we don't we don't want to push the tnb files and also the fetch environment files so here let's create a dot to get ignored fire so in the vertical ignore the quickest way to have a delta gt ignore is to use the get ignored io so you come here you put in your technology so i'm going to you and i'm going to put in django here i don't know it's using french these days so when you put in django they can give you a starter the things that the jungle project shouldn't expose in version control so the next so when we add that you can see like pi cache is is ignored you can see oh these are not ignored i believe so let's go ahead and ignore these two so in the what is this oh we need to make sure it's in the router yeah so now you can see our tnv is ignored and also the buy caches right not let's also go and and ignore the dot nvidia but so dnv oh so we are seeing this one here too okay that's gonna also ignore this as you can see so i'm gonna actually use a branch here so let's check out my that's for the branch name and if you wanna get from me be sure to leave that in the comments i will be sure to to make videos about it but there are some videos that are available but if you want mine specifically just mention that and i will be happy to create them so git commit minus m then i want to say deploy project oh we need to put git at first so get that then let's push this to github so git push so i need to push to this branch so let's go on there and create a pull request so the free project is create a pull request for now we are just going to match it in because we really we just want to get this thing deployed so now that we've merged it in i'm going to copy the name there and i'm going to go to heroku and say create a new app so i'm going to give it the name let's see if this one is available it's not so we need to get this one away oh this is sorry okay so we just use this then we just create an app so now to deploy we want to go to the device section then we want to click on github you can use the heroku cli but using github makes it easy that whenever we push code to github hero can go ahead and pick it up and deploy the newest code without you actually deploying so if you have not connected to github you're going gonna have a button to like connect github that's gonna ask you to authorize heroku and it's gonna get your account here once that's done you wanna search for the project you wanna connect then this is the one we wanna connect we're gonna click there so we want to enable automatic deploys so that means next time we push to github we should deploy heroku every time we push the main on github so let's go ahead and deploy mine right now so now locally since we we used another branch i'm gonna check out the main branch and i'm gonna pull to make sure that my local main branch is the same as the remote main branch so now we need to change our database instead of using sqlites to use postgres so let's move down here you see this is using sk right so this is what we want to change oh our so our deployment failed here so let's go ahead and set an environment variable that should disable correct static so what you can do is in the settings you want to click on reverse so you want to set this set it to one so we don't want it to collect static when it's deploying we are going to be everything is going to be managed by why it's not we need to retry the deployment so let's go back down and deploy branch yeah so like i was saying we need to change our database to use postprogress and we're going to be using dj database url to set that one up but we are going to be using the postgres database that gives us so let's wait for a record first set it set it up for us and then we can use that also application run into an era that's because i added the code that wasn't correct so let's go ahead and correct that so yeah we said os dot environ let's see that was funny so i want to do to get here so for now i'm just going to push this to main so it can we can deploy quickly [Music] fixed code then let's push to main so now that we've pushed this should go ahead and start really praying again so if you come here and click on overview you can see that the build is now in progress and we didn't actually go ahead and deploy again so it's just picked up the new changes so let it deploy and we see where it gets to so as it deploys so as it deploys i want to also go ahead and set up this so i want to go ahead and install it so so want to go ahead and install it so when i click that then i want to install dj database url and of course you can use the normal way of setting up a database so here where is it where is it yeah so here you could come in and you change the engine and you change the database but you're gonna have to write like five lines of code which we have i just want to avoid by using this module here so heroic actually uses this to configure databases so with this module whenever we have a connection string in as an environment variable we only have to do this add this line here and it's going to pick up the the connection string by default so if we want to hard code it inside the code then we can use this here where we say dj database url dot pass so basically this is going to allow us to to to pass the connection string itself you know it's going to have some random characters so you want to use bus to make sure that django database url picks it up correctly so for us you're going to be having it in an environment variable so we want to have just this line here and we're just going to put it after the databases just so we can repress this you can replace the default one so let's make sure we have the imports so we need to set the secret key to so you want to go to settings and go to reveal and set the secret key so i'm just gonna set it to secret key here so notice how django notice how heroku was able to set up a database url for us so we also want to change this we want to go to our settings we want to go to our.env so like here we want to have something like this so you use the syntax when if you're in windows so the value for this is going to be this whole string i'm just going to copy it and bring it here so you can see it's very random and that's why we need to use pass if you're going to to use the past syntax and not use an environment variable so let's use this here and of course we need to use export so let's make sure our m sample is is updated git commit you can say at db connection string let's push it so now heroku should try to deploy again let's go here so the deployment has started hopefully we don't get any any other issues but just like just like you can see whenever we get issues we are still able to fix them so let's wait to see how this this way to see how this one now behaves all right so it looks like this one is done now so when i click on open app this time it's actually opening here so you can see it opens here and we have our api so if you if you ever want to create like an admin user so they can be able to log in and manage campaigns you can go here in heroku then you want to go to run console and here you can run command like you're running it on your django server so you can do python manage.py create super user let's make sure our database is create is also linked so create super user let's run that so let's give the username i'm just going to put christchurch here email just use christchurch in a password the password that never gets old it's too common i'm sure so you can see we're able to create a super user meaning that the database is linked so now that means we should be able to go to the admin section by doing admin and here i guess and here we can login so i'm going to use the christian and my newest password now for you to be able to add a campaign you're going to need certain environment variables for cloud binary to be able to upload images so you can go to the settings then you want to go to configures which is here then you can add your settings here so i'm going to go ahead and add mine and then we can test out the addition of campaigns so in the end we're going to need all this stuff be sure to use yours if you use this they won't work that's what i promise you so let me use this and this one is also a test obviously this is just demi i just don't want you guys to see my credentials but you can use yours that you can get from the ordinary your ordinary page so be sure to get yours and then you make sure you have them here you have them you have them set all right so once you're done setting up then you can come and test out this so we wanna just create a simple campaign let's make sure we can upload i'm gonna click up choose picture so i'm gonna choose any picture i find close i'll just use mine for our app i'll click save and you can see it gets it goes ahead to be created so that means that in our api so in our documentation and to make sure we can be able to fetch the one we just added and you can see we get it so thanks guys for watching if you enjoyed the video give it a thumbs up don't forget to subscribe i'll talk to you next time hey guys welcome back so let's go ahead and deploy our next cs application to heroku so our application is in the front-end folder so right here so i'm going to stop the server and if we do an ls you can see we have all our next files so what you need to do here is make sure this is a git repository so what you want to do is go to github and create a repository and connect it to heroku so here i'm going to create a new repository so let's create let's call it cm next i said cmx but i did sm next two guys anyway so i'm just gonna copy this text i'm just gonna copy these default commands and just replace them inside the front-end folder so that's gonna go ahead and push it the readme file here so we want to push all the code now the git project that makes just sets up actually ignores all the env files and also these modules files and dot next files so what you want to do now is push all the code so i'm just going to push i'm just going gonna add all of them and then push them so git commit minus m add all code let me push it so get push and that should update on github so what we wanna do in heroku we wanna go heroku.com you want to have an account of course you want to be able to login then you're going to have a button to create a new app so we're going to create a new app this time it's going to be cm next yes like this let's create it create app so once it comes what you want to do is click github on the deploy section then you want to connect it to github if you haven't connected your github account it's going to give you a button to connect then you can authorize for your code to access your account so once that's done then you want to connect your repo so i'm going to put sm sure it's going to come up so this is it i'll click connect and it's going to go ahead and give us more options where we can customize deployment here so we want it to deploy every time we make a new change so we want to click on enable automatic deploys forget the ci one it doesn't matter so much because you're not using the hero ci so then you want to deploy branch so this since this is what contains our main code heroku is going to be running the yan build command and since we want next year's fetch data at bureau time we want to make sure that it's connecting to the right api so here if i run yan build it's gonna go ahead and do some some checks so first off you're gonna see that it fails because we have an issue in inside underscore document.js so we want to correct it so this is just a linking issue jsx issue so once you correct it we can run again so we're going to do yen build notice that it fails because it can't make a request to the localhost so what we want now is to update our application to point to the remote url our remote url is going to be this this is what we want to have now so i'm going to go to the front end the tnv and replace this on the back end we need to enable cores for this front-end to connect to it we want to enable this front-end to make cross-origin requests or server so i'm going to go and update our back-end code to also accept the front-end so i'll just go to the back end then go to the settings py where we had cause allowed origins we can add our new front-end urls all right just move this trading slash now that we've updated our backend code let's go ahead and push it to github just so it deploys again such that by the time we deploy the front end the back end will have updated so backhand gauge add commit minus m update cause list let's push it okay so that's good so on our front end so on our front end okay so for now we just want to make sure that our remote is update up to date so let's just do git add commit push okay okay so now once we come back to heroku so let's click the play branch again and also let's uncheck wait for ci so it's going to go ahead and do a new install for dependencies it should run here and build let's wait for it only absolute errors are supported yeah so you can see that it failed here and that's because we have not set the we have not set an environment variable for our api so if you go to envelope we need to set this in heroku so i'm going to copy this and go to settings then we want to go to [Music] key so for the king it's going to be that i'm just going to copy the very actually cut so that's going to be the key then the value is going to be this one i'll click add and go back to deploy and trigger a red player again so the play branch again okay so this time you can see it's finished successfully and you can click on view so when you click on view you can see we have our next year's app and it's on here you can even click here and it goes to the detail page so now we have our static app that's built on top of django and next and it's live on the live you guys can even check out this thing i promise it's gonna work so that's gonna do it for this video so in the next one i'm going to be showing you guys how to set up google analytics with the next year's project just so we can track who is visiting this app just so i can see you guys when you try to visit that thing okay yeah so we're going to be starting here in the next one thanks for watching subscribe i'll talk to you later hey guys welcome to the last video in the series so in this one we're going to be setting up google analytics with our next yes application so before we continue i want to mention that i will be working on a full stack cost that will be using django and next js so it's going to be an instagram clone meaning that we're going to be building everything you see in instagram to the best of our knowledge using django on the back end and next years on the front end so if you guys would want to build that application with me use the link below to sign up for updates on when that course would be available all right so with that out of the way let's go ahead and set up our google analytics so let's create an account so we can get a tracking id let's call this a tracking account the name don't really matter so we're going to scroll down click next so for the properties we want to give it a name so i'm going to call this cm pro property then they're going to ask for business information so what do we want to do so here we need to accept the agreement let's accept we already have enough emails so just not check any and right here we want to add a data stream so a data stream represents where you expect your users to be coming from so ours are going to be on a web app so for the website we want to use our heroku app so you can call it xcm next this is it i'm going to copy this and when i go to analytics repress here the protocol is already prepended so we want to keep just the domain and we need to give it a name so in our case we can call this cm website so once that's done then we're going to have the measurement id so this is what we care about so we're going to click this and these instructions here don't worry about them so what we want to do is we want to go to our next year's app and add this to our environment so here we want to say next public underscore ga id ga measurement id so once we have this then we are going to be using the we are going to be using most of the code in the in the with google analytics example we want to go to our custom document and we want to add this code here so we're actually going to be copying every piece of code we have in this example we can press this one there so we need to bring in the tracking id we're just going to be bringing in from bringing it in from the environment so one other thing we're going to need to do is configure dtag utility that's going to be responsible to set up a way to log an event so an event is basically a custom action that the user performs that you would want to track maybe how many times the user clicked the login button oh and also the page view so we're gonna get this so new folder let's call it lib so inside there let's create a gtag.js so we'll put in this code here and instead of using the environment from the component we're just going to to export it inside the util file inside the lib file and use it everywhere so let's make sure here we are exporting it as next public gm measurement id so now here we can use ga tracking id and that should add the import that's what is being used here and our input has been added good so next thing we're going to need to do is in the app.js file we need to basically tell we need to log events on route change so if a user goes on the home screen we should be able to say that they visit the homepage ten times they visited the detail page seven times that's kind of thing so we're gonna put some events on the router and we will do that inside app.js so here before the return we can have this code here we need to import router we need to import use router so let's add that input let's also add this input for g tag because we are going to need it to to basically count a page view so here we can add this input i'm actually going to import it import g tag from that should be the same should be okay one other thing is if we want to look custom events like when a user clicked a button we can use the so you see the youtube we set up here for for for the event so we can use this here to be able to log an event so what we'll do is we have an example here in the code so if you go to the contact.js file we have this example here where you can log a custom event and maybe the data that the user entered so here we're going to copy this very same thing and uh then we want to go to where we get the successful submission and we need to log an event so here we'll have this here so we'll have g tag event submit form category contact and then and then for the label we can log the email that was actually submitted so we can get the email obviously from the email in our state and that should be good what i want to do here is actually keep the imports input as alright and then this is what we are going to have here so so right here then we want to import it similarly all right okay so now that we have this then we can go ahead and then you can go ahead and push this code to heroku and also update our environment in heroku to recognize this to recognize this uh environment file so i'm going to copy our environment variable and go to heroku i'm actually gonna save here too and go to heroku right here so heroku.com so when i click on the next yes app then we need to add the environment variable so go to settings let's click on reveal so right here we want to put our one output next year's fabric measurement id for next yes geopublic measurement id then the value is going to be so make sure you use yours and i'm going to save inside app.js we need to import use effect okay and now let's push again okay so now the deployment is done we have a deployed here so i'm gonna go to the site now so so now you can go to the site by clicking open app and if you're not using heroku obviously you just go to your site but for us you just click open site and you can see here this has opened so i can go navigate on the site as normal and now if you go to analytics so you can click on reports so i can click on reports and i'm going to actually minimize this a bit so when you go to reports and click on report snapshots you can see that we have a user active and right now i'm in uganda and all these details here will update as we have more users visit our website so if i click on real time we can see we have a users i mean kampala if you guys didn't know and then here we can see that someone visited was visited the homepage and then went to the detail we can see i'm on desktop okay so i'm going to be posting the video here guys if there's something you want to know about google analytics just google it i'm sure you're gonna get an answer or just ask in the comments if i know if i know about your question then maybe i can answer it so thanks guys for watching if this video helped you give it a thumbs up don't forget to subscribe i'll see you in the next series so talk then make sure you subscribe have a great one
Info
Channel: Cryce Truly
Views: 699
Rating: 5 out of 5
Keywords:
Id: zS3vKMbsUfY
Channel Id: undefined
Length: 207min 6sec (12426 seconds)
Published: Sun Sep 26 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.