Gatsby V3 Tutorial and Recipes Site Project

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up everybody and welcome to gatsby version three tutorial video so a few weeks back we as we rolled out its latest version version number three and as with all the new versions there are some major changes so it only made sense to record a new gatsby video during the video we'll cover such things as file system route api new syntax for css modules and of course new plugin to handle images in gatsby as with all my videos in order to make things a little bit more interesting we'll utilize our knowledge by building a cool project a recipe site if you'd like to take a project out for a test drive just visit the url gatsby version 3 tutorial recipes dot notify that app again the url is get b version 3 tutorial recipes dot netify and lastly this video is first part of my gatsby course where we build more cool projects with gatbjs all right and welcome to the course and i guess let's start our journey by answering the most basic and yet pressing question first well what is get bgs and most likely the explanation you have heard is this one gatsby is a static type generator and while it's true at the end of the day gatsby does generate a static site at this point in time gatsby just is far more closer to a full-blown framework than to just another static site generator gatsby is built on top of react so if you do enjoy the amazing dev experience that comes with react so think things like components modularity and etc you will feel right at home when using gatsby now that experience is of course nice but what about the final product what is so special about gatsby you see once we're done with our project gatsby will do its magic and without doing any extra work we'll get things like code splitting fast page loads image optimization data pre-fetching and i can go on and on and on since the list of the benefits we get straight out of the box is extremely long what's also cool is that the static content gatsby generates can then be enhanced with client-side javascript with the help of react hydration and even though it's a muscle it simply means that we get best of both worlds not only our gatsby set can have app-like features so think traditional react app but it's also super fast and optimized sounds pretty cool right so keep watching the course and i can guarantee you that you'll be extremely happy with what gatsby has to offer as far as the course structure in the first module so the module you're currently watching you'll find a useful info about the course in the second module you'll find extensive gatsby tutorial and after that every module contains a unique project where we test out different content providers as well as advanced ksb features lastly let me just mention that in order to make the knowledge thick and also in the process make things a little bit more interesting during the second module so the gatsby tutorial one will also build a cool project a simply recipes project where we create a nifty recipe site when it comes to course requirements my expectation is that you are at least familiar with react basics so things like components and props have some experience with modern javascript so es6 and up specifically array methods like map filter and reduce as well as the structuring and spread operator and while you can still follow along with the course even if you have very little experience with react and modern javascript in some cases you might need to utilize some external resources since i want to keep gatsby as the main focus of this course and therefore my plan is to cover extensively only the gatsby related topics if you are struggling to find a good place for resources i'm going to be biased and suggest my own youtube channel called coding addict where you'll find lots of useful react vanilla javascript node css and html content specifically look for javascript nuggets series where i cover most asked course questions in isolation and great detail as far as the dev setup since gatsby is a node app and will install quite a few dependencies you'll need a node on your machine and when it comes to my text editor and browser i prefer visual studio code and chrome but of course they're not mandatory and lastly all of the services i suggest during the course have a free generous tier so you can leave your credit card where it belongs nicely tucked away in your wallet like i mentioned previously for development i prefer visual studio code or vs code for short which at this point is probably the most popular option out there and since i do a lot of recording i keep my setup very close to the default one with some exceptions like font size and zoom level throughout the course just to speed things up and avoid a necessary boilerplate i will use few extensions but i'll cover them later just so you get a better understanding of the benefits now if you are interested in my overall setup just navigate to my github profile john milga and look for the repo vs code setup and there you'll find all the extensions i use as well as my settings json file with all my config options all right and welcome to our first module gatsby tutorial module and like i already mentioned previously in order to make things more interesting during the module we'll also build our first project simply a recipe site if you want to see project in action or maybe you're interested in complete source code like always the fastest way is probably by navigating to johnsmilk.com so hit the url johnsmilk.com then look for the project page and then in the projects page more specifically look for the gatsby ones in here you'll find all the course projects and you're looking for the recipe site if you click on this link you'll see the project in action and then if you want to access the source code look for star files or source code in this case they both point to the same repo and in here you'll find complete source code for the project lastly since i find gatsby documentation extremely helpful in order to support my arguments and showcase where you can get more info in future i will reference gatsbyside somewhat often especially during gatsby tutorial part and the url is getbjs.com again the url for gatsbyside is getbjs.com nice and let's kick things off by installing a gas bcli package which is a tool that will allow us to quickly generate gatsby projects and if you're familiar with create react app the idea is exactly the same instead of spending our precious time on config and setup we'll be able to spin up a gatsby project with the help of one command they do suggest installing globally so in mac don't forget to add sudo and once i'm done with my install i'll share a great resource if you do hit some roadblocks or just need more info on the whole setup so i'm going to navigate back to my terminal and i'll massively zoom in the command is sudo since again we're installing this globally then we go with npm i dash g and the package name is gatsby cli and i'll be prompted my password and once i enter the password of course i kick off the install it looks like everything went great i don't see any errors so i should have the package now if you do want to double check just type gatsby and then hyphen hyphen version and if you see gatsby version 3 e in terminal you are in good shape however if the terminal spits back that no such command is found then of course you haven't installed the package and you'll have to troubleshoot now if you get stuck or just need more info i suggest navigating to the gatsby docs then look for tutorial then click on this link and here they go over how to set up your dev environment where they cover how to install node on your particular machine set up git if you haven't already and that sort of thing so if you do hit some roadblocks i strongly suggest using this resource for guidance and once we have the gas bcli at our disposal let's take it out for a spin and the command for the new gasb project is following gatsby new than the project name followed by the starter project name of course is totally up to you and as far as the starter it's a url to the github repo and just like the name suggests star provides some default setup now if you omit this star url altogether it will automatically use the default starter and don't get me wrong there's nothing wrong with default starter and in most cases that's exactly what you'll use but since it comes with few bells and whistles for our first project we're going to use a hello world starter which essentially is bare bones gatsby app why i went this route because i think is going to be more beneficial if we add those bells and whistles together since that way at least in my opinion you'll have a better understanding of the whole setup lastly in order to spin up the dev server the command you're looking for is gatsby develop so let's do this people i'm gonna navigate back to my desktop i will zoom in and first i'll navigate to desktop you can set it up your project whatever you like but i always prefer desktop so i'm going to go with cd and nest up and then of course we just want to go with command so gatsby new as far as tutorial name not going to be particularly original and i'm just going to go with tutorial and at this point we can either type out the url or we can simply navigate to gatsbydocs and then we're looking for the starters now technically they're under the features but you're not gonna find them under this features link at least at the time of this recording so instead keep scrolling scrolling scrolling scrolling and then all the way in the bottom you'll find the stars and then by default they'll set it up as version two again at the time of this recording eventually things might change so instead we're looking for version three and then this is going to be the default one so basically the one that you're going to get if you omit the url altogether and then the one that we're looking for is hello world so notice here the search box we can simply search for it here now the idea for all of them is pretty much the same where if you're building some project and if you know that you'll need a specific config for example the strappy one or the shopify one or whatever you right away can get a star project with bunch of things pre-configured and since they're github repos you can simply of course navigate and take a look at the source code and see what the starter is all about so essentially what are you getting now in our case like i said we're looking for hello world hello world and then i'm just going to click on a link and we can visit the demo set and all that but i'm looking for this command now in my case i'm not going to copy the whole thing because i only need the url since as you can see here they go with this name and i already have my tutorial so take the url part then navigate back of course and then copy and paste and once you do that that's bcli is going to start bootstrapping our project and at this point you have two options you can run the gatsby develop from the terminal or you can run it from the visual studio code because visual studio code also has the integrated terminal and in my case i'm going to go with second option so i'll close my terminal then i'll open up my visual studio code drag and drop the project in the following video i'll go over the general structure of the gatsby project for now i just want to quickly get something on the screen and therefore i'll open up the integrated terminal and that's a virtual studio code thing where effectively they have the terminal that is right away pointing to our project to my tutorial in this case and then i simply want to go with gadsby develop so that's the command that spins up the dev server and it is always my preference to work side by side with a browser so effectively i'll make this smaller again this is not a gatsby thing this is actually a mac thing where i go with new window so new browser window and i just set them side by side with my text editor and then i'll also open up a new tab on a bigger browser window so i'm going to go with localhost and we're looking for a thousand and if you see hello world on the screen you are in good shape so i'll set them side by side here this is going to be our complete project and that's the project we're working on and then for time being i'll just close these two tabs and then i'll do the same thing here we're on a smaller browser window i'm going to go with localhost 8000 and again if you see hello world on a screen that means that everything is correct and you can proceed to the next video beautiful and as far as the typical gatsby project structure we have cache folder where gatsby stores the cache then we have node modules since at the end of the day it is a node app so basically this is where we keep all our dependencies and so i honestly i don't see any reasons why you need to go here and do any modifications while you're setting up your project then we have a public one so this is where our production ready project lives and i'll cover it in more detail when we take a look at the different commands we have then we have source and more specifically pages so we have source directory with a pages directory and since we'll spend most of our time in source folder i'll just leave it at that there's really no point for me to repeat myself then we have a static folder where we can set up assets that are going to be publicly available as well as we can access it in our project however i'll talk about the gotcha in a second so don't start placing all your images right from the get go in static one then we have get ignore which is just a file for search control so in this file we specifically say which files or directories are going to be ignored once we push this project up to github for example then we have prettier ignore and pretty rc which are just used for the package that the gas b comes with and the package name is prettier then we have gadsby config so this is where we'll set up all our configuration for our site things like plug-in site info and all that good stuff license pretty self-explanatory package lock json and package.json so package lock is used for the dependencies of the dependencies we know that in node map once we install dependency it possibly can have dependency on its own so package log just make sure that we can get the correct versions of the dependency dependencies and then of course we have a package.json where we have our dependencies and let's not forget readme the markdown file where we can find useful information about our project and i guess let's start by exploring the package.json as you can see we don't have that many packages if we keep on scrolling we have dependencies of course gatsby react as well as react down and then for development they use this prettier package and actually you can run a command and the command is format and it will format the project for you now my preference is using this extension instead so let me go to my extensions and i actually prefer using the extension by the name of preview and effectively the difference is that it runs automatically so once you install this package and make sure you add this configuration to your settings json that's definitely a must with the later versions of vs code if you won't do that it's not going to work and then the moment you do that you don't need to run the command because in this case notice the package json effectively if we want to run the formatter we need to run this command correct but once you install this extension and once you set up the proper configuration in settings json it will automatically happen once you save or once you copy and paste whatever setup you choose and you can control that in two places you can either use the gui so first navigate to the settings and this is going to be the graphical interface and just type format and in my case i use format on paste and format on save or of course you can do it directly in settings json i have editor format on paste and format onsave so those are the options i use but of course you can modify them to whatever makes most sense to you then as you can see we have more commands we have one for start one for serve clean and we also have one for build remember when we talked about the public on i said that this is where our production ready project is going to live and in order to set it up we need to run gadsby build so let's try it out first in order to stop the dev server we simply need to go with control c then i'll clear the terminal so i'll just type clear and then we run gatsby and then build so this will do all that gatsby magic now there's also another option later once we host our project actually we'll set up our hosting provider to do the build process for us but it doesn't change the main idea where eventually there is a public folder with our project ready to go with all the gatsby queries so this is where we have all our image optimizations all the prefetching and all that cool stuff and if you take a look at the result you'll notice that it's just a bunch of static files and again this is the key thing about the gatsby where once we're done building our site once our project is ready to go we just ship it as bunch of static assets so there is no back and forth with a server we just send our project over the wire it is extremely fast because it's just a bunch of static assets and once it arrives there then of course it does the whole rehydration thing and user gets this nice react experience that should do it for the public folder and next i want to talk about the static one remember i just said that whatever asset will place here will be publicly available and you'll see how gatsby will nicely transport that asset to the public one now here's the key gotcha just because you can does not mean that you should so imagine this scenario on my desktop i have this cute image of these two puppies i can simply open up my tutorial and then drag and drop into my static one and currently in my static one you can see that we have a favicon and if you're not familiar with favicon it's just this icon in the browser tab and once i spin up my dev server again the command is gatsby develop or notice how they also have this start script and if you have worked with create react app you know that they also have this npm start which just spins up the create react app so this is similar where i can run either a gatsby develop myself or i can run npm start and in turn that will run the same command so i'll go with npm start just to showcase that it works and once my server is up and running i'll be able to see the cute jpeg in two places i'll be able to see that once i navigate to a localhost 8000 and then more specifically let me zoom in i'm going to go with forward slash and cute jpeg and yep i have my puppies and i can also do that in my project now don't freak out again there's going to be a proper introduction for the source one but since i want to get something on the screen i'm just going to navigate to the index.js in the pages and then above the hello world just for the time being i'll showcase that we can access it here as well and i'm gonna omit the alt attribute and then once i save and then once i refresh of course i have my cute image now just because you can does not mean that you should if you read the gatsby documentation they actually are trying to discourage you from this kind of pattern because if you add your assets in such a way where you just dump them into a static folder essentially you're not using any of the nice optimizations that gatsby provides so the whole point of using gatsby is because of all the magic that it does behind the scenes in this case you're just adding it to a static one and then you make it publicly available and if you want to see that take a look at the public one and you'll see the cute jpeg so my whole point is following where be mindful of what you place in a static one just because you can does not mean you should and of course all the following videos i'll show you a proper way how we can add assets and in turn we'll use all the awesome gads beakeries so i'll remove the image for now and i'll also remove it from my static one okay and then let me just go back to the package.json and let's complete our list of commands so we covered build this is productionreadyproject we have also covered develop we have covered format as well as start and then we have serve clean and test now there's not much to say about the test but as far as serve and gatsby clean so with serve we will serve our project locally so our production ready project we can take a look at how it looks locally because keep in mind that as far as our current setup we are looking at our development project once we are done running gadsby build and that's a must because you cannot have serve without the public folder then go with gatsby and then serve and then of course you'll be able to see the project at this point there's not much to see this is pretty much the same project but if i go to a localhost and 9000 so that's going to be my production ready project and then eventually we have this one the gatsby clean and this is super super super useful once you start working with images because once in a while you'll hit the glitch where the image gets stuck in a cache and once you run gadsby clean you'll notice something pretty cool where if i go with gadsby clean it will tell me that the cache folder as well as the public one has been deleted and throughout the course you'll see me run this command again it's super super super useful once you start working with images so imagine the scenario you add an image then i don't know a minute later you decide to change a path and even though your code did not change the image actually changed and then you are trying to spin up the dev server and you're getting this weird bug now the bug is not because there's something wrong with your code nabaga is there because gatsby is still looking for the older image again something to keep in mind and lastly let me just mention something about this whole dev setup in the gatsby docs they mention that as far as the dev server it uses the hot reloading what that means well that simply means that once i spin up my server so npm start again and if i go to the pages and index.js again don't worry i will give it a proper introduction for time being i just want to showcase how the hot reloading works and if i go here and if i change this text to hello people once i save the changes should automatically take place in the browser now in my case the dev server is still spinning up but the idea is following where the moment you save you should see the changes in the browser now notice i use the word should because in reality as far as my experience whether that was version 2 or with a version 3 you'll still have to refresh now it doesn't mean that you'll have to refresh each and every time there are times when everything is going to work so if i'll go back to the hello world and if i'll save notice how in this case it updated everything nicely just don't be surprised where not only you need to save the file but you also need to refresh and also in gatsby version 3 they added this error model and the best way for me to showcase is by removing this div so notice if i navigate to a bigger browser window of course and as a signal i'm looking at 9000 should be looking for 8000 you'll see this helpful modal that explicitly says where is the error now again this is something that might pop up even if there is no error now i'm not saying that it's gonna happen each and every time there's gonna be times when it's very useful so for example in this case it points directly where is my error but yes once you start dealing with images and all that it might pop up once in a while where there is no need and if that is the case simply start by refreshing the browser and if of course it doesn't go away which in this case there is clearly an error so it's not going to go away but if it's there by mistake then you'll see how it disappears and of course throughout the course we'll probably hit those bugs so that's when you'll see that in action that should do it for the overall setup and now we can start working in our source directory where like i just mentioned we'll do most of our work not bad not bad i think we have good initial understanding of typical gatsby project structure so now let's get our hands dirty and finally write some code and while there are many things i like about gatsby the two that i like the most are following i find gadsby set up extremely straightforward and since it's built on top of react trust me if you have done any work with react you'll instantly feel at home since a lot of things are very similar to typical react project case in point if you take a look at the source folder you can see that there is a pages directory now million-dollar question what do you think we're going to do in the pages directory and if you answered well we'll be setting up pages for a project you're 100 correct so the only thing we need to do in order to create a page in gatsby is just navigate to source folder then pages directory and then just create a file so simple javascript file so if you'll call this about.js then you have about page if you'll call this product js then you'll have a product page and hopefully you get the gist so that's the straightforward part now what about familiarity well if you take a look at the content in the index.js what do you see over there and as far as what i see when i'm looking at it i see a react component and effectively in order to create a page we just need to set up a area component now that could be class-based component even though i highly doubt you'll create one because with arrival of hooks pretty much the common convention is setting up functional components but yes you can do that or you can go with functional component which is something we're going to do throughout the course so as you can see we just import react and then we export our component now one gotcha is that this export has to be default and i'll show you what happens if we don't do that but as far as the setup it is straight up react component again this could be a regular function when you're setting up functional component or this could be a arrow function and don't worry we'll cover both of those cases in a second and then whatever we return well that is displayed on screen so if i'll change this of course around and if i'll say that there's going to be a heading 1 instead of a div and we'll say hello and people if everything is correct we should see a hello people on the screen and what do you know now of course we have hello people and just to give you a visual representation this is going to be the project we're going to be working on during the tutorial and of course it has multiple pages it has recipes page it has tags page about page as well as contact page how do we create them we simply go to pages directory and just create files now i'm not going to set up all the files in this video but in order to get some practice i will navigate to the pages and in here i just need to say new file now we have multiple options in visual studio code if you want to use the icons here on top you can do that as well in my case i just used a right click and i'm just going to create a simple about js page so i create a page and this is where i need to set up my component now in order to speed this up i actually use this extension so let me make my extensions bigger and let's see let's see we have this one the es7 react redux and blah blah blah so i'm not going to read the whole thing but basically you get these snippets so if you take a look at the extension so now of course i just need to make this one smaller you'll see a bunch of snippets that they provide and effectively it just saves you time on typing out the boilerplate now the ones that we're going to use the most are for setting up the components so keep on scrolling keep on scrolling eventually you'll hit the r so this is going to be for setting up d components so rcc is going to be for class class-based component and pretty much i'm just going to show you one example because like i said throughout the course we'll use the functional components instead and then the snippet for that is let's keep on scrolling so we have rcc and then we have the functional component one now keep in mind that we right away want to export as default and that is extremely important so again if you want to find more info just look for the extension and i highly suggest installing because throughout the course i will use this extension to save some time on setting up the boilerplate so let me close this one and again we can go with r and then they're going to give us suggestions to notice once i type ra this is going to be for the arrow function and i right away want to go for the r a f c e so this is going to set up a component and right away export it as default and as you can see it right away takes the name of the file so since i named my file about just set up a component with the same name and export it as default so let's write here hello from about page or you can simply type about page and for now we haven't set up the navbar yet don't worry we'll do that in a second but if you navigate to url bar and if you type about there you go now of course we have hello from the about page and just to get a bit more practice why don't we create one more page so say new file in this case let me show you that of course we can do it from the visual studio code gui as well notice this is the new file option let's click here and i'll call this one contact page again if we want to set it up as class based component we can definitely do so and the snippet for that is rcc notice how we're setting up class based component again with the arrival of hooks i don't know why you'd want to do that but it is definitely an option and it's going to work so i'll say contact page once i save again i just need to navigate in my url bar for now so i'll say contact so i do have the contact page that works and another option we have is setting up functional component but not as a arrow function like we were doing in the about we can simply set it up with good old function keyword and the snippet for that is r f c and i just need to click now i have my function which is contact so i'll say testing contact let's save it and if everything is correct i should see testing contact on the screen so in this case i'll have to refresh now i have the testing one now just to showcase what happens if you don't set it up as default why don't i create a testing page so i'm gonna navigate to pages i'll say testing.js and in this case i'm going to go with functional one but i'll omit the e at the end for my snippet so simply go with a arrow function and as you can see i'm not exporting as default so right here fail and then once i save i'm gonna navigate in my url bar to the testing one and then once you navigate there we have our big fat error and the reason why we have this error because every time you set up a page you need to export it as default so the named exports are not going to work and at this point we have multiple options either you can just refactor it to the export default here in the bottom or you can go to the testing one and say export default and then of course we can just omit all of this stuff so we don't need to come up with a name and now of course it's not going to fail so say testing here and once i save it and then once i refresh there it is i have my testing one so two things to keep in mind always export it as default and in order to save some time i suggest using this awesome extension because it nicely takes care of all the annoying boilerplate nice work at this point i think we are experts on how to set up pages in gatsby but while we're still on the topic let me mention two more things and the first one is going to be 404 page so imagine the scenario the user visits your project and then for some reason he or she is looking for a resource that doesn't exist so in this case i'm going to be looking for the company page but that page doesn't exist in my project and what we're going to do we're going to display a nice error message and then possibly you can add the link whatever you'd want so essentially you are setting up the page which you're going to display if the user cannot find the resource and just to give you another example for example if you take a look at the gatsby documentation and if you go for the error page notice this is what they're displaying as far as their page and notice how we can nicely navigate back to the homepage and the way you set that page in the gatsby is following so again in the pages directory however the name in this case is important if previously you could just set up whatever names you want over here just keep in mind that they will show up in the url when the user is trying to access that resource when it comes to 404 when it comes to the error page the file name is important and we go with 404 and js now the one gotcha with the snippets that i showed you in the last video is the fact that they right away create a component with the same name as the file name now the problem of course is that in react or more specifically in javascript we cannot name functions with numbers correct so this is going to be the case where i need to rename it i'm going to go with error and i'll also export as error and for time being will simply go with arrow page again this is a standard page so we can set up whatever functionality we want over here and in order to test it i'm just going to go to a testing and then maybe info now of course we don't have that resource so in development we'll see this page first so this is going to be displayed first and then of course we can click on preview on custom page don't worry once we deploy our project this screen won't appear and if i click preview now of course i have my arrow page hopefully that is clear that's how we set up arrow pages in gatsby beautiful and while we're still on a topic of pages i also want to show you how to set up nested pages in gatsby now what am i talking about well if you navigate to the gatsby site and then hover over the docs link notice how you have these options correct and then if you click on for example how to guides check out the url so the url is the domain yes bjs.com then we have docs and then more specifically how to and the way we set up this type of structure in the pages we just need to create a folder so again keep in mind whatever you're going to name your folder will show up in the url so if you'll call the second bank in the url you'll have to type the domain in our case localhost 8000 then shaken back and then whatever the page name so in here i'm going to go with new folder and then i'll just call this company company and then whatever file i'm going to create in the company again is going to be displayed in the url but in the url i'll have to have the forward slash company as well so if i create a new file and i'll call this history and gis and of course we create a component we already know how to do that we have history one and we'll say this is history of our company now of course in order to get there i need to go with company so i need to say forward slash company and then the history one so let me zoom out a little bit and i'll say history so now of course we're going to navigate this specific page so again we can set up whatever pages we want here so i just need to come up with the file name and then set up my component just remember that the url will contain the folder name in this case company and lastly i just want to mention notice how in the pages we actually have index.js now index.js always signals a root and of course when we talk about pages that means that it is going to be our homepage so once the user navigates to your domain again in our case localhost 8000 whatever you set up in the index that is going to be the home page now why am i telling you that because at the moment notice how company folder does not does not have index.js and what that means if someone just navigates to forward slash company well there's no page for that so of course now we'll display the error page now there is a page for the history so of course we can navigate to company forward slash history we just saw that but there is no page for the company so if at any point you do want to create that page for the company simply create a new file in the company folder and just call it index js so this always signals root now in the pages that root is our domain and in the company of course that is going to be forward slash company so again i'm gonna go with my component and i'm just gonna say hello from company and of course we don't have the error and we can clearly see hello from company that should do it for setting up pages in gatsby and now let's take a look how we can navigate from page to page using gatsbylink component not bad not bad i think we are comfortable with setting up pages in nasbi now let's take a look how we can navigate from page to page using a link component instead of the url bar because yes technically i can force my users to do that but you would probably agree that that's not the best user experience and if you have done any work with react router dom setup here is going to feel extremely familiar because under the hood gatsby uses reach router which in fact is built by the same people who built a react router dom and the way we set it up we just need to import link component from gatsby and i'm going to do that in my home page just keep in mind you can do it in any of the pages and then again this is a named import so we need to specifically say a link and this is coming from the gatsby now the problem at the moment is that i have my component but i'm returning just heading one and we know that in react in fact we can return only one thing so if i want to set my link side by side then of course i just need to set up a parent div and then right after the heading 1 i'm going to go with link and then this is a component and it's looking forward to prop so in this two prop we just specifically say where we're going to navigate so if i want to navigate to about page i simply go with forward slash and then the about so if i want to navigate to a company and then history you get the gist you just need to type forward slash company and then the history so i'm just going to add about and then whatever text you place inside of the link of course is going to be displayed on screen and since we're navigating to about page we might as well set up a text as about and once i save my index.js and if i click on my about link check it out now of course we can navigate to about page and notice this awesome react experience where essentially we're not doing the full page reload and again if you're interested you can take a look at the source so in this case i just need to refresh and you'll see that at the end of the day yes it is a link so for example that is important when you set up styling you're still looking for the link element however again under the hood gatsby does all this magic where essentially we have a react app and with that said please keep something in mind where we can use still traditional links and we do need to use them when we're setting up a link to external resources so the link components are intended for navigating around your project not to the external resource as a side note i'll place this one in a div just so they are in separate lines so create my div and then i'll just set up regular html link element and as far as the ahref let me try one more time to about and i'll say regular link and you'll see this full page refresh and again in this case i just need to navigate back to the home page and refresh notice this is going to be this regular link and notice the difference of course in this case i just navigate and there is no page refresh however if i press on the regular link check it out we have this refresh so the idea is that when you set up links around your project you don't want to use the regular html element however when you're setting up a external link yes you do need to use it so if we set up link back to the gatsby docs and i'll use this full url here then of course i go with link i can copy and paste and then i'll say i don't know gatsby docs and once i set up my link i just need to navigate back to the home page so let me see i'm going to go back to my route and then click on gatsby docs so this works nicely where we use the regular link element and we can just navigate to the external resource but around our project we're going to use the link complement now to hammer this home i'll add one more link and i'll just show you how to navigate to company and history so we have a link remember the path we need to go with folder name in this case company and then whatever is the file name so we're going to go with history and here i'll simply say history and once i have my link in place i simply need to click on the link in the browser and there it is now we nicely navigate to company history page now you're probably wondering okay but why are we always navigating back using the browser can we set up the link and of course the answer is yes so in this case i'll simply copy and paste and i'm not going to set up links in every page because like i keep mentioning eventually we will make a navbar so for time being i'm just going to go to the history one import my link i already have the div here so why don't i wrap my text in the heading two the one that i currently have in here and set up one more link back to the home page just to showcase how is that going to look like so in this case i just need to use forward slash that's how we can navigate back to the home page and of course whatever text so in here i'll say home page so now of course let's test it out i'm gonna go to my history page and then in this case i do need to refresh and just like that i have my homepage so once i click i nicely navigate back to the home page so whether you just have one pages directory with simple pages or you have a nested setup where you have nested pages the navigation is exactly the same you just go with a forward slash and then whatever is the path so if you want to navigate to about you go with word slash about if you want to go to history which is inside of the folder then you go with the folder name and then whatever is the file language of course in our case is history excellent once our project has awesome routing let's take it a step further and add the navbar now i must warn you though there are going to be few iterations of navbar so don't be upset if after this video or nav does not look exactly like in the complete project however this is our goal so eventually we want to have a nav like this so this is the look on a big screen and then if we make this smaller notice we'll have a nice button that can toggle the links as well and our most basic setup could look like this we're back in the index.js since i have a div and you're not at this point i'm going to close the terminal just so i have a bit more real estate in here and inside of a div let's just say nav and then i can have one link to the home page and then the second one to the about page like i said there's going to be few iterations we're going to say to home so that's going to be our home and i'm not going to add the page text here and let's say to about we're just going to go with about let's save that one now of course i have a nice looking nav where i have the home as well as the about links now the problem of course with the setup is the fact that if i want to add this nav to all my pages as you can see i'll have to copy and paste and since we know that our pages are react components in react we can actually nest another component inside of the component correct so we can obviously do that in gas b as well so let's try it out and the way we're gonna do that is in source we're going to create another folder now you can name this folder however you would please just keep in mind that common convention is naming it components so in this case i need to go to the source and i need to go with new folder just make sure that you don't place it inside of the pages again the goal is to place it inside of the source and like i said common convention is calling this components and then of course we can be rebels and come up with whatever component name we would like and in my case i'm going to call this surprise surprise navbar js and then i'm going to set up my good old regular component and again my preference is always using the arrow function syntax so therefore throughout the course this is the syntax that you'll most likely see but if you prefer different setup i believe i covered those options in the previous videos and as far as this component to return well i can simply go with nav and the same deal now since i don't want them to be e in the same line i'll just place a on our list then list item and then same deal we need to import our link from and you guessed it from gatsby so we go here with our link again same addresses we're gonna go with two prop and we'll just set up to home page so that's gonna be forward slash and now let me copy and paste this list item and we're gonna go with about and let's just add here about as well so let's save this sucker here and once my navbar is ready to go then of course i just need to go to any of the pages that i want to set up the navbar import the navbar and return it in my component so back in the index.js we want to set up the import and of course since i'm exporting as default i can call it whatever i want notice here export default navbar so back in the index.js i'm going to go with navbar and then from and now of course in this case we're looking in the components and then more specifically navbar so now of course i don't need to hard code it i just simply go with navbar like so and now of course we have a good looking navbar so in here if i click on about i navigate to about page and since i want to navigate back to the home page i'll do the same thing e in the about.js so let's import the navbar let's set it up here on the top so i guess in order to speed this up i'll just copy the component and then copy and paste i guess and then as far as this text so it's easier for you to see i'll just place it in the heading too so let's say this one should probably restart now i have the navbar in the about page as well as the home page so that's how we can add a component to our gatsby pages now in the next video i'll show you even an easier way how we can set up a navbar in all our pages nice we have a way of adding components to our pages and throughout the course we'll definitely use this option but not for the navbar why well because navbar typically is a global component meaning a component that we want to display in all our pages and a typical project you also want to display footer in all the pages maybe a sidebar modal and hopefully you get the gist as you can imagine if we'll start importing all the components all the global components in all our pages it's going to get messy pretty fast so what option we're going to use instead a wrapper component approach now before we set anything up let me just stress something this is not a invalid syntax so we will use this approach where we set up the component and then we use it in one of our pages or maybe two of our pages but the idea is that if you have a component that is displayed in all your pages there's a better approach where you set up a wrapper component and that way you can group all your global components in that one wrapper component and then you don't have to import all the global components in all your pages now in order to stress the point of multiple global components first i'm going to navigate to components and create a file by the name of footer and then i'll create that wrapper component now a common convention is calling this layout just keep in mind it is just a file name it is just a react component so of course you can be a rebel and call it whatever you want just keep in mind that if you're reading someone else's code most likely you'll see this convention of naming it layout now first i'll go to footer and in here i'll just create my react component and i'll close the sidebar just so we have a bit more real estate and as far as the footer i'm just gonna go with footer tags and for time being i'll just go with hello from footer like so so we save the sucker here and then of course we need to go to the layout now layout is going to be the component that wraps pretty much all the pages and the way we set it up we just go with component and then in our return we're going to place our global components and then we'll use this layout to wrap all our pages so first i guess let's start by importing all our global ones the moment we have two so we're gonna go with import and we're looking for navbar it is sitting in the same folder so we simply go navbar and at this point i'll use two cursors so say here footer and then like i said we just need to place them inside of the return so i go with a navbar and then the second one is the footer now keep in mind one thing when we use layout of course this div will show up in our source code so at this point you have multiple options either you can return it as a main you can return it as a section or whatever element you want but just keep in mind that that element will show up with this particular setup in your source code so my approach is always using the react fragment so you can write it the long way react.fragment or the shorthand is just using the angle brackets and effectively it is a pattern to return multiple elements because keep in mind that in react we still need to have this parent but using react fragment we can group children without adding the extra note again that is just a react thing and that is my particular setup i just prefer keeping my source code as clean as possible so i'll save the layout i'll open up the sidebar and you know what i'll remove all the files that i'm currently in but we're not done we will have to return to layout because there's one key thing missing with the current setup but i just want to show you what is going to be the error and now of course i just need to navigate to about an index and then wrap both of those pages if i want to display the footer as well as the navbar and we're going to first remove the navbar just so you don't think that i'm cheating so notice how i'm removing the import as well as the component then i also do the same thing here where i'll remove the navbar and from the return as well and now in the index.js let's start by importing the layout so we go with layout from and then of course we're looking in the components and then we go with the layout and then like i said what we're going to do we're going to wrap all the return so everything that we're returning from the page in our layout component so at the moment we have div and i can simply replace it i can say that instead i'm going to be returning a layout now keep in mind that the moment you'll save you won't see any contents of the homepage because we haven't handled that in layout component and once i save i do have the navbar as well as the footer but what about the contents of the page well we don't see anything because we haven't handled that in the layout and if you're familiar with the react you know that in react of course we have a props object so let's quickly console.log the props for our layout and now i'm going to navigate to the bigger screen just so we can see a little bit better and in the console notice the object and i'll try to zoom in and basically props object is a way to pass in the props into the components so that is the react setup now one special prop is children and essentially this children just represents whatever you have inside of the component so whatever is placed inside of the component so i'm not talking about the return of the component i'm just talking about whatever is placed inside of the component and since i want to display the contents of the homepage i need to access the children and then set up my return where i'm also returning a children and in order to access them there's multiple ways i can do that you can either go with props.children somewhere here or you can just structure it right away in the parameters and the syntax for that is the curly braces and then we go with children and then once i have accessed the children now of course i just need to decide how my return is going to look like and then since i want a nav bar on the top and then footer in the bottom i simply set up children in between like so so once i save notice now of course i have the contents of the homepage now in order to make it less confusing why don't we head back and instead of hello people we just say home page so we save it and now i can clearly see that this is my homepage now keep in mind one thing where nothing stops you from moving the navbar a common approach of course is placing navbar at the top and that footer in the bottom but there is no rule that says that you always have to do that as long as you display the children basically the contents of the page that you're going to wrap and as long as you have a valid syntax for the component you're importing of course you're going to be in good shape and now to hammer this home why don't we do the same thing in the about.js so let's navigate to about.js we need to go with import then we're looking for layout from and again components and then the layout and now of course i'm just going to wrap the return of the about page as well and as you can imagine if you have more global components you simply create them and then add them to your layout and in turn that does two things first it keeps our project cleaner where we have only one place where we have all the global components and second you don't need to hop from page to page for every global component that you create and in order to test it out why don't i go to my navbar and click about so notice this is my about page and i can nicely navigate back to the homepage as well so that is a wrapper component approach where effectively we set up one component then import all the global ones that we're going to use in all our pages and then we simply wrap all our pages in this layout component but don't forget about the children because otherwise you won't see the contents of the actual page good job i think at this point we have a solid understanding of the gatsby basics so switch gears and look at the styling options in gatsby as a quick side note since the primary focus of this course is gatsby and typing out the css takes a long time for all the course projects including this one all the css is already prepared and ready to go we might type few lines of css here and there while we work on some examples but that's about it for the most part styling is exactly the same as in regular react so if you already have the preferred styling method you will be able to hit the ground running in no time now since i don't want this module to be three hours long i will only cover the major options as well as my personal favorite just keep in mind that gatsby fully supports other options like bootstrap tailwind emotion or any of the gazillion options that we have out there as well and you can find those implementations within matter of seconds by just performing a quick search in star library or utilizing your favorite search engine all right and the most basic way how we can style our gatsby applications is using inline styles so if i go back to index.js and for example i want to style the heading 1 i can simply add a style attribute but just keep in mind that when we work in jsx we're actually working with javascript now what that simply means is that if i set up my double curlies and again the reason why we're setting up double curly is because for a style it is looking for the object and then in order to access javascript we simply need to use these curly braces so the first curly braces is to go back to the javascript and then the second one is the object because again that is what is required in the jsx when you're setting up the style attribute because at the end of the day you're setting up the javascript and the same goes for properties and values for example you cannot type color and then colon red like you normally would in the css why because this is javascript so the value needs to be in the quotation marks and then of course once we save there it is of course my heading is red and like i said the same goes for the properties if i want to set up text transform notice i don't write text hyphen transform again we cannot do that in javascript as far as the object properties so we need to go with text transform and then as far as the value again e in the quotation marks and capitalized so that's the most basic way how we can add css to our gatsby application while setting up our styling using inline css is definitely an option you can kind of see that it's going to get messy pretty fast and we don't need to even add that many elements so for example if i set up multiple heading ones so there's going to be hello world and copy and paste and hello people and what if i want to style them exactly the same of course you can say well you'll just grab the style and then you'll copy and paste okay but what if i later want to change all my heading ones to green am i gonna hop from one heading one to another one and keep changing these values okay and what about different pages we have about we have contact and hopefully you get ages so a better approach is setting up a global css now eventually we'll set up a separate folder for that for all the assets the images the css and all that but for time being while our project is still nice and cute i'm just gonna head to components and then we need to come up with a file name and since i'm going to be attaching this to the layout i'm going to go with layout and then css so at this point this is a traditional css file so you can do all the cssc things that you like to do so you can import fonts you can set up css variables and all that cool stuff now in our case we're not going to be that dramatic we're just going to go with body and then we're going to go with font family and i'm going to go with a system one like so and then maybe let's add a bit of background as well just so we can see that it actually works and maybe let's go with red so maybe we will be a bit drastic in the beginning now of course nothing is happening because we haven't imported this css and next i'm also going to style all the heading ones and i'm just going to set them up as color blue and then where do we import this file well since we have a layout and that layout is going to wrap all our pages i think it kind of makes sense if we just import this layout css here now with this one since it is a css file we don't need to specifically say what we're importing however we do need to use the extension so remember how when we use nav bar and footer we simply went with navbar and footer notice there is no js with the css one you need to have a full extension since it's not a javascript file so we simply go with import and then forward slash and then layout and then css now again we don't need to say what we're importing now of course i have my background red as well as the color for the hanging ones now let me mention two things first keep in mind that since we have a inline style in our project it will always be stronger than the global one so even though i said all my heading wants to be blue because i'm using the inline style for the first one whatever color i have here is going to be applied now why am i telling you that because there's going to be cases where you are not setting up the inline style for example you're using a third party library and that library adds that inline css and then it's your job to go back to the source code and check what styles are applied so that way you can either override them or maybe you can just fully understand what is happening as far as the css now the second thing with gatsby version 3 they have this interesting setup where during the development even though contact or i don't know testing does not have the layout component the styles will be applied so previously the setup was following where only the pages that had layout the css was applied that's not a scenario anymore with gatsby version 3. what am i talking about well if i go to about i can clearly see that i still have my footer and bar correct and i have hello from the about page so that makes sense of course the global style is present but why i have the global style also in contact so if i hop over to the navbar and if i add a link to a contact so say contact here and contact you'll notice something interesting so once we save first of all we have a link in navmar that makes sense and then once you press check it out notice how the page is read and if you still don't believe me if we go to the contact and just change to heading 1 and change the text to contact page you'll see that there is no navbar so there's no navbar footer so we don't have the layout but the background is red and of course the heading one is blue so again we will still have to use the layout we'll have to import the layout set up the layout and all that but the global css in usb version 3 is already applied but let me be very clear as far as i tested this is only happening in development so once you deploy your project if the page does not have the layout styles won't be applied while global styles are great and we'll definitely use them in our project as your project gets bigger eventually will run into two issues where you'll have to get creative with a class names because you don't want to have name collisions and second it's going to get harder and harder to manage the global css and in this video i simply want to show you the name collision problem and then in the following videos we'll take a look at the approaches that we can use in gatsby to avoid them and i actually want to start by removing this background red because i do find it a bit annoying and again we have multiple heading ones and you know what in these videos i'll just focus on the about an index.js again eventually we will add layout to the rest of the pages for now let's just work in these two pages the home page as well as the about so in the about i'm just going to change it around and i'll simply say about page and of course i just need to navigate back so let's go to about and for some reason it tells me that there is no page so let me refresh of course everything works and as you can see i have the about page and i have the home page and in both cases i have these heading ones and they are blue and of course in order to avoid that i just need to go with maybe a class of about heading and then i'm just going to say color and we're gonna go with green and we can do the same thing with home heading so home heading and then as far as these ones well why don't we keep them as blue so i'll just remove the global style and i'll set up a color and i'll say color is equal to blue now if we head back to index.js first i guess let's just remove the inline style for these ones and then i want to simply apply this class so where i can apply the class well i can probably come up with a div and inside of this div i'm just going to go with home heading so home and then hyphen heading and then whatever heading i'm going to place inside of the div of course all of them will be blue we can clearly see that and then the same thing we'll do in the bot so let's say here that i'm going to create a div and this is going to be an about heading class name and about heading and now of course if i navigate to about page the heading should be green but it's not so let's see first let's try to refresh that didn't work and maybe at this point i'll have to restart the server so let's go with npm start and then once the server is up and running we definitely should see that green color so that's the thing sometimes in development yes the hot reloading is technically working but once in a while you might need to restart the server and then once you do and once i refresh notice now of course i have the about page and like i said as your project gets bigger and bigger you just need to get really creative with these class names because you want to avoid the name collisions as much as possible and also the second issue is the fact that as your project gets bigger and bigger and bigger it is harder and harder to manage the global css file so in following videos we'll take a look at two solutions that we can use in our gatsby project all right and the first solution that we have in gatsby is built into the gatsby so you don't need to install anything and it is called css modules now i have to be perfectly honest i actually don't use that solution because i do find it a bit clunky and i actually prefer styled components option instead and i'm going to cover that in next video again that is just my personal preference it doesn't mean that it's a bad one i just find styled components easier to use and the way we set up css modules we simply need to create a file by the name of module css now what i'm going to do is in the source i'm going to create a new folder and i'll call this examples and effectively in this folder i'll just dump things that eventually are not going to be part of our project meaning part of our recipe site but just in case you ever want to have a reference you can just find it in the examples so in the examples we'll create two css files and the first one will be home module css and the second one will be about module css so as you can imagine for every page you can create one for every component you can create one it really comes down to your preference so in the examples i'm gonna go with home and naming here is important so come up with whatever name you want so in my case i'm gonna go with home then module and then css so that is the proper syntax and let's do the same thing for the about as well so we're going to go with about module css and if you want to create one for navbar one for footer of course you can definitely do so and then in here we just need to come up with a class and since i don't want to be creative with my class names i'll simply say page so i go with page here and then i just need to come up with the styles so in this case in my page i want to have a color and i'm going to go with blue so all the elements the color will be blue and then let's also set up a text one so that's going to be another class and in this case i'm just going to add text transform text transform and we're going to go with capitalize and just to showcase that we're not limited to only setting up the classes meaning we can use other css selectors instead i'll also write page and planning 1 is going to be color and for time being why don't we go with blue violet so i'll save it here and now i just need to import now since i named my one home module css now of course it only makes sense if i navigate to index.js and then i go with import and this is the difference between version 2 and version 3 where in version 3 you need to be specific of what classes you're actually importing previously you just got the whole object and then somewhere in your code you used it now in this case it is different where they actually want you to name it now you can still import as the whole thing and i'll show you that in the about page but a typical approach is getting the exact classes that you have in the module css file so in my case what classes do i have i have page and of course i also have the text now where is it coming from of course it is coming from examples and then the file name is home module css again since it is a css file you need to provide a full path and then i just need to decide well where i'm going to apply those classes and let's start with the page class well this one kind of makes sense if i'll apply to my div correct and then that way i'll right away style my headings and then this text one well i'll have to create a paragraph and probably add that text class so we go here with class name and then we need to use this dynamic approach where of course now we have imported the class name by the name of page so we simply go with page like so so once i save and once i navigate back home check it out i can see that all my heading ones at the moment have this color now if you don't see it try refreshing the page and then of course i also want to create a paragraph with some lorem text so say lorem and apply the text and of course in here notice how the text is blue why well because i say that everything is going to be color blue but then the heading ones are going to have this blue violet color now if i want to capitalize this of course i need to go back to index.js and i already have this class so the same deal we go with class name and then we go with the text now why it is so powerful because i can do the same thing in about module meaning i can use the same names and just change the value so let me copy this copy and paste and i don't need to come up with about page or home page or contact page or whatever i can simply change these values so for example i'm going to go back to the annoying red one so all the text is going to be color red and then the heading ones are going to be i don't know yellow maybe yellow green and then as far as the text i'm going to go to uppercase so notice how i'm using the same names i'm just changing the values so now of course if i navigate to about again i just need to import we go here import page and then text from and then the module of course examples and then about module and then css and in here again instead of the div why don't we go with a page so that's the class that i have and then of course right below it let's add a heading 1 with hello world just so you can see that it is actually working and we can check it out notice at this point nothing was updated so again at this point we'll have to refresh and there it is now i have about page as well as the hello world and then right below it why don't we set up a text and again this is going to be a paragraph with just some dummy text so we'll use lorem once we save and then again once we refresh it is going to be red why because that's the styling i have in my about module and then lastly if i want to have this uppercase i simply go with text and i add that to my paragraph so i'm going to go back to about and then if we go with class name and then if we say text then of course the moment we'll save and again in this case we'll have to refresh of course our text will be uppercase so as you can see using these modules solves both issues first we don't need to be creative with our class names and yet we can still use the proper css selector so if you come up with one class name you can just say that i'm going to style heading ones or paragraphs and all that and the second thing your files will be way more manageable because of course in here for example i'm just going to apply styles to the homepage and in the about module of course that is going to be 40 baht module in navbar one the styles are going to be for navbar and hopefully you get the gist again it is my preference to use styled components because i still find it a bit clunky but it is definitely a good option and what's really cool it is right away built into the gatsby now lastly i just want to showcase that of course there's also an option where we don't have to name them and we simply do it this way where we go with a star and we say as and then we just need to come up with a name in here i can say about styles now every time i access this one i also need to use about and styles and then class name didn't change so class name is exactly the same but of course the beginning part is different so at this point i'm not setting up named imports i'm not saying hey get me the page or text i'm just saying get me everything i'm gonna rename it as styles about styles and then i'm just going to use this value so that definitely is another option you can do and let me just save the text and let me refresh and showcase that nothing changed and at the very end i just want to showcase that if you navigate to the browser notice the elements so if we go to the gatsby one right now and then instead of the div and then inside of the div notice the class name it is home module and then page and then whatever value over here and the way the modules work effectively they set up these unique class names so that's why i can use the same name in my about module the same as in home module and in any page module that i possibly have so here notice we have this class that i'm styling heading once and the same works for the paragraph where i have that text one again this is a unique class name so that way you won't have those name collisions and if we navigate to about check it out again this is going to be different name for that div so about module and then page and then again some kind of different value and with that said now let's take a look at the styled components approach awesome job we're almost done with the styling and as a last topic in this module i would like to cover styled components now i can tell you right away that we will only be scratching the surface of what styled components can do and we only cover them since in later course projects i'll provide css using styled components and therefore i want you to be aware of the general setup as a side note if you are interested in style components i do have entire course dedicated to style components and you can check it out by visiting johnsmilga.com now the idea behind style components is very similar to that of css modules they add unique class names so we don't need to worry about naming collisions and also provide modularity so we don't need to jam all of our css code in one file what's also interesting in order to add style components to our project we'll learn how to add plugins to our project and you can think of plugins as a way to enhance our project's capabilities with the help of gatsby community so with that said let's first navigate to the gatsby docs and we're looking for the plugins link so go to the gatsby docs and then look for the plugins once we navigate here as you can see we have many many many many many plugins at our disposal and the idea is following where if i have a gatsby project and if i want to add some feature i just go to the plugins get the plugin and basically somebody else in the community has provided that feature for me now there's official plugins so plugins made by the gatsby team they're plugins made by the companies and as an example later in the project we'll use the contentful one and of course since we can create our own plugins there's also plugins made by the community and in my case since i don't want to search through all the plugins just to find the styled component one i'll simply go to the search box and i'll type styled and once we do first option is going to be gatsby plugin styled components that's the plugin we're looking for and what i really enjoy for most of them the documentation is super super well written where they right away tell you everything you need to install everything you need to set up and as a result you are up and running in no time in this case they right away tell us what libraries we need to install what dependencies we need to add to our project so we simply copy this line and then navigate back to our project now we do need to stop the server so press ctrl c i'll clear the terminal and copy and paste and then keep on scrolling and notice how to use we need to add in the gatsby config our plugin and what's really important gatsby config is a node file so this is just a export syntax for node files they use common js that's why we call it module exports we're exporting a object and then in that object we have plugins array and this is important don't rename it to john peter or susan it has to be a plugins that's a must and then we have two options some plugins will be set up as objects if we want to set up more options and some of them will be set up only as a string now in this case they showcase as an object but in fact we can use it as a string so just copy this string keep in mind that these are template literals those are not quotation marks and that is very important so now i have this string and again i'll navigate back to my project and of course in this case i'm going to be looking for my gatsby config and then notice i have my array i just copy and paste and successfully i have my first plugin now every time you install a dependency or make some changes in gatsby config i suggest restarting the server otherwise the latest changes might not be applied so npm start we spin up the dev server and the way we set up style component we simply go to examples we'll create a new file and i'll call this button and more specifically button.js so let me zoom out for some reason i didn't add the js extension and the way we work with styled components we go with import and common convention is calling this styled but it is a default export so technically you don't have to follow the conventions then we go with styled components and the way we set up our styled component we either can go with export default or a named export and effectively we're right away setting up a react component now under the hood it is still going to be a html element and i'll show you that in a second in the browser so in my case i'm going to go with a named export option where i'm going to go with export const and then we just need to come up with the name example button is equal to styled dot and then whatever html element we want so if you want div you just type div if you want article you type article if you want a section you get to just type the section now in my case since i have the file name by the name of button as well as the component name i might as well go with the button and then we go with this interesting syntax of tag template literal now they're not unique to style components in fact they were introduced in es6 but the way style components use them is we simply add here the styles and they will be applied to our react component and in turn our html element so if i go with background and green and also add maybe a color of orange and font size is going to be two rems you'll see that once we render the button all these styles will be applied now quickly i want to mention that if your screen looks a bit different than mine it is simply because i'm using this extension the vs code styled components i believe that was the name style components extension yeah and this extension does two things it adds colors to properties so properties are different color than the value so probably in your case you probably see everything as orange and second it right away checks for the bug so for example if i remove the semicolon right away tells me that hey listen there's something wrong with your code if you don't have that extension then you'll have to debug it yourself so that's the extension let me make this smaller now once we have the button in place and by the way you know what i messed it up i did not save gatsby config so my apologies but i'll have to restart it otherwise i might have to do that later anyway so again i stopped the server control c in this case i have saved all the changes and then i go with start okay now back in our file system of course in the index.js i want to get that button so i'm going to go with import now since it is a named export i need to go with example button from and then of course we're looking in the examples and then the button and then i just need to decide where i want to render it so i'm going to go above the headings and i'll say example button now as far as the text inside of the button we're just gonna go with click me so once i navigate back home the moment i don't see it but once i refresh i should see my button and that's interesting okay now it is so i guess it took a little bit for the server to spin up now of course we can see the button now just to showcase it is still a html element here i also need to refresh so gatsby div and then notice this unique class name that's what's responsible for setting up those unique styles so we don't need to worry about the name collisions so these styles will be only applied to this specific button not to all the buttons that we have in our project and the way we'll use later styled components in our upcoming projects is following where basically i'm going to go to about.js keep in mind that you can do it in any of the components i'm just going to use about.js as an example and i'm going to go with import styled and then of course i'm looking for styled components and then typically i'll set up my style component below my actual component and then i'll just wrap my component in the style component so we go with const and usually i'll probably call them wrapper and then i'll say style again whatever html element you want so sometimes it's going to be a section sometimes it's going to be div and you get an idea so in this case why don't we go with section here and then as far as the styles why don't we copy the ones from the about module css so just grab everything and i'll show you how we can set it up in the style component and a setup in a style component is pretty much just like in normal css since i know that i'm going to be wrapping my component in this style component i actually don't need this page anymore i can simply say that whatever elements are going to be inside of my wrapper well the color is going to be red and the same goes for heading ones i don't need to have this class anymore i'm just going to say all the heading ones that are inside of this wrapper we'll have this yellow green now we can still use the classes if we want in a style component if there is going to be a text class inside of my styled component then of course the text transform will be equal to uppercase now the only thing left to do is just scroll up and then i'll remove these class names we don't need them apart from the paragraph one that one we will add back later but first i want to just change the div to my wrapper so that's my style component and then like i said let's also add a class name of text for my paragraph and we'll save it and of course this is the home page so now i need to navigate to about page and notice how my styles did not change and if i'll change it from red to blue in this case once we save once we refresh of course the text color right now e is going to be blue now why do i find styled components easier to work with than the css modules simply because i like the fact that all my styles are in the same file as my component so that way as i'm setting up the functionality i can right away add the styling as well the reason why i find the modules a bit clunky because you set up the logic and then you need to rush back to the module css file look for the class look for changes and all that now again for some people that's not a big deal but my preference is always to have the styles in the same file and effectively that is going to be the setup in a future project where i will prepare all the boilerplate for you so we won't create the components every time from the scratch it's only in this project in tutorial one where we're doing that and then also with the setup there's going to be a styled component in the bottom with all the styles so we'll simply need to add the wrapper to our component and we'll be in good shape and you'll have all the styles and also you'll be able right away to see what styling i applied to my component now i'm not complaining the default modules option is a very good one it's definitely better than global css but i personally prefer using styled components instead that should do it for the main styling options we have in gatsby and now we can move on to our next topic nice and before we cover data in gatsby why don't we spend some time on our current project so it looks more like this than whatever we have right now and we're going to start with some house cleaning so i'm going to navigate back to my project and in the pages i'll remove that company folder again that was just to showcase how the nested structure works we actually don't need it for a project now if you want to keep it that's definitely your option but in my case i will remove it and visual studio code is concerned but i'll say yes i want to remove the company and the same goes for testing as a quick side note you probably noticed that in a terminal you get this warning so even though i said that yes this is one of the options that you can use when you're setting up the arrow function where essentially you just go with export default and arrow function at this point they right away set up the warning and basically they just suggest using other approach where we set up the name and then we export as default which here is going to be my option throughout the course anyway now why am i telling you that because i want to remove the testing anyway so go with remove and we'll remove that sucker as well now that's a great start then in the components i'm not going to have the layout all the css is going to be in a different folder anyway so yes i want to remove the layout css as well and then one by one we'll add the basic changes to all our pages as well as create all the pages we eventually will have in our project so let's start with index.js i don't want to keep this module one and that was for your reference same goes for the example button and i simply can remove example button as well as this class name now to tell you honestly i'll just have the layout for now with a heading 1 of homepage so i'll say home page let's just keep things simple at this point and since i removed the files and all that it looks like i'll have to restart so let's go here with npm start we'll start it up and then of course next one is the about js again the same deal i don't want the import for the module i also don't want for the styled ones and i have another complaint where the layout.js is of course looking for layout.css so let's remove this one as well and once that one is fixed in the about just of course we don't have the wrapper anymore so remove that one and also i'll remove the whole style component here also wrapper goes and the same deal i'm just gonna leave one heading one with a about page so again let's see yep that fixes it so i have my current navbar home about contact and then i just have hello from footer and effectively this is the structure that i want to set up in all my pages and i guess let's continue by setting up all the pages that we're going to have in our project so if i take a look at the complete one i have home i have recipes page i have tags page about and contact and of course the error so effectively we need to create two more we need to create recipes as well as the tags so since i'm gonna use pretty much the same setup i can just copy whatever i have in the about and now in the pages let's create tags page so tags js as well as new files and we'll call this recipes js so copy and paste now it's probably a better setup if we change the name keep in mind we're exporting as default so technically it doesn't matter but just to stay consistent i'm gonna go with recipes and i always suggest using the capital casing and i'll show you when we work with navbar why it is better and essentially it's because of react hooks but don't worry we'll get there and i'll say here recipes as well i'll just say instead of about page page let's save it okay awesome and then i want to do the same thing in the tags so copy and paste everything and again instead of recipes we're going to go with tags here and tags here as well and recipes will become tags page now since i want to quickly navigate around my project just to see whether everything worked i'll go back to navbar again there's going to be multiple iterations of this navbar so we will have to restructure it a bit later but for now let's just copy and paste and remember that we have tags as well as the recipes recipes okay let's save it and of course i didn't change these values here so that's why i have multiple contacts so tags recipes over here and i can clearly see now all my pages so i have home about contact and of course in the contact page i did not add the layout so that was my bad i guess let's go back to the contact page so where it is over here and now since we already have this setup why don't we copy and paste it's going to be faster so let's go back to the contact select everything in here i'm showcasing the function approach meaning the good old function keyword approach but we'll just change it to a arrow function instead so i'm looking for recipes and i want to change it to contact so let me in this case select all three of them we'll say contact here and then if we refresh of course we also have right now a navbar as well as the footer in the contact page so now i can nicely navigate around and i can see that i have all my pages and lastly i just want to add layout to my error page as well because if you remember i said that error page is just a typical page so we can do all the same things that we do in other pages and again i think it's just going to be faster selecting everything copy and paste and just change the name now if you're wondering why nothing breaks well it is simply because layout of course is sitting in the same place so as we're setting up the files here in the pages this path will always be correct now of course if you'll have nested structure that's a different scenario so say here error and i'm going to do it here as well and then lastly for the heading 1 let's just say error so let's save this one as you can see all these pages are set up correctly and now i just want to test out the error so simply add i don't know whatever gibberish after contact this is going to spit me back this screen and of course now i can see the error page so we have good fundamentals in place and now we can move on to our next task all right and once we have general structure in place now let's quickly deal with styling and don't worry since it's a gas because i won't make you type out dcss we'll simply copy and paste the styles from the final project and if you want to access the styles you have two options probably the fastest one is just going to be using johnsmilk.com navigate there again we're looking for the gatsby project and then we're looking for a recipe site and then click on either the star files or the source code both of them lead to the same place and basically you'll hit the repo now another option of course you can look for my github profile johnsmilk.com or i'm sorry john smilga and then go for gatsby version 3 tutorial recipes and once you hit the repo in the source look for the assets one and in there more specifically look for css and finally you'll hit the main css and i suggest just clicking on raw and essentially these are all the styles we're going to use in the project so just click select all copy and navigate back now again in my case i'll keep the same structure because later i'll use those assets so in the source i'll create a new folder and the name is assets like so then in this folder i'm going to create another one and i'll call this css and then finally in this one i'll create the new file i'll call my one main css i'll zoom out copy and paste and we have all the styles now you'll notice that at the very top the fonts are commented out because later we will use a plug-in to set up the funds and of course i'll talk about it once we get there for time being if you want to have the same funds as in the final project just uncomment the fonts that's all you have to do now of course nothing changed in that project because we still need to include it and the way i'm going to do that i'm going to go to the layout one and instead of looking for the layout css now of course i'm going to go with import and then in the assets folder css and again the file name is main css and the moment you save notice right away we have the styles now i also prefer using normalized css in my projects keep in mind this is nothing to do with gatsby it is just the thing that i like to use now if you're not familiar with normalize effectively it preserves useful defaults and tries to normalize the styles across the browsers basically it gives us a safe starting point and if you're familiar with css reset it is just a nicer version of this one you probably have seen this one margin zero padding and then zero and then box sizing border box normalize just uses way more complicated setup than that so i'll remove this dummy code and if you want to use normalized just quickly go to normalize css now you can click on download and you're going to get entire css code and you can create a new file that is definitely an option and then copy and paste whatever code you have over here or you can use the npm module which is going to be in my case so i'm just going to copy this line of code i'm going to navigate back to my project stop everything clear the console copy and paste install normalize css again this is the case where i don't need to set up anything in the gatsby config i don't need to set it up as a plugin because this is not a gatsby thing effectively this is a reacting and of course i just need to navigate to my layout and before i import main css i'll also import my normalize so in here i go with import and then i look for normalize and css that's all we have to do and the moment i import my normalize as well i'm just going to restart this server and of course normalize has been added to our project and once that is out of the way now of course we can move on to the next step beautiful once the styling is in place now let's knock out some components and we'll start with the basic ones so the ones that don't have any queries or images and once we have more knowledge about gatsby then we'll complete the complicated ones as well and i guess our footer can be a great starting point so if you take a look at the complete application of course you can see the footer and this is going to be our first component and i'm going to navigate to the footer that's my component and at the moment i just have this footer tag with a heading 2 and instead i'm going to use the class so i'm going to attach the class that is coming from my global css class name is page footer and then as far as the return there's going to be a paragraph and first i'm going to use this html entity where i do want to have this copy one and once i save i have my black footer as well as the copyright symbol and then after that we're gonna go with date now first i'll hard code this and then in a second i'll show you how we can make this dynamic then we have a span and a span we'll simply write the name of the site so in my case that is going to be simple recipes then right next to this pan we are going to have a text and text is going to be following built with and why don't we use the href so why don't we use the simple link element because i want this link to navigate to external resource more specifically gatsby site so let me go back here i'm gonna go back to the main site and then i'll just copy and paste the url here in the href and then we'll simply place a text and i'll simply write gatsby we save it that's our look and then the only thing that is actually missing is the dynamic year now since we know that we are of course working in the jsx in order to go back to the javascript plan we just need to set up the curly braces and then we can just use a javascript date we can go with a new date so that gets us the date and then we can go with get full year which is a method that of course gets us a full year and that way we don't need to come back every year and update the hard-coded value will always display the correct current year as far as the css if you're interested in styles that i set up just navigate to main css and use the shortcut command f and then just type whatever class name so in this case of course you have page footer so these are all the styles that i applied to the footer and the setup for next component is going to be the same we're basically we'll be working on our return and we'll just add the classes so that way we can save some time on typing out the css and lastly i just want to mention that the site doesn't look exactly the same as the complete one because of course we need to work on the other components as well so eventually yes the footer will be all the way in the bottom and it's not going to be hanging out by the home page but we just need to add more components and add more css and then we won't have those issues and once the footer is in place our next step is going to be our error page so let me navigate in complete one and there it is so place a 404 some text and we'll be in good shape so first i'm going to navigate back i'm going to close all the files and then i'll open up the 404 then i'm going gonna close the sidebar and i'm also going to remove the finder and then we'll still have a layout but we'll have a different structure where there's going to be a main tag with a class name of error and page and then inside of this main let's place a section and then instead of the section we're going to have a heading 1 with 404 and then also a heading 3 page not found that's it we save this one and now of course we want to test it out so in the browser let's navigate to the error like so now of course we don't have the page for that so then we open this up and of course we have 404 page not found awesome that concludes the error page all right and our next step is going to be a contact page and basically here we have text on the left hand side and then a working form on the right hand side now for the time being we'll just set up to return and eventually we will add the service that takes care of the form submissions but for time being let's just not worry about form submissions and just set up the return now as far as this component we'll work on this one later because here we're fetching data from contentful and in fact we are reusing this component all throughout our application if you take a look at the about it's the same component it's actually the same component in recipes now i know there's more recipes right now but of course we'll make our component flexible where we just pass in the data and then the component displays those recipes same one is used in home here as well as the tags so if i go to a specific tag this is the same component again less data but same component so once we create that component once we understand how we can fetch data from the headless cms then of course we'll add it to the contact page as well so let's navigate back and i'll open up my sidebar and of course i'm looking for the contact page and then in contact inside of the layout i just want to place a main first and we're going to add a class name of page like so and then inside of the main we have a section with a class of contact page contact page and then inside of the section we have those two articles so one is going to be a form and the second one is just a text so i'm going to go with heading 3 and in order to speed this up i'm just going to copy this i'm not going to write it now if you're interested on where i'm getting this text my preference is using hipster ipsum and the site for that is ipsum and then you come here and you just say how many paragraphs you want in my case of course i'm gonna go with five and then if you want you can start with i'm baby if not then of course you can just unclick it and then you bear me and of course there is this is the text again in order to speed this up i'll simply copy and paste the values from the complete page so that way you don't have to watch me type out the text so this is going to be my heading and then i'll have three paragraphs so essentially three paragraphs one after another and i have this one as well and then i have the third one right so copy and paste and then the sucker as well of course i have my heading as well as three paragraphs now i said that i'm going to add two articles and for some reason i skipped on that one so let me add an article i'll add a class name here and i'll say contact and then hyphen info and now let's place the headings as well as the paragraphs inside of this article my bad let's do it and once we save then of course i'll create another article and in this case there's going to be no class and then inside of the article we're going to go with form tags and then we're looking for two classes form and contact form and then i'm going to remove the action because we'll work on this one later we're not worried about it right now and then we have a form row and instead of the form row we'll have a label and the input and effectively we'll have three form rows and as i said i need to fix this bug this should say email and also of course we'll have the submit button as well so let's navigate back and then like i said for every input there's going to be a form row and then inside of this div there's going to be a label so we're going to go with label and as far as the html4 well it's going to be name because of course the id on my name input is going to be named so say your name and then input now type in this case is going to be text and then we'll have name is equal to name and then id is also equal to name and once i save that's our first input and in order to speed this up i'll copy and paste our entire div and then i'm looking for the name and i just want to change it to email so i'll use command d again to get all the instances of this one and i'll change it around to email now there's one bug this shouldn't be email should be name so let's save it now of course we have the second one and the third one will be our message and that is going to be a text area so this is not going to be the case where i'll copy and paste i'll simply say form row and then inside of this form row let's add another label now this is going to be for the message so let's write the text message as well and then right next to the label let's just go with our text area and i did already set up the css so we only need a name so i'm going to go with message and then the id also message but as far as the columns and rows that's controlled by the css so i'll just remove it and then like i said eventually we also want a submit button so we just go with button and submit now i do want to add some classes here and the class names are btn and block and then instead of the button write whatever you want so in my case i'm gonna go with submit so once we save that is our contact form so let me go here and check it out so that's my home page of course i have the contact page okay awesome as well as the error page so let's see this sucker here as well and of course that's my custom one and yes and with this in place i think we can tackle a bit harder component and that is going to be our navbar nice congrats on completing our first three components i think we're in good shape and we have finally arrived at the navbar component now before we start typing away we do need to get some assets because if you take a look at the navbar there is a logo so there is going to be a imaging navbar as well as on a small screen we have the button and then instead of the button there's actually a icon now for my assets i'm going to get them from the complete project because i already have the logo of course and when it comes to icons i prefer using react icons but you don't have to if you have your own assets if you have your own logo as well as you have a preference for icons you can definitely use your own assets nothing stops you from doing that now the only thing yeah you might need to change some css around where maybe your i don't know logo is bigger or maybe your icon is smaller and something along those lines and as far as getting the assets simply navigate to complete project so again i'm going to go to my github i'm looking for gatsby version 3 tutorial recipes and then at this point i'm just going to get the whole project so i'm going to clone it and then in the project i'm looking for the assets folder so i'm going to navigate back and i said i actually don't need this one open because once in a while it kind of opens up the window that's a side note but while you're recording it's just the email pops out so we're gonna go with cd and stop like so git clone and i'm just gonna clone it here so that's my recipes and as a quick say note it is actually a working project so if you want you can open up a new window and just drag and drop and then i purposely left all my credentials as far as the headless cms because that way you can definitely see that the project works so first you just need to run npm install and the second one will be gadsb develop now keep in mind that it will spin up the dev server on localhost 8000. so of course it's going to ask for a different port so let's spin this up while i'm installing dependencies i'll simply go to the project here and then in the source i'm looking for this whole thing so i have the assets i have css i have some data which we're going to use a little bit later and i have the images so i already have the css folder so simply take these two folders and i'll just copy and paste and set them up in my tutorial so in here i'm going to go back to the source i'm going to go back to the assets i'll zoom in so you can see better and i'll just copy and paste now i have the data again something we'll use later and then the images so notice this is my logo svg and then i have some images that we're going to use later as well as a quick side note as you can see it's a extremely basic logo and yep notice here it says can i use a different port and of course i'll say yes and back to the logo like i said it is extremely basic logo that i just made infigma i've been getting questions how you can make such image i just went to figma and just typed out the text and added different fonts and colors and all that that's it that's all i did and as far as the icons i prefer using react icons but again this has nothing to do with gatsby that's just my preference regardless whether it is a gatsby project or not and i simply like them because they have tremendous amount of icons and you actually import them as a react component and what that means that you're going to add a class you can have all kinds of effect and it's straight out of the box so you don't have to do anything and you simply install it as a dependency so again the command is npm install react icons now their site is react hyphen icons github io and what's really cool that you can basically search for the icon so for example if you want to have a person icon use that person and notice how you have all of these options and the way the syntax works you install of course which we're going to do in a second then you import the icon so that's going to be the name but then you need to be specific from which library because notice these are all the libraries they use so you import the icon specifically say which library this is going to be from and then you just stuck it in your code and everything works i mean it's as easy as it gets now they do show two installs one straight up react icons and then the second one with all the files but i don't think we'll run into this issue since we literally need four icons and therefore i'm just gonna go with a first option so copy and paste this command of course you can actually copy here to the clipboard as well then navigate back to your project stop the server copy and paste again we don't need to do anything in the gatsby config and if you want to take a look how it works let's just go back to the navbar and i'll show you which icon we're going to use so now of course we need to spin up the dev server let's say npm start and then we're looking for import and then the icon name is f i and then align and justify justify and this is coming from react icons that's the main library and then specifically the icon library is this one the fi and like i said it is a component so i can simply stick it in my return and i'm going to be in good shape so we just go here with fi online justify and then once i save and probably i'll have to refresh as well there it is that's my icon and again what's really cool it is a react component so if you want you can take a look at the source code and you'll see that we're getting a svg and what's also really cool is that if you want you can for example add a class and then style it and all that cool stuff so again a very very cool library that i use not only in gatsby projects because it's very easy to get up and running it has tons and tons of options for the icons and at the end of the day they are react components so working with them is really easy and finally let's just go back to our localhost i believe it's going to be 8001 right here and i'll show you that of course you can have a complete project so 8001 and there it is that's the complete site so if you ever want to compare your code to mine just get the complete project and you're going to be in good shape all right and our last simple component is going to be a navbar component but since it has toggle functionality we'll split this up in two videos first i want you to navigate to navbar.js and let's just start from the scratch so remove everything and we're going to return a nav element then we want to right away add the class so go with class name and it's going to be a navbar then inside of the nav we're going to have a div with a class of nav center and then instead of this nav center div we're going to have two more we're going to have nav header one so this is where the image as well as the button with icon is going to sit and then right next to it we're gonna go with nav links and we'll add a show links class as well so there's another div with a class of nav links and for time being since i want to showcase how the links are going to look like i'll also add this show links class now eventually this is the class that we're going to use to toggle our links on a small screen so we have these two divs and let's start with a header and in a header the first thing that i want to do is add that image and as far as this logo will do the traditional react way just so you understand that it is definitely an option and then in the following videos of course we'll cover how the gatsby image works and what kind of goodies we get when we use gatsby image for time being we'll just go the traditional react route where we first need to get the image so we need to import it and then just set it up in a source again a straightforward react way so we go with import then we need to come up with the name so in my case it's going to be a logo and then we're looking in the assets as well as images and then finally we have logo svg again it's not a javascript file so we need to provide a full path and then inside of this nav header i want to place my logo now we can just place the logo directly or we can place it in a link and just to showcase that we're not limited to setting up links with text that we can also set up a link with images if i navigate to tags and notice if i click on my logo i navigate back home so in order to do that we simply need to go with link component then we need to pass in the to prop so where we're going to navigate and that's it we just need to place our link so i'm going to go with img and then like i said for the source let's place in our variable so our logo and then as far as the alternative will just say simply recipes let's save that one that should do it now of course we have our header and then right next to my logo i want to have my button so i'm going to go with button and then inside of this button i want to place my icon so i'm going to go with a icon knife again align justify and as far as the class is i'm just going to go with class name and we're going to go with nav btn now eventually there's going to be also on click but not for time being so that should do it for the header once we save notice this is going to be our logo and if i click notice how i navigate back home and then also i have my button and now of course i want to set up my links now as far as the links you can place them in our list if you want but the way i set up css and everything i simply dump those links in this div so here let's start with a link component and two prop and we're gonna have a forward slash and then as far as the text let's go with home let's save it and then once i have my home link in place now i just want to add few more attributes first of all i want to add a class name so we get the styling so this is coming from my css i'm going to go with nav link and then i also want to add a attribute by the name of activeclassname so this is coming from the gatsby and what it's simply doing notice how once we navigate to the page well the link that represents that page just changes the color now again you can set up whatever css you want but basically gatsby provides this active class name attribute and then whatever class name you pass it in it's going to be applied to the link that represents the page so just to showcase if again you navigate to i believe which one was it main css sorry got lost a little bit there if you go to active and then hyphen link so this is going to be the class that we had notice the css again sky is the limit you can add whatever css you want but basically gatsby behind the scenes the moment you'll navigate to that specific page if you add the active class name the active link it will dynamically add this class to the link so here whatever you set up is going to be applied to the link so now let me go back i'll close the sidebar and then i'm going to go with active class name that's the prop that you need to pass it here and then we're looking for active and then link and once i save notice how it changes the color now eventually there's also going to be on click similar to what we're going to have on a button but for the time being why don't we just copy and paste the links and we'll worry about the functionality in next video so now just copy and paste and the first one will be to the recipes so we just need to change the two prop of course and then the same goes here for the value we go with recipes and notice how this one doesn't have the color but the moment we navigate the recipes of course now we have that color applied to this specific link then we'll copy and paste two more times i believe so we have tags and about and the contact one is going to be a bit different because if you take a look at the complete project it has a different styling so for time being let's just copy and paste two times so we have one two homepage then the second one we have i believe it was what it was for the recipes of course and then we have one for about and then we have tags as well so let's scroll up so we have home recipes then let's add those tags and then of course the path also is going to be to the tags and then eventually why don't we set up here about and then as far as the text it is also going to be about so once we save there it is we have more links now and everything looks pretty cool and now of course we just need to add that contact link as well and i want to place that content link in a div and it's going to have class of nav link as well as contact link and again this is just for different styling and then we're gonna have a link and then again to prop so this will still direct you the contact page so we're gonna go to and then contact now i do want to add a class name of btn and then eventually again there's going to be on click but we're not going to worry about it right now and then let's just add a contact and that should do it now we have a nice looking navbar and if you want to test it out on a bigger screen let's just refresh again custom page okay awesome that's our error one and this is the look on small screen again we right away showcase them eventually we'll have the toggle functionality and then once the screen says gets bigger now using css we'll hide the button and we'll also change the layout of our link so that's the look on a small screen without the toggle and then this is going to be a look on a big screen one last thing that i like to mention normally in my project i don't like hard-coding my links so normally i set them up as some kind of array in a different file and then just iterate over however for our first project i thought that's going to be an overkill so don't worry we will do that in a later project but in this project i just thought that it's going to be a bit easier for all of us if we hardcode them again biggest takeaways this is just a straight up react approach where we import a image and then we set up the source for the image tag and then as far as the icon i just placed the inside of the button all right we're done with the simple nav bar return so now of course let's set up the functionality and if you take a look at the main css you'll notice that for the nav links by default they're actually hidden so the height is zero and overflow is in and only if we have this class of show links then we add a height and of course at the moment we're doing that manually so for example if i remove show links we're not going to see the links but if i add them back up and of course we can see them again now the idea is that we'll set up a state value here using use state and then we'll just toggle it so based on that value we'll either show links or height links and before we continue let me just stress something i fully aware that this is technically cheating because i'm hard coding the height meaning if we'll change the amount of links we have of course css will also be affected now if you took my react course you probably worked on the projects and you know that in one of the projects we actually covered how we can make this dynamic however for the gatsby tutorial i thought that it is going to be an overkill so i just thought that this is going to be a easier setup and back in navbar first i want to get a use state hook from react so we're going to go with use state and then i just want to set up that toggle value and i'm going to go with const and i'm just going to go with show and set show and that will be equal to use state and then by default it is going to be false and now of course i need to scroll down where i have the nav links and i need to make this dynamic so instead of adding both classes right away i'm going to go back to the javascript land and i'll say if show is true and as you can see i'm setting up the ternary operator i'm going to go with nav links as well as showings so if the value is true then i have both classes if not then i'm just going to have the nav links class so now links class over here and then once i save of course links are hidden so now our job is of course to add on clicks on the button as well as the links and i'll show you why i want to add on the links as well so here let's go with on click click now we do need to set up of course here the arrow function otherwise it's going to run instantly so i set up my arrow function and we go with set show and then whatever is the value in the state we'll just pass in the opposite so i take my function and then whatever is the current show value i just pass in the opposite and that way we get the toggle functionality so now of course once i click check it out now of course we can see the links so we check the state value and if it is true then i have both classes if not then there's only one now why do i want to add on click on my links as well well because on a small screen what i want is the moment i click on one of the links so basically the moment i navigate to one of these pages i just want to hide those links i think that's a better setup so here we simply need to copy our on click keep on scrolling keep on scrolling and then this is going to be our first link the home one and then we go set show but in this case i don't want to pass in the opposite i simply want to pass in the false because i know that i can only click on those links if the navbar is already open basically if i can see those links so now of course we grab this value and just copy and paste so one by one we just add it to all the links now technically if you don't want that functionality you don't have to add the same click but in my case i'm going to do that so let's keep on scrolling and then all the way in the bottom we have the contact one as well copy and paste and we're in good shape where we also have the toggle functionality so now once i click on tags check it out not only i navigate to the tax page but i also hide the links and then if we take a look on a big screen notice this is going to be our navbar of course notice how we're adding this class dynamically using the gatsby goodies and then once we go to the small screen of course there is our button and then like i said if you want to take a look at the css you can check it out how i'm hiding right away button on a big screen and it only appears on a small screen that should do it for navbar and now of course we can start talking about images in gatsby all right we're done with the simple components and next i want to cover how gatsby handles images and if we're being honest in a typical web project images can be a real pain and oftentimes are solely responsible for slow load times and bad user experience but fear not gatsby is here to save the day and before we start tapping away let me just demonstrate some of the goodies gatsby offers straight out of the box so i'm currently staring at the complete project and i'm going to go to the dev tools and more specifically network tab and you know what i'm gonna make my sites lower and i'm gonna go with 3g so i'll refresh and you'll notice something pretty pretty cool where check it out gatsby actually preserves the size of the image so you don't get that annoying jump because you know that if browser is waiting for the image but there's some content underneath it then the content first is on top and then when the image comes in then of course everything is pushed down because now of course the space is taken by the image so that's number one number two notice the nice placeholder that i have for the images so i have this nice svg placeholder pattern and then while the image is loading the user sees the placeholder but then the moment image loads then of course the image is displayed then if we take a look at the elements we'll say something even more nifty so i'm going to go to the elements and we're going to take a look at the page and then more specifically section recipes container so i'm looking here and then recipes list so i just want to showcase these three images so this row and in here you can see that okay all of them are links that's fine but we also can see this div now this is going to be a wrapper div so effectively when we'll work with gatsby image plugin that's the plugin we're about to use it wraps our images in this wrapper and then if we inspect this wrapper even more we can notice the picture tag so we have this picture element and also we have a source element and more specifically source set attribute now if you're not familiar with source elements in short they provide different sources for the browser to choose from so gatsby created multiple sizes of the same image you can see it over here again in the source set notice this is the same image but gatsby provided multiple sizes then browser pricks whichever size makes the most sense and a result we are not forcing a huge images on smaller screens so think smaller devices and what's super super super nifty we get all of these and other goodies with very little config we simply pass a path to the gatsby component and we're good to go yes that's how easy it is and lastly i just want to mention if you're interested in learning more about responsive images essentially all this gibberish that is written here i highly suggest this resource so go to your search engine just type responsive image mdn then follow this link and in this well written article you'll find about all the benefits that the picture element the source element as well as source set feature provide okay in next video we're going to install gatsby plugin image but before we do that i want to create a little sandbox where i can demonstrate some of the features side by side now this is optional eventually it's not going to be part of our project and i'm simply setting this up so later if you ever need to you can go back and find the reference if you don't feel like setting up the examples component just kick back relax and watch me struggle and since i don't want to over populate our current project what i'm gonna do is just open up my sidebar and then in the examples i'll create another one i'll create the images component and then i'll render it i guess in home page because it's just going to be easier as far as navigating around my project and then once we're done setting up the examples of course i'll just remove it from the homepage but the images component of course is going to stay here so if you ever need to you can go back and take a look at the reference so in the examples like i said new file let me zoom in and i'll call this images js all right awesome then i'll create a new component of course and it's going to be called images and for starters i guess i'm just going to get styled components because i'll add a little bit of styling over here so i'm going to go with import styled from let me close the sidebar and of course styled components i will call this wrapper so const wrapper is equal to styled and again it doesn't really matter but i'm going to go with section here and then let's just add this wrapper like so and then let's just add a text with i don't know heading two and let's just say gatsby image let's save this uh let's just list it out whether we can see it in a home page so i'm gonna navigate of course to my index.js i'm looking for import one for images from and you guessed it of course we go to examples then we go to images folder and right below or above doesn't really matter in this case we're just gonna go with our images component okay we save it and then of course i have my gatsby images we are in good shape but i'm gonna do something a bit extra where i'm going to go to the pixels to one of the awesome websites you can get nice images and i'm just going to download a massive image again this is optional you don't have to do that but i just want to demonstrate how the typical project is going to look like so let's go back and i'm going to open up a new tab i'll say pixels and then once it finally opens for some reason it just decided to quit on me i guess i'm going to go with food and then i'll pick any of these images so i'll pick the first one and i purposely go in with original size so i want to get this massive image let's do a free download then i'm gonna go to my downloads and i just need to find the sucker somewhere here and i'm gonna call this a big and then let's just say big you can add image if you want but i'm just gonna leave it as big so move it out and then of course i want to place it in my source in the assets and in the images so and drag and drop and let's just first right away check the size for the sucker so i'm going to go here and notice it is 2.5 megabytes that's good to know and now let's see how that is going to look like in traditional project so let me remove this tab i guess we won't need it anymore we simply go to our images since this is going to be our sandbox and i'll say import big that's the name and then i'm looking in the assets then more specifically images and then i go with big and i believe the extension was jpeg and now above the heading 2 i just want to display that image so i'm going to go here with img source and big and as far as the alt let's just say food and once we save of course we can see the image but just to hammer my point home i'm gonna go with image so i'm selecting all the images that i have in the wrapper and i'm gonna go with width of 200 pixels so technically using css i will make it smaller correct so now of course the size of my image is smaller but here's the million dollar question does that mean that we'll be sending a smaller amount of bytes over the wire since we know that our image is actually massive or we'll be still sending 2.5 megabytes well i don't know let's test it out so i'm going to go to the bigger browser window and of course i'll refresh okay first we definitely see this jump we see that while the image is still loading we have this gatsby image underneath the home page but then once we're done then of course we push it down so that's the jump that i'm talking about and the second thing well let's see the size of it i'm gonna go with inspect and then i'm gonna go to network i guess i'm just gonna right away go for images refresh and surprise surprise so even though in my css i set up my image to be 200 pixels i'm still sending 2.5 megabytes over the wire and i fully understand that you can make a reasonable argument that it's probably not the wisest choice to use these type of images to begin with with such sizes and i get it understand this is just for demonstration i just want you to see the difference when we use gatsby image plugin beautiful once i have my image sandbox in place next i want to install gatsby image plugin now if you were not following along with the previous video you do have to follow along with this one so make sure you do install the plugin otherwise when we'll need to add the images to our about as well as home and setting them up with headless cms nothing is going to work and of course we already know where we need to go we need to go to gatsby site then we're looking for plugins but there's a major major catch do not do not install this one gadsby image because this one is with version 2. so when the version 3 came out they rolled out a new plugin and the plugin you're looking for is gatsby plugin image even though this one has more downloads again the reason for that is because this was used in version two now in version three they rolled out a new plugin so bravely either search for it here or just click it it's going to be probably one of the top plugins and once we navigate here you can probably right away open up the link the gatsby image plugin reference so i'm going to open this up in a new tab we will use it quite extensively in following videos and then let's start with an install so i'll just copy this whole line of code and then i'm going to go over why we have that many plugins so let me go back to our project and stop the dev server clear everything copy and paste and just like with our previous plugin the styled components one we actually have multiple plugins so basically we get the gatsby plugin image okay then we have two that are providing all the goodies so we have plugin sharp and transformer shop and then we have one for the file system now we'll cover this plugin more extensively a bit later when we start setting up the queries but this plugin is responsible for interacting with a file system and this is a pattern that you'll see quite often where just like npm dependencies they have dependencies on their own so the same works with gatsby plugins effectively we have the main plugin where we're going to get our components that we're going to use but of course this plugin depends on some other ones as well so that's why we need to install all of them and as far as gatsby config like i said we will cover the source file system more extensively later so that's when we'll actually set it up as object in this case you don't need to even set it up in gatsby config you simply want to add plug-in image plug-in sharp and transformer shop so grab all of these suckers here one by one and notice how none of them are set up as object they're simply strings we navigate here and then of course we need to go to the gatsby config like so and we already have plugin styled components okay awesome then just add a comma and copy and paste so let's save this one and now let's go with npm and start let's spin up our project if we don't have some massive red errors in a terminal we are in good shape and we have successfully installed gatsby image plugin nice and once the plugin is in place now let's take a look at our options so if we keep reading the plugin documentation we can see that gatsby image provides two components and those components are static image and gatsby image now gatsby image is used for dynamic images and we'll use it later when we fetch our data from the headless cms and the static one as the name already suggests is used for static images so basically those are the images that will be the same each time the component is used and a good example is our hero so this one in home page then the same goes for about but then when we'll be fetching recipes from the contentful we'll be iterating over our recipes and every time we'll call that gatsby image that image is going to be dynamic now don't worry the setup for both of them is extremely similar the only difference is that with gatsby image we just grab the data from the query something we haven't covered yet but as far as the customizations i mean the setup will be extremely similar so for now let's put the pin on the gatsby image let's work with a static image but i can guarantee you once you understand how static images work you'll have no problem switching to the b1 instead so again let's go back this is the documentation and we simply need to import static image from gatsby plugin image so similar how we imported link from gatsby in this case we have gatsby image plugin or plugin image i guess more correctly and we're importing this component static image and then we just need to provide a path in the source and what's interesting we have two options we can either provide a local file so that's why under the hood it uses that source file system plugin that we covered in the last video or we can actually provide the url so that's also cool where we can provide an external route but again the main idea with the static one is the fact that the image will be the same each time the component is used so i guess the only thing that's left to do is take it out for test drive so i'll simply navigate back to my project again i'm working in the images example and then i want to import a component again the name is static and image and then of course it is coming from gatsby plugin image and then i'm going to delete the big one i don't think there's any need for it we just need to go with static image then the source prop and again we need to provide a path to the image so since i want to speed this up a little bit i'm just going to copy and paste again this points back to the same image and then the second thing we need to provide is alt prop and here we provide a text explanation of the image so we save and then check it out we right away get this image however now it is wrapped in that gatsby image wrapper with all those goodies so if you want to test it out we can navigate back to the big browser and i'm going to be in the homepage and notice how we don't get the jump we right away get the placeholder now we don't have the svg yet don't worry we'll set it up in a second but we already have all those goodies the moment we provide the path and if you want to see even more cool things than just navigate to the network again you're looking probably for the images or you can look for all and then just look for the image check out the size is this 2.5 megs no it's not of course it is much smaller so right away without doing any extra work just by passing the path into the static image component we are in good shape we get all these extra benefits and just to showcase that we can use also external images i'm gonna go to my course api site and essentially this is the site where i provide all the apis for my courses and i'm gonna look for the slides this is where i keep the external images and again you can choose any of them in my case i think i'm gonna go with this one then copy and paste the url then back in the project copy and paste the static image so let's set up two of them and of course i'll provide that new path and as far as the food well it's not going to be food it is going to be code and once we save it of course we can see that we get our image and before we take a look at the various customization options we have with the static image as well as the gatsby image i quickly want to mention that there are restrictions on how we can use static image and this is the case where we're going to switch from the plugin docs to the actual documentation so just go to the docs and then we have to we have reference guide as well as how to guide so in this case i'm going to look for the reference guide and then more specifically we're looking for gatsby plugin api and essentially it's going to be the same link that i opened when we navigated to the plugin docs so it's the same place and basically keep on scrolling keep on scrolling these are shared props which we're going to cover in the next video i just want to show you the restrictions so notice where they say this does not work and effectively we cannot provide this path as a prop so you cannot go back to the images and then set up a prop where you're going to be getting the path and then pass it from the home page that does not work that's not how you can use the static image and also what we cannot do is get some kind of prop value because like i said in the next video we will cover the props and how we can use the props to customize our image but as far as the values for these props they have to be in the same file so you cannot get them from somewhere outside so basically both the path to the image as well as the value for the props need to be set in the same component so you cannot just randomly get this value from somewhere else and expect that everything is going to work now you can add some dynamic features for example in here they say how you can calculate the height yeah that is allowed but notice all these values are still here they are still within the same file it's not like you're getting them from somewhere else and once we have covered restrictions now let's take a look at the props we can provide and how we can customize our image nice hopefully we are good with restrictions so now let's scroll back up and first let's take a look at the shared props and like i mentioned before the following props can be passed to both get the image which we're going to use a little bit later as well as the static image and we may also pass just any valid image that props that is also a option because at the end of the day there is the image element somewhere inside of that wrapper and then as far as the shared props we have alternative actually e is required so if you won't pass it there's going to be a warning that's just for alternative text we also have as prop where we can change that element if you remember initially when we set it up it was a div that wrapper but you can set it as a section as an article or whatever we have a loading one by default it is going to be lazy now if you want you can set it to eager as well then we have two class names one is going to be for the wrapper so if you set up class name and then i don't know about img that about img class is going to be added to the wrapper and then if you go with img class name prop instead then of course this class will be added to the image and effectively that just allows you to avoid all the hacking you simply add those class names and then you can target them from the css we can add inline css again this is going to be for the wrapper in line css and this is going to be for the image then we have a background color if we ever want to which is going to be applied for the wrapper as well as object fit and object position okay hopefully we're good with the props and don't worry of course we'll use it in examples as well so i'll just leave it at that and let's just keep on scrolling and now we have image option and like i previously mentioned yes there are some differences of how we can pass in those options and it's simply because for the static one effectively we're hard coding we just set up the component and we pass it in we as a dynamic one will be getting that data using graphql and of course it will make way more sense once we get there and options itself we have a layout which probably is going to be the most important one because with this option we'll determine how the image is gonna be resizing basically we have fixed option we have full width and we have constraint and as you can see again we have some defaults so the image that we currently have is actually constrained because that is the default now the only thing why they're so small because if you remember i added in a wrapper the css so that's why the size of them is 200 and as far as the other ones we have aspect ratio we have width and height so of course you can imagine that you can control the width and height of the image this is the placeholder one remember the svg pattern or dominant color or there's also a blur option well this is where we can control that and by default it's going to be dominant color then we have multiple formats and of course you can experiment with that but in my experience the default setup works really well as well as transform options and then if we keep on scrolling keep on scrolling then notice we have the layout one and again this probably will be the most important one that's why they have a awesome awesome visual representation so notice the first one obviously is going to be the fixed one and that one stays fixed regardless of the screen size but when we take a look at the constrain one and full width the difference is following where full width is always going to be the size of the container regardless whether we're talking about the phone screen or we're talking about the desktop now with the constrained one yes it is going to be the size of the parent container however once the container gets bigger than the image then of course it will just maintain the original size now that should do it for the theory part now let's apply this knowledge in our sandbox beautiful and once we're familiar with our options now let's navigate back to the images and i think at this point i can just remove big for good so my big image and then i'll do a bit more house cleaning where i'm going to go with different image just because i want to show you something regarding the constraint layout so you know what at this point i'll remove everything i'll just set up wrap or clean and instead i'm going to go with static image i'm going to go with the source and then pick one of the recipes once so i'm going to go with recipe one but just go with these ones since they are not that big and that way we'll see features of the constraint layout so i'm going to go to source again i need to provide the path i'm going with assets here images and then the file name is a recipe hyphen one and a jpeg now as far as the alternative i think we can go back to food here and then i'll save it for time being okay notice if you get this technically error once in a while don't worry about it just close it and then refresh now of course we have our image now i want to remove this css selection and we're not going to use it and then inside of the wrapper eventually we'll set up a three column layout where i'll show you the fixed one the full width as well as the constraint one side by side for now in this video we'll just work with the constraint one and that's why i'll set up here a heading 4 with the text of constrained and then default so we know that that's the default setup so once i save check it out now of course the image is much bigger because we're not targeting from the css correct and i guess let's start adding those options to our static image and again we simply need to provide them as props so let's do it we can go with the height and i can say 400 and the moment i set it up again unfortunately there's going to be this tiny error there for a while and then we get the image so that works we know that we can add the height now if you want you can add the width as well just keep in mind when you set width and height for constraint you're actually setting max width and max type not fixed values so if you want fixed values you might as well go for fixed layout instead but yes if you want i can add 100 pixels here and save it now of course my image is going to be smaller like so so we refresh so now i have a tiny image that's good i guess i'm just going to remove it and then we have remember a placeholder so this is the pattern that we can show while the image is loading and in here we have blurred we have dominant color we have none as well as traced svg and if you remember dominant color was the default one so in this case i'm gonna go with traced svg don't worry we will cover the other ones later as well then i'm going to set up a layout just keep in mind that constraint is already default so i'll just showcase how that works we're going to go with constraint but as far as our logic well nothing is going to change it's still constrained so it doesn't really matter and then eventually i just want to showcase how we can add the class name and i'm just going to go with example img and if you remember this class will be added to our container and you know what why don't we try one more remember the as prop let's keep on scrolling that was the options one and here we had as so why don't we try this one why don't we say as and i'm going to set it up as a section so we're going to go here with a section so i have an article inside of the article i have heading 4 and then i have my static image and as far as the styling well i'm just going to add some border so you can clearly see how the constrained one works so i'm going to go with width now this is for the whole wrapper and we'll set it up as 70 of the screen with and we'll add some margins here zero auto so it's always going to be in the center and then we're going to go with article basically i want to style the article and for some reason it's just a tag that's not what i wanted so i'm going to go with article and then i just want to add the border and then you'll clearly see how the constraint and full width option work and we're going to go 2 pixels solid and let's go with the red because why not and then of course i also want to add a little bit of styling to this class because remember we add this class to the container so why don't we use it and in this case i'm just going to add some border radius to my image so let's go with example and then hyphen img and we're going to go with border radius and let's go with one rem now i think it's going to be easier if we take a look at on a big screen so let's navigate there localhost 8000 we can refresh now eventually i will open up the devtools but i just want to showcase how it's going to look like on a small screen so on a small screen notice how the image is spanning exactly the size of the container and let me see my zoom number yeah it is 175 but then the moment container gets bigger than the max size of the constraint image so effectively once the container is bigger than the image then of course we just use the width of the image so that is going to be the difference between the constraint one and full width full width is always going to be full width regardless now the constrained one unless you set up the width it's basically going to be dependent on a parent but the moment parent actually gets bigger notice of course at this point the parent is bigger then of course we just go with the width of the image you can clearly see the border radius which we applied using the class name and of course we selected it here in the css and if you want to take a look at the other options for example placeholder i'll simply navigate back to my browser i will refresh and there is you can clearly see the placeholder pattern more specifically traced svg and what's more interesting if we start drilling down we have a section now keep in mind this is my styled component one that's the one that i created and we keep going down down down and then of course we have the article and then what do we have inside of this article well we have a section now why do we have it as a section well simply because that is the value that i provided for my ass prop and then as you can see we have some classes here we have gatsby image wrapper and then we also have gatsby image wrapper constrained so i guess they add this class if the image is constrained and then of course i have my own one i have my example img and then of course whatever css i applied notice how it is added to my wrapper and that's how we can set up options in the gatsby image beautiful and to really hammer this home why don't we set up two more articles with different layouts so that way we can see them side by side and i guess i'm just going to start with a bit of house cleaning i'll remove the height for the time being from my static image and then also i want to add a little bit of css here in my wrapper so width will stay the same margin 0 auto that stays the same or i'll set it up as a display grid so display grid and we're going to go with text line center as well so text align and we're going to align it in the center and then we'll also add some gap in between our columns and rows and that's why we'll go with gap and then two rems and also at the very very bottom why don't we set up a media query media so once we get to the i don't know 992 so min width 992 i'm gonna go with a three column layout so 992 pixels and then once we get there grid template columns and let's just go with one fraction one fraction as well as one fraction okay awesome that should do it for the css and now i just need to copy and paste and then like i said i'll change the layout values so that way you can see the fixed one you can see the full width one and all that and also we'll change the placeholder one as well so let's take the whole thing so the article copy and paste two more times now for the second one i'll set it up as fixed so i'll change the text as well now alternative will stay the same as far as the placeholder if you want to go back to the suggestions just remove everything and then once you add the quotation mark notice again these are the options i'm going to go with blurred in this case now as far as the layout well i don't want to constrain right so that was my default instead i'm going to go with fixed and then with fixed if you add just width height will be automatically calculated but if you want to be more specific of course just add the height and that value will be set as the height for the image so in my example i'm going to go with 200 just notice how you need to set up the curlys here so that's not a string that you're passing in here you're passing in the number i'll leave the class name as it is because i still want that border radius and i guess it's not going to be a section in this case we're just going to go with div now i don't know whether i'm going to go and check whether i actually have the div but hopefully you get the point now i think i made a tiny bug where fix one is actually all the way in the bottom so let me remove and i'll place it in between again it doesn't really matter but i just like to keep things in order so there we have fixed one and then last one will be our full width again same deal same image as far as traced svg or remember that by default we have a dominant color correct so we can use that one as well keep in mind technically i can just omit it i'm just showcasing what is the name of the value here and then as far as the layout well let's go with full width so we're going to go with full width example image class yep that stays the same and i don't know this can be an article maybe so let's save what we have and then we're going to navigate to the bigger browser window and of course notice since i added the article it also added right away the border because if you remember here i have a css selection for the article so since i render this as an article that's why we have that extra border and then notice something interesting so on a small screen they're exactly the same right and by the way i didn't change the text in this one and just say full width here basically they're the same they're spanning the size of the container but if you keep making it bigger bigger bigger at some point what is going to happen this one well the container is going to get bigger now in our case we cannot really see that because we have that at 992. so why don't we change this around just so you can see clearly so let me comment this out for a second and at this point i guess this one is just spanning all across so let me make this smaller and now you can clearly see so this is going to be my image with constraint and this is going to be the full width so full width always spans across regardless of the screen size now the constrained one again is going to be dependent on a parent but the moment parent gets bigger then of course we just render the image as it is and fixed one pretty self-explanatory notice whatever size we pass it in the height gets calculated and we're in good shape now if you want to add the height as well let's just keep scrolling back and we're going to go with height and i don't know maybe 600 like so so i had this one and of course this is my image now if you refresh notice this is going to be the traced svg and as i said i think in this case we'll have to slow down the network a bit we're going to go with three fast 3g hopefully you'll be able to see all of them so we're going to go here this is going to be i believe the blurred one and we already covered the dominant color so i think we're mostly interested in the blur look so notice this is going to be that placeholder while the image is loading so essentially these are our options and as we're progressing with the project of course we'll use those images and now you already know what options you have when it comes to props so if you want to use different options in your project so if you don't want to follow along with my options feel free to do so and you'll be in good shape i think at this point we have good initial understanding how we can pass props and options into our static image component but before we start setting up images in our simple recipes project i also want to cover width and height for constrained layout versus the fixed one and how we cannot pass the height for the full width one and what in my opinion is a niftier solution when we deal with height for constraint and full width now i know that there's a lot to unpack so let's start with width and height for constraint versus the fixed one so if we go to the gatsby docks and if we keep on scrolling notice here we have width and height and what they're saying here that for the fixed layout these define the size of the image displayed on a screen however when we talk about the constrained one these define the maximum size so that's the biggest difference that's why i'm saying that for the constrained one it will be the size of the container but once the container size gets bigger than the maximum size that's why you see that space in between so that's number one number two if i go back and for example add a height for the static image everything is great and in my case i'm gonna go for 300. now i'll remove the height for the fixed one i think it's getting quite busy in the browser and if i'll try to do the same thing for the full width one i'm actually gonna have a big fat complaint in a browser so let me navigate back this is my localhost and then once i refresh check it out i have a error basically tells me that failed prop type height 300 may not be passed when layout is full width so that's something to be aware of yes you can pass in the max height for constraint one remember for constraint one width and height are max values yes we can do that however for the full width one well that's not allowed so what would be a solution if i want to have height for both of them for full width as well as the constrained one well a niftier solution in my opinion is using this example img because in here i can kill two birds at the same time first if i add here this max height i cannot really control it when i add this height 4 constraint i add 300 and that's it essentially it's set in stone however if i add the height for my clash for the example image not only i can control it depending on screen size but i can also control my full width so let's keep on scrolling i'll add my media query back up and then notice this example mg why don't we set it up this way where i'm going to go with height and then 300 that's gonna be on a small screen and then once we get to the bigger screen i'm gonna make it smaller so i'm gonna go with height and we'll set it up as 200 pixels so let's save the sucker and then once we move to a bigger browser window notice the difference and as a side note this one is just lower because of the text so let me go back and fix it because it's important that you see that both of them actually behave exactly the same way so notice the difference yeah of course on a small screen size we have the height correct we have the height that we set over here and that one was 300 but then the moment screen size is gonna get bigger notice how we're gonna have this 200 now i'll zoom out so you'll definitely see so this is going to be the 200 one and then once we go to the smaller screen size of course the height is going to be 300 again that's just my approach of fixing the height issue where once you add the height to the class a i can control it on multiple screen sizes so depending on the screen size i can control that value and you can also add that height to the full width image because notice without using that prop i can actually control the height of the full width one as well nice i think we have a solid understanding of how static image works and now let's put it to good use by adding some images to our simple recipes project and i guess i'm going to start with about page so if we navigate to complete project we can see that this probably is going to be a static image as well as in the about page so where do we start here and then next video we'll work on home page now i do want to keep my project somewhat clean so in the pages i'll start by removing the images component again you always know where to find the reference and i'm not sure maybe later i will get the link back but for the time being i don't want that warning in the console in the terminal so remove it as well and then of course we want to navigate to about page and first i guess let's start by changing the name here and what i mean is i want to capitalize it because that's the proper setup for react component and then we're going to go with our static image of course we do need to import it so we're going to go with import and then i'm looking for static and image and that is coming from of course gatsby plugin image so we have our static image then i want to import link because we will set up a link to the contact page and eventually we'll add some more imports but not for time being so we're going to go with import then we're looking for a link and again this is coming from gatsby this time so we go with gatsby here all right that's awesome then inside of the layout we will set up main so let's go with a main tags we'll add a little bit of css so add a class name of page here and then there's going to be a section with the class of about page so let's go with section and then the class is about page and effectively we'll have two articles one for the text and then the second one is going to be a static image now when i say articles i mean two columns so one column is going to be an article and the second column will be my static image so again if we navigate to a complete project i'm going to say that this is going to be the text side of it and then on the right hand side we basically have the image and again i can always make it smaller and you'll see that this is going to be look on a small screen and then this is going to be the look on a big screen let's navigate here and i guess let's start with a text like i said i'll just group everything in the article in this case there's going to be a heading 2 and also i'll add two more paragraphs now i'll copy and paste the text to speed it up but i'm just showing you the structure so heading two then two paragraphs and then like i said i also want to make a link to a contact page the link to and then as far as the address well we go to the contact page so i pass in the path here correct and then of course i want to have some kind of text so contact and then let's also add a class name so let's write here button again this just comes from the css i just add a little bit of styling to my link so i'll save it here and probably it would make way more sense if in the browser i would be in a contact page and there it is now as far as the text like i said i'll just speed this up i don't see the point of typing everything together i mean you probably have way better things to do so copy and paste and the last one as well okay that's awesome i mean we have the text and now like i said two column layout this is important because i already have the css of course so i have article this is where the text is sitting and now of course i want to set up my static image okay so side by side with my article i'm going to go with static image and now first we know that we have a source prop correct so we go with source and as far as which image i want to show well i want the about jpeg that's it now if you want a different one if you want to download your own i mean feel free to do that so we're going to go with source and again i'm navigating to the assets now i guess one annoying thing here is that it doesn't show any suggestions you know that when you're working with imports here it right away auto completes it for you in this case it is not happening so we go with assets then forward slash then we go with images and then the image name about jpeg now as far as the alternative i just took the info from the image so it says there person pouring salt in ball that's it again i didn't make this one up that's in the info of the image and now let's close our static image and then eventually we'll add two more class names so let's save it for now we should have this giant image okay that's good and if we can see it in a big browser as well then we are in good shape so we do have the two column layout but as you can see we do need to apply a little bit of css because it's probably not the look that you're shooting for yes it looks somewhere okay on a small screen but once the screen size gets bigger then of course we just have this giant image and we already know how to do that we know that we can apply a class name right and the way i set up the css there is a class by the name of about img so in this case i'm going out class name so remember we're adding this class to the wrapper not the image to the wrapper and we go with about img and then as far as the placeholder well why don't we try out the blurred one again my favorite is the traced svg but once in a while i like the blurred one e instead so let's navigate now to the bigger browser and what do you know of course we nicely have two column layout where we have the text and image side by side again i can make this smaller and you'll see how it looks on a small screen and then once i make my screen size bigger we have our two column layout and then as far as the css it's pretty typical css and probably the fastest way how you can find the styles is by navigating to main css and then again the command is command and f and you get the search window and then just look for about and probably the most interesting thing here is the setup for the about img since we just covered how we can add those classes to the static image so notice how i have this about emg and first let me just showcase that is going to be added of course to my wrapper so there it is once i navigate here notice the class names i have about img so that's for my wrapper and then i set up the height for the small screen in this case i go with 500 pixels i also add this border radius and then if you keep scrolling notice the media query so my about page so the parent for both for the text article as well as my static image it's actually a grid so we set it up as display grid and then once we get to 992 i set up two column layout and then i set up the height for the whole about page as 400 pixels and then for my static image i just say height 100 meaning set your height based on a parent so if this parent is going to be i don't know 800 then of course my image is going to be 800 now if the height is going to be smaller then of course my image is going to be smaller as well so hopefully you get the gist unlike the previous video where i hard coded based on a screen size so remember i set one pixel value for the smaller screen size and then added media query and set the pixel value for the bigger one in this case yes i hard code for the small screen where it is 500 but then once i have that two column layout i want to set my height based on a parent and if we navigate back and in this case i'll zoom out just so you can see better and i guess i'm going to look for my about img and then notice what happens if i remove that height of 100 so of course now this image is bigger now it is that 500 correct and then once we remove the 500 as well now it's even bigger again that's something nifty you can do it's not part of official gatsby documentation but again the idea is that instead of adding that prop you can simply set up the class on the wrapper and then that way you can control it way better because you can add all kinds of nifty css and then in this case we are actually setting our image height based on the parent and once we're done with about page why don't we tackle the homepage as well now eventually there are going to be more things in the homepage if you take a look at the complete project you can see not only we have the hero image with some text but of course we'll also have the tags for the recipes as well as the recipes itself but for the time being let's just focus on this image and then of course once we learn how to fetch data and set up that data in our headless cms the contentful in our case then of course we'll knock out these two suckers as well so i think i'm gonna clean my workspace first and i'm just gonna close all my tabs okay that's good and then in the index.js okay i have the react i have the layout that's good i think i can close the search for now and then as far as the imports well i just want to get my static image right so i'm going to go with import and then i'm looking for static and image again it's coming from and gatsby plugin image good and as far as the return yes i'll still have the layout that stays the same and again i want to go with main tags and i want the class name off page and then inside of the main i'm just going to go with my header and the class name will be hero so header and a class name is hero now instead of this hero i'm gonna have two things i'm gonna have my static image with a layout on full width so we can keep on practicing and then the second thing is going to be my text let's go first here with a static image and then as far as the source well i need to go to my files and let's see i think i want to go with the main one here so this guy and again the path is following where we go with two dots and we're looking in the assets and more specifically images and then we go with main and jpeg now that's good then i want to have the alternative one and let's see what it is i guess i don't know a flower and eggs so let's just write eggs so let's go here with eggs and then i want to add a few more props so class name again added to my wrapper we're going to go with hero img important for the styling then as far as the placeholder i want to go with my favorite one with traced svg and then as far as the layout now i'm going to go with full width one instead let's save this one here and now i want to test it out in a browser looks pretty good and then like i said i also want to set up that text and as far as the text how i was able to set it up here in the center well i'm doing that using the css so first let me set it up and then i'll go over what's happening here so we're going to go div with the class of hero container and then inside of it there's going to be another div with a class of hero text and then instead of this div this is where we'll place a heading one with some kind of text in my case simple recipes and then heading four and we just say no fluff no fluff just recipes let's save that one now we have a little bit of styling as well as the text is sitting in the center so let's take a look at the css i'm going to go to main css again i'll look for my dot hero and then first of all notice how the height is right away hundred percent so i'm adding this class on the wrapper the hero img and then i right away set the height to be 100 percent why well because hero my parent has the height of 40 of the screen size so again in this case i'm using the parent to control the height of my image because i add the class on the wrapper and then i just set it equal to 100 now as far as how i was able to set this text on top of the image well the hero container here is actually position absolute so i take it out of normal flow and i just set width and height equal to 100 percent and then since hero is a relative essentially it's spanning all across the hero and i add a little background that's why you can see that it is darker so if i remove it notice of course it's going to be lighter now the reason why i add that background is because i want to see that white text better and then of course you can also see that we add a little bit of border radius so we match to the one we have for the image and as far as how i was able to place the text in the center well the hero container is actually a display flex and i just set my text e in the center by using align items and justify content that's about it if you want you can go here and by the way i'm showing you the complete one this is how it looks currently in our project again if you want you can inspect and you'll see all the properties in action for example if i remove my height now of course i have this massive image that's the reason why we need to set this height as 100 and then it depends on the parent and the same goes for hero if you remove it of course now just have this massive image now if i'll set back my height to be 40 percent of the screen size or if i want it i don't know 30 then of course it is going to be smaller hopefully this makes sense i know that i covered quite a bit of css but in this case it is very important since setting them up in the layouts is a big part of working with images and i just wanted to cover clearly my approaches when setting up layouts using gatsby images awesome work on setting up the images and next one up we have graphql or how to work with data in gatsby you see up to this point we have been using standard react practices to access our data in our gatsby project and while there's technically nothing wrong with that particular approach in essence we're not utilizing all the awesome features gadsby offers in order to change that we will have to understand how the gatsby data layer works in a nutshell we'll learn how to load our data directly into our components using graphql if you are new to graphql i fully understand that syntax might seem a bit foreign and intimidating at first but believe it or not once we'll get few graphql queries under our belts i doubt you'll want to go back to good old rest api and actually at least in my opinion gatsby makes it very easy to start with graphql since a lot of complexities have been removed and we really need to worry about writing the queries since it is a major major course on overall gatsby topic here are a few of my suggestions of how to tackle it and i guess i'll start with this one whatever you do do not throw in a towel or in other words give up and yes it is that simple look you can only get better if you practice and sometimes it just takes a bit of time to get used to the syntax and logic behind it second if my explanations are not good or clear enough try gatsby documentation like i have mentioned already a few times they have awesome and comprehensive docs so if necessary try to utilize them i would also suggest spending some time in graphical just writing some queries and testing results and you can think of graphql as it is also called as a sandbox for your graphql queries since graphql is such a major gatsby topic we will spend multiple videos just practicing writing queries testing results and only then proceed to cover multiple ways of how we can render our data also starting from this video we'll spend a lot of time in our sandbox and the url for this sandbox is going to be http then localhost 8000 underscore underscore underscore and then graphql now you can easily find the url if you run gatsbydevelop and all the way in the bottom you'll have two urls one for the 8000 which of course displays our project in the browser and then the second one for the sandbox and at this point you have two options we can either command click which will right away open up in a browser or we can copy and paste the url now my problem with command click is the fact that it will open up the sandbox in a smaller browser window and in my opinion it's kind of hard to work in a smaller browser window as you're working with a sandbox i think you have a much more clearer view of what is happening if you're doing that in a bigger browser window so in my case i will copy the url like so and then i'll navigate to my bigger browser window open up a new tab copy and paste and there you go now we have our sandbox and we can start writing queries and getting data into our components whenever dealing with complex subject it always helps to keep things in perspective so let's give it a shot in this case as well since gatsby is built on top of react we know that our project will consist of components now those components could be small components big components at this point it is irrelevant at the end of the day our project will have a bunch of components in some of those components maybe in all of them we would want to render some data now that data could be really anything external apis local files and images markdown site metadata just to name a view in order to access that data we'll utilize graphql and in a nutshell graphql is the syntax that describes of how to ask for data it allows us to specify what data we would need and uses the type system to describe that data in gatsby we can create and test our queries in the graphical ide or simply sandbox and once we are ready to display or render our data we can do that with the help of static or page queries static query could be used in any component including the page component but when it comes to page query we can only use them in our page components what makes page query so special is the fact that unlike static query it can also accept variables so nutshell we have components that want data now we use graphql to get that specific data test our queries in sandbox and render it using static or page queries since we'll spend a significant amount of time in our sandbox let's get familiar with an interface now please keep in mind that it is just an intro video and i fully understand that a lot of things might look sketchy confusing and even flat out scary i hear you don't worry when it comes to writing our actual queries we'll start very nice and easy i'll probably repeat the same thing 20 000 times to the point where you will scream at the monitor but hopefully by doing so you won't feel overwhelmed and will be able to set up your own queries in no time as far as the interface on the left hand side this is where we'll set up our queries and then on the right hand side we'll have two options either we'll get a result for the query we just set up and of course we can just copy and paste that query into our project and we're good to go essentially we will get our data or we'll have an error so if we will have an error of course we'll have to troubleshoot now later as our queries get more complicated we'll also have to set up query variables and this is exactly where we'll set them up as you can see we have a name here query variables but at the moment we don't have to worry about that just remember later that's where you can find your variables as you can see right now on the left hand side we have a bunch of very useful comments and as a side note even though some of it might not make sense i would suggest just kind of skimming over it just so you understand the main idea now when it comes to running our queries we have a few options either i click on a play button right here hard to miss or we also have an option of shortcut and that shortcut would be control and enter then as we're setting up the query there might be a time where you would want to format it because as you're writing the query it might get messy it is much more easier to see if everything is nicely formatted and in order to do that we just click on prettify and that one would be shift control and p then we have a history which should be self-explanatory as you can see these are the queries that i wrote in your case if you just open it up probably it is blank and then we have your next future best friend why am i saying that because even though as we will set up our first queries we will write them out manually because i would want you to struggle i want you to understand how it works all the nuts and bolts but later we will use the explorer and what's really cool about the explorer is the fact that the only thing you really need to do is check off boxes so for example i have a query with the name of all site these are the options i have for example i'm looking for the edges and again i fully understand that none of this makes sense right now i'm just showing you what is going to be our future so edges then we have node and then these are all the options that i have and you can notice that without typing anything i can pretty much set up my query and once my query is done i can run it i can get back my results and i'm good to go now if the explorer is awesome because it allows you to set up the query by just clicking on the check boxes and you're ready to go in no time code exporter allows you to save on typing out depo elephant so essentially as you can see it prepares the code that you would need to use in your component of course there's going to be some modifications and we'll add some more code and delete some of the options that they provide but in general again it allows you to save some time in the beginning we will type all these things manually because i think that is the best way to learn but of course later we will utilize our code exporter as far as the options we have page query static query hook that will cover a little bit later and static query so for example if i would go with static query option notice my code would change but again it is generated for me i will close the code exporter for time being as well as the explorer and then we also have a docs now i won't gonna cover docs right now because i think they will bring a necessary level of complexity so i think it's better if we cover them once we have some basic understanding of graphql and the last thing that i want to do in this video is to go over the basics of graphql and in order to do that i'm going to look in my history so in your case you'll probably not have this query and when it comes to graphql the setup is following so we have a query in this case we're looking for the products but unlike the rest api which essentially just dumps all the data and then you're the one who is stuck just coming up with which property and value you're looking for when you're setting up the query you are right away being asked to be very specific and in graphql we have fields now when we talk about fields think of them as properties on the object so for example these nodes represents all the products that i have the thing is though right away as i'm setting up my query i need to say which fields and am i looking for in the specific product because i cannot just say okay give me all the products graphql is like nope you need to be specific of what you would want to get back so if nodes has more subfields which in case it does so fields within the fields then you need to say okay i want title i would want url i would want size but then as you notice if the field has its own subfields then we need to drill it down even more and as a result we get only the specific data that we were looking for and one more thing that i really like about gatsby is that i can only set up these queries if i have installed the plugin and what that means is that i don't have to memorize 10 000 queries so only if i'll install the plugin then i'll have access to that specific query and only then i'll have access to that specific data by far the best way to learn graphql is by writing queries but here's the kicker first we have very limited amount of actual queries since we have very few plugins installed and second at this point in time we have a very limited amount of data as well and i guess let's fix the data issue first and we're going to do that by adding some site metadata in our gatsby config and you can think of site metadata as info about our site and once we set it up we can pull that info anywhere in our project so basically we can access it and do something useful with it for example later we'll use it to set up search engine optimization component or seo for short let's navigate to gatsby config probably want to start the server right away meaning stopped server my apologies then i'll close again all the files that i'm currently working in and of course i'm looking for gadsbconfig then above the plugins i guess i'm gonna go with a property name of site meta and data now please please please please keep the same syntax i know looks a bit sketchy but yes you need to write it site meta data like so and i'll talk about it at the end of the video basically why it is important as far as the syntax and then inside of it we can go really wild and crazy and we can come up with whatever property names we want so in this video i'll just set a bunch of them so we can get a good practice when we set up the query and then eventually we'll remove the unnecessary ones so let's start with the useful one not is going to be the title of our site and yes i'm going to go with simply recipes because why not then i'll add a comma again this is normal object so make sure that you follow all the proper rules then i'm going to go with description and we'll say nice and clean recipe site recipes site then i'm going to go with author and in this case i'm going to go with at and john smilga if you want you can add john doe or susan though whatever and then i'm going to set up some properties for practicing graphql query so start with a person property which actually is going to be an object and then instead of that object i'm going to set up a few more properties one will be named and second one will be age awesome then i'm going to go with simple data and in this case it's going to be an array so simple data that is equal to an array and we'll just go with item one and then item two you guessed it item two and then let's set up also a complex data it is going to be an array but it's going to be an array of objects again the reason why we do all of this is because i want you to get a good practice when we're setting up our first query let's write here complex data and like i said it's going to be an array of objects so i set up the array and i'll simply copy and paste just so i can speed it up a little bit name john age 32 let's leave it the way it is and then copy and paste one more time and let's change it to good old susan and she's going to be 21 so let's save it make sure you save the gatsby config i suggest always stopping the server and then restarting the gatsby config so i'm going to go with npm start over i'm sorry it's a gatsby config amount gatsby dev server and let me stress something when it comes to site metadata property you need to use the same exact name if you want you will get a big fat error in your terminal since it's a property on this export object now on the other hand the properties inside of it that's a different ball game you can name them however you like whatever makes the most sense to you and just so you don't think that i'm making this up let's navigate to gatsby docs let's use their awesome search option and then we can type gatsby config here gatsby config and let's just go with api option and then once we navigate here keep on scrolling keep on scrolling and there it is we have configuration options so we have options available to set within get b config and then notice these are our options so we have plugins which is an array then we have plags and all that so obviously you can read them and site metadata is that object so if you'll go with your own name gatsby is going to spit back the massive error because you're not supposed to add your own properties on that object there's a reason why they set up that object and on that object you're only allowed these properties now if you're interested in learning more about site metadata or the plugins and all that feel free to read the documentation in my case we're going to go to the graphql now and actually practice setting up the query similarly how we always should restart the server when we make changes in get b config or gatsby node you also want to always restart the browser when it comes to sandbox so the moment you make some kind of change as far as data in our case we added that site metadata if you want to have access to it make sure that you restart it otherwise you might have the scenario where you do make some changes you come back to the sandbox and unfortunately you don't see that query now i'll remove the comments just keep in mind that we'll use this guy often at least while we're writing everything manually and then of course eventually once we learn how to work with explorer then i guess we'll do that a little bit less but again in general this is a very very good helper so again the command is control space so now let me remove everything so i'm going to go with command a i'll remove everything and of course i'll zoom in so we can see a bit better now the way we set up the query we just start here with the curly braces now there is a query keyword and also we can name them and we can pass some more options and yes we'll cover that but as far as the basic query let's just start with simple curly braces that's all we have to do and then like i said our best friend is going to be the command of control and space and there it is so these are all the queries we can set up and you're looking at it and you're like well wait a minute that's not that many and not to be redundant but again the reason for that is because we're using bare bones gatsby application so of course we have no plugins so we also have no queries once you install the plugin then you'll get the query that's how it works and again in my opinion that's a very cool setup because you don't need to memorize 20 000 queries if you have the plugin then you have the query that's all there is to know so in my case i'm looking for the site query and then the moment i type site notice i get this red squiggly line and i have the error field site of the type site must have a selection of subfields did you mean site blah blah blah and in simple terms what graphql is saying hey listen buddy you're looking for the site but site has more subfields so more options and you need to be more specific again it's not like rest api where we hit the url and then server just dumps all the info no with graphql we need to be extremely specific of what we're looking for and in order to get those subfields we simply need to add the curly braces and the moment i add those curly braces again i can check for suggestions so essentially i can see what subfields i can access and what do you know what do you see over here no i see site metadata why well because we just created that object so i go with site metadata and again i have this red squiggly line again i have this error but at this point we already know why because site metadata is the object so now we simply need to start pulling these properties one by one now at minimum you need to provide at least one but then if you want all of them just add them to the query so again we need to go with a curly braces and then again we can use our suggestions so control space i have my title i have my description i have my author and on and on and on so i just go with my title i run it and what do you know of course now i have my title and if you notice as far as what response we're getting back we have this data object so that's going to be the wrapper around our response and then we basically have this mirror image of our query now let me run right now the prettify here just so it looks a bit nicer and then notice of course i'm requesting the site so i'm getting back the site i'm requesting site metadata and hopefully you get the gist now they also dumped this extensions on us but at this point in our gatsby journey we're not really concerned with it so just focus on this data object so that is going to be our response and again whatever is going to be sitting inside of the data object is going to be mirror image of your query now let me showcase what happens if we run with that red squiggly line and effectively the graphql the sandbox does nice suggestions so if i run it notice it right away pulls some default one so for example title description and author so that is also a case but once in a while you might run into some errors so of course it's always better if you're explicit of what actually you're looking for and again your best friend is going to be control and space to see the options so now let's take a look at our options one by one i'm gonna look for the title i'll go to the next line i'll look for description of course and again if we want we can run prettify just so our code looks clean and then of course i can go with author and now we come to the person so let me run before the person as you can see as straightforward as it gets we have the property and of course inside metadata we have the value so i'm looking here for the property and i get my my response so here i say title description and author and i get back the properties with the values and of course in our code we'll access those values and do something meaningful now what happens with a person well person is an object right and since it is an object we shouldn't be surprised if i type here person and i get this red squiggly line because again we need to be more specific we need to say hey get me the person but more specifically since it is an object get me such and such property what are our options we have name or age so again we go back to the suggestions and we can clearly see that we have option for name as well as age again i run it and beautiful i get my person with both values now we have the array i believe it was simple data so let's just go here with simple data and if the array just has simple item like we have with simple data we'll just get the array with those items so let me type simple data let me run it and there it is now of course i have simple data and whatever items i have so of course in our code we're going to access the array and then we can iterate over the items now what do you think is going to happen when we try to query complex data and not to be redundant but we'll have to be a bit more specific where we go with complex data like so so let me run here for some reason it just gives me that annoying suggestion so complex data and again the issue here is simple where each item is an object so in graphql we cannot just say hey get me the array of objects no you need to go with okay get me the array of objects but from that object this is the property that i'm looking for and i know that i keep pretty much repeating the same thing but this is crucial for understanding graphql since in my opinion if i really need to oversimplify everything this is the biggest difference between rest api and graphql as far as working with it again i'm not comparing them as technologies don't get me wrong what i'm talking about as far as the user biggest difference you need to be extremely specific so we need to go again with suggestions and check it out now i have name and age why well because these are the properties that i have in my object so if i go name and also if i go age and if i want to make everything pretty i just run prettify and then of course at this point i think i can zoom out a bit and then if we run not only i get the simple data so if we have single item array essentially where the items are not complex structures whether that's number whether that's string or whatever then we'll simply get the array and we'll have to iterate over and in this case though we need to say well what are we looking for so for example if i want complex data but i don't want the age i say get me the name just always remember if you have more subfields you need to request at least one otherwise you'll get an error and once we have a solid understanding how we are going to set up queries now let's take a look at the explorer and how it's going to make our lives easier just to showcase how much faster we'll be able to set up our queries using the explorer why don't we try to recreate the same query using the explorer option instead so i'll remove everything just so you don't think that i'm doing some blackmagic there it is must provide a query string so obviously we have some kind of error now i'm going to click on the explorer and then again we just need to look for the same query now what was the query that we used because that was the site one so i click here and basically if the query or a field is going to have more options you'll have essentially here this triangle on left-hand side so i click on the query now up on the top these purple ones are going to be arguments and we're not going to talk about them right now because i don't want to dump too much stuff on you right from the get-go but if you notice we have these fields so this build time of course doesn't have any subfields so i simply can click it and again i get some arguments and all that but as far as the value i can simply click it and again this returns the data object and then instead of the data object i have a site and build time so essentially i was looking for this build time field and i got the value back now i'm going to unclick the build time and of course we're looking for what we're looking for site metadata now of course i have author i have description i have simple data and title all the fields that have no more sub builds we can write a way query and then the same goes for complex data and person we just need to click on the triangle so we open this up of course in this case we just need to be more specific okay i want age from the complex data and then when it comes to person i'm going to get both and hopefully it is clear that we can set up the same query within a matter of 10 seconds and that's of course why throughout the course we'll use the explorer option instead congrats on completing your first query and now let's talk about our render options and in general we have two we have static query and page query and the setup for both of them is very similar so once you grasp the setup for one you'll have no problem implementing the other one as well in general static queries are intended for regular components and page queries are used in the page components with that said we are allowed to set up a static query in the page component but not the other way around so you're not allowed to use page queries in simple components and the reason for that is because unlike static queries page queries do accept variables which makes them dynamic and later in the project we will implement the page query variable feature when setting up our pages programmatically lastly for static query we have two syntax options one using render props and one with use static query hook provided by the gatsby team and since the react hooks have become pretty much a standard and most likely that's the syntax you will encounter when working in gatsby we will use only the use static query hook for all our static queries just remember they both accomplish the same task just the implementation is a bit different all right and once we know our options let's pull data using use static query hook now in the next video we will set up everything from scratch since in my opinion it's important to understand how stuff really works not just blindly copy and paste the code but in this video since i want to showcase how fast we can get something on a screen we'll cheat a little bit and use code exporter option e instead so back in my query i actually want to add the other property in complex data as well so i'm just going to go with my name i'll run it and that is my result and like i said we'll use code exporter and once you open up the tab notice we have these options we have page query static query hook as well as the static query now since we'll practice with static query hook of course pick this option and then you can just select it here notice they provide this option of copying this to the clipboard and of course that's what i want to do so once you have this code just navigate back to our project and again i'll set up some examples just so you have a reference for later and we'll just call this fetch and then data js you can simply copy and paste the whole code like i just mentioned we will set up everything from scratch so you have a better understanding how stuff actually works but for now i just want to get something on the screen so let's save now you'll notice how they set up component name and then right away export as default and that just means that they can keep this generic name meaning since we're exporting as default it doesn't really matter what we call it here inside of the file that's just a side note and of course i can navigate to index.js i think it's just going to make a bit more sense if we do it there and then i'll import my fetch data so import and i'm guessing i'm going to call it the same way i'll say fetch data and that is coming from and of course i'm looking in the examples and the file name is fetch data and then right below the header but still within main i'm just going to go with fetch and data and if you see this string on a screen which you should let's see yeah there it is now of course i can see this giant string everything works now at this point it's not particularly useful i can clearly see the same info here in my sandbox now what's more interesting is the fact that i can access this data so i'm going to go back to the fetch data and then remember this is a giant object now at the moment we use json stringify and all that that's good but instead what i want is to set up some kind of div here and then instead of this div why don't we set up a heading 2 with a person name and in order to practice a bit why don't we iterate over the complex data and i don't know show multiple people again just a small practice of how we can access data and don't worry of course since it is an object we can structure it and we'll do all that cool stuff later for now let's just do the old-fashioned way where we'll literally drill down to the necessary property so for example if i go with heading 2 i know that i can go back to the javascript land and i have the info inside of this data so we set up the query and then notice this result will be in data just like in our sandbox so what we're looking for of course is this data variable and then i need to go site site metadata and more specifically i'm looking for the name of the person correct so let's set it up we're going to go with data since that is the name of the variable then cite then site meta and then data make sure that the property name is exactly the same then of course we have the person and of course i'm looking for the name so i'm going to save it and the moment i save i see john now if you have different value of course you'll see the different value and just to kind of hammer this home notice the complex data i want to do the same thing we're right below the heading 2. now i just want to iterate over that array and display a paragraph with both values the name and the h and we're going to go with another div and then instead of this div i want to look for the property by name of complex data so in order to speed this up a little bit i'm just going to grab site metadata again later we'll take a look at the better options instead for now let's just copy and paste and let's do it the long way and of course i'm looking for complex data that is my array so i can use the map method and then i'll just reference each object as the item and then as far as what i'm returning well like i said i'm just going to return a paragraph and in this case since i'm returning an array i need to add my key of course that is just a reacting when we have a list so keep prop and we need to pass in something unique so in this case i'm just going to grab the index and then as far as the values well i have the object correct and i have two properties age and name and it's represented by my item so here simply i can say item dot name and then colon and then another set of curly braces and i'm going to go with item and age and once i save i see john 32 and susan 21 so that's how easy we can set up the query and then once we have the data we could pull it in our components using gatsby beautiful we're successful with getting the data on screen so now of course let's recreate everything from scratch and in a process we'll cover what is graphql what's the deal with use static query and all that good stuff so i'll remove everything and i'll just create a new component using my snippets and as you can see the name here is patch data but i purposely created with a lowercase because i want to showcase what giant error you're going to get if you'll try to use the use static query hook with a component that has the name with lowercase so for time being let's just write heading 1 and we're gonna go with hello from fetch data let's save that one and of course at the moment i have this again annoying thing there and then once i refresh everything is correct so go with hello from fetch data and then in order to use use static query hook we need two things we need a hook and we also need a graphql tag template now both of them are named exports so when we import we definitely need to set up the curly braces and then we say use static query and also comma and then graphql now since i'm using the snippets once in a while it spits back the snippet for something else so in my case i'm just going to go with graphql and then from academy so once i have these two imports you need to invoke use static query but then it's looking for an argument of graphql and then since it is a tag template you pass e in the query and if you take a look at their example so if you take a look at the code exporter notice how they pass graphql with a query right away in the use static query my preference is always to set it up above here so above the component because that way i believe my component code is cleaner so i'm going to get back and i'm just going to simply create a variable and again name is really up to you but i'm going to go with get data and then we go with this graph ql and like i said this is a tag template and this should actually ring a bell why well because if you remember when we were setting up the button what we were doing well we had styled that button so we're creating an element and again i was setting up the tag template and the only difference is the fact that in style components we pass in the css in the tag template and then those styles are applied to the button now in gatsby case we pass in the query so again under the hood gatsby does something with the query that we provide but it doesn't change the syntax again we're using this tagged template basically a javascript thing where we just go with a template literals and then we pass in some data so in our case what is our data well of course that is the query now where we can get the query well we need to go back to the sandbox and then we have a few options either you can just grab the whole thing but since i haven't covered the query keyword as well as the name and what gotcha you should be aware of i'm just gonna take everything starting with the curly brace and including the closing one and i'll navigate back copy and paste and we'll save now once we do that we get back some kind of value that will make sense to use static query and that is the hook that we need to invoke now since it is a react hook all the react hooks rules apply meaning we can only run it in a functional component okay that looks about right then we can only run it inside of the function so you cannot run it outside here and lastly we can only run it if the component name is uppercase and you'll see that in a second if i just go with cons data and don't worry we'll recreate everything from scratch one more time in a second and if i just invoke this one we'll have a big fat error right now and the reason for that is because use static query is called in a function fetch data that is neither and you're not i think at this point i'm just going to go to the bigger screen sorry my apologies so we have here uh if we refresh we're going to have this react hook use static query is called in a function fetch data that is neither a react component nor a custom react function now again the reason why is that happening because the name here needs to be with a upper case so once you set it with a capital case now of course we're not going to get that error so let me set it and then i want to pass in that get data variable again if you don't prefer setting up this way of course you can just directly pass in graphql with a query so i'm going to go here with get data and actually first i just want to console.log it so i just want to see what i'm going to be getting back so i'm going to go with console.log and notice i'm just going to console.log the result that i'm getting from my use static query and then once i save and i guess i'm just going to do that on a big screen because i think you'll see that way better and then once we refresh we should see the site now what does that site represent well that's the object that we're getting back right this is the object that we're getting back that's it and of course since we'll assign it to some kind of variable the value data will be assigned to that variable and then inside of that variable we'll have site site metadata and of course then we already know the drill then inside metadata we have author we have complex data and all that good stuff and at this point it is really a javascripting whichever method you prefer using when you're pulling the data out of the object well that's the one that you're going to use so for now what i'm going to do is simply go with const and data again some kind of variable and this is going to be equal to that object that i'm getting back and then if i go the long way i'm going to go with heading 2 and let's just say name here so right here name so again i go with data i go with site and i'm going to go with site meta meta and then data and then i'm looking for a person and more specifically i'm looking for the name and then once we save and once i refresh my name is john so that's definitely one of the options that we can use so i'll leave it for your reference and i'll just comment it out and then another option we have is of course the structuring so since i know that i'm getting back the object i can right away destructure it i can say you know what in the object get me the site property now the thing is if we take a look site property is an object itself right so what are we really looking for well we're looking for site metadata so i can just say all right so get me site meta and then data okay but that is the object itself so i can keep on the structuring this way and since i don't want to keep on doing this i'm just going to go with title which is a simple property so i'm going to say title now title is not an object it is just a value so i can simply save it and now instead of doing this whole dance of data sites and metadata each and every time i can simply go with a heading 2 and i can just write site title is and then colon and then i can just access the title like so so save it and there it is i have site title is simply recipes again at this point it's really just javascript so it really comes down to your preference some people find the structuring confusing and therefore they're used either the long way of accessing the value or you can also set up a variable assign it to data site site metadata and then instead of accessing all the time using this long way you can just access the variable and then for example look for the person and don't worry throughout the first project and the other ones as well i'll try to switch it up so we're not using all the time the same syntax but of course in my case for the most part i always go the destruction route instead and one more time let's go over to setup where we do need to have a component and then we import use static query hook and all react hooks rules apply as well as graphql tag template now in the graphql tag template we pass in the query and then we can either place it right away as an argument in the use static query or we can just assign the value that we're getting back to some kind of variable and this one we can do outside of the component but the use static query we need to invoke it inside of the component and per react hooks rules the component names must start with a uppercase letter and then once we invoke use static query with our variable or with graphql with a query we're just going to be getting back the object now which object well same one that we can see here in our sandbox basically this is what we're going to be getting back the data object and then we have multiple ways how we can pull that data out either destructuring either ascending to variables or we can simply drill down to the property we're looking for and then we'll just display that data on screen as you are setting up the first query i bet you found one thing extremely annoying and that is a simple fact that each and every time we were setting up the query or we were accessing the data we had to use this site metadata and trust me this is not even a long name once you start working with images once you start working with headless cms these names will get even longer it's not like i can just randomly start typing something else right i need to be specific of what i'm looking for however there is a way around it where basically in graphql we can set up aliases so before we cover keyword as well as the name why don't we take a look at how we can add alias because i think it's just going to make our lives much easier and we simply need to go back to our query here and we need to come up with the name so call it bugs bunny call it bubble it doesn't really matter and in my case i'm just gonna go with info and then the syntax is following where you need to add a colon now keep in mind one thing we're still looking for this property it's not like i just randomly came up with a name what i'm giving here is the alias so when i'm going to be accessing this data then instead of using this site metadata blah blah blah i can simply run it and notice my response i have info so nowhere in my response i have the site metadata so when i'm setting up the query i'm saying yeah get me this field but from now on i'll access using this name instead and now of course we want to test it out in our project and please be aware that the moment we'll change it just in a query we will have a big fat error and i'm doing that on purpose so let's go back over here and then inside of this site metadata like i said i'm gonna go with info instead we will save but there is going to be a big fat error now can you guess why we have that error well let's scroll down let's scroll down let's scroll down now is anywhere in our response the property by the name of site metadata since i'm trying to destructure it and keep in mind even if you're using this long way you'll still have the error why well because site object does not have the site metadata property anymore in response what name we have well info since that's the alias so instead i'm going to change this around and i'm going to say info and we'll do it over here as well it's all right info and then once i save again it's annoying but we'll have to refresh and now of course everything works site title is simple recipes so that's how we can add alias in our graphql query if we have a long and annoying name or we just simply want to be hipsters as you're going to be progressing with your gatsby applications and setting up more and more complex queries eventually you will come across the syntax where query keyword and query name e is used like i mentioned at this point in our journey it's optional but later once we'll work with more complex queries we will use query keyword now few gotchas i like to mention are following query names must be unique and once you start tinkering with query data in the file you might need to run gatsby claim to clean the cache and restart the server so let's start with a query name please understand one thing where yes you can run the same query in multiple files you're not limited one query per one file no that's not what i'm saying what i'm saying is that if you're setting up multiple queries with the same name yes you're going to get an error so please be careful basically every time you use the query name make sure that it is unique that's first second if i navigate back to my project and if i simply write a query keyword everything should work now i emphasize the work should unfortunately you'll see this error and even though i keep on refreshing well i can clearly see that in the cache there is some kind of bug now again in order to avoid it because i know that this syntax is correct i just use the query that's it nothing else so i shouldn't be getting this bug now in order to avoid it i simply need to clear everything are on gatsby and unclean and of course we'll run gatsby build or i'm sorry what built develop so we're going to go with gatsby develop and you'll see when the dev server spins up that we won't have that error anymore so now let me just wait a little bit and then once the dev server is going to be up and running you'll see that our query is going to be correct so let me go back and there it is as you can see it wasn't the query that was causing the issue it's basically the cache so if you run into that problem where you can clearly see that the query is correct but you're still getting some kind of cash bug then make sure to run gas be clean and one more thing i want to mention if you just use query keyword you're going to be in good shape meaning i can grab the whole file copy and paste and everything is going to work again we're just talking about the name so the name that comes after the query keyword those ones have to be unique so if you go with first query and then select the whole file and again since i made some changes there's going to be this bug but if you just grab this whole query and use it in a different component yes you will get an error because query names must be unique all right and once we have covered use static query hook now let's take a look at our page query option and for this temporarily i will create a page but eventually it's not going to be part of our project so i'm going to go with new file and i'll just call this testing gis now same rules apply of course we need to export as default okay that's good and then i'll right away rename it even though in this case it's not really going to make much difference and then we're going to go with heading 2 and then we're going to go with testing and the way it's going to work will again import graphql tag template but in this case the setup is going to be a bit different so let me close the sidebar and first i just want to check whether i have the page to begin with so let's say testing and for some reason i cannot see it okay that's interesting even though i saved it and again i have these weird bugs okay and now everything works so as you can see i just needed to keep on refreshing and now i can see my testing all right so that's a great start and then yes we will import our graphql tag template and then of course it is coming from the gatsby and then i'll use the same query just because i don't want to over complicate things but in this case we're going to be exporting the variable and we'll be able to access this data in the props now just so you don't think that there's some black magic i simply want to show you that by default every time you create a page gatsby will provide already a bunch of props so if i look for props and then just console log the props just like in any normal component if i go to the bigger screen and again if i go with testing i'll see in the console that gatsby already provides a bunch of things so notice that's my prop object and notice all the cool things gas b already provides now the kicker here is following that once we set up our graphql tag template assign it to a variable and export that variable the data that we're getting back so again we're talking about this one whatever we have access over here that one will be available in the data property in our props object now as you can currently see there is no data property so of course we do need to set up that query so let's go back to the testing site and i'm going to do it over here so we do need to export that's a must for the syntax to work then we go with const and in this case i'm just going to call this data and then we go again with graphql so graphql that's our tag template that is coming from the gatsby and then again we just need to pass in the query so i'm just gonna go back to the fetch data and in a second i'll show you what error we're going to get if we run with the same name just to hammer that point home but for the time being i'll just take everything apart from the query and first query so let's take this one let's copy and paste let's save it and then we'll see whether we need to refresh or not so in this case i'll refresh and now notice something interesting where now we have the data one right so once we set up our variable once we export this and of course once we pass in the query in a tag template then we have access to the data in the data property in the props again i know for some students this is a bit confusing where they're like wait a minute so i'm just setting up the variable here and then i have the value in the props yes behind the scenes at the build time so when our project gets created gas be smart enough to read this value and then just provide the data that we're getting back in that data property and then from that point again it's just simple javascript of how we want to access the property values so in this case we know that we can destructure right away in function arguments so i can simply say you know what instead of looking for the whole props i just want to get that data and just to showcase another way how we can access the value i can simply go with const and author and that one will be equal to my data and then of course i have the info since i use the alias and i'm sorry i need to go with cite my apologies since i'm getting back the object that is in my data and then of course i have site i have info and then of course i have the author as well so some people prefer this syntax instead again that's really up to you if you like to the structure everything you can do that if you like to do the long way where you drill down the properties in the return that's also an option or you can assign to a variable instead so here let's just change the round to author and that one will be equal of course to my variable and we're in good shape so once we save of course i have arthur johnsmelka now just to showcase what happens if we use the same name well let me copy and paste the first query and i'm gonna go back to the testing one okay i know that this syntax should work but i right away have this error and basically this error is just gonna tell me that we have multiple queries so notice here multiple root queries found first query and first query only the first first query will be registered so again if you just remove the first query if you just leave it as a query everything is going to work so there is no error if you just keep using query keywords however the moment you add the name make sure that that name is unique and let me also just emphasize the fact that yes you can use the regular use static query hooks in the pages you can do that however you cannot use page query in the components you can only use it in the pages so essentially in the files that are sitting in the pages directory because in the page queries we can also pass in the variables which we're going to do a little bit later and effectively that way we can make pages programmatically again something that we're going to do later and don't worry if at the moment you're a bit iffy on any of this stuff remember as we're going to be progressing with a course we'll write more and more queries we'll set up more and more use static queries page queries and all that and the more practice you'll do the easier is gonna get i think at this point we're more than comfortable with setting up the queries and display the results in the browser so let's keep it up a notch and start interacting with our file system in order to do that we'll have to use yet another gatsby plugin and plugin name is source file system if you remember we actually already installed the plugin it was one of the dependencies of the gatsby plugin image but just to repeat the steps and since i have nothing better to do i'll install it one more time also we'll set up the plugin as an object so in the video i'll set up the code first and then explain it in detail as a side note if you ever want to check whether you have a plugin installed just go to the package.json and then look for dependency name and then if you have it in dependencies then of course you are in good shape but then like i said i have nothing better to do so i'm just going to stop the server and then we'll navigate back to the plugins and the plugin name is source file system now it's definitely going to be one of the top plugins so you can just find it here or of course you can use the search box and then navigate to the docs the command that you're looking for is this one so copy and paste like so now i'm going to close the sidebar for the second and then we're going to navigate back to the docs the first sentence says it all a gatsby source plugin for sourcing data into your gatsby application from your local file system now as far as the config let's keep on scrolling keep on scrolling we need to set it up as an object and at this point you have two options you can either type everything in the gatsby config or it's always my preference when i work with a docs just copy and paste and of course once i do that i just modify the code so it matches to whatever i want to do but that way i just avoid the unnecessary typos so just grab this first object again make sure that the syntax is correct though make sure that you get both curly braces the opening one and the closing one and all that so make sure you copy that then navigate back and of course we need to work in the gatsby config so let me navigate to this file and for time being i'll close the terminal and of course just remember that we'll have to restart it copy and paste and now i just want to change some values around and then once i change the values then of course i'll go over what is happening as far as the logic so in my case i'm going to go with name of images and then instead of looking for the pages directory i'll remove that sucker and then i want to go to assets and of course in the assets i do have the directory for the images so i'll say images instead let me save it and now let me restart the server just so i can see that everything works because if you'll provide a wrong path it right away will spit back the warning and the error that basically the path that you provided does not exist now since i don't want to restart your server i'm not going to show you what is the warning just trust me that's the case now what is happening here as far as the config well we have this resolve property and here we just pass in the name of the plugin so in our case it is gatsby source file system now let me quickly double check yep notice there are no warnings so i'm in good shape and then we have this options object and then for this particular plugin we have two properties we have a name property which is just your name for the resource that you're providing so for example if you don't like my name you can simply set up here as photos and yes in a few videos i'll show you where we use that in the graphql but again keep in mind this is your name for the resource so sky's the limit you're not limited to using the same name as the directory name and then we need to provide a path and here we need to provide a absolute path and a node we have this underscore underscore their name so what underscore underscore their name is doing it sets up a absolute path to the directory where the file is sitting so in our case we have gatsby config this is in a root correct so we get the absolute path to the root and then we just point to that specific folder so in my case source assets and images if you have a different folder of course you set up a different path for instance if you didn't set up a assets if you just went with images of course you just go with source and images and of course we need to do that because eventually we will host the application and it's not like the same path is going to be for example on nuttlefy as it is on my computer okay hopefully that is clear and the way it works is following so essentially we come up with a name we come up with a resource so now when we'll be using our queries will have access to all those files but just keep in mind that as far as queries are concerned we will only have access to the images directory meaning whatever files you have in this directory those ones you'll be able to access so it's not like as a magic you just access all your files no on purpose you are setting up the options where you say okay so get me only the images and the name for this resource is going to be images now what is the benefit of that well the benefit is the fact that we can have multiple instances so for example i can copy and paste and i can say you know what this is going to be a instance for my css so call this styles and then of course i'll change the directory because it's not images anymore if i remember correctly it was css and then once we save and then once we spin up the dev server one more time now i'll have both of these directories available now i'll have nine files at my disposal because if i remember correctly i think i had eight images and then i have one four mainstays and then of course if i want to have access to the data then i can add the data as well so every time you'll need to access another resource you'll set up another instance and of course you'll add your own name now why do you want to add the name and actually a name that makes sense at least to you well it's simply because when you'll be setting up the query of course if you have two of these instances now you're getting all the files but imagine the scenario where you're like okay you know what just get me the images i want to do something with images and then you have this one lonely css file in the middle of it so of course when you'll be setting up the query the graphql query you'll explicitly say hey i want to do something i want to get those files but only get those files where the source instance name and that is just a official name for this one in graphql is equal to images or it is equal to styles and i'm not sure whether you're expecting a mind grenade but i'll throw it anyway and first i'll just start by copying pasting and then we'll just comment out and i want to showcase that technically we can get all the files so for instance here i can just say project and then instead of assets instead of css so for example i can just get all the assets that's also allowed or i can simply get the whole source folder that is also an option and you're looking at it and you're like okay weirdo then why we're not doing that why we did this whole song and dance where you showcase the images then you show these files i just want to get my entire project yeah but keep in mind that there are trade-offs at this point i'm getting all the files all the files that i have in the source but imagine the scenario where in my project i'll only be working with images that's the only need that i have for source file system so every time i'll be setting up the query i'll have to jump through the hoops just to get to this one and at this point it really comes down to your preference and what you're trying to do in your project if you just need to access to this one resource whether that is images whether that is styles whether that is markdown posts or whatever then you just set up this one instance where you point to that folder and trust me it's just going to be easier to work with those files because you don't have to spend that much time in a graphql basically filtering out the images now if of course for some reason in your product you want to have access to your entire file pool of course definitely just set up the source and you're in good shape just keep in mind that when you'll be setting up those graphql queries you'll have to do way more work just to get to a specific file compared to these two options that's why i'll remove my last example and you know what i'll add the styles but we'll do that in a few videos so i don't overwhelm you and now of course i want to uncomment everything and again i'll save it and just stay on the safe side i will stop and start one more time of course you don't have to do that if you are not adding these changes here and once the server is up and running then of course we can navigate to the sandbox and see what fields we have with this plugin all right and once we have our plugin in place we have access to two fields we have access to file field and we have access to the all file now the difference is that with a file field we'll be working with single file node now if we work with all file this just means that we're working with collection of data and this is going to be the same with our future source plugins as well so for example when we'll be setting up the recipes for recipe there is going to be a single query there is going to be a recipe query now for all the recipes if you want to work with collection of that data then of course we'll work with all contentful recipes or all strappy recipes so get comfortable with this all that just means that you're working with collection of data now it doesn't mean that it magically creates that data if in the images i'll have only one image it will treat it as a collection basically we'll get back the array but of course there's going to be one item so hopefully you get the gist and we'll start with all file so i'm just going to show you how we can work with collection and don't worry of course you will practice with file as well and as you can see of course i have more options i have my triangle and once i click it here at the top i have my arguments which we're going to actually cover in the next video and then we have quite a few fields here and as you can see we have more options and all the way on the bottom we have this field by the name of total count and as i can clearly see with my lonely checkbox that effectively it just returns a value so click it here and i'll run it because i get back my data okay that makes sense and then i have this all file and total count now total count is eight which again just underscores the point that i was making in the previous video effectively we're pointing to the images folder so if i were to go back and then in the source and in the assets i'm just going to copy one of these images i don't know which one doesn't really matter so i'm just gonna make a copy here and if i navigate back now and if i refresh the browser and then run it one more time what do you know of course the value right now is nine why well because i increased the amount of files that i have in that resource so again hopefully it is clear that we have that one resource we have that images and this is what we're working with okay that's a great start now if you want to interact with the list of those assets meaning if you want to interact with all of those files you need to look for the nodes now the old way was doing edges and then the field name was node inside of it but i'm not going to show it i mean it's been already a long time since we're using nodes so i'll just stick with nodes but again just remember maybe in some old source codes you might see the edges and then more specifically node and the way it works when we run nodes for every instance of course in our case what is our instance that is the file we're getting back to node and in that node we have more options that's why again we have this error where graphql is complaining that there's more sub builds now why is that well because each instance is represented by the node what is a node well if we navigate back to our gatsby config remember the complex data and remember i said this is an array and then each item is an object and node has the same structure basically it is an object with bunch of properties now of course their setup is way more complex where they have properties that are actually objects that have more subfields and all that but the idea is exactly the same and if you remember what steps did we need to take in order to access name orange essentially to avoid that error when we were working with complex data well we needed to be more specific correct so in the nodes i can see these are my values and effectively these are the subfields that i have access to now again some of them just return a value correct some of them like for example child image sharp something that we're going to work on when we set up gatsby image well that's actually a pretty complicated object where we can drill down multiple levels and as far as what values i want to see well i at least need one correct so i'm gonna go with i guess relative path here and then once we run it notice these are going to be all my files again i have the nodes like i said each file is represented with this node so eventually when we work with the recipes each recipe will be represented by that node in this case it's a file so it says relative path and here it says logo svg now i can just look for the name for example we can run it and now of course not only i have relative path but i also have the name we can also check for the size we can check for absolute path again bunch and bunch of cool stuff so run it i'll close the explorer for now and notice this is what we're getting back again we have all file to work with all the files in that source and then we have the nodes field and that nodes field just represents that list and those items are going to be coming back as nodes and in those nodes you have the subfields that's why when you set up the nodes field you'll have to be more specific hey what do you want back as far as data so again they're not dumping the whole thing on you they say okay you want to have access to all the files great but you need to be more specific you need to tell us well what properties are you actually looking for and that's why you drill down you say okay i just want a name or i want a size or absolute path or whatever hopefully it is clear and now of course we can move on to our next topic beautiful once we have covered all file field now let's see how query arguments work we'll use query arguments with the same all file field just keep in mind that the idea is exactly the same with other fields as well and basically query arguments allow us to be more specific of what data we are going to be getting back and the syntax for the query arguments is following where we go with a field name and then we set up the parentheses and then of course we get the suggestion whether we want to filter limit skip or sort and you can also see that of course we can access those arguments when we're working with explorer and for this all file field notice these are my arguments effectively everything that is in a purple color those are my arguments so again if you want to type it out you can definitely type it out but in my case we'll set up everything using the explorer now since my response is somewhat busy i'll also remove these two fields these two subfields and essentially i'm just going to be looking for name and size so notice these are my file names of course and then those are the sizes and let's start with the most straightforward one and that one is limit so basically we're limiting amount of nodes that we're getting back and in order to use this argument i simply click on limit like i said you can type it out if you want and i'm gonna go with three and then once i run it check it out here i still have a total count nine since that tells me how many nodes i have in the source and then this is my response now keep in mind two things first we can combine these arguments and later once our queries get more complex we'll definitely do so and second if we're just using the limit technically these items are random meaning we say graphql get me three items and graphql just dumps three items so at this point we're not specifically say what we're looking for we just say hey in my response just limit this to three so of course when it comes to limit in most cases you'll use it in combination with one of the other arguments because in that case is just going to make a bit more sense but the whole idea is that we're limiting the amount of nodes that we're getting back so for example if i'll change it to five again i just get two more items okay hopefully that is clear then we can skip and this is going to start skipping from the first item in my response i run and i get back nine and if i'll go with skip and i'll skip the first three you'll notice how logo about and main will be missing so once i run notice i right away start with the recipe and then all the way to the big copy hopefully that is clear then we have filter and sort and as far as the sort notice how sword has more options so it has this triangle and then it will still return all the items because in a second we'll take a look at the filter filter actually limits the items that we're getting back with sort effectively we're getting all nine items but we'll just sort it in type of order so we go with sort then we can check which field we want and literally here sky is the limit notice this source instance name we'll work with this one in few videos however once you click on it notice these are all your options so you can go here as wild as you want so in my case i want to sort based on name and size i think those are going to be two good instances so let me just check the size first and then we have the order and then as far as the order we have ascending so start with the smaller one or we have descending where of course we'll start with the bigger one so once i run it check it out logo is the smallest one that's why it's the first one and then of course we get the big copy which is going to be the biggest image okay then if i go with descending of course the order is going to be the opposite where again my total value did not change i'm still getting back all nine however i'm sorting and now the two biggest ones are first and of course we can sort based on name as well so if i'll change this around and if i go with name and of course if we go with ascending then we'll start with about and then two big files will be next and hopefully you get the gist so effectively we sort our response in alphabetical order so that's sort and then finally we have a filter and for the filter i'll make some changes in my images so i'll go here with the source i'll zoom in and then again we're looking for assets images and i'll create recipes folder and i'll place all of these suckers in there so go new folder and i'll call this recipes and then all the recipes images i'm just going to move into the recipes folder and once i do that you'll notice something interesting where once you run it i still have nine so i'm still pointing to the same source so that did not change however if i use filter i can say hey listen get me only the recipes ones and hopefully i named the recipes let me double check because for some reason i think that i named it product so not asset images yep recipes good awesome sometimes i do the weirdest stuff when i'm actually recording so it's always good to double check as far as the filter same thing notice we have multiple options and as you can see since we have a triangle these ones have more options themselves and what is a relative directory well that is going to be a director that is sitting in our instance correct so in this case i'm going to go with relative directory and then i have these options starting with equal and we have non-equal as well as the rejects so in my case i'm going to go with relative directory is equal to and then i just need to provide that value so in here i go with recipes and notice the syntax that you have to write so again you start with an argument name then you go with a colon then you go with a object because again you have more options here right in the filter and then since the relative directory has more options that's why again you go with one of the options and then you provide the value now the reason why i'm showing you right away the explorer because in my opinion that's probably the option you're going to choose yes previously before explorer was available you just had to type out the arguments but in my opinion with explorer there's very little use case so in this case i'm going to run it and now notice how my total count changed and now i'm getting only the nodes that are in that folder and like i said we can combine them so we can combine these arguments for instance i could sort them based on the name or size whatever so i'm going to go back to the sort and you know what i'll go with size and i'll say that i want to have the biggest ones first and notice again the syntax where we have filter here that's our one argument and then we have the second one where we go with sort again we run it and now of course not only i get only the four recipes but i get the biggest one first then smaller smaller and eventually i get the smallest one hopefully it is clear and you're not overwhelmed don't worry the more practice will do the easier this stuff is going to get as a quick side note if you're following along with the videos you'll most likely get this warning in a console simply because in the images component remember that was the first component we set up in the examples as far as the images where we were testing out the static image component we provided a path where we say acids then images and then recipe one now since we copy and pasted all the recipes into recipes folder of course now this path returns nothing so the gatsby is complaining that could not find the image for assets images and then recipe 1 jpeg so at this point either you can change the path where you include the recipes folder as well so we'll need to go with assets images and then recipes folder and then recipe number one or we can simply go back to the file system and then i'll grab my recipe number one and then just copy and paste back in my images folder so i'll still have my recipe one jpeg directly in my images folder i think this is going to be the approach that i'm going to take so again i can restart the server and if everything is correct there should be no warnings in terminal all right that should do it as far as the arguments so now let's take a look at file field and what i'm going to do is just delete everything here notice i just go back to this nice clean layout and then like i said when we work with all file we work with collection we work with all of our nodes now when we work with file we work with that one specific node so for example i could go here to the file and notice how we're getting all of these arguments and you're probably okay why is it so many why for all file we had only four and now i have this huge list well let's see when we set up the data for example i'm gonna go here with the name and i'll run it and it's beautiful i'm getting back my logo and if i really want to double check of course i can go with i don't know relative path and i'll see that of course the name is logo svg and that's awesome because now of course i can access the same fields like we did with all file field when we're iterating over those nodes however there's one gotcha i mean i'm getting a logo file right but what if i don't want the logo because i can clearly see that in my project in the images folder well i have about i have big copy big or maybe even i want to access one of the recipe images how can i do that because this logo svg is awesome if i want that logo svg but if i don't want it it's kind of useless correct and again we have to use the arguments that's why we have so many of them here where essentially we say yeah get me that one file but with the help of arguments we specifically say which file we're actually looking for and again you can use any of them over here but the one that i'll use is going to be relative path and again we have more options here and i'm going to go with equal and once i have this in place i just need to provide the name of the image for instance if i'm looking for big jpeg i go with big and then jpeg and if i run it of course now i have this file now if i want to access the recipes one of course i need to point to the folder and then the file name so if i go here and if i say a recipes and then if i try to look for big well of course that file is not there that's why i get back the null just keep in mind that when we're talking about a relative path we're already pointing to the images correct and then relative path just means well once we get to the images relative to images where do we want to go and in this case i want to go to the recipes and then of course the file name is a recipe for example one and i believe it was jpeg so we run it and now of course i get back that single recipe and again from here once you get to that particular file same thing again you have all of these fields that you can choose and of course you can just do something with that data in your application and since i promise you that i'll show you an example where we'll use this name property in our query in this video i'll set up another instance and we'll just set up the query using the arguments now this video is not intended as a code long if you don't want to you can just sit back and relax so at this point i want to copy and paste and since i have examples folder right next to the assets well i'll simply set up another instance pointing to the examples as far as the name i'm going to go with the same as the folder and of course i'm not looking in the assets now i'm looking in the examples like so so we save it and then of course we need to remember that we need to restart the server so i'm going to go with npm and start now once we navigate back then i'm going to set up all file query one more time so let me delete everything here and then i'm gonna look for total count and you'll notice something interesting where now the total count is 14 because now of course we have two instances not only we're sourcing the images but we also have access to the examples but if i want to do some work with examples and if i don't want to deal with images i simply need to add my argument and in this case i'm just going to say you know what get me only the file whose source instance name is equal to examples so we go to the filter and then we keep scrolling keep scrolling and this source instance name represents the name that you have in gatsby config so we go source instance name we have more options again and i'm just going to go with equals and then i just need to type the same name so i'm going to go with examples and now of course once we run it the total count is five and if you don't believe me i can show you that if i take a look at the nodes and then we keep on scrolling keep on scrolling and for example we can go with a name option so i click it here and there it is these are all the files that we have in the examples all right and up next i want to work with gatsby image remember when we set up the gatsby plugin image we had two options we had a static image and gatsby image and i said that the only difference the biggest difference is the fact that when we work with gatsby image it is expecting a dynamic data and we provide that using graphql and that point of course didn't know nothing about graphql well now we do and i just want to create a simple gallery where essentially there's going to be a component where we'll set up the query we'll look for all our images since we know how we can do that and then we'll iterate over and then of course we'll provide that dynamic data to the gatsby image component and of course in the process we'll learn how we can work with gadsby image component first i want to do a little bit of setup where i'm going to navigate back like i said this was just for your reference i don't want to deal with the source instant name and all that so i'll just remove it and then i'll restart the server i'm going to go with npm start then i'm going to keep on scrolling and in the examples i want to create a new component by the name of gallery so let's go with gallery js and then inside of it let's go with a component and by the name of gallery of course all right and we'll just say simple image gallery and you're not why don't we place this actually in heading 2. so we'll go with simple image gallery now i'll render this component in the test page just because it's easier but of course you can do it anywhere in our project now i do want to clean out a little bit our index.js because i don't like that it is getting so busy so remember the fetch data i'll remove it and i'll remove it here as well that's an awesome start then i'll navigate back to the testing one now since i want our gallery to look a bit nicer i'm also going to look for my layout that is coming from the components if you remember so we have a layout component then we'll remove our current query because essentially we'll just render our gallery one so there is no author of course and of course i'll remove the page query as well again don't worry there's going to be plenty of practice for the page query so i'll remove it here and then like i said i just want to wrap everything in the layout and then i want my gallery again the reason why i'm doing that in testing because i'll remove the whole testing one so then i don't need to hop around my project and just remove them one by one so let's go here with import we're looking for gallery one from and in this case we're looking in the examples and of course the file name is gallery and then it's not gonna be an author we'll simply go here with a gallery so now of course we should see the heading 2 but of course i do need to restart i guess or i guess refresh and there it is now i have my simple gallery component now since i want to have a bit better css i'll also set up a page here so i'm going to go with main with a class off page again that's just a css class that just makes sure that we have navbar on top and the footer is all the way in the bottom and once we have this setup in place now of course we'll head back to the sandbox and see how we can get that dynamic data that the gatsby image component is looking for all right and once we have our setup in place now let's set up the query where we'll get the data that the gatsby image plugin is looking for and as i know i'm not going to need this graph url here so i'm going to delete that one now as far as the setup once again select everything and just remove because i want to start from scratch and then we're looking for all file okay and in this case again gives me all these suggestions that's not what i want and i don't want the filter yet don't worry in a second we'll set it up and then i don't think i'll need the total count so the only one that i'll leave is this one the name so basically i just want to showcase what we're getting back we get all these files great now what well now if we drill down we can see that we have this child image sharp and i know that the field name is somewhat interesting i get it i was also surprised the first time i saw that one but this is where we get the info and if we open this up then we notice that we have fixed and fluid so these ones we used in the gatsby version 2 and now we have this new one so this new one is gatsby image data now notice how it has way more arguments and we'll cover them in a second just keep in mind that effectively this is a object that provides all the data that the gatsby image is looking for and if you remember when we talked about the images i said that the setup is almost the same meaning for the static image and gatsby image and the difference is simply how we pass in this data for instance when it comes to source placeholder and all that now we're going to do that here in a query for instance source is right away provided notice how we look for gas bmh data and we're good to go the source is provided but notice our options here so for example i can go with a layout remember that was one of the options when we were setting up of course our static one and what do you know i have fixed there i also have full width and constraint so hopefully you get the gist where again the setup is the same in here i'm hard coding that for every static image in here i just say all right get me all the images then specifically get me this gatsby image data and that's a must you must provide this one and then if you want to provide more options you can definitely do so so in this case i'm going to go with fixed layout as far as the placeholder i'm going to go with the blurred one and just to showcase that we have more options i'll also go code transform options and that's something we didn't cover in the static image because i didn't see the point of covering all the options that we have and then we can just go with a grayscale and we're going to go with true and you'll see once we set up the gallery how it looks like so once we run it now of course we provide those options not only we provide the basic setup because remember when we set up the image whether that's static or gas b of course there's going to be some defaults that's what i mentioned before when it comes to options there are some defaults that's why if you just run gatsby image data yes you will get some data the correct data but of course with just some preset options in this case i'm more specific i'm saying hey get me the layout and i want layout fixed get me the blurred one and hopefully you get the gist so everything is nice we're getting this data basically we just need to set up the query in our gallery and we're going to be in good shape but there is a catch and if we go back to our project and if you open up the terminal you'll notice you can't use child image sharp together with logo svg so effectively we need to remove our svg file from the query and that's a bummer but that gives us a option to practice on our arguments if i scroll up i can filter i can say you know what get me all the images apart from the ones that have the svg extension we bravely click on filter then we keep on scrolling keep on scrolling and of course we're looking for the extension there it is that's our extension and then we say the extension is not equal and we simply go with s v and g and then once we run it notice how our first image is actually about so it's not svg like we were getting before now it is about and then at this point you have as always multiple options you can go with code exporter and then look for the static query hook but again my issue with this code and i really appreciate the fact that they provide this code don't get me wrong i'm not complaining but my issue is that they're again set up everything here in the component and in my opinion it just makes those components bloated so that's why even if i go with a hook option i always go for page and then i grab everything apart from the export that is just my preference you don't have to do that if you are okay with this setup where basically everything is in a component feel free to do so at the end of the day you'll have the same data now in my case i will always use the page one and then i'll just grab everything here like this so copy this one then i'll navigate back to my gallery like so now of course we'll have to make some imports of course so let's copy and paste and of course we need to have a graphql that's a must and also we need to have our use static query hook so we go with import then use static query hook of course and then the second one is my graphql tagged template and then this is coming from and of course d gatsby one now i also want to get that gatsby image correct because remember we cannot use the static image with dynamic data because again keep in mind we're iterating over the nodes so as we're iterating each and every time we'll pass different data and that's essentially why we need to use that get the image plugin so we go with import and instead of the static one we go with gatsby image and then of course this is coming from a gatsby plugin image so once we have all the imports in place i just want to see whether i'm getting the data i want to do a console log and if i have the data then the next video will work on the return so let's go with const and let me scroll down data is equal and now i use my use static query what is the name of my variable it is simply query here and then let's log the data if we have a massive massive massive object then we are in good shape so let's go back and of course this is going to be my testing let's spin it up and if we inspect and in the console i see this object we are in good shape so notice we have all file and we're not surprised because that's the query that we set up and then i have the nodes and of course nodes is my array and we know the rest so in the next video let's iterate over our data and display something meaningful on screen all right we're done with our query and before we go any further let me just showcase where we can find useful info about the gatsby plugin image so remember previously i showed you the reference guides well now let's take a look at the how-to guide and then we're going to keep on scrolling and we're looking for adding images and media and more specifically how to use gatsby image plugin now they start here from the scratch of course we already covered that one we know about static images we keep on scrolling keep on scrolling and we come to dynamic images so like i said in order to set up dynamic images we need to go with gatsby image data that's the field that we're looking for and as i said i'm just looking at this width and i just remember that i forgot to add it so let me quickly go back my apologies i know that some of you are probably very annoyed by this but let me close my exporter for a while and then i'm gonna go back to explorer and then of course this is my filter that's not what i want i'm gonna keep on scrolling and remember we had options for height and width and in this case since i'm getting fixed it only makes sense if i'm going to go with a certain width and in my case i'm going to go with 200 keep in mind that yes technically you can run it without width it's not going to break but of course you'll have to do more work e in the css and since i want to avoid that i'm just going to add that option here instead and let me quickly swing back to the code exporter and then like i said i'm grabbing everything here as far as the page query the only thing that i'm avoiding is that export and then i'll copy and paste again you can simply add here the text i just wanted to go through all the steps so you're not surprised where i'm getting this info from all right that should do it now let's swing back so we have this gatsby image data and this is what we're going to pass into our component and we keep on scrolling blah blah blah we have display the image and again the difference here is that we grab gatsby image component and there's also going to be a helper function which i'm going to cover in the next video for now we just need to grab this gatsby image and the way it works again in their case they right away showcase with a helper function but the idea is that we just drill down to that gatsby image what was the name gatsby image data this is what we need to pass in in the prop by the name of image in the gatsby image component so we're going to go back we have our gatsby image but since i first want to test out how we can iterate over our data why don't we simply set up some kind of array list or whatever where we just iterate over and display the name and once we understand the name then of course it's going to be much more easier to add that gatsby image now i might need to add a little bit of css so i'm going to go with styled components in this case and of course i'm looking for my styled components i'll quickly set up my wrapper and we're going to go here with a const wrapper again this is optional you don't have to do it styled and i'm going to say section and eventually i might add some styles for the css flexbox and here i'll just wrap everything with my wrapper and then as far as well how we can access those values we'll remember that of course data is a massive object so in my case i'm going to set up nodes so this is going to be in the data and then we just need to scroll up and see okay in the data there's going to be all file and then i have my nodes so that's going to be that array that i'm looking for so i simply go with data all file and then nodes and now of course i assign this to a node variable and then inside of the wrapper let's just set up the curlies and we'll iterate over the nodes and for time being let's just set up map and i'll call this image like so so that represents that individual object and i'm just going to go to return and let's set up the article now i'll use the key here meaning i'll use the index for my key because i don't think that i query for any meaningful id so i'm going to go with key index because again we're returning a list so this is a must and then as far as the data for time being let's just go with the paragraph and we'll say single and image now the reason why i'm doing all this because i want to showcase what we're going to have inside of this image so i can see the list that's an awesome start and now let's go to the bigger browser window and see what actually we have inside of that image an image is an object and it has a name property and child image sharp and again we shouldn't be surprised we're iterating nodes we're getting back for every item that node and in that node these are the fields we have name field which just returns a value and then like i said there's going to be more complicated fields that have the subfields themselves and of course that is the child image sharp so for time being i simply want to access this name and here i'm going to switch things around and i'm just going to do a bit of the structuring where i'm going to say that i'm looking for the name that is sitting in my image object and instead of single image let's just look for the name now of course we have all these names okay we are moving in the right direction and now of course we just need to see well where is our gatsby image data well that is sitting in child image sharp correct now what gatsby image was looking for was looking for gatsby image data so now again we scroll back down and right above the paragraph i'm going to go with my component gatsby image here and then remember the prop name was image and now in this image we want to pass in that gatsby image data so again if you wanted to structure it you can do so in my case i'm going to code image child image sharp and of course get the image data now if you want to add aliases feel free to do so in my case i'm just going to go with image then child image and sharp and then of course we're looking for gatsby and then image and of course the data one now i want to close my component and then i'm going to save it and what do you know we have all the images that we currently have in the images directory even the ones that we have in subdirectory and you're probably wondering okay but why they're black and white well because we have these transform options grayscale if you remove this one then you'll see that they have their color now this case i'll add manually here the height as well so go with height keep in mind we're not using the sandbox here and we're going to go with 200 we save and of course it's going to split back me the error but eventually i should have the height as well now of course all my images are 200 now if you don't like the grayscale which i do but for example if you don't you can just remove it again it's annoying i understand but that's how it is we just have to refresh and now of course we have all of these images and then why don't we set up a nice column layout so in here i'll say wrapper and then pretty much every article is going to be placed in the line with the help of flexbox so say that my wrapper by default will be display flex here then flexwrap will be equal to wrap that just means that if there's not enough space we'll wrap to the next line we'll say wrap and then if we navigate should get the size by side now of course it's not going to be on a small screen because we have 200 by 200 if you go to the big screen and if you refresh and yep of course we have the gallery displayed now what's missing is the alt problem so it's complaining that we don't have the alt prop okay let's do that one let's say that for the gatsby image we'll add alt as well and in this case i'll just pass in the name so i'll say name and once we add that we scroll back notice how we don't have any warnings now also let's remember that we have shared props meaning if i want i can add the clash on this gatsby image as well for instance in here i can go with class name again this name is exactly the same like we had in the static image so in the static image we have this class name and remember we were accessing it well this is going to be the same the difference of course now i'm adding to all of the images the same one so i'm not doing that manually i'm adding to all of them and i'm going to call this gallery img okay now i'll also add a class here with a item just because i want a little bit of space in between so i'm going to go with item and first i'm going to say that every item class is going to get a little bit of margin to the right again we're not worried about css i just want a little bit of space in between so my apologies if you're not a fan of my css and you're not actually instead of all margin i'm just going to go with margin right and then remember now we have gallery img so i can simply add for example a border radius so i have that class on my wrapper so i can simply say gallery img and here i can say border radius and this one will be equal to one rem again we'll have to go back to the big screen now we have ourselves a nice gallery i guess the key takeaways here are following where we're iterating over the list and then we need to look for child image sharp and more specifically gatsby image data and then inside of this gatsby image data these are all the options we can set up just like we did with the static one the difference is that of course here we are doing that using graphql and then of course we just need to pass this in into a gatsby image so we import gatsby image then we need to set up the component and then we have image prop this is where we pass in that data with whatever configurations you have again you can technically leave this open just deal with a default setup and then of course we have alt prop and then rest of the shared props that we covered with a static image and if you do that you'll display all your list images using gatsby image and while we're still on a topic of gatsby image i also want to cover this awesome helper function that they provide and the name of this function is get image now what this get image function is doing it basically provides a path to the gatsby image and if you're looking at it you're like well what's the big deal and just type out the path myself i'm going to go back to the plugins or i guess not plugins i'm going to go back to the reference guides in this case and again we're looking for gatsby image plugin we'll scroll all the way down and then we'll look for the function and notice this get image right now why is a big deal that we have this function it is a big deal because it uses the conditional chaining where essentially we need to understand that at the moment yeah we're iterating over our list and i know that all my list items are images however please understand that we are accessing here the object property but if that object doesn't exist in this case if the child image sharp does not exist we're looking for the property on and all and as a result we're going to get a massive error and the way the previous setup worked even if one of the items was missing that image your whole site broke that's it it just broke because it was iterating over the list it was looking for the object and then instead of the object it was getting null i literally cannot stress how many questions i was getting from the students where they were like hey listen what's wrong my data is technically there i mean my code is exactly the same and the only difference was that one of the items was actually just missing that image because keep in mind again we have image object then we have child image sharp and then we have gatsby image data for instance if this child image sharp does not exist we're looking for a property on a null and you cannot do that so if there is no object then how you can access the property on that object you cannot and that's why this is really cool because now of course you can just set up that function and effectively if there is no object then it's going to return as undefined and again it doesn't probably seem like that big of a deal right now but yes i can tell you right away that once you start working with headless cmss i mean mistakes do happen and then if that image is going to be missing then of course your site will break your whole site just because of one image and now let's go back and test it out so i'm going to navigate back to my project i'm looking for get image function and then we keep scrolling down and of course i just want to use it somewhere and the way we set it up we just go with some kind of variable now in their case they just name it image i guess in my case i'm going to say path to image and then we go with our get image function and then you need to provide the path all the way to the object where the child image sharp is setting so in our case of course that is the image itself so i can simply pass here the image and then instead of writing image prop is equal to image i can just say that i'll have path to the image so we save it here we refresh and if we don't have any errors we know that this is going to work again you need to provide path all the way where the child image sharp is sitting so if for example you have a different structure and i believe they showed that different structure here where notice how they're querying for the blog post and then there is this avatar property and then as far as what data you pass in you pass in data blog post and then you're looking for the avatar okay so make sure that you provide a path down to the object where the child image sharp is sitting again in our case that object is a image itself because we're iterating over those objects but there's going to be some cases where you need to provide a different path hopefully that is clear and now we can move on to our next topic when it comes to data in gatsby effectively we have these two options we can keep it locally basically store it in our project or store it in the cloud when it comes to local data at the time of this recording these are our choices json format markdown or mdx mdx is a very cool option that allows us to combine a markdown and react components and as a quick side note we will make an interesting project later in the course using mdx and as far as storing data externally most likely you'll use something called headless cms or content management system for the most part the setup for both options the local one and external one is almost the same first we need to create data so think data first then set up query so of course we need to pull it in and lastly render it in the component so either in the page component or a typical react component now the major difference between the two is the fact that most likely external option offers a graphical interface for data entries so think nice gui and in most setups you can add or update data later without actually touching your project and don't worry we will implement that in our project as well and because of those two reasons we'll take an external route right from the get-go now once we have established that we will use headless cms for our gas b project it would probably be very useful to learn what it actually is so headless cms is a concept of decoupling your data from your project so if you think of traditional cms aka wordpress the moment you want to use your data separately you will face many challenges and hit numerous roadblocks and the reason for that is very simple because it is meant to go hand in hand with your project now the way headless cms works is the opposite in most cases you'll get a gui more graphical interface where in a matter of few minutes you can set up your data and then consume that data the same data in literally any front end so of course in our case we will use gatsby but the same way we just as easily could have used react svelt or even vanilla.js as far as the choices at the moment headless cms space is a wild wild west and if you don't believe me just visit headlesscms.org and be prepared to spend the remaining of your afternoon scouring through your options but the two major types of headless cms are open source meaning in most cases it's free and i'll talk about it a bit later what i mean by in most cases and a closed source basically where you pay some monthly fees for using their service in most cases paid options do provide a generous free tier so you can sign up for free and unless you're building the next facebook it should be more than enough now let me also point out that while i myself use free tier options when it comes to headless cms open source does not does not always mean it's completely free once you introduce a dynamic element to your app for example users you'll have to host that back end somewhere and at that point standard hosting rules will apply so which headless cms option did i pick for our tutorial well that would be contentful before we go any further let me just clarify they are not sponsoring this video and i don't have any affiliate program with them the only reason why i picked this particular service is because i use it myself i find their service really good and in my experience you will be up and running in a matter of few minutes which at the moment is probably the most important thing they do offer free tier so you will not have to pay anything they do host your data so that's taken care of as well and their interface is as straightforward as it gets in order to sign up just visit contentful.com and just keep watching the videos since we'll set up the account together all right and why don't we kick things off by creating a free contentful account and in order to do that we need to navigate to contentful.com again the url is contentful.com then look for this get start option and then specifically go for sign up for free then you'll need to provide your data so in my case i'm gonna be peter smith as far as the company i'm gonna go with coding and addict as far as the email i'm gonna go with one of my dummy ones learn code at mail.com as far as the platform javascript job title other job function other and just get creative with your password so it's hard to hack and then once we set up they will send us a confirmation email so make sure that you wait for the email and click on a link and then once you get the email like i said click on confirmation link beautiful and then they will ask you this question how do you usually work with content and essentially they're just giving you a free trial to one of their services so in my case i'm just going to go with explore content and then they will be setting up the trial space for you and eventually you'll get the second email where they basically just say that you're getting that 10-day trial now don't worry the way we'll set up everything you won't have to pay a dime because we'll go with free option then we can navigate back once everything is in place this is going to be our dashboard and mostly we'll work with content model so this is where we'll set up the structure for our data and this is where we'll set up a content now as you can see when they set up this example space you have all these entries as well as content model however i want to start everything from scratch and in contentful they basically set up something called spaces and you can think of it as your databases and in a free option you get only one so that's why we'll have to delete the example one that they just set up and we can do that if we navigate to the settings then more specifically we're looking for general settings and then notice that our space and we're going to go with this delete space option so now let me just grab the text because that's what you need to provide and then once we remove it then we can start from the scratch and in this case we go with add a space then we want to go with the free one here and web app only because as you can see rest of them will have to pay so monthly total is going to be zero like so so then we click on continue and we just need to come up with a space name so in my case i'm going to go with gatsby tutorial and again you can go with the example space where they already provide a content type as well as some entries but in my case i'm going to go with mt1 and i strongly suggest you do the same so we're going to go with create space and then once everything is in place of course we go here and once we're done setting up the new space we'll be back in our dashboard however notice the space name of course now it is gatsby tutorial and since i went with empty space option i have no data in here so i'll start everything from the scratch all right and we're going to start by setting up our content model and you can think of content model as a structure for our data so we'll be setting up the recipes correct now what do normal recipes have we have title they probably have description prep time cook time servings maybe an image as well so of course we just need to set up that structure and then later of course we'll be able to add our entries we'll be able to add our data but we always always need to start with content model where again we set up the structure for our data and we go with add content type now you can add as many content types as you like but in my case of course we'll have only one we'll have one for the recipe so just go with the name and of course the name will be recipe now once i set up my content type in the content model then i just need to add those fields so we click on add field option and notice these are all the types that we can have so for example for title we're going to use a text for the description we'll use text however we'll use long text just so you can see how we can fetch that data on the front end for images we'll use media and hopefully you get the gist so now let's start setting up our fields and we'll have i believe eight or nine and we'll start with a title so i go with text like i said there are two options short text or long text and i'll show you the long text when we set up description and for time being let's just go with the name and that will be title now we can go with create or create and configure and as far as configuration options well you can modify the field for example you can set up the validation where the field is required but just keep in mind that even if you go with create option you can still get to the settings of this particular field but in my case i'm going to go right away with create and configure and even though during the video i'll not set up all the fields as required just so i can save some time it is my strong belief that you'll avoid a lot a lot of unnecessary bugs if you do set them up as required because that way when you're adding the data you can right away see like okay i miss this field because trust me it is much harder to find it on the front end later so you just go here with validation and then for the title i'm going to click on required field and in this case since we'll be setting up the pages based on title i'll also go with unique field and lastly i'll also limit the character count just because when i'm displaying them in recipes or in home i'm displaying that in cards and i just don't want to have long titles where they're spanning e in two lines again that's just my preference technically you don't have to do that and i'm gonna go with max of i don't know 25 characters like so so let's save this one and there it is now we have our first field then we'll have a cook time so let's go with add field and in this case i'm going to go with integer so notice we have this number of course and then more specifically we can go with decimal or integer so essentially in this field we'll set up how long it takes to cook the recipe and i'll call this cook time so i'm going to use this capital casing again normally i would configure where the field is required but in this case i'm just going to skip but i do want to showcase that if for instance you don't click on create and configure right away you can still access it in the settings so go to the settings and basically you'll have the same modals available then we're looking for description and again it's going to be a text however we're going to go with long text just because there are some differences when we access it and i'm going to call this description okay we create then again how many servings that's going to be an integer so servings here we'll keep it as an integer awesome then we're going to go with our image and if we want to add an image we go with media and then we have options of one file or many files now of course the difference is when you're accessing it the data structure is going to be different if you go with many files so that's why in my case i'm going to go with one file and if you want to follow along exactly like i code in the videos i also suggest using this one file now again you can use many files just keep in mind that you might need to do some hacking later since when the data comes back from the contentful the structure might be a bit different so in my case i'm going to go with image and i'm going to go with one file and this is going to be the case where i'll definitely set up my validation and i'm going to go with required because keep in mind that images are always a pain if they are missing then we have featured and essentially this is going to be the setup where some items are going to be displayed in recipes and home and for about on the contact page will only display featured items so only the ones that have feature property set to true and as far as the field type well this one will be a boolean so we go with add field and then i'm going to go with this boolean option and the name of it will be featured and then we just create here and then we have one more integer at this point we have cook time and servings and i'll add one for the prep time as well so again we go with number and more specifically integer and then we go with prep time here we create this one and last one will be our content where i want to showcase how we can set up a json object in contentful and effectively the reason why i want to set it up as a json object is because if i take a look at the recipe notice i have these tags here which is going to be an array then i have instructions which is also going to be array ingredients and tools and all of them effectively are arrays and just to showcase how we can work with json data in contentful i'll set them all up in this one field so i'm going to go back and i'm going to go with add field in this case i'm looking for this json object and i'm just gonna call this content here let's create this one and then once we're done setting up all the fields we just bravely click on save and we're good to go and once we have our content type in place now of course we just need to add some content i do suggest adding at least four items so three are going to be featured and one not featured because that way you can have the same setup where basically we'll display all the recipes in home as well as the recipes but when it comes to about as well as contact will just display the featured ones now if you want you can set up one as featured and then maybe the second one has not featured that's also an option but i'm gonna go with four and three and the way we add the content instead of content model where we were setting up the structure for our data now of course we just need to add those entries so i'm going to go with add recipe and then notice what happens if i try to publish without the title which is required as well as my image well i'm going to get the errors i'll have required here as well as required for the title and that's why it's so important to add those validations because that way you can make sure that you always provide the data because i don't want to repeat myself but it's much harder to later find it on the front end and in order to speed this up i'll use the values again from my complete project and i'll also open up the hipsum where i can get my dummy text i'm not going to start with i'm baby and then let's go back as far as the title let's see what is the first one in home page we're gonna go with this one here so let me copy this one copy and paste as far as the cook time i'm gonna go with 10 minutes then for description like i said i'm just gonna grab from the hipster ipsum like so so we're just gonna copy and paste when it comes to servings i'm just gonna add here four now for the images these are our options so i can go with add media now eventually once we add already some images of course we can choose from add existing but at the moment we have nothing here so i'm just going to go with add new and then we can either get it from our file system we can get it from the search and of course you can see all of your options now in my case i'm going to go actually with the file system and then more specifically i'm going to look for my project because if you remember in the assets i had the photos for my four recipes so if i go to the assets and then images and then more specifically now recipes since we set up one more directory i can easily access them so i can say open here and of course i'm going to get my recipe and with images you'll have to publish the image first make sure you do that and then of course you can just navigate back now as you can see once the image is published we are in good shape and next one is featured so like i said i'll set up three items with a feature of yes and then one is going to be with featured of no now for the prep time i'll simply go with value of four and up next we have the content field where if you remember we went with json object type and therefore of course whatever we set up over here we need to follow the typical json rules for instance all the properties must be in the double quotation marks so for example here i can say items and i can set it up as an array now in order to speed this up just so you don't have to watch me type the json object as well as for your own use i provided already a dummy data for you so if you navigate back to the project and look for data in the assets so first assets and then data directory more specifically look for recipe json and this is the example one that you can right away use notice this is an object i follow the json syntax and all my four properties are arrays so one for tags one for tools ingredients as well as instructions so if you want to speed this up just grab everything here and then navigate back clean out and copy and paste now i do suggest changing at least the tags because if you take a look at our complete project i'm using those tags to showcase how many recipes i have for one tag and notice how this value is changing and then we are querying for that specific tag so we get all the recipes that match that tag so what i'm trying to say here is that once you save as you move from one item to the next one try to change these tags around now i do suggest keeping this food because that will make sure that we have one tag that has all the items but you don't have to and of course if you want to change these values around for example instructions or ingredients you already know what to do just go into the quotation marks and just change the value now please keep in mind you have to have a proper jsons index so if i'll remove this comma notice i'll get this this is not a valid json so we always always need to follow proper json rules now before we continue let me stress something where of course this is not the only way how you can set up the content type for this particular project case in point i could have just set up four different field types one for tags one for tools and all that and then again just set them up as arrays why i went this route first i wanted to showcase how flexible the json object is that pretty much we can set up as complicated as we want and second well that way i can just provide the entire object and in my opinion it just speeds up the data entries for you as well as for me and as far as the tags for my first item i'm gonna change them around and i'm gonna say beef and then i'm gonna go with lunch here and again i'll keep the full tag for all my items so all my items will have the same food tag just so we can see the functionality in action and once i'm done setting up my json object of course i have all my fields in place so i can just publish my entry so click here and then once it's published if you go back to your content you'll see that you have one item in place and now of course i'll stop the video and i'll add the rest of them just because i don't see the point of you watching me add all my items and then once you're done adding all of your items then of course you can move on to the next video where we'll connect our gatsby application to our contentful i successfully added the rest of my recipes so i have four total and just to showcase how we can add an existing image i'm just going to create one dummy one so if i go with the recipe and then if i find my image like i said we have two options add new media where we can get from the internet or from our computer and of course once we add some images of course i can click from the current assets as well these are my images i can just select from one of these ones and i'm good to go and then i'm not going to save this one so i'll just say delete and we're gonna go with permanently delete i guess like so and once i remove that dummy content let me just showcase that for greek ribs i went with featured false so rest of them have features set to true but this one has it as false so this one won't show up in the about page and contact page and second as far as the tags try to set up some repeating tags because that way you'll be able to see better our tags functionality in action now we have the data how do we get it into our gatsby application well we'll have to use a plugin for that and i'm going to navigate to my docs and more specifically i guess i'm looking for gatsby and i'm going for plugins and we're looking for content for one so gas b source contentful we keep on scrolling we can see that we need to install the package and of course we need to stop the server for that so clear everything copy and paste okay we install the package then we keep on scrolling and we'll have to set up our plugin as an object because of course we need to provide those options and in this case we need to provide space id as well as the access token now in this video i'll just copy and paste them just because i quickly want to test whether we get some errors or the connection is correct and then in the next video i'll show you how we can work with environment variables in gatsby so please do not push this up to the github after this video because if you'll do that you'll just expose your api keys in your source code so i'll grab this object so i'm looking for this gadsby source contentful and of course i need to go to the gatsby config i'll go below the file system one copy and paste and notice this is the name of course for our result and then in the options as you can see for a different plug-in we have different properties so here we need to provide a space id and second one will be our access token and like i just said in next video we will set up proper environment variables but for time being we'll just pass in our values directly in the gas b config and where we can get those values well we need to go to our content for one and then look for the second ones and more specifically api keys and of course we haven't set up any yet so we need to go with add api key and i'm going to call this one gatsby tutorial if you want you can add description but you don't have to and you just save it here so we save and then this is going to be our key and then this is our space id and as you can see they're not hiding the space id so we can simply copy and then go back and again make sure that you copy and paste correctly within the template string and then in this case we'll do the same thing with our api access token but just make sure that you get the content delivery one so the preview one is different then we go back again copy and paste we save and then once we spin up the dev server if we don't have any errors in a console we are in good shape trust me if you provided some invalid values then you'll have big fat errors in your terminal when the gatsby application is trying to connect to the contentful and if you scroll up here you'll notice that process data and then we're creating four contentful recipe nodes so we're fetching data we are in good shape because i can see that i'm getting four entries all the four recipes that i just added and once we have successfully connected gatsby application to the contentful before we take a look at the graphql so how we can set up our query i want to showcase how we can hide these sensitive api keys all right so we're successfully fetching data from contentful however there's a major issue in our current setup you see the moment i'll push this up to the github anyone who looks at my source code can just take my api key and that's something you want to avoid at all costs and in order to hide this value we'll have to use env variables now env variables are not unique to gatsby in fact they're part of node and then since gatsby is not application of course we have access to env variables as well now if you want to see the whole setup how it works just follow this link so in my case i'm going to go here just because i want to showcase where you can get more info so keep scrolling keep scrolling and we have two options we have one file the environment variables file for development and one production now i'll right away set up both because you want the production one if you run the gatsby build locally now there's two options when we push this up to the netify we can either drag and drop which is going to be a local build option or we can do the continuous deployment and in that case we don't care about the production one since we'll have to set up those values on metal files separately anyway however i'll right away set them both the development one as well as the production one so let's keep on scrolling again they just mentioned how you can create these two files one for development and one for production and the syntax is following where for env files we need to go with dot emv first and again in gatsby it's development and production keep scrolling keep scrolling and in order to access those values you'll have to require the package now the package comes already as dependency on gatsby so we don't need to insult or we'll have to add this line of code whenever we want to use those values so whenever we want to use the values that are coming from the development or the production one and then we just keep on scrolling keep on scrolling and notice in order to access we simply go with process env and then whatever is the variable name so let's go back to our project and i'll open up the sidebar and then you want to create both of those files in the root and you'll for sure need a development one but i'll also right away set up the production one so when we perform a local build we don't get the errors again you create that in the root not in a source that's extremely important and we go here with dot env and we're gonna go with development like so and we'll right away set up another file and here we'll say production so we're going to go with new file and dot env and production now in development one i'll set up my variable and i'm just going to call this contentful contentful api key api and underscore key and now of course you want to go to gatsby config and take this value now you don't need to set it up as a string you can leave it the way it is and if you're wondering how come the colors in my development file meaning in my env file are different for the property and the value well because i'm using this extension let me make this one bigger and let me see okay so i'm using this one this dot env so that's the one that makes the color values different and then i'll save my development of course and then back in the gatsby config remember in order to access those values we need to require that package the one that comes with a gatsby as dependency and the package name is dot interview so just take these three lines of code can copy them here as well navigate back and somewhere here top of the gatsby config of course we want to invoke this one so we want to save it and then scroll down and then simply just write process env and then whatever e is them so in this case contentful api key so navigate back and save it and of course i want to do the same thing in production where i'll take my variable my contentful api key and i'll just copy and paste so now we'll save gatsby config and again this is going to be the case where once you restart the server if there's something wrong with the setup you'll right away see the errors trust me there's going to be big massive errors in the terminal if you don't that means that the setup is correct and now what's really cool is the fact that once we'll push this up to the github then these values the api key values will be hidden because if you take a look at the git ignore you'll see that we're actually ignoring all the env files so keep on scrolling and notice dot env all of them are going to be ignored keep in mind that if you're setting up your own project and if you don't have the git ignore it's crucial that you also add all the env files otherwise whatever we're doing over here doesn't really matter because it's going to be pushed up to the github anyway now if i check my terminal looks like everything went correct again we can scroll up and we can see that we're fetching data from contentful and we're successful we're getting four entries so now of course we just need to go to the graphql and figure out how we can set up the query for our recipes all right and once we're done setting up our env variables next i want to set up a query where we fetch all the recipes now in order to do that we need to go back to the graphql and if you don't see these fields for example all contentful asset or the contentful recipe make sure that you restart the sandbox and then of course you'll see all these fields and the ones that we're looking for is the all contentful recipe as well as the recipe one so we have contentful recipe why do we want these fields well because this one we'll use to get all the recipes and this one we'll use later when we set up our pages programmatically and again not to be redundant but what's really cool is that the moment we install a plugin then we have access to those fields so it's not like you have to memorize them or remember them they're only available once you install the plugin and then of course in order to set up the query i need to pick a field and in this case since i want to query all my recipes in this case well i just need to go with all because remember that was the rule if you want to work with list you go with all and in this case since my content type is a recipe since i named my content type recipe that's why i need to follow the same name and then if i want to get one specific recipe of course i'm going to go with content for one now in order to set everything up we just click on the triangle for all contentful recipe and then if you remember if we want to work with that list we just need to go with nodes and of course as you can see we get all the fields so pretty much everything that we just set up in contentful we have access to and of course at this point we just need to ask ourselves so for this first query do i really need all the data or i simply need my image i need the title i need the prep time as well as the cook time and of course the answer is i only need these four values plus the id because we'll be setting up a list and if you remember in react we need to use key prop and we need to provide something unique so we might as well use the id that is coming back from the contentful now later when we'll be setting up individual pages yes of course we'll grab not only the instructions ingredients tools and tags but also servings as well as description but for time being we really need only these four things plus the tags so something i forgot to mention we'll also need to get those tags out of that content because side by side i want to set up my tags with my recipes so let me stop talking and we'll just navigate back and get those fields now where do you see the id here so we click on id and notice i can run it and i right away get my array that's my nodes and then in there i have four values why i have four values because i have four recipes and at this point we simply need to provide which fields we to query so i click on a title and in my response i'll see all the titles if i want to have a cook time then of course i just need to look for that field and add it to my query now i also want to have a prep time and like i said i also want to have access to the tags so i'm going to go to the content if you remember content was an object but then inside of the content i have the tags correct so we go with content since it's an object we're more specifically looking for a tags which is an array and that should get us back our tags and lastly of course i also want to get my image now in order to get the image first i need to look for the field name which surprise surprise is an image and then if you remember in order to set up gatsby image component we needed to provide this gatsby image data now something important i want to mention you will only have access to gatsby image data if the people who built the plugin made it available to you and in fact that's one of the reasons why we picked contentful because they made it available since gatsby image component comes with version 3 you might run into some plugins that do not support that yet and if they don't support it then your only other option is building a plug-in yourself where effectively you do provide that gatsby image data now again that is definitely out of the scope of what we're trying to do just keep in mind that again if you use some plugin that doesn't support gatsby image data then there's no way you can use it unless you build your own plugin now in our case people who built the plug-in for contentful were nice enough to provide it so of course we just need to go with gatsby image data and then if you remember we can run it as it is or we can provide the options and in my case i'm gonna go with layout one and i'll say that the images are gonna be constrained and also i'll use my favorite placeholder which is going to be the traced svg so once i run it we're going to get back these giant response with all this data i know that it can be a little bit overwhelming because once we add that image data i mean the response is just going to be massive that's why i was starting with simpler ones like id and title and again the main idea is following where we'll only have access to the fields once we install the plugin then the field name will correspond to our content type which in our case is recipe now since i want to work with the whole collection i'm going to go with the field that starts with all and then i can access all the fields that i set up in my headless cms and i just need to check on boxes and i'll get back the values and you know what before we go why don't we make things a bit more interesting and also sort our response based on a title so essentially i want to sort my response a to z so i'm going to look for my sword argument and then as far as the fields i'm going to go with title and then when it comes to order i'm going to go with ascending and then once i run it notice how we're sorting our response a to z and once we have this setup in place now of course i just need to go back to my application and set up a component that takes advantage of this query beautiful once we have our query let's navigate back to our project and in the components i want to create a new component and we're going to use that component in two pages we're going to use it in the recipes as well as the home now inside of our component there's going to be two more components because if you remember i mentioned previously that one of these components we will reuse all throughout our application in about pages as well as the template pages so that's why first i'm going to go to the components and i'll right away create all three of them now the main one where i'll get all the data is going to be all recipes js and the other two are going to be tags list and recipes list so we're going to go with tags list js as well as the recipes list recipes list and we go with js now in all recipes for time being let's set it up as a component and then we can right away import our tags list and recipes list so for time being we can set up a heading 4 and we can just say all recipes just so we can see something on the screen and then let's set up these two components so again i'll use my snippets tags list and we'll say this is tags tags list okay awesome and we're going to do the same thing here so this is going to be our recipes list recipes list we save and of course in all recipes i want to import both of them so first i'm going to look for tags list and that is coming from the same folder so i simply say tags list and we're going to render right after our heading four so we're gonna go with tags list and then we're gonna copy and paste and we'll set up the recipes list so in here i think i can just go with multiple cursors and we'll remove and we'll just say recipes list so we save it and now i want to navigate to both of my pages to the index one as well as the recipes one and just grab my all recipes component so import we go with all recipes from and of course we're looking in the components and we have all recipes component so right after the main but still within the layout that's important render the all recipes and we should get the text once we refresh there it is all the way in the bottom we have those this is a tags list and you know what actually it should be here in the main my apologies yep now it looks better so we have all recipes this is tags list and this is a recipe list and the same thing we want to do in the recipes page as well so navigate to the recipes page and simply go with import and then the same import we go with all recipes from we're looking in the components and then we're looking for all recipes and then as far as the return we'll have a layout then we'll have a main with a class of page and then inside of it let's just render again all recipes and then let's see what we have in the browser so i'm going to navigate to the recipes now i have my component there as well and once we have the setup in place now let's navigate to all recipes and set up the use static query hook so we can pull that data so we can pull that data into component and then we'll pass it in into the tags list and recipes list again why we're doing that because recipes list will reuse throughout our project so set them up separately and then we can reuse this sucker in different pages as well remember this is react so you can set it up in all kinds of ways this is just one of the ways how we can set it up and in order to use the use static query hook we need to have two things from gatsby graphql first and also we need to have this use static query and we just need to import from the catbee and after that i want to set up my query however i think i will use the code exporter option because i think it's going to be faster so again my preference is using the page query even though i'm not going to be setting up a page query of course we're working in a component so i'll just omit the export and i'll take everything after that so i'll take const and all the way to the closing tag template and i'm going to copy and paste that's my query and in order to invoke it i just need to go with some kind of variable and i'm going to go data and of course i'll use my use static query and i'll pass in my query and for time being i just want to check whether i'm getting back that object if i do then i'll pass my nodes array down to tags list as well as recipes list so in here i'm going to go simply with data and i'll cancel log it just so i can see that i have something on the screen can refresh testing that's where we were setting up the gallery in this case i want to go to the home one and i want to take a look at my devtools console and of course i have my giant object and then instead of that object i have property by the name of all contentful recipe and then that property is an object and inside of that object i have those nodes and again at this point it is simply javascript if you want you can destructure it here you can say that inside of this object i'm looking for all contentful recipe and then more specifically nodes that's definitely an option or just drill it down to the nodes so first let's do the second option where i'll still call this data and then i'll come up with a new variable i'll say recipes is equal to data and then remember the property name all contentful and recipe recipe and dot nodes and of course if you want again you can console log it and yes in first examples we'll do quite a bit of console logging and then later of course we'll do that less and less if i refresh notice now of course i have access to the array and the way our functionality is going to work will pass this recipes variable down to both components to the tags list where we'll set up some functionality as well as the recipes list so in the recipes list we'll just iterate over that list and display those nice cards now the tags list yes there's going to be a different functionality at this point i simply want to showcase that both of them effectively do the same thing so if i'll comment this out and if i go this route where i do the structuring all content full and recipe which is an object and then we just look for the nodes and i can give it an alias and i can just call it recipes please try to understand it both of them do exactly the same at the end of the day you just have access to the array and really comes down to your preference some people prefer the destruction like so and some say that this is more readable and understand that there's no way for me to please everyone and therefore i'll go with whatever i prefer the most and in most cases here is going to be setting up the destruction but just so we can start nice and easy i'm gonna go back to the first option instead so i'll set this up as data and again in a console we'll see the four recipes and then like i said in order to set everything up we'll have to pass in this recipes so our nodes array down to the tags list component as well as the recipes list so i'll set up props on both of them i'll call it recipes and i'll set it equal to my recipes variable and the same thing you want to do here so we can just copy and paste and now both tags list and recipes list has access to the array and in one component we'll just iterate over them and then in the second one in tags there's going to be more functionality not bad not bad we have all recipes component in good standing so now of course we can work on the other two as well and i think since i want to get something fast on the screen we'll set up the recipes list first and then we'll work on our tags list and as far as the recipes list well let's start by removing this heading 4 in all recipes and you know what as far as the return why don't we also change this div to a section and we'll add a class name just so we can get a little bit of styling so we'll go with recipes and then container okay awesome and then i'm going to navigate to recipes list and we want to do some imports first now what are we going to be looking for i want to get a link since cards are actually going to be links and they will navigate to that single recipe page and don't worry for time being we'll have some errors because we haven't set up those pages yet that's still coming up but i still want a link right away so i'm going to go import link from and of course i'm looking for gatsby and i also want to have a gatsby image because of course now i want to display those images but for dynamic data we need to use gatsby image component so we go with import we're looking for gadsby image that one is coming from gatsby plugin image those are our two imports and now of course we just need to set up the functionality now i know that i'm getting my recipes prop correct and that's where i have my recipes alright so simply destructure it right away in the parameters and since i will use it all throughout my project i might as well set up a nice default where i say that if recipes are not provided then the default value will be empty array so again that way you just avoid some unnecessary errors then as far as the return i want to iterate over my recipes so the list that is going to be passed in and for return we're going to go with div and we're going to add class name so we get a little bit of styling recipes list and now let's iterate over our array so inside of this div i'm going to set up recipes that's the name of course for my prop and i know that it is an array and as far as the parameter i'm just going to use the name of a recipe and what i want to return for each and every recipe well let's just start very simply by saying return and we're going to go with paragraph and i'll say recipe title just so we can get something on the screen and of course then we'll work on more meaningful return and how do i know that the title property is there well i simply know that because when we take a look at our graphql what do i have there i have the nodes and then inside of this node i have my tile property and don't worry we can also cancel log here and you'll definitely see that as well you'll see that object and then once we save we have banana pancakes and rest of them as well and again if you want to double check where we're getting this info now again there's going to be some warnings because we're not using the key prop yet don't worry we'll do that but take a look at our console we have four objects so we have an array and i'm just iterating over that array and then for every item i'm getting back this object now of course we just need to construct our return so it looks more like this like these cards here and the way we're gonna do that i'll right away the structure those properties out of my object so we go here with id we also want to get a title we want to get a image and we're going to go with prep time and cook time cook time here and all of that is coming from my object and as far as the return i'll right away wrap it in a link and i'll provide a dynamic value so the way it's going to look like i'm going to say link and then we need to add a to prop so where we're going to navigate once we click on this link however in this case i want to set up a dynamic value so unlike the previous cases where i was hard coding i said go to the forward slash home or about or whatever we need to keep in mind that eventually there's going to be a page for every item and the url is going to be forward slash and whatever is the name of my recipe now there's going to be some magic where we'll add these hyphens in between as well and when i say we of course i mean gatsby but we don't need to worry about that just worry about the fact that we need to set up our links with forward slash and whatever is the name of the recipe just keep in mind that we have four so that's why we access this variable name where we say okay so we're gonna navigate to and we'll set up here a curly braces because we want to go back to the javascript plan and since i want to access a variable i'm also going to set up right away a template literal i'll say forward slash and then whatever is my title so we're passing in this dynamic value for our url okay let's save that one so now of course we have them as links but like i said we haven't created those pages so of course the moment you'll click on it you'll have the error page because notice these are all the pages we have and we don't have one for forward slash banana package or greek cribs or vegetable soup we will create those pages later but i right away want to set up these dynamic links where the values depend on the title that we get out of the recipe let me just navigate back to the home page or recipes it doesn't really matter and then inside of the link why don't we also right away set up a gatsby image and so i want to set them up as cards now i do want to add a little bit of styling here and i'll say a recipe that's the class that is coming from my main css and also since i have a list in react i need to add a key prop and something dynamic now in this case something dynamic and unique is going to be my eddy something that the contentful already provides for me and then inside of the link i right away want to set up my images so i have the card and each card has the image and of course that represents that particular recipe and i already imported a gatsby image component since i have dynamic images the value of course is changing from one recipe to another one so it's not the same so it's not static and here we go with gatsby image component we have image prop and initially i will drill down to the property by the name of gatsby image data and then later we'll use the helper function as well again if you're a bit lost of what's happening remember we are querying for the image and then inside of that image we have gatsby image data object and this is a giant object that provides all the necessary values to our component to our gatsby image component and this is also where we passed in our options so now we simply need to go with image that's the name of the property and inside of it we have this gatsby image and data property that's all we have to do now i have some css in place so we also want to go with class name and recipe hyphen img and also as far as the alternative we can simply pass in the title so whatever we have as a title value we can just simply pass it here i'll close it and then once we save notice we have our nice images displayed on screen as well and then right after the gatsby image i'm going to go with heading 5 with my title so i'm going to go back to javascript plan and i'll access the title variable and then we have paragraph with two values we have one for prep time and second one for the cook time so let's go prep and colon and let's access the variable so prep time here and then second one will be cook time and you know what it's also out here min and i'm going to add that vertical bar and i'll say cook and of course this one will be cooked time so we save it and if we navigate to the bigger screen there should be no warnings in the console okay that's good and we can also see the prep time as well as the cook time now as you're hovering notice these errors we'll have them for time being so these are different these ones are because gatsby is trying to pre-fetch that page which will eventually set up and of course the moment the page doesn't exist so don't worry about it we'll fix it later now one thing that is missing here is cook and i also want to add a min and then let's also utilize our helper function so at the moment i'm accessing my image property and gatsby image and the way i set up my contentful the image field is required but just in case the image is missing so there is no image property but i'm still trying to access a property on that image since i don't want to get that big fat error i can go with my get image remember that was my helper function and simply we can set up a new value again i'm going to go with path to image and that will be equal to get image and then i simply need to provide my image property so i go here and instead of image we simply go with path to image so once we get to the object where the gatsby image data is sitting we are in good shape notice we provide that one and everything works now if you'll mess this up nothing bad is going to happen so if by mistake i type here recipe that's not going to be a direct parent of my gatsby image so once i save notice my images are just missing but i don't have those errors so this bug does not break my application which is super super cool and that's why the get image helper function is very useful so i'm going to go back to my image again that's where the gatsby image data is setting and once i provide that i get a proper path and we're in good shape where we have the recipes list in two pages we have it in the homepage as well as the recipes page and since we can access recipes as props that's our setup in our recipes list will just provide different value for recipes so in this case i'm providing all my recipes whatever i have currently i have four but if i'm gonna have four thousand then of course i'll provide four thousand in the all recipes however you'll see how in different setups will provide different data and while we still have our query in sandbox why don't we do just that why don't we worry about rendering recipes list with different data in different pages and then we'll switch back to the tags list because there's also a bit more functionality we need to do in order to showcase the tags like i have in the final project so first i want to go back to my sandbox and now let's think about the changes we need to make first i don't need to have tags here so i can simply go back to my explorer and remove the tags so i'm not looking for them i also want to change a little bit images so they're a bit different so instead of the placeholder option i'm going to go with a blurred one and probably the most important part is the fact that in this case i want to filter my response i want to get only the recipes which have featured set to true and remember we can combine all these arguments so i simply go back to my filter argument and then i'm looking for the featured one where it is where it is where it is yep there it is that's my featured and i'm gonna go with equals option and notice how it right away tells me that it is a boolean so either i can go with true or false and in my case i just want to set feature to true so only the items who have featured set to true so in my case three items those ones will be returned again it's going to be very hard to see in our response because of course we have that gatsby image data now if you want you can just scroll down and you can take a look at the total count that's one of the options let's scroll down and in my case it's going to say 2 which is weird because i told you that i set three of them so let me quickly fix that i'm going to go back here and let's say greek ribs okay that one was for sure no and let's see vegetable soup and this one i just didn't set up so by default it is going to be just false so something to keep in mind but then remember two things first every time you modify data in contentful make sure that you publish the changes otherwise you won't access the latest value so make sure the one that you just modified you also have it as published not just changed and second we need to restart our project because we want to get the latest data so i'm going to go with clear npm start i'll spin up my dev server and then i'll just have to wait a little bit and then once i have the latest data my total count should be equal to three and once the dev server is up and running if i refresh and if i run it and if we take a look notice of course now the total count is three which is exactly what i was looking for so now i can remove that total count and i'll simply use my code exporter in this case i do want to use the page query because we'll be setting up this query in the about page then we want to navigate back to our project and i'll start with about page where below my component i will set up my query okay awesome that is working then we want to make some imports here as well so at the moment we have a link we have static image but i also want to get that graphql from the gatsby so make sure that every time you set up the query you also import this graphql that is a must and then of course i want to get my recipes list again keep in mind something we're not talking about all recipes all recipes has both it has tags list and recipes list in this case i just want to grab the recipes list and we'll provide the value that we're getting back from our query so that's how we can reuse it in multiple parts of our application and every time we'll pass in different value so every time we'll just change what recipes are rendered so in the about.js i'm gonna go with import and i'm looking for recipes and list from and i'm looking in the components and then recipes list i scroll down and then right next to my first section i'm going to create another one now there's right away a class so i want to add a little bit of styling and therefore i'll go with featured and then recipes like so and then inside of this section let's start with a heading 5 and let's just type look at this awesome sauce awesome sauce exclamation point and then let's go with our recipes list and what's really cool since i have in a recipes list this default value if i don't provide something by mistake for example then nothing bad is going to happen so if i navigate back to my project and of course i want to take a look at the about notice how nothing bad is happening right so everything still works so if i take a look at the console yeah i have these ones but they have nothing to do with my current setup but if you go to the recipes list and if you'll remove this one then you'll right away have the big fat error because you're trying to render a component and that component is looking for a prop it's looking for a recipes prop however in the about page we're not passing that's why it's always nifty if you add those default values and again this has nothing to do with gatsby or react it's just straight up javascript where i say you know what if the recipes are not provided well simply treat it as an empty array and that way of course we don't have anything on the screen but what's important is that we also don't mess everything up and before we deal with the recipes if you ever have this type of situation where you can see that the image is not loading try running gatsby clean so i'm going to go back i'm going to stop my server and then we simply run gadsby clean and then we're going to go with gatsby develop and you'll see that everything is going to work once in a while you might have something all stuck in a cache so that's the reason why you have this box so if i navigate back and if i refresh notice how everything works smoothly and of course i have my heading 5 and at the moment i don't see any recipes because we're not passing them in and if you remember the difference between the component query and the page query is the fact that with a page query we don't need to use our hook we simply can access it if we take a look at the data property and in order to check that we simply go with data as you can see i'm right away the structuring and i'm going to go with console.log and data so once i navigate back once i refresh and all the way in the bottom i have my object and then inside of it again i have all contentful recipe and nodes and all that now the difference of course in this case is that this nodes array is smaller because we're only getting the items who have featured set to true and again if you want you can assign it to a variable just like we're doing in all recipes but in my case i'm to go with the structuring in the function parameters so i'm going to go back to about.js and then here i'll say that instead of the data there is a object by the name of contentful recipe and then inside of that recipe object i have nodes and i'll right away give it an alias of recipes again at the end of the day the functionality is exactly the same where now i can scroll down and since the recipes list is looking for recipes prop i can simply pass in my recipes and now if you navigate to about page and if you refresh by the way here i guess i'll have to save it one more time and there it is now of course i have my recipes however these ones are the featured recipes and i know i said this before but what's really really really cool is the fact that we can reuse this component so i can do the same thing in a contact page i simply need to go there and first i guess i want to start with my imports and you know in order to speed this up i will copy and paste so i'm looking for these two suckers and we're gonna do copy and paste okay awesome that will do the same thing with a query okay awesome and then all the way in the bottom in the contact page we'll set up our query and then the same thing we have access to the values in the data and in this case again let me switch back to the drilling one where i'm going to go with recipes is equal to data and then the value was all contentful and recipe and then nodes correct and of course i just need to scroll down we're going to go with the same section just like we have in about.js so i think it's going to be faster if i just navigate back here select my whole section and render it in the contact page as well and now if i go back to my big browser i can clearly see that i have my featured ones in the about page as well as the contact page again main takeaways are following where we change our query a bit so we look for different fields and i removed the content one then i added another argument in this case we're filtering for the recipes that have featured set to true and then we just set up two page queries one and about and one contact and in the page queries we access it directly in the component so we don't need to use the hook and we need to look for the data property and from there the setup is exactly the same where we have the component which is looking for the recipes and we just render the recipes list component and provide the value for the recipes prop not bad not bad i think our project looks nicer and nicer the moment we can display the recipes as well and up next i want to work on a tags but there are two major issues you see unlike the recipes we're not going to be able just to iterate over tags why well because tags are actually an array e inside of the items so we have array within the array and moreover there's a content property as well that's number one so our data structure is more complicated for the tags and second check out this is the result that i want so i want tags i want them in the alphabetical order and i want to showcase well how many food items i have with that tag for food i have four and then for beef i have only one so it's not like with recipes where we just took the array iterated over and then displayed the image title and all that unfortunately we'll have to do a bit more work and if you don't believe me we can just navigate back to the project i'll close everything here i'll close the sidebar and here as well and let's just simply go to components we're looking for the tags list here and then remember we're passing in the recipes right so i'm going to go with recipes and then if we cancel log you'll see that of course the structure is more complex so i'm going to navigate to the home page or recipes page it doesn't really matter since we render in both pages in the console and i guess i'll have to refresh in a console eventually i should see the tag list and that's again one of the unfortunate things where you need to hop back and forth just to get the latest results and as you can see so that is my array those are my four items and then those tags are inside of it so we have here a content property and then inside of it we have that array of tags and that's why we'll set up a separate function now why we're setting up the separate function to pull out those particular tags well because there's going to be more functionality and i want to reuse that functionality in the tags page so i don't want to set it up here and then copy and paste we might as well then just set up a separate folder and call it utils and then reuse that function so here's what i want to do i'm going to go back to the source i'll create a new folder and i'm going to call this utils once i create that folder then i'm going to create a new file and i'll say setup tags set up tags and it's simply going to be a function so i'm not going to set it up as a component i'll say const and then set up tags and it's going to be looking for one thing as an argument it's going to be looking for my recipes array so i'll just name my parameter recipes and then for time being i'll just return the recipes i mean we don't have any functionality yet and then of course i want to export it and since i'm not going to have more functions here i'm just going to go with export default and then setup tags and now of course i need to go back to the tags list and then import the function correct so we're going to go with import and you know before we import one and we also cancel log just so we can see that our import works because it's the worst thing ever if you spend half an hour on functionality and then something doesn't work but it's not the code it's actually the fact that you messed up on the import so i'm gonna go with hello from utils here just so we can see that our stuff works and back in tags list again i'm gonna go with setup tags from and of course i'm looking in the utils and more specifically setup tags and instead of console logging the recipes why don't we go here with setup tags and we'll pass in the recipes and eventually we'll get some new tags back so i might as well come up with some kind of variable there and i think i'm going to go with new tags so i'm going to say const new tags is equal to a setup tags and then we pass in the recipe so once we save if everything is correct then in the home page or in recipes page doesn't really matter we should see hello from utils and that's awesome that means that our function works at least the initial functionality and now we can just head back and pull out those tags from our array and before we continue let me just stress something this is by far not the only way how you can do it i set up my functionality in a certain way just because i thought that it's going to make way more sense for gatsby tutorial and if at any point you get stuck and you need more info i suggest referring to the javascript nugget series that i have mentioned already quite a few times because in there i cover the topics that i'm going to use to set up the functionality and also eventually i'm planning to add a video where i specifically tackle this topic and i try to do in multiple ways and lastly if you have a better approach don't be shy to share it and i'm going to start here by just looking at the recipes and we need to understand that of course recipes is an array correct so my approach was following where i'm going to create a new empty object so i'm going to go with const all tags is equal to an empty object and then i'm going to set up a for each and i'm actually going to iterate twice i'm going to iterate over recipes but then remember since tags was an array itself i'll also iterate over those tags so every time as i'm iterating all recipes i'll set up a forage inside of that recipe over the tags as well so go here with recipes then for each and then we need to set up some kind of parameter that will reference the item and in my case i'm going to go with recipe and then instead of my function body like i said tags are sitting where they are sitting in the content correct so we need to go with recipe not recipes but recipe so that's that individual recipe then we have content property and then we have the tags property which is an array so again we can use the for each and in this case i'm going to call my item a tag and instead of this function well we can start simply by console logging the tag so you can see what is happening again i'm going to navigate back and then notice in the console so these are all the tags i have and first i just want to add them to an object and not only i want to add them to the object i want to make sure that i add only the unique tags that's number one because if you take a look at the complete project i only have the unique ones so they're not repeating and second i want to count them i want to know well how many food i have how many i don't know dinner or whatever so how many similar tags i have so i'm going to go back and remember we have all tags object and here i'll simply set up the functionality where i'll say if all tags object has this particular tag then i just want to add plus one basically i want to add one value to that tag because if i have four foods then of course i want to count them now if the item is not there if there is no property on that object then of course i'm going to create one so i'm going to go with all tags and tag so if the property already exists i'm gonna go with all tags and tag plus one initially it's gonna be one and then every time there's a repeating tag we just add plus one now if the tag doesn't exist which can be our second option we're going to go with all tags and we'll create that property and we'll set that property equal to one and in this case i'm not going to cancel lag tags anymore i just want to cancel out the all tags just so you can see what is the result of our iteration and as you can see we have a object and we're counting the tags so for beef we have one for breakfast we have one like i said in my case i set up four food tags just so the functionality makes sense and of course i have two for lunch as well as soup and actually we are in pretty good shape we have the unique tags we have the values and all that but there's two more things that i want to do i want to turn this back into the array that's number one and second i do want to perform sort one more time to always make sure that we definitely have our values based on the alphabetical order so they're always sorted so i'm going to navigate back i have all the tags and then i'll create a new variable i'm going to go with const new tags and that will be equal to the object and then entries and if you're not familiar with this method it returns a property and value in the array and i guess the easiest one is the showcase by actually console logging new tags and if you go back to the console notice now i have array of arrays each item is set up as an array like i said property and the value and then that is all sitting in one giant array and once i have this one in place now i want to error proof it by running sort on this array so i'm going to navigate back and we're going to go with sort method now sort method iterates over array and we can access every item on that array and they're represented by some kind of parameters and in my case it's going to be a and b now since we're sorting based on the alphabetical order we need to keep in mind that of course i want to access the string not the value because at this point i have an array as an item not just one simple string and in order to access that string i'm just going to go with const and then i'll rename it first tag and that is coming from the a now this is actually arrayed structure the first item is going to be an array and then from the array get me the first item and again if you want you can cancel log it and you'll see that we're getting both strings so we're going to go with second tag is equal to b and then lastly as far as the functionality for the sorting i'm just going to go with the return and then first tag and then we have this awesome method in javascript where we can right away compare strings based on their text i can say locale compare that's the function name and then i pass in the second tag so not setup tag sorry second tag as a result you'll see that we are comparing those string values and we'll always make sure that they are in the alphabetical order and of course eventually i just want to return the tags so i'm going to go with return and instead of recipes we're going to go with new tags so if we go back to the tags list and if you console log new tags you'll see that again we have this array of arrays and these items are always going to be in the alphabetical order and each item is going to be array and then inside of that item we have a string so that's going to be the value and then we have the actual number so this represents well how many tags with this value we have and from then of course it's the same thing we just need to iterate over and then display the links to the tags pages awesome and once we have our array in place now let's just iterate over it and then set up the links to the tags pages again we do not have those pages yet we don't have for example page for the carrots and in that page we display all the foods that have a carrot stack now we don't have it but eventually we will set it up and therefore we'll have right away links to those pages and where we're going to do that in tags list of course we're not going to cancel log anymore that's it we have all the tags and we just need to work on the return and here simply we'll say that we're returning a div with a class of tag container tag container and we're going to start with a heading 4 here so say heading 4 and we're going to go with recipes so we save it because now we have the heading four and then there's going to be another div with a class of tags list so let's go with tags list and then instead of this div now i want to iterate over the new tags array so we're going to go with new tags and we'll map it over and then instead of the callback function i'll reference each item as a tag and we also need to get an index because of course we have a list in react and then as far as the return let's just simply start by returning a link and then we'll add all the necessary data so i'm gonna go with link now that is a named import and it is coming from the gatsby like so so for time being let's just display all the tags here so i'll simply say that i'm displaying a tag yep there's gonna be some errors and all that don't worry about it and as i said no for some reason i have here a template string so these are going to be all my tags okay that's good but just keep in mind that this is an array so it's not a string or number it is actually an array so again we'll have to do that array destructuring just like we do with use state i'm going to go with const and then the first item i'll name it as a text and the second one will be value again both of them are coming from the stack because it is an array and as far as the link first i'm going to set up the key prop because of course i have a list in react and i'll pass in that index that's number one then inside of it i'm gonna go with two values i'm gonna go with tag value and then the actual value as well however i'll place this in parentheses now again this is just for display i mean doesn't do any functionality as far as these parentheses and we'll say a value so again we'll save it one more time now you can see that these are all my tags okay nice and then lastly i just want to set up a two prop and it's going to be based on tag name now i notice here that i messed up a little bit it's not a tag should be here a text now of course it's gonna look like it should and back to the prop we're gonna go with two and again we're not hard coding this value because eventually there's going to be a page for every tag and therefore we go here with the curly braces we'll set up a template string because i want to access the value here and we're going to go with forward slash and then we're gonna go with text so again the moment there is no such page so once you save and then once you navigate to a beef page of course it doesn't exist don't worry we will set up those pages shortly and once we have our tags list in place we should see that in home page as well as the recipes page and while we're still on the topic of tags why don't we set up a tags page now the only thing we need to do here differently is setting up a graphql query so i want to get a query where i specifically only get tags now keep in mind that the structure actually is going to be exactly like we have in all the recipes so if you go back to this component notice of course we have the query we get the recipes of course we're using nodes and all that now in the tags page though we're only interested in this content property with a tags property because keep in mind that we'll still get back the array so we'll be able to pass the array into our setup tags function and of course we'll get back that array of arrays and if you want to see how the tags page is going to look like in complete project we have the tags here and then once we click on it we just navigate to that specific page where we get only the food items that have that tag that's it that's all we have to do and i guess first let me start here by setting up my query and simply i'm going to be looking for contentful recipe and you know what i'm just gonna remove everything and we'll start from scratch and i'm gonna go with explorer of course i'm looking for all contentful recipe i still want to get the list i still want to get all my recipes then nodes but in this case i just want to go with content and then tags that's it that's all we have to do we run it and notice again i'm getting back this array of actual recipes of course and instead of that recipe i have content property with a tags so the functionality in our utils function will still work so that doesn't change we're just not grabbing the rest of the items in the object and in order to export it i'm going to go with code exporter so grab here my query of course now i just need to navigate to the tags page so let's go to the pages directory there it is we have a tags below the component i'm going to copy and paste okay awesome then i'm gonna have to set up some imports so i'll go with import then graphql that's for my query and then the second one is of course linked because again they will be links both of them are coming from the gatsby and also i want to get those setup tags so in here i'm going to go with import setup tags and it's coming from myutils so let's go to the utils folder and setup tags and then inside of the component we're going to do the same thing where we go with new tags is equal to a setup tags and now of course remember with a page query where we can access this value so where i can get the nodes and of course the answer is in data property so we can destructure the data property and then pass the value into the setup tags now of course i need to pass in the nodes because setup tags is looking for that array so we simply go here with data dot all contentful again all contentful and then nodes and as i say note i need to add here a recipe recipe like so and now of course we just need to iterate over that array and display something meaningful in a tags page so for them being i'm just going to go to the tags page and then as far as the return i'll still go with a layout okay that still stays the same i'm gonna go with main tag here so let's set up a main tag and we'll also right away add a class name of a page so let's save that one and then inside of this main tag we're going to go with section and we'll add a class name of tags page so a little bit more styling and then again the same deal we'll iterate over those new tags and then for every tag will display a link to the tags page so let's go here with new tags then map again i'll reference each item as a tag and then we need to have a index and in here i'm gonna go with const and again i'm looking for text and value that is coming from my tag and then as far as the return well we'll simply go we return and then we're going to go with link here and we'll close it out and inside of the link in this case i'm going to go with heading 5 and as far as the value i'll pass in the text and you know what there's also a tiny bug i just need to add here a parenthesis and then right next to the setting five i'm gonna go with a paragraph i'll pass in the value value here and i'll say recipe and then the same deal as far as the two prop it's going to be a dynamic one so therefore we're going to set up template strings we'll say 2 and then i want to access my text value now i do need to add a index so we're going to go with key and we'll pass in the index again we have the list in react that's why we need to do that and lastly a little bit of styling so add a tag class as well and once we save we have ourselves a nice tags page and this is going to be the look on a small screen and this is how it's going to look like on a big screen and once we're done with our tags next we're going to cover extremely important and interesting topic and that is going to be how to set up pages programmatically beautiful our project looks pretty nice but every time a user clicks on the tags or the recipe he or she sees the error page why well because we haven't set up those pages and so far in the course every time we needed a page we rushed over to pages directory and then created either a folder or a file and then the moment we create that file of course we have the page but before we do that with tags and recipes we kind of need to think about it is this really the best approach am i really gonna go over all my recipes and create those pages manually and the same with tags and what for example if i change the name for the tag or name for the recipe am i really gonna hop back and forth and then try to manually keep my project up to date with my headless cms and of course the answer is no a better solution in gatsby is creating pages programmatically and we'll take a look at two approaches one approach that's pretty much the latest and greatest is file system route api and the other one is setting up in gatsby node and since i want you to be aware of both approaches for the tags we'll use the gatsby node and that one is coming up and then for recipes we'll use the file system route api now since there's a lot to unpack we'll do a bunch of small videos and also in the beginning just type out the code with me and then i'll go over everything in detail so first i want you to go back to your files and once we're here we need to look for pages directory so that's not changing however we need to create a file with a very funny name so basically i want you to set up the curlys and right away add js and then in here remember when we were setting up the query we used a field by the name of all contentful recipe now in your case if the name is different please use that name but in my case it was all contentful recipe and now we need to type that field without the all i'm gonna go with contentful contentful and make sure the syntax is exactly the same so again if the name in your case is different if you're named your content type differently make sure you use that name otherwise you're just gonna get an error so go with contentful recipe again without the all up front and then i need to look for specific field so in my case i'm going to go with title and of course later i'll show you that we have other options as well so once you create this file then of course i can zoom out so we create a file and then i'll use my snippets to create the component now this gives me this funny name of course i don't want to use this name so i'll remove it and i'll just say recipe and then template and inside of it i'll do the same thing there's going to be a heading 4 with the text of recipe template so we save it and just to be on the safe side i'll restart the server so i'll clear everything i'll close the sidebar and we're going to go with npm start and once the server is up and running i'll show you something extremely extremely cool and that is the fact that we created pages for all our items so if you go to a localhost 8000 and then just navigate to a page that doesn't exist so in my case i'm going to go with another page that is obviously not there and now notice something interesting i have pages now but the value e is 12. and if i keep on scrolling keep on scrolling check it out we have one for vegetable soup one for greek ribs and one for banana package as well as the last one here we iterated over our recipes and created page for every recipe now granted there's not much here we just have a recipe template but trust me this is a huge huge deal and then like i said since there's a lot to unpack i'll divide this into multiple videos just so you're not overwhelmed by the amount of info all right and i guess let's start with the most pressing question first what just happened well what just happened gatsby was smart enough to run this query and then for every recipe gatsby created a page and the url of that page is actually equal to the title and then if i were to have i don't know 20 more recipes i'll get all those 20 pages the moment i set up of course my query and the reason why we went with title here is because gatsby uses that property value when it sets up the url and since i want my urls to be more user-friendly since i want text instead of just some random id i prefer using the title now keep in mind you can use other properties that are in the object as well you're not limited to the title one and notice how this needs to be in the curly braces and then we need to add still this js and of course this is the field without the all and then i pass in the title so i go with dot title now you can set up a different property so for example if you don't like the title then of course you can go with dot and then id but the difference of course is the fact that the id is going to be used in the url and in the typical setup you want your urls to be friendlier and that's why you use some kind of text and effectively it's called slug if you're not familiar with that and what's super super super cool is the fact that notice the url gatsby is smart enough to take our title and then basically turn it into a slug into a usable url because if you're familiar with urls we cannot have a space in between so gatsby sets up everything in case and adds that hyphen in between and as a side note our current project still has the issues with the links that we created together and don't worry we will fix it in a second because at the moment if you take a look we actually still have the error if we click on this link because check out the url again we still need to fix it but when gatsby creates the pages casb is super smart and it right away sets it up as a slug okay hopefully that is clear so you can set up the query over here just make sure that you follow this syntax and then remove the all so in your case if the name is different make sure that you use the same name and then more specifically that title so for every recipe i have gatsby will create a new page using this template and then in the url i'll have the title of my recipe and you're probably wondering okay but what's the big deal i mean at the end of the day i still have the recipes template that's it that's all i have well remember that recipes template or recipe template to be more correct is still a page correct and remember that behind the scenes gatsby passed in a lot of useful information when the page was created and the same works over here if you go to the recipe template and if you type props and if we can't log it you'll notice something pretty pretty cool so let me navigate back i have my greek ribs now let me go to another page just so you can see the difference and again the easiest one you can just navigate to the narrow page and you'll see all the pages that you have in your project so in my case i'm going to open up a new tab and i'm going to look for my banana pancakes and let me refresh just so i know that for sure i'll see my props and if i open up the dev tools check it out now of course i have this params property and in the params primary i have a title and what is the value here well that is greek ribs now you can probably already guess that if i go to the banana pancakes page and take a look at the same dev tools i'll have a different value and you're correct because notice we still have this params property and inside of that object we have title now this style of course is different the same how the url is different so for every title we create that page and this is why it was important remember when we're setting up the headless cms i set up a unique value for my title so that way of course if i'm creating the pages i specifically create page for every item instead of creating i don't know some duplicates or something like that and now of course we can try to access this title and i'm gonna navigate back again remember the property name was params so instead of the heading four why don't we go with adding two here and we'll simply drill down we'll say props then params and the end title so now of course you'll notice that i have banana pancakes here and then in greek ribs because the title is different the title is unique to that page and again this is super super super super useful to us because now we don't have to manually create those pages gatsby does everything for us now there's still one piece missing and that is the fact that of course we need to go back to this recipe template and we need to set up another query and in this case we'll be looking for that one specific item so when we're setting up those pages we use this query so for every recipe we created a new page but in that template we'll actually have to set up a single query and in that query we'll use something that we covered at the very beginning and that is a query variables now first let me just showcase where you can get more info about the file system api and simply go to the gatsbydocks again and then we're going to go with search and we're looking for file system file system and route api that's the one that we're looking for and here you can find all the info so again there's more setups available and like i say notice here they go with pages and then in the product they set up the query you can set up a path inside of the folder as well just like we did previously with examples and then we have the query and notice how again they're not using this all so they're looking for all the products but they don't add this all and then by default there's always going to be this id but then since they add dot name so that is a different property then of course they get the name here as well now why is that important because we can also use the id when we're fetching data about that one specific recipe and behind the scenes they say that it is faster if you do it that way but i mean in our case we're just gonna use the title now as far as if you have a bit more nested structure if you have a recipe and then you have the field that you're looking for inside of the field that is an object so if it is a subfield then you go with a property you're looking for that is on the nodes object and then in this case they go with underscore underscore and then they look for the skew so again in our case if we were to have a nested structure then we go first with a contentful recipe then dot the property name where is that nested structure and then you look for the actual property so again if you want to find more info just navigate here but in our case we're pretty much done setting up the pages programmatically as far as this approach now of course we just need to connect the dots and set up the query in such a manner where it's dynamic because keep in mind again this is not just one single page basically we create page for every recipe so somehow we need to make our query dynamic where we can pass in that title value and based on that title value we'll get specific info about that one recipe not all of them but that one specific recipe and of course by doing so we'll actually have the pages for every recipe item all right and before we take a look at how we can pass in dynamic values into our queries so how we can start using the query variables let me just fix our tiny bug where currently in our project if i click on one of the cards on one of my recipes i don't navigate to the page and technically the page is there so this shouldn't be happening now the reason why is that happening because we just take the title and then we pass it as our url however if you take a look at the syntax that is not allowed so when we're setting up the url we need to have hyphens between the words now we don't have this issue with the tags so for example if you go to home notice tags is just one word anyway so it doesn't really matter so this is going to work we're not going to have to do that in a tags list however with the recipes list we need to sluggify our title now alternative is setting up another field in headless cms and again common name is calling the slug which just represents a friendly url and you can manually set this up some headless cmss offer this option where when you enter that field it right away has the type of slug and it does that for you in strappy as you're typing the title in our case it right away creates the slug for you like so that way we don't have to do this extra work but since contentful does not do that and since i don't want to go back and manually add them as slugs i'll show you how we can set that up programmatically and in order to do that we'll have to install another package and again this is not a gas b plugin this is just a npm package and the name is sluggify so we go with npm and of course we need to go with install and we'll just run sluggify we run this one and then once the package is in place i'm just going to go with npm start then we need to go to the recipes list and of course i want to import that one so i'm just going to go here with sluggify logify and that is coming from the sluggify so i get my function and this function will return my title in a manner that is acceptable as a url and we're going to create a new variable i'll call this slug and this is going to be equal to the sluggify then we pass in the title and then we'll set up some options and we do that by just passing in the comma and then the object this will take this string and this will sluggify for us so this will make it in a syntax that is acceptable as the url and here in the object we just say that we want to pass e in the lower and we'll say that it is equal to true so i want everything lowercase and pretty much we're done because by default it will add the hyphens in between and now if i change this around and instead of title if i access the slug you'll notice something pretty cool now once i click on one of those cards we will correctly navigate to our template if i go back to my home page and if i click on banana pancakes there it is now of course we navigate to banana pancakes now at the moment we just have the heading for there don't worry we're gonna work on that next but the idea is that every time you click on one of those cards we correctly navigate to the page because that's the url that gadsby set up for us because again this is the syntax we need to use when we set up the urls we cannot have spaces in between and with this in place now let's focus on the query that will fetch the data about this one specific recipe beautiful so how we can make our queries dynamic first let's back up a little bit and cover the basics we learned in previous videos so first i just want to remove everything and i'm going to go with my explore option and specifically i'm looking for contentful recipe field now we already know that this works so there is no issue here but of course we'll just get some random recipe because in order to get a specific one of course we do need to provide what well we need to provide the arguments correct so if i go here with the title yeah this is awesome if i'm looking for vegetable soup but if i'm not looking for vegetable soup then of course this is meaningless because yes of course i can access for example cook time here and everything is going to work but if i'm looking for my banana pancakes i mean what good does it do for me nothing okay so why don't we do this why don't we open up a new graphql sandbox just so i can get all the names since i will use them and in this case i'm going to go with graphql okay awesome and instead of this one i'll remove it we're going to go with explorer and let's go back to all the recipes so we're going to go with all contentful recipe then we're looking for notes and i just want to grab the title and we're doing that because i want to copy and paste and i think it is going to be faster and of course once we run it we get all the recipes and more specifically we get titles so now of course we can go back to our first sandbox and in here i can add the argument correct i can open up the explorer again and i can say you know what get me the recipe whose title matches to whatever i'm passing in and of course in order to do that i just need to look for my title 1 here and i need to say equals and simply we can start by copying pasting and in this case i'm going to go with banana pancakes so i'll pass it in and then once i run it i can clearly see by my title that this works so that's an awesome start of course because now if i'll add more fields here i'm going to get a specific data about this recipe not just some random one and of course we control that with our argument so now let's take a step further i want to pass this in as a variable and i must warn you that in the beginning is going to look useless you're going to be like well it's pretty much the same thing but trust me there's a reason why i'm showing you that first i'll just give it a more meaningful name i'll say get single recipe and now let's set up the variable you see we can pass in variables into our query now the way it works first we need to instantiate the variable and syntax is following where we go with a dollar sign and then the name of the variable now i'm going to go with the name of title but here sky is the limit just keep in mind that later we'll have access to the title variable simply because that's how we set up those pages programmatically so i strongly suggest you use the same name and then we just need to say what is going to be typed for our variable and i'm going to go with string okay that's a start and of course i misspelled it here it has to be a string and then of course i can use that variable so in here instead of saying equals to whatever text i'm passing in i'm going to go with equals and of course now i need to use my variable and i'll say title after that in query variables what i want is to set up a object and of course i need to give it a name for my variable which has to be exactly the same so since i'm using title here of course you can guess that i'm going to use title over here as well and of course i'll do the same thing where i'm going to navigate back and i'll just select one of the recipe titles and if i go back and if i run it now of course i get a specific data about this one recipe and i'm controlling that using the variable and like i already mentioned probably your first thought is following okay but what's the big deal i mean the only difference is that now i'm passing in my string where i have the variable instead of passing it directly in the query but the end result is the same every time i want to get that specific data i need to pass in that value and you're correct but here's the kicker what if i go back to my recipe template and i'll import graphql here so i'll say graph ql coming from the gatsby and then below my component i'll set up my page query and we do that by export then const and query and of course we just need to provide the value correct because we have the graphql so let's set up a graph ql tag template and i'll set up the template strings and of course i just want to copy and paste this query so i'll grab it i'll copy and paste and let's console log the props one more time so let's go with props here and let's see what we get back so if i'm going to navigate to vegetable soup one and if i'll refresh you'll notice something interesting where in the console i have the object again that makes sense but what do you see here in the page context i see the id and i also see the title and remember how in one of the previous videos i mentioned that when gatsby sets our pages programmatically it actually makes query variables available by default it will pass e and the id and then whatever field you set up in a query of course in our case that field is title and as you can see we can access those variables in a page context property now what's even better when it comes to query gatsby will pass that value automatically so we don't even need to do anything just make sure that the variable name is the same and again in our case the name has to be titled since in query the field that we're using is title and once we do that we are good to go so here when we are setting up our single query we just say that yes there is going to be a title variable coming in and for every page that value will be unique so we won't have to do that manually gatsby will do that behind the scenes the only thing we need to do is set up a query with a variable where we say yes we set up the file path using the title property so now this title will be set up as a variable and that value will always be unique and it will represent the actual title so therefore if again we go to banana pancakes in this case we can see that the same thing works here where now i have the page context and of course i'm getting the banana pancakes so basically what that means is that we just need to go back to our sandbox get all the properties that we want for specific recipe and then we'll be able to access that in our template and then for every recipe we will set up this unique page so i go to my recipes and i can click on any of the recipes and in there there's a query that gets specific data about the recipe and just pulls it in so that way of course we can have the page for every recipe hopefully that makes sense i fully understand that this looks scary a bit in the beginning where we have the syntax of setting up the variable we need to say that it is a string and then of course we just use it somewhere in our query that's why we did everything step by step where first i showed you how we would do that manually then we pass in the value ourselves and then lastly just remember that whatever you'll set up here e in the file path is going to be available as a variable that's why i said that in my case i'll definitely use my tile variable so if you use the different property of course then use a different variable and then once we pull the data we're pulling data for that specific recipe nice and once we know how we can access the variables in our sap template now let's set up a proper query in the sandbox and of course then we'll use it in our template as well so let me scroll up a bit now we just need to explicitly say which fields are we looking for so i'm going to grab all the content ones i'm gonna look for ingredients instructions also check the tags and tools then i also want to get the description but just keep in mind that since description is a long text it's actually an object so if we want to get the value we need to go with description and then description so if you run it notice this is going to be my recipe and if i keep on scrolling i have description object and then the actual value is inside of it with the same name that's just the contentful setup after that i want to look for prep time as well as the servings and finally let's not forget about the image correct so we're going to go with image we're looking for gatsby image data and then i want to go with a layout that is constrained and also i want to go with my placeholder and i'll set it equal to the traced svg so again i just grab this whole thing now and copy and paste in my template in recipe template so in a graphql i'll remove whatever i currently have and copy and paste and in the next video of course we'll set up the return but first i want to grab all the imports and then i'll also destructure it right away and you know what i'll start by removing these props because we need to understand that this is a typical page at the end of the day so the data that we're getting back from our query is going to be available in the data property remember every time we were setting up the page query the return was available in data so the same works here i was just showcasing the props for two reasons first the query variables are available in the page context gatsby provides them but i was just showcasing where you can find them don't worry you don't have to go with page context and then dot title i was just showcasing what variables are available to us that's number one and if you want to access directly the title property you can either go with pagecontext.title or params.title now in our case i don't want the title of course i'm getting the title here anyway so it doesn't really matter and that's why i'll remove the heading 2 and also console.log for props we'll simply get back the data but before we do any destructuring i just want to set up my imports and i'm going to go with import and first i want to get the gatsby image then i want to get a image function so from and that is of course coming from gatsby plug-in image i think i can make this one smaller a bit and also i want to get some icons because if you take a look at our complete project notice i'm using these icons for the recipe so we might as well import them right away and this one is going to be a bootstrap one so start with bootstrap and then clock and history then we have another one with a clock and the last one will be a people one so let's say bootstrap and people and that is coming from the react icons and we go with forward slash and of course the bootstrap one that should do it and after that i want to structure all our data just so we can see what we're getting back and in here i'm going to go with const and i'll set it equal to the data and then what is the field name well that one is this one the contentful recipe if you want you can give it an alias but in my case i'm just going to go with dot and contentful recipe so i'm getting back the object and then instead of that object i have contentful recipe property and the property is an object itself so now of course i can pull out the titles the cook times and all that so in here let's just go down the line we're gonna go title cook time and content as well as prep time prep time we have servings here and also we have description but just remember that description is an object itself so we're going to go with description e is an object and then more specifically we're looking for the description property inside of it and then lastly i want to get the image so i'll say this one and then right below it why don't we set up the path to image right away so we're going to go with const and remember we just need to pass in the object where the gatsby image data is sitting so we simply go with some kind of variable path to image is equal to get image our helper function and then of course we pass e in the image object and right below this one i want to pull out from the content if you remember content was an object with those arrays with ingredients instructions tags and tools and i will iterate over them so that's why i want to pull out all of those arrays i want to pull out the tags instructions ingredients as well as the tools and we simply do that by again setting up another line for the structuring where we go with tags instructions then ingredients just need to make sure that i don't do some dumb typos because i'm an expert on doing that and that one is equal to the content again tons of ways how you can set this up if you want you can structure it here or even in parameters it only depends on your preference for this example i just chose this one there's really no rule that says that you can do only one way and you cannot do the other way and then as far as the return let's simply set up our page as well as the div inside of it and then next video will display everything so for time being i'm just gonna go with a main tag and we'll add a little bit of class name we'll say here page and then inside of this page we're gonna go with div with the class of recipe page and then inside of his div since i want to see something on a screen again i'm going to go with a title one so for time being there's going to be a heading 2 with my title just so i can see that my structuring works and now of course i just need to navigate back to home page or recipes then look for one of the recipes and then once i click check it out of course i have my banana pancakes now just double check yep this is going to be four degree cribs and of course what's left to do is just grab all of these properties and set them up in a meaningful return not bad not bad i think we're done with the structure so now of course let's work on return but you know what i think i forgot in a previous video to get my layout so i'm gonna go with import layout from and of course we're looking in the components and then more specifically layout so now let's scroll down and then let's just wrap our return in the layout so that way we'll get our navbar as well as the footer and once we save of course now everything works and then there's going to be two parts of this return first we're going to have a hero where there's going to be a image with the title description some icons as well as the tags and then we'll get another set of columns where we'll display instructions ingredients and tools so i'm going to go back to the page to the recipe template and i'll remove that heading 2. i'll add a comment for the hero this is where i'll set up my section with the class of recipe and then hero and then we'll right away set up another section where we'll place the rest of the content so rest of the content and again this is where the instructions the ingredients and all that so i'm going to go to section and again same class name recipe and content beautiful and then let's start working on hero first and we're gonna have another two column layout where one is going to be a gatsby image and then the second one will be the article with the rest of the info so we just start here with our component remember image prop and then we pass in the path to the image that should work and then as far as the alternative i'll use the title property now i did add a little bit of styling to the container so i'm going to go with class name and about img let's close it and yep of course i have my gatsby image so that's the first column now the second column is going to be my article with a class of recipe and hyphen info and then inside of it let's go with heading 2 where we'll display title properly now and i'll scroll down a little bit and then we'll right away grab the description and then remember the biggest gotcha between the long text and the short text is the fact that description is an object itself so if i scroll down notice that's my title and this is my description and the only difference is that this is sitting inside of the object so keep that in mind then there's going to be a div with a icons and right next to it there's going to be a paragraph with a tags so let's right away set up the structure we're gonna go with recipe icons like so so that's where we'll set up the content and you know in here i'll say icons and then right next to this div we will place the paragraph so say here tags and then we'll just basically iterate over our tags and display it inside of the paragraph and i think we can start with this one so i'm going to go with paragraph and then the class name is recipe tags again a little bit of styling and then as far as the text i'm just going to go tags and then colon and i want to go with tags map now remember tags is an array and in this case we're not passing it through the setup tags the helper function we created this is just write-up array and i'll reference each tag with a parameter of tag surprise surprise and i'll also set up my index so tag and index because i have the list and i need to use a key prop and as far as return well i want to grab the link so it's kind of funny in last video i was getting all the imports and i missed out on two important ones so scroll up and just look for the link from the gatsby and then let's return here and then we'll go with return we're returning a link to now in this case again keep in mind the url will point to a page that we haven't created yet in the following videos we'll set up the tag pages in a similar fashion now we'll use gatsby not for that but the idea is going to be the same where for every tag there's going to be a page set up programmatically for time being we'll just navigate to the error page and we pass into now this is going to be dynamic again and that's why we need to use the template string forward slash and then we access the tag here so i say tag and then we need to add a key here so key and that will be equal to an index and then inside of this link let's display the tag so save and there is now of course we have tags and these are all the tags again these are links so once you click on them you'll navigate to the error page and then eventually we'll fix it now emmett i guess or the formatter he is trying to help me so i'll just remove this one this really has nothing to do with our return and then i'm gonna swing back to the icons and then in the icons we'll set up three different articles pretty much for every icon that we have and then of course we'll add some text there as well so i'm going to go here with article and in the first article i just want to display my clock so i'm going to go here not clock history just clock and again that's just a react icon and it is a component so we go with heading 5 with some text so prep prep time here let's save that one yep and also let's actually access that dynamic value so in here i'm going to go with a paragraph and we're just going to go with prep time and we'll add here min as well as that and that's our first icon so now let's copy and paste and we just need to change the values so there's going to be three of them second one will be a history one and of course this will be a cook time and the property also is going to be a cook time and then lastly we have servings so we're going to go with a bootstrap people one and in here let's access the servings value and let's also change here the text let's say we're getting the servings and once i save and once i refresh i should see three of them now of course i have all my three hong kongs and lastly we just need to scroll down where we have the recipe content and we'll have to set up a two column layout one is going to be four instructions and the second one will be for ingredients and the tools but again the idea is exactly the same where they are arrays so i'll set up some kind of html element and then in that element i'll iterate over those arrays and return something so for example for instructions i'll return this step one two three and whatever and then these will be the values for ingredients i'll simply iterate over the list and hopefully you get the gist so let's go back we have a recipe content and we'll start with setting up two columns first one will be article and it's not going to have any classes so we simply have an article and then the second one will have a class of a second column second column as you can see i was a bit lazy with the class name here and then inside of the first article this is where i want to set up a heading for with the text of instructions and you can probably already guess that we'll iterate over our instructions array since that's the name in my heading 4 so we'll go here with instructions it is an array so we can use a map and then i'll reference each item simply as an item just because i'm lazy and then as far as return well here's the thing i want to return a div and instead of that div i'm going to go with my step as well as the actual instruction so let's go back and we're going to go with return then i said we're going to go with div we do need to add a key prop we say here index and then also let's add a class name and we'll say single and hyphen instruction and then instead of this div i'm gonna go with a header and in there i'll set up my paragraph with that text off step so i'm gonna go with paragraph and then step now for the step you can set up the index however it's not gonna make sense because you'll have step zero one two and i think it makes more sense if we add just plus one we start with step number one instead of step number zero and then right next to it i'm going to set up a div and there's a reason for that that's how we have this horizontal line so let's save it and now of course we have the line as well and then right next to the header so not within the header right next to the header i'm going to go with paragraph and i'll say that i actually want to render that item meaning my instruction and now of course i have it now as you can see i was pretty smart and i iterated over the ingredients so my bad i need to go back to instructions instead and of course once i do that i have my proper instructions then we're going to scroll down to the second column and we'll set up two more divs in a similar fashion one four ingredients so the suckers that i was trying to render a second ago and then of course also for the tools so the setup is going to be almost the same we're going to go with div here and then we have a heading 4 with ingredients hopefully i'm spelling this correctly then we're going to iterate over ingredients and then of course we just need to go with our map again i'm going to be lazy and i'm just going to say item so whatever ingredient i have i'm going to reference it as an item and then when it comes to return we're going to go with paragraph we do need to add the key of course so we go with index then let's add a class name of single and then ingredient and then instead of this paragraph let's just showcase the item and now of course i have my ingredients and at this point i think i'm just going to copy and paste because it's going to be faster so everything starting with this div and ending with the closing one just copy and paste and we just need to change some values around where of course we have the last array and the name is tools so we go with tools then we are not iterating over ingredients we are iterating our tools i still reference this as an item and then the class name will be also a little bit different we'll go with tool and once we're done with our tools of course we can navigate to the bigger screen and that's our banana pancakes page and of course if i go to the different page this is going to be a recipe page for that recipe and hopefully you get the gist again key takeaways we can use the file system route api to set up those pages we pass the value the property value as a variable and then of course we can set up those queries using the variable name so in our case of course since i'm looking for the title property i have access to the title variable there i get that unique value and of course i can set up my query and get the data about that one single recipe nice i think we're in good shape now we have a page for every recipe where we display all the useful info and of course this data is only about this recipe so we get the title description and all that and now i want to do the same thing for the tags however for the tags we'll take a look at another way how we can set up pages programmatically and prior to the file system api which was introduced i believe at the later versions of gatsb2 gatsby node was the only way how you can create pages now don't think that gatsby node is a old way how you can create pages yes of course you can use the file system route api and it's an awesome way how to set up pages because you can basically do it faster because you'll see in a second that gatsby node is a bit trickier however don't dismiss this approach and there's a reason why i'm showing that because there might be some cases at least in the current gatsby setup where you still need to use the gatsby node approach because it just gives you more flexibility now if you want to find out more about gatsby node just go to the docs and more specifically look for gadsby node and essentially the way it works we can respond to events during the build lifecycle and we do that using the special functions that are provided for us so in our case we'll use a function by the name of create pages and you can probably already guess by the name of it what this function does so yes it creates pages for us that should do it for a theory now let's head back to our project and we don't have the template folder we don't have the gatsby node so let's just start with that so unlike the previous setup where we directly set up the page inside of the pages directory a common approach when you set up the pages in the gatsby node is to create another folder so let me just close everything here so i can start from the scratch and then in the source again name is up to you but a convention is calling this template like so let me zoom in that's my template and then inside of this template you create another file as always you can go as wild and crazy as you want but a typical approach is just calling it whatever page you're going to be creating so in our case we'll be creating tags pages and that's what i'll call this tag and then hyphen and then template and then of course i'll add the js now i do want to create a component here so i'll use my snippet and again i just need to change these values here because of course i cannot call my component like that and i'll just say tag template and then instead of just div let's just say tag template and page and once we have our template in place next i want to create that gatsby hyphen node.js file again this is the case where name matters and also the location so don't set this up in the source make sure that you're in the root and then in the root go with gatsby and of course gatsby and then hyphen node and yes so that's my file name and of course now we're back in the note line and you'll see why it's important in a second also keep in mind that every time you'll type something in a gatsby node you will have to restart the server that's why i'll try to move somewhat slow since that way i can avoid some unnecessary typos and bugs and as a result you don't have to watch me constantly restarting the server and like i said we have the api provided already for us meaning those functions that we're going to be exporting are already provided for us so we just need to access them and the setup is somewhat similar to what we have here in the gatsby config notice we have this module and then we're exporting the object correct and i mentioned previously that the property names here are important so the same works in gatsby node where again we go back to the node lan and that's where we use the node syntax the common js one where we go with exports so now we're exporting and the function name is important so we are creating a function here and the function name is create pages so now gatsby knows all right so this is going to be a create pages function and you just need to provide the values and i'll do the rest now from this function we need to return a promise and if you're familiar with javascript we can either use promises or we can right away set up a sync await and this is going to be my approach where i'll right away set up the create pages function as a synchronous function because that just means that by default it's going to return a promise and it's going to be easier to work inside of this function because we'll have to wait for some promises to be settled now since this is a function we actually get parameters and more specifically we're looking for the parameters of graphql again this is provided by gatsby it's not like i'm just making this up and then also the actions object and then right away inside of the function body i wanted the structure even more from the actions i want to get a create page function so i'm going to go with const and then create page and that is coming from my actions object keep in mind that of course if you want you can destructure it here instead i just thought that it's going to be easier for you to understand if we do it in new line and once we have our function now i want to set up my query and essentially the idea is similar to what we have here in the pages so if we take a look at the page folder we can see that we have our contentful recipe title and the idea is the same here where i'll have my query i'll get back the result and then i'll iterate over those nodes and then for every item i'm going to create a new page now of course the difference here is that we're going to be a bit more explicit where in this scenario gatsby does a lot of things behind the scenes so we just set up the query and we're good to go we say yeah get me all the recipes and then behind the scenes gatsby creates the page as well sets up the url and all that good stuff in this case we'll have to do more manual labor and first we want to start by invoking this graphql now idea is exactly the same where we pass in the query however since we are in a node land so this is not a react file now of course we need to use the parentheses so there's a little bit of different syntax and essentially the way it works i'm going to come up with some kind of variable and i'll call this a result and then i'm going to wait for this promise to settle because this graphql returns a promise and since i set up my function my create pages function as asynchronous i can just use a await keyword inside of the function and here like i said we go with graphql so graphql but instead of tag template we are going to go with a parenthesis because this is different this is a node file and then we'll set up the template string now second you're probably wondering okay but what kind of query we're gonna pass it in well the one that gets the stacks so if i go back and if i take a look at my sandbox and you know what i'll remove everything here and then i'm just going to set up a query where i'll query the all contentful recipe field then i'm looking for the nodes and more specifically i want to look for the content and then tags and you'll notice that once i run my query i get all my tags and that's exactly what i'm looking for so now of course we'll just have to set up the functionality and gatsby node where again we iterate over the nodes array and then more specifically we iterate over the tags array inside of it and then for every item we create that page so hopefully that makes sense just like we set up regular queries in the components in the pages as well as with a file system route api we do the same thing in gatsby node now in this case we do need to provide the value that is exactly the same as in our sandbox because if you remember in here the syntax was different correct we use the field without that all in front of it now when we're working in gatsby node no the query needs to be exactly the same and i think i'm going to start by giving it a bit more meaningful name first and i'll say get recipes so then take everything here and navigate back and copy and paste and just so we understand what is happening i will cancel log it now that just means that i'll have to restart the server and i'll have to stop it one more time because there's more code coming up but since i want you to be aware of what's happening i will do it so i'm gonna go with log and i'm just gonna set up some hashtags here and then i'll just showcase what we're getting back so the idea is that we still have access to this data object so that doesn't change now of course the difference is that we're working in the gatsby node and you could probably already guess that we'll have to use somehow this create page function and for now i just want to showcase what we're getting back as a result and notice right away the moment i open up the terminal it says develop process needs to be restarted to apply changes in gatsby node so always always whenever you do something in gatsby node remember to restart the server and then since i have those hashtags i just need to wait for my dev server to spin up and once it's going to be in full gear somewhere in the terminal i should see the result now if you don't see anything if there's some errors or whatever please troubleshoot because it's important that we get back this data and hopefully you can see i have my object and then inside of this object now i have the data property and as you can see the result is tiny bit different because if you remember in components we were right away accessing the object the data object that we're getting back in this case we're getting the whole thing so i get the whole object so that's also something that we need to be aware of and once we can access it now of course we just need to do a little bit of javascript magic where i want to iterate over the nodes then access the content and then more specifically tags and then for every tag we will run that create page function and we'll have to pass in that variable manually if you remember when we were setting up the pages with a file system route api gatsby provided that variable for us correct in this case we'll have to do that manually and the way we do everything and by the way just so i can have more room i will remove my terminal for time being and then i'm going to go with result so that's the object that i'm getting back the property name is data then more specifically i'm looking for this all contentful recipe like so copy and paste then i want to access nodes property and i want to iterate over it and i'll use my for each and i'll reference each and every item as a recipe so far so good then of course i want to access those tags now because keep in mind i'm just iterating over the recipes so i'm just iterating over my notes what i'm looking for is actually the tags since i already created pages for recipes i don't need to do that now i want to access the tags and we do that with the help of recipe then content because that is the property name then tags and then one more for each so we set up two four eaches and then in this case i'll reference my tag with a tag parameter and then inside of this function this is where we finally call this create page and then in the create page we pass in the object with three properties we need to set up the path so what is going to be the path for the page so for example remember when we set it up for the recipes meaning technically gatsby set it up for us we had a forward slash and then the title for recipe now in this case we are in charge so what is going to be the path well i'm going to set up my property first and then i'll say that the path will be forward slash and then whatever is the tag value because if you remember when we were setting up the links in the tags meaning in a tags list this is what i used so i have access to the text and i just passed it in the url so now i'm doing exactly the same where i go with path and it's going to be forward slash and the tag name now nothing stops you from adding more info here you can go here with tags and then forward slash and then tag now the reason why i'm not doing that is because when i was setting up my links for the tags of course i just used a forward slash so sky is the limit here just keep in mind that both of those values need to match and therefore i'll remove this tags one and i will save it and once i have my path in place next i need to provide two more properties i need to provide the component as well as the context property where we'll pass e and d variable now why do we need component because we'll need a template because if you remember when we were setting up the recipes pages well the file was used correct so the file where we're setting up the query that was used as a template however in this case we're doing this manually so we need to point to some type of template and of course we already have the template folder and then inside of the template folder we have a tag template so that's the file we're going to use so this is where we'll eventually set up the query with a query variable just like we're doing in the contentful recipe title one now i think i'm going to rename it my apologies i think i set it up as template and actually want as a template and then back in the gatsby node now i want to set up a component property so let me close my sidebar and make this one smaller and again the name here is extremely important you cannot call it whatever you want you need to go with component and then that one is equal to the path to the component however since we are in a node file we need to provide a proper path and in order to do that we need to use one of the built in modules and node and that one is the path one again the syntax is going to be a bit different because we use common js syntax and we just look for path so this one we don't need to install comes preinstalled with node and of course we have access to a bunch of properties and methods that this module provides now the one that we're looking for is path dot resolve which basically will point to the directory in our case it's going to be a root and then from there we want to point to our tag template.js so i set up here the parentheses and then i just say that in the source look for templates templates and then forward slash tag template if you have a different name please make sure that you use that name instead otherwise you'll have the bugs then i need to set up the last thing and that is actually the variable so again something that gatsby does behind the scenes when we use the first approach in this case we need to explicitly pass that value in and the way we do that the way we pass in that variable is by using the context property and it is an object and now we just need to set up a key value pair so first one is going to be the name for my variable and the second one will be value so in my case for the name i'm going to go tag and as far as the value i'll pass in the tag as well so this will be the name that i will use in my query and this provides me the value so now of course i just need to save it and restart the server and if everything is correct once we navigate to the error page you'll see that we created more pages in our project so now we're programmatically creating pages for all the tags so let's see that i'm going to clear everything and we're going to go with npm start and once dev server is up and running and if i don't see some massive errors in a terminal we should be in good shape where once we navigate to a page that doesn't exist you'll see that we have more pages in our project so let me just go to the browser hopefully everything works i will refresh and yep i should see it so notice the amount of pages i have now we have 21 so for every tag we also set up a page so if i navigate to the food of course i'll have my template and we can test it out in our project where either in a tags page or in recipes or home just simply click on a tag now of course i navigate to a breakfast one so if i'll go to the food then this is going to be a food template and hopefully you get the gist where again for every tag that i have i'm able to set up a dynamic page and in that page eventually there's going to be a query and i'll use my variable to access specific values and let's just go back and go over the setup where again we work in gatsby node we need to set up that file first it has to be in a root and since it is a node file we use a common js syntax with require as well as exports we create a function by the name of create pages and the name is important now we do need to return a promise from this function so we right away set it up as async and as parameters we have access to graphql function as well as actions object now from the actions object we access a create page function and then first we set up the query now since the graphql returns a promise we wait for it to settle and the difference in the syntax is the fact that since we are in a node line we set up the parenthesis and then inside of the parenthesis we go with a template strings and then we pass in the query then just like with a normal query we get back the result and then we iterate over our list now in our case not only we are iterating over the recipes since the tags are sitting inside of the recipe and is an array itself we actually iterate over a recipe and then inside of the recipe we look for tags and then we create a page for every tag and we do that by calling a create page function where we pass in the object with three properties a path property which just sets up a path in the url for that page so forward slash and then the tag name then we point to a component and this is where we use the path module where we go with resolve which points to a directory where the file setting in our case that is of course our route and from there we just point to a specific template which in our case is sitting in the template and then tag template and eventually we want to pass in the variable since we'll use it e in the query and we do that by setting up the context property it is an object and then we just need to come up with a name of the variable and the value so in our case we're setting up the variable with the name of tag and the value for this variable is equal to the current tag in our iteration and as a result you'll have more pages in your project that are created programmatically using gatsby node not bad not bad once we have the tag pages in place i think we can simply start by console logging so i think at this point i can close the gatsby known one and then back in the tag template remember these are still pages and we can access of course all the props from here i'm gonna go with props and i just want to specifically show you where we can access the value again this is going to be done technically by gatsby so we're not going to have to worry about it but i just want to showcase where are we getting the variable from so if you go here and then expect and of course this is going to be for the food and of course in this case again i'll have to probably cancel log for some reason i thought that i'm going to skip that part and there it is now of course i can see my path and then notice that page context same how we had with a previous setup but of course the difference in this case is the fact that in the previous video we set up that variable correct we set up that variable and here's the value so now of course again we can set up the query where we look for specific recipes that match the tag and now of course we just need to go to the sandbox and set up the query for that where we use this variable name by the name of tag and i'm going to leave this one open just because of course i'll grab once in a while some tag values just so i don't have to type it out and i'm going to go to the second one to my second sandbox and i want to repeat one of the previous queries because we need to keep in mind that eventually when we're setting up the tags page it's not going to be a single return like we have in the recipe page no what's going to happen in the tags if you remember we have the recipe list component and essentially i'm just going to get a array of recipes and i'll use that component to render those recipes if you go to tags where the value e is for notice now i have the list so the same list that i'm using in the home page same list that i'm using in recipes page as well as about page and hopefully you get the gist so this setup will be a bit different where we're not rendering info about one tag we basically get a bunch of recipes that have that tag value hopefully that makes sense so now let me navigate to my second sandbox and here i'll repeat our first query i want to get all the recipes that's why i use all content full recipe then specifically i'm looking for nodes and as far as which properties i want i want to get the id so select it here then i also want to have a prep time and cook time because remember that's what the recipes list is looking for it's looking for a list of recipes and more specifically those values so we look for prep time cook time then i also want to get a image so let me see i have the image i have gatsby image data and i just want to set it up as constraint so as far as the layout is going to be constrained and also for the placeholder i'm going to go with my favorite one i'm going to go with traced svg so that of course gets me all the recipes now i want to sort them first and second i want to filter them and i want to filter them based on a tag so first let's sort them and we're going to do that by saying all right based on the title field and we're gonna do the ascending one so we just go here we run it and now of course we are sorting it alphabetically okay that's step number one now second i want to filter based on a tag and remember in the gatsby node that's the variable that we're passing in in the gatsby node the variable name is tagged so set it up exactly the same in my sandbox where i'll say filter and then as far as the value well it is still going to be a content because the tag of course is sending in the content so i'm going to go with content then tags and then equals so effectively what we're saying here is get me the recipe where one of the tags is equal to the one that we're passing in so set equals and for time being why don't we hard code this and i'm gonna go with food so we can get more values so i'm gonna go here i'll pass it in and once i run it this should get me four of them now if i'll use another one if i'll use beef then of course i'll get only one value correct so we go here we set up the beef and this is going to return only one value hopefully that is clear again it's exactly like our previous setup and now i'm just going to give it a bit more meaningful name and i'm going to say get recipe by and then tag now i want to set up my variable again since i'm passing in the variable by the name of tag i'll set it up exactly the same in here once i tag it is going to be a string and now of course instead of hard coding this value it will depend on my variable name so i just need to go with a tag and then in the sandbox of course we'll have to hard code that so again we open up the query variables we set up the object and in here i say tag and let's just use the same one let's say food let's run it and again this will return all the recipes since i added that tag to all the recipes but then if i'll use i don't know i believe one of them was soup then i'm gonna get less because less recipes have that specific tag and now of course the setup is exactly the same where i simply want to take this one and something to keep in mind where if you go with code exporter notice how it omits the setup it omits the query keyword as well as the name so that's something to be aware of that if you'll just copy and paste essentially you'll get an error so make sure that you do this manually with me so we're going to navigate back to the tag template page then we'll set up our query and probably it's better if we import first the graphql as well as the recipe list because we'll iterate over so go with graph ql from and then of course this is coming from the gatsby then after that i'm going to go with my import and then recipes list from and in this case i'm looking in the components and then recipes list and then let's just scroll down and set up our query i'm going to say export const and then query and that is equal to my graphql and then of course we set up the template strings and now i want to pass in the query so in here i have a bunch of things open so let me just grab this one and again let me stress something the only reason why i use this tag is because that's the value that i set up in my gatsby node if you set up a different name of course use that name instead i'll copy and paste and then if you take a look at the props you'll notice that of course now we'll have access to the data and in that data we'll have that array of recipes again let's save it and let's go back to the food one and if you inspect and if everything is correct we have the object okay that's the props like i said we have the page context where we pass in the tag what's more interesting notice the data now now of course i set up the query i set up the page query again i have access to the data property and what do you know i have nodes array and that array has four items so what's the only thing left to do well we just need to go back to our tag template and again in my case i'm going to use the structuring i'm going to say i want to access the data and in order to set up proper syntax i need to wrap it in the parentheses so that's my property i will grab my recipes by drilling down so i'm going to say data and then again i need to use this guy all contentful recipe that's the property and then more specifically i'm looking for the nodes and i just need to pass in this recipes variable with its value into the recipes list so as far as the return again i'm going to go with layout and sound again i forgot to import that one so let's go here with a layout layout from and we're looking for the components and then the layout one i'll wrap my whole return in the layout and then inside of this layout let's go with a main tags again with a class of page and then instead of domain we're going to set up a heading 2 and for time being i'll just hard code that and i'll say tag name and then right after this one we're gonna go with div with the class of tag recipes and this is of course where we go with our recipes list and we provide those recipes so in some cases just going to be an array with one item and in some cases like in our example with the food we're going to have more recipes available so we save here we navigate back to our project we refresh and in this case it is complaining that there's some kind of bug so it tells me that the recipe is not defined and yep of course i made a small typo it's not a recipe it is recipes and then once we refresh we have our tag name something we'll work on in a second and notice these are all the recipes that have that specific tag so if i go back to all my recipes i have beef blah blah blah and if i go with lunch this is going to get me these two recipes now how we can get this one dynamic well if you remember it was in one of our props and more specifically page context prop and again behind the scenes gatsby is using it to pass it into this query but in our case since i want to showcase that specific value i can simply go with comma then page context and then where i have the heading 2 instead of the generic tag name i'm going to go with page context that's my object and i'll just access the tag and now of course this value will be dynamic and that concludes another way how we can set up pages programmatically ian gadsby and that is by using gadsbynodejs nice at this point we're familiar with two ways how we can set up pages programmatically in gatsby but before we continue let me fix two possible bugs with our current setup and in order to demonstrate that i'm gonna go back to contentful and i'll show you that i created a testing recipe and as far as the values they're very similar to our previous recipes now the gotcha here is in the json object if you take a look of course i have tags array but as far as the value for my first tag it's exactly the same as my recipe name and then also for the second tag i use two words instead of one and once i restart the server and i pull in the latest data i get two following bugs first if i try to navigate to a testing recipe page unfortunately i'm not able to i only navigate to a testing tags page and second if i take a look at my tag where i use two words now if i go here i can see that the url is following and that's definitely not what i want and also once we restart the server we can actually see this bug because notice gatsby is warning us says attempting to create a page testing but the page testing already exists and finally if you definitely want to see what is happening simply navigate to the page that doesn't exist and notice we have one page for testing one and this is in the tags and then if i keep on scrolling i have one for testing in the recipes as well now as far as the effects we simply need to go back to our gatsby node so let me close my terminal here and then i want to change the url where instead of setting up as forward slash tag remember i said we are in charge here so i can simply go with forward slash and then tags and then the tag value now since i have now a tag with a two words now of course i also need to implement that sluggify remember when we were setting up the recipes list we implemented sluggify now we need to do the same thing in three places or maybe more correctly in four places we need to do that in gatsby node we need to do that in a tags list tags page and also for the single recipe because there we also have the tags now gatsby note is in the note land so in here we need to go with sluggify and we need to use a require syntax so i go here with sluggify then i'm going to scroll down and then instead of setting up the tag i'm going to go with const and i'll call this slug or tag slug whatever and this is going to be equal to a sluggify i'll pass in the tag i'll pass in the options object and we'll say lower is equal to true and now instead of this tag i'm going to go with tag and then of course we're going to call this slug so tag slug okay let's save it now cats b is going to help me and restart the server or at least the browser or no it's actually restarting the server so let's see whether that works and now of course i'm going to close the terminal and then like i said we need to do that in three places first i'm going to go to the tags list now in this case we're back in the react land so we simply go with sluggify from and of course the package name is sluggify then scroll down and this is going to be the case where i want to speed it up a little bit and i'll just copy and paste so in the tags list i'm not going to call this tagslog anymore i'm just going to go with slug simply and then instead of going forward slash and then the text of course now i want to pass in the text into the sluggify and then forward slash tags and then the actual tag and like i said we need to do that in the tags page as well as well as the recipe page the single recipe page because that's where we also have those slugs meaning tags set up as links so let me save in the tags list and again in order to speed this up i'm just going to copy and paste and i'll start with a tags one so copy and paste and notice again i have the sluggify i just need to import so let's grab this logify here and then let's keep on scrolling again the url is going to be the tags and then slug and lastly let me do the same thing in contentful recipe page as well first let's start by importing the slug and up at the top i'm gonna get my slug then let's keep on scrolling and then notice i have those tags so now of course i just need to set them up first so let me go back here we might need to change something around because now of course i'm getting a string value with a parameter of tag so instead of text i'm going to go back to the tag this will be my slug and i'm going to go with my tags page and then of course i'm looking for my slug so once you save we should fix both bugs now let me go back to my homepage and of course once i navigate to the testing one and clearly see that i have a recipes page for testing not a tags page and now if i click on this nice rice check out the url everything worked i have a nice hyphen and rice and of course we can double check this by navigating to a page that doesn't exist so let's say here some kind of error page and i'll see that all my tags are under the url of tags forward slash and then whatever is the tag value and i nicely set up my own slug and then if i take a look at the recipes ones of course i still have the one with the testing so that's how we can fix the possible issue of the duplicating values when it comes to tags as well as the recipe name nice at this point we're actually done with our project but before we deploy our project to netify to setup hosting i want to add some small but necessary features to it and let's start by pre-loading our fonts you see our current setup works great especially in local development but if our user has a slow network connection he or she might experience some issues why simply because we fetch our fonts after our project loads what's the solution of course another plugin and just to make my case if i navigate to our local project and then inspect more specifically network and if i look for css we can clearly see that we're getting our fonts once our project loads and once we're done setting up our plugin effectively we will preload the fonts and let me start by navigating back to our project i'm looking in the assets i'm looking for css and then i'll scroll up all the way up up up up up up so let me see it's not what i wanted there it is and i want to remove my import like so or you can comment it out that is also an option so let's save that one of course now i won't have my fonts and by the way i'll probably need to restart here so let me stop my server npm start and probably i should have cleaned the cache as well so let me run gatsby clean and i'm gonna go with gatsby develop and then while the project is loading i'm going to navigate to gatsbyducks and then we're looking for the plugins and more specifically we're looking for the plugin by the name of web fonts now if you'll type fonts in search you'll see that you have many many plugins available and you can pick any of these plugins but let me just warn you that for some weird reason font plugins constantly get depreciated i have no idea why just be aware it when you make your decision and actually the same goes for the plugin i'm about to show you so the plugin we're about to install since you're going to be watching this video in the future at that point plugin might be out of date now i'm not saying that it will but i'm just saying it might be the case since again for some weird reason font plugins constantly get depreciated now if that is the case just simply look for a different font plugin the good news setup for all of them is almost the same so switching to a different plugin should not be a cause for too many headaches so i'll remove my fonts and i'm gonna go with web fonts instead that's the plugin i'm going to use as far as the setup we just need to use this command and as i said let's just check yep notice we don't have the fonts anymore so we need to prefetch them instead and at this point i'm going to stop my server we will install the plugin so let me see where's my terminal there it is install the plugin awesome and then the setup for all of them is pretty much the same where you'll have to set them up as objects and then of course the value for resolve property is going to be equal to the name of the plugin and then whatever options you want to set up meaning whatever fonts you want to use now for this particular plugin if you just want to use the google fonts setup is actually easier where again you have resolve and then within the options we go with fonts google and then of course we have the family as well as the variants so in my case i'm gonna grab this object i'm gonna navigate back to my gatsby config and then i'm going to keep on scrolling right after the contentful one i'm going to copy and paste my plugin web font and then i just need to change these values around in the main css you can see which ones i'm using so i'll start with the first one and i'll just copy and paste so instead of roboto i'm getting this one and as far as the variance i'm just going to go with 400 in this case and then the second one this is where i'll get more variants so second front family and then i'm going to go with 400 500 and seven hundred so let me do that four hundred five hundred and six hundred okay let's add a comma and one more time just to be on the safe side i'm gonna go with gatsby clean even though i already ran a second ago i'm gonna go with cats be clean and then get b develop beautiful and once the server is up and running you can just go to localhost 8000 once you refresh notice we're not fetching the fonts when our project loads but i can clearly see that i have my fonts because if i double check with my complete project the fonts are exactly the same now if you want to see where are we getting the fonts if you take a look at the head element you can see that we have some link elements with a rel attribute set to preload which just ensures that our assets in this case fonts are available earlier and as a result improve our project performance asam we're done with our fonts now let's work on our contact form and when it comes to form submissions in gatsby since we ship our project as static assets so there's no back and forth between the server and the user effectively we have two options first we build our own server or second we offload this task to a third-party service and since building our own server is definitely not an option since of course this is a gatsby tutorial i will show you my favorite service for handling forms in gatsby keep in mind you have plenty of options to choose from just utilize the search engine and you'll be in good shape and the service i like the most is called form spree and mainly i like it because it has generous street here and the setup is extremely extremely straightforward so navigate to formspree dot io so again the url is formspree dot io and then i'm gonna click on get started even though i have the account and i'm gonna go with my dummy one i believe it was let me just double check learn code mail.com learncodemail.com as far as the password let me pass in my uncrackable password here and then no i don't want to get the news let's register and once we do that they are asking us to verify the email okay good not a robot that's awesome and what's also really cool that you can actually use the service in local development so you can test it right away and once you verify the email address then look for the new project in my case i'm going to call this gatsby tutorial i'm going to create the project then i want to set up the form and notice here we have form name and i'm going to call this recipes form recipes form okay good let's create that form and once we do that notice the easy setup so that's the url we're going to use and if we keep on scrolling as far as the simple html setup it's following where we have the action attribute and then we just pass in the url and that's the same url so you can simply just copy and paste and of course we need to add a method of post so let's try this one out i'm going to copy these two values then of course i want to navigate back to my contact form so let me look for my pages and then inside of the pages of course i have my form now i'm not using the link so i might as well remove it here okay good let's keep on scrolling keep on scrolling that's the form and now we just need to add these two attributes and once we have the setup in place you know what just to stay on safe side i'm gonna go with npm start one more time and once the server is up and running i'll try to submit the form so i'm gonna navigate to the contact page again that's the local project that i'm working and i'm just gonna go with my name with some kind of dummy email and as far as the message i'm just going to say hello there now let's see the server is up and running that's good news so now let's try to step into form so i click here and check it out now of course i can see that the form was submitted awesome and if i go back of course i'm directed back to my project and effectively two things just happened first i got the email from the service from the formspree and also i can check in submissions and i'll see that i have one submission where i have the message name as well as email so basically whatever you set up with that name attribute will show up in those submissions so for example for me it was name message and email and of course i can see those values e in the submissions now if i navigate back to my email i can also see that i just got a form submission and of course there are paid options you can do more integrations you can do tons and tons of things i'm just showing the basic one but as far as get up and running with form submissions in my opinion formspree is a pretty solid option okay and let's also see how we can change default favicon and if you're not familiar with favicon it's an icon in the browser tab so this thing over here gatsby does provide a default icon and it is located in the static folder so we simply need to get our own icon and just replace it and while there are tons of resources for the favicons the one that i enjoy the most is this one and the url is favicon io then i usually go with the text option and i'll close the ad then let's keep on scrolling and we can change the font color we can change the background color as well as we can set up the text so in my case i'm gonna go with letter r and i'll leave the font color white and i'll just change it to my background so again in the main css i'll have my primary color this one over here then of course i just need to navigate back and then copy and paste hopefully it is going to work and now i simply just need to download and then once the download is complete you can probably already guess that we'll simply just swap them out and of course this is my download now i'll pop it open and more specifically i'm looking for that favicon ico notice they provide multiple options but we just need this one so now i need to go to my tutorial where i have the static folder i simply can drag and drop and i'll say replace and then you might need to restart the server or even clean out the cache so let me just first try by refreshing and actually it works even without doing those things so of course now i have a new favicon again the steps are following just get the favicon and replace the one that you currently have in a static directory beautiful and now let's set up a search engine optimization component or seo for short where basically we'll set up a metadata for our project and it's very useful if we want to increase the visibility of our site for relevant searches keep in mind two things first since it's not a seo course we'll just scratch the surface and second we'll start nice and easy with just bare bones setup and in a later course project we're going to take a look how we can set up a more complicated component faster by utilizing the gatsby dogs for starters the main idea is following where if i take a look at my source of course i'll see that i have html tags that's what the gas b returns and then of course we also have the head element and then instead of the helmet notice these meta tags so that's a metadata about our project so here we can control things like title description and that sort of thing now the thing is it's not like i can hack into it myself manually because keep in mind in our project we're just working with components correct so this is my homepage and effectively this is my component now once gatsby is done performing its magic then of course i get back this html and the way around it is by installing another plugin and in this case we're looking for gatsby plugin react helmet so you can either search for seo or just search for helmet and believe me with 1.6 downloads you'll definitely be able to find the plugin and then as far as the dependencies we need to install gatsby plugin react helmet as well as the react helmet so under the hood this plugin uses react helmet which pretty much is a standard these days when it comes to react applications and setting up the metadata and let's just grab those commands and of course i'll navigate back i want to stop my server and once i clear everything copy and paste okay that seems to work now i also want to add this string of course in my gatsby config okay let's keep on scrolling let's keep on scrolling and then somewhere all the way in the bottom but still within the array i want to install my helmet one then let's start up our server and i want to go to my components and create a new one and i'm going to go with the name of seo and then once we create this component then i want to start by setting up the react component and then i also want to right away set up my imports and we'll be looking for the helmet from react helmet so that's the package and also i want to right away get the use static query and the graphql because we will utilize the query here as well so let's start with our helmet one and this is a named import so we go here with helmet and then this is coming from of course the react helmet package and then once we have this imported like i said we're going to go with use static query and i also want a graphql tag template from and it's coming from the gatsby as far as the component instead of returning div i want to return a helmet component so we're going to go here with helmet component and then this is where we set up the meta information for example if i want to change the title of my page because at the moment i have localhost 8000 i just need to pass in a title prop and i need to set it equal to some kind of value now we will make this dynamic in next video for time being i'm just going to go with title is equal to home so that is going to be my title element e in the head element and then the value will be home and like i said we are returning a helmet component from our seo component let's save it and now of course i want to take it out for test drive so i'm just going to navigate to index.js then we go with import we're looking for seo component it is coming from of course our components and then at the very top i'm just going to go with seo component for time being we're not passing anything in we just save it and then the moment we do that well complains that cannot get it from the components because of course i didn't specifically say which one i'm looking for my apologies once we save we should see the title with a name of home and of course once i do notice now in my tab you can clearly see that the title of my page is home so that's the basic setup for this plugin where effectively we need to import a helmet component that is coming from react helmet then we'll need to set up props on that component and return from this component and then of course whatever meta information will set it up will be added to our page and if you're interested in even more info just navigate to the bigger browser window and let me refresh just so everything is up to date and then take a look at the elements if i open up the head element notice now here all the way in the bottom i do have my title tags so i have my title element and of course the value is home so everything works whatever i'll set up on the helmet component it will be added to my head element and in turn i'm going to be setting up meta information about my project all right so this works pretty great we can have title we can have it also in the browser tab but of course the issue is that if i wanna reuse this component at the moment i'm hard coding this value and we already know what we can do in order to solve this problem because of course at the end of the day we have the component we have the react component so we can right away set up two props and i'm gonna go with title prop as well as the description prop so these are the two things that we'll pass in and then in order to test it out of course i'll have to set up a description meta tag as well now this one is a bit more complex because we need to have property and there in most cases they set it up as an array so don't worry we'll get there let's just start by testing out the title so this is the first prop that i'm going to be looking for title prop and then instead of hard coding this home i want to go with title and what this allows me to do is to reuse this component so i take my seo component and now of course since i'm looking for the title prop i can render it in about page and then pass the about page value instead of hard coded home correct so first let's go back to the index just so we can test it out and of course we have now tile prop and as far as the value let's just write home and page and of course the moment i save it check it out of course now our title is different all right so let's write the same thing in the about page so let me select this one again in order to speed this up i'm just going to copy and paste and then i'm looking for the return and of course like i said we're going to go with seo and then as far as this title let's just say about and once i say i do have a tiny bug because i do need to close it out and then the moment i save everything seems to be working fine i just need to go to the bigger browser window and then once i navigate to about page again everything is working i have my title and of course the value is above because that's what i passed in the prop and the same thing i can see in my source code awesome so now let's see how we can pass in that description and like i already previously mentioned as far as description it is a bit more complex because we are setting up meta tags and usually you set up quite a few of them so the syntax what they're looking for here is following so we go here with meta and then we'll set it up of course with curly's and then we'll be looking for array and then it's going to be an array of objects and now for this meta description tag we simply need to say name so this is going to be the name of our meta tag then we need to go with template strings and then we just type description so that's going to be the name of our meta tag and as far as the content let's just set it up equal to our description to the prop that we're passing in but in the next video i'll show you how we can actually use our gatsby config and more specifically remember when we're setting up the site metadata well now set up a query to pull in that data and first i want to add the comma just keep in mind we're still working in the same object and we're going to go with content again that's the property name that we're looking for and then we pass in our description now i'll save and i simply need to go back to my index.js and i'm just going to write some gibberish i'm going to say here description and we're going to go with this is home page because in the next video we'll use our site's description and then i'm going to go back to about.js and in this case i'm looking for seo component of course and i just want to copy and paste now i do want to change the value around and i'll say about page and again the reason why we're just hard coding this gibberish is because in the next video i'll show you how we can pass in the site description so now i just want to navigate back i want to refresh and then if we take a look at the header element and if we keep on scrolling keep on scrolling notice here we have meta so the name is description and then as far as the content of course in the about page i'm going to have this is about page now if i'll take a look at the home page whereas this value will be different now of course i will have a this is a homepage all right and lastly in this video i just want to showcase how we can set up a language for our project now this one will be a bit different because this one we're adding on the html tag and the way it works in the seo component on a helmet we need to go with html attributes and then we'll have to set up an object and they're looking for the property of a language so they have a language property and you just want to set it equal to whatever language you want so in my case i'm going to go with english i will save and again once i go back to my project notice the html element now of course i have the language and that is set equal to an english so that's how we can add more tags to our head element by using our plugin beautiful i think we're in good shape but what's missing is our site's information if you remember in the gatsby config more specifically in site metadata we already have info about our site so why don't we try this why don't we pull in this data in the seo component and then utilize it and we'll have to start by setting up our query and i simply want to go with my explorer i'm gonna go with site i'm looking for my site metadata that's not a surprise and i'm gonna go with my title and description now i will run my query and of course i can see that i'm getting back my simply recipes as well as my description i just want to grab everything and i'm going to go with code exporter in this case and now of course i just want to take everything apart from export i'll navigate back to my seo component copy and paste and then instead of the component i wanna access that data and i know that i'm gonna be getting back my object and inside of it i have the site so right away the structure and i'm going to go with use static query and i'll pass in query and once i save there seems to be a cache bug so let me try this let me try clearing out the cache and once i run gatsby clean and restart the server everything is working as expected so now of course we're pulling our site's information and in here i'll use it in two places first i'll set up a vertical bar for my title for my page title and what i'm trying to do here is having a title with home and then vertical bar and then whatever is the project name and if you're interested how it's going to look like take a look at the complete project notice here we have home and vertical bar and then of course we have our sites title that's the first thing that i want to do and i simply need to change this value here where it's not going to be just title i'm going to go with template string then i'll access the value and i'm going to go with title then like i said we're going to go with our vertical bar and then right next to the vertical bar we'll place our site's title now where's the site titled setting of course it is sitting in sight select metadata and title now in my case i'm not going to structure it i think i'm just going to drill down to the property so let's go with site site meta and then data and of course finally i want to access the title property and again once we save once we refresh we should see these simple recipes and finally after struggling with it a bit now of course i can see my home page and also i have the site title now i think in the index.js i will remove this home page i think that's better and as far as description i want to make it more flexible where if i pass in the value for the prop then of course i'll set it up as my value for my meta tag however if i don't pass it in then i'll use our site description and the way we do that we go to the meta and then take a look at the content of course at the moment i'm looking for my description however above the return i can just set up a new variable and i'll call this meta description and this one will be equal to the description and i'll use the or operator so if the description is passed then of course we'll use it if not then we'll default to site description again we go with site site metadata and then description again the only gotcha here is this or operator i say get me a description if description is undefined so if it's not passed then use site description and of course i need to change it in my meta prop as well so i'm going to go with meta description and in order to test it out i'm going to go back to index.js i will remove it and i'll do the same thing in about so this is going to be my about page i pass in the title but i will remove my description let me save it and in order to test it out i'm going to go to my bigger browser i can see that title is correct and if i take a look at my head element somewhere there should be meta tag with a name of description and notice the value now of course i have nice and clean recipes so if i were to go back and actually add this description for my page so if i'll say this is about and then page then of course if we navigate back and again we just need to refresh and navigate to that about page of course we'll be able to see that the content is different and hopefully you see how it works if we pass in the description awesome then of course we'll use it if not then we'll always default back to site description and now of course i just want to set it up in all our pages again a little bit of copying pasting but i'm not going to pass in the description i'll always default back to a site's description and we simply want to start by setting up our seo component in 404 that's going to be our error and again we simply want to set it up in return so we go with seo and as far as title i'm just going to say error and then i'm not going to test it out right now i want to add it to all the pages and then we'll test all of them together that was my 404 then of course we also have the contact copy and paste we need to set up our seo component and we just need to set up our title so this will be a contact and then of course we're going to close the seo component then i'm looking for the recipes again we import seo component and then we go with seo and title will be equal to recipes again close out our component and then lastly we have the tags where again inside of the layout i want to go with seo component and then title and of course the value will be tags let's save this one and now of course we have two dynamic pages we have content full recipe and also a tag template so let's start with contentful recipe we'll get our seo component again as far as the return we just go inside of the layout but as far as the values now of course this is dynamic so we're getting the title and description for every recipe that we have because remember we are creating this page dynamically so here we simply go with title is equal to our title property whatever we're getting back from data dot contentful recipe and the same thing will be with description so we're going to go with description and we'll just pass in that description and of course we want to do the same thing in our tag template we navigate there copy and paste the seo component inside of the layout we're going to go with our title and as far as the value remember if we want to access that specific tag we need to go with page context and then dot tag so here we go with title and that one will be equal to our page context and then we're looking for the tag again i'll close my component and now of course let's go and test it out on a bigger browser window i'm first going to go to about page i can see that everything works i have my about and of course i have simply recipes then tags then recipes back to home then contact and then eventually i also want to test out my error page so just type some gibberish and we'll take a look at the error page and it looks like everything is working great and then let's take a look at our programmatic pages so in here i have my banana package and i can clearly see that everything works as far as the title okay and then if i take a look at my description that also should return some value and of course i can clearly see that i have my meta with my value that is coming from the contentful and lastly let's just take a look at the tags so now in this case i want to go to home and then take a look at one of the tags and once we navigate there you can clearly see that in the tab i have the correct value this is for the ribs and we're successfully done setting up our seo component beautiful at this point our recipes project is complete and now we just want to host our project online so everyone can see our awesome work when it comes to hosting you have plenty of options to choose from since at the end of the day our project just contains cluster of static files and for the most part we have two options we can build project locally with the help of gatsby build or use the continuous deployment where we utilize git and of course in the following videos i'll cover both options i prefer hosting provider called metalfi and i like it because the setup is extremely straightforward and i do offer generous free tier but of course like i said it's just one of the options out there now in order to create an account if you don't have one already navigate to notify.com again the url is netlify.com and just follow the signup link and once you create the account just log in this is going to be your dashboard and at this point we have two options we can do the drag and drop where basically we will build our project locally and then the second option is the continuous deployment where we'll push our project up to the github and then from there netfly will build our site for us so let's start with the simpler option first which is the drag and drop and then next video we will take a look at the continuous deployment and in order to set up the drag and drop you simply need to go to this site here and then keep scrolling keep scrolling and here all the way in the bottom you have this window so i'll make this smaller and maybe not this small but i'll set it here and what i want right now is to go back to my project stop everything and then clear my terminal then first i want to run gets be clean i just always prefer running this first and then we want to run the gatsby build now keep in mind something extremely important your local gatsby build will fail if you don't have this env production or if the values here are incorrect that's just the way it is that's why for development we have one and then for the production we have another one so make sure that if you do get some errors to first check what is happening with eme production and here we simply need to run gatsby and then build and now of course gatsby will build the production ready site for us and once the gatsby is done we can go to our folder and then of course we have the public one and this is where our production ready project is setting so at this point we simply need to take this public folder and just drag and drop again the setup is going to be pretty fast once you're done with gatsby build because middle file doesn't really need to do anything of course now we are in good shape and before we check out the site let me just change the site name so click on the site settings and then more specifically site name now if the name is already taken of course you won't be able to use it and therefore i'm going to go temp gods be tutorial hopefully that name is not taken so gatsby and notice how they will add this notify that app so eventually yes of course you can set up the custom domain that is definitely an option but for time being of course we're not going to do that and once i'm done changing the name i want to navigate to the url and this is my set notice how it is live because of course i have my netify that app good so let's see we have recipes we have tags everything seems to be working i can click on a recipe this is going to get me the individual recipe beautiful contact page yep still everything is in place and now let's test out that error like i said you always want to test out those arrow pages actually in production and just like that we're done with the drag and drop option and our site is live all right and next i want to showcase how we can use the other option the continuous deployment where basically we set up a github repo and then nettlefly does the building for us so it is smart enough to check if there are any changes in our repo and the moment we push up some changes then nullify restarts the build process since this is somewhat of a advanced course i'm not going to go over the basic git commands as well as how to set up a github repo if you need to brush up on that please utilize the search engine so i'm staring at my github dashboard and i want to create a new repo and since i'll remove it once i'm done with this video i'm gonna go with temp gatsby and then tutorial okay awesome and i'm gonna go with public one i'll create the repo and i right away wanna copy and paste these three commands because i want to point the url to the repo and i guess let's start by navigating back i'll clear my terminal and i want to set this up as a github repo so just in case it is already a github repo i'm just going to go with rm and rf and git i remove the github repo and then i'll create a new one get in it then i'll add all the files and again just make sure that you have a git ignore and that you're ignoring the env variables otherwise everyone will be able to see your secret api case and i'm just going to go with git commit and i'll just say first commit and then i'll copy and paste those three commands so now i have the url pointing to my repo and then from there i simply need to go back to my repo refresh and of course this is my project and once i have my repo in place now of course i want to navigate back to the netify and i'll create a new site however now there's the other option new site from git and as a provider i'll pick my github and then more specifically i need to look for my temp one so let's say i have temp and then once i find my repo so temp gatsby tutorial then we simply need to set everything up and as you can see i have the owner i have the main branch okay that is correct and then notice how right away netify sets up the command the build command so this is what i said netify will build the site for us and then as far as the published directory it is public so make sure that these match now in most cases netflix is smart enough to get the correct commands but if you do experience some bugs make sure that the commands match exactly that because this is where our gatsby project will eventually sit and also in our case since our project is more complex we want to add this env variable because we need to keep in mind that since netflie is doing the build process of course it also needs to know well what is the value here correct otherwise everywhere where we use that can be variable nut fly is going to be like hey listen you want me to provide some kind of value here but i have no access to it and therefore we're gonna go with show advanced and in a second i'll show you where we can do that in the dashboard as well just in case you ever forget so here we go with new variable and now you want to go back to your env file take the contentful part and then do the same thing with the value so select everything and then copy and paste and then of course we just need to go with deploy site now i can tell you right away that the process takes longer therefore i'm going to go back to my dashboard and i'll simply remove this site so in the process i can show you how you can do that so go here to the site settings again keep scrolling keep scrolling and notice we have this option of delete the site so i'm going to copy and paste we delete the site then i'll add the same name for this guy notice we're still building and again we do that in the site settings change site name and then i'm gonna go with the same one so i'm going to go with temp gatsby tutorial we save it that's awesome and then as far as the build process if you want to take a look what's happening or if you want to check errors if you do get some then go with deploys and then notice this is our current build so in here you'll be able to see what is happening as far as the build process now if you ever want to change those env variables if you want to add a new one or maybe change it then again you're looking for domain settings and more specifically you keep on scrolling or no sorry you're looking for build and deploy and then of course we have the build command we have publish directory so this is also a place where you can change that keep scrolling keep scrolling then we have hooks which we're going to cover in a second and then of course we also have the environment variables so notice if you ever want to add a new one or edit the existing one again look for this window and then more specifically for the edit variables option so let me navigate back and i'll take a look at deploys now the network is still building like i said this will take longer because now netlify is doing all of the work and it looks like everything is nice because my site is live and again if you ever need to check for the errors or what's happening just navigate here and you'll be able to see what's happening with your project so i'm gonna go back to my project and again everything works pretty nice now why do you want to use this option why do you want to go with continuous deployment even though it looks like there are more steps involved simply because at the moment i'll push a new change up to my repo netify will rebuild my site for me so i'm not gonna have to do this manually and as always the most basic and drastic probably way is simply adding some kind of background color so let me scroll down and where it is where it is body and then instead of the background of whatever i have as a css variable i'm just gonna go with red now i don't think i'm going to run it locally but i'll right away push it up and i'll say testing testing background and red let's see okay i want to push this up and as i said i'm using the visual studio gui for this notice we just need to add a message then i click on commit and then in order to push it i go with a push option and now of course i just need to double check that in my repo so let's navigate here that's a fresh notice i have testing background red so that's good and then what's even nicer that if you navigate back to your project you'll notice that there's another build process started by the nettle fire so again netflix smart enough it has hooks right now in the repo so now every time we push some kind of change metal fire will rebuild the site for us and at this point i'm not going to wait till the build process is complete since that seems like a waste of your time and once everything is done i'm just going to showcase that of course the background color for our project is going to be red and once netflix is done building my latest project of course i can just double check and i can see that everything went fine and we of course can check out our full project as a very very quick side note if one of the build processes is going to fail then of course it's just going to revert back to the old one so for example if this for some weird reason would have failed then we would still be using the original one something to keep in mind and let's just test this one out and of course now my background is red so hopefully you can clearly see the benefits of using the continuous deployment all right and as a last thing in our first project i just want to showcase how we can utilize the webhooks now before we do anything webhook related let me just remove this background color because it really annoys me so let me go back to my background color again i'll make another commit in this case i'll say back to default and then we push this up like i said i'm using the gui and i'm just going to go with push and as far as the web hooks the idea is following where if i go to my content folder right now and if i log in and for example add a product with our current setup either we need to go manually to netlify and restart another build here you can clear the cache and trigger another deploy or we need to add some kind of change to our project and then push it up to the github because we know that the deploy process will be triggered that way as well however there is a better option we can actually connect it to where we set up something called webhooks and the main idea behind the webhooks is that we send a post request now in netflix we need to go to our site again we're looking for domain settings more specifically build and deploy keep on scrolling keep on scrolling and notice we have this build hooks now we add build hook here and we just need to come up with a name here i could say contentful contentful recipes we save it and then we want to copy and paste this value so we copy this one so this is going to be the url where network wants us to send a post request and then if we go to contentful and more specifically settings and then the webhooks we can simply add that value i want to add a webhook now for the name here of course we're dealing with contentful now some names don't need to match is just something that makes sense to the contentful and then we copy and paste the url this is where we need to paste and here i'll say nettle file recipes just to showcase that those names do not need to match so we save it here and what's gonna happen every time i'll make some change to my project again netlify will restart the build for me and i think the easiest way for me to showcase that is by removing a item so i think i'm going to go with this one i'll say on publish and notice how we cannot directly delete it we first need to unpublish then click it one more time and then delete it and i can right away see that something is happening if i take a look at my web hooks because i have right now the successful calls and if you click on it notice there were some http requests okay that's good and then if i go back to my notify application and more specifically again i'm looking for deploys notice i have another deploy triggered by the hook now of course if you want to be more specific when you will send those post requests then you need to do that when you're setting up the webhook because notice by default it is triggered for all events but just keep in mind that in some cases it might get annoying where you have data for multiple projects and then every time you change one data then you're rebuilding all your projects so we're not going to cover that but just keep in mind that you do have the option of only triggering that if there is a specific event and now of course i want to go back and once the build process is complete let me just navigate to my project i can clearly see that i have only three recipes and that just means that we're successfully implementing the logic this concludes our project hopefully everyone enjoyed it and i hope to see you in the next one
Info
Channel: Coding Addict
Views: 18,354
Rating: 4.9886041 out of 5
Keywords: gatsby.js, gatsby, gatsby v3, gatsby.js v3, gatsby.js tutorial, gatsby tutorial, gatsby.js v3 tutorial, gatsby filesystem route api, gatsby-plugin-image, gatsby image, gatsby contentful, gatsby.js v3 image plugin, gatsby.js v3 css modules, gatsby.js v3 project
Id: JlxXHlygVLM
Channel Id: undefined
Length: 559min 13sec (33553 seconds)
Published: Mon Apr 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.