Build a Portfolio and Blog website using Next.js, GraphCMS(HeadlessCMS) and Tailwindcss - Part 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone hope you're doing well today we're going to be building a portfolio website with portfolio items such as you know with an image your description and things like that suitable if you're you know a web design agency or a hair salon it's it's really multi-purpose we're going to be building the front end of that in next.js we're going to be adding a blog to it as well with authors for the blog and yeah we're going to use nextgs on the front end and graph cms on the back end so it's a headless cms it's we're going to be using graphql now my normal go to is you know for my website i would just use markdown for the content and this is really aimed at businesses that want to have that collaboration so you'll see with graphcms you can have on the community edition i believe you can have you know up to five users on the project and it's it's a really good headless cms there's a lot of options there's a lot of similar options however this is what we're going to go with for today and we're going to be using graphql to query the cms and of course there's not going to be any mutations or or writing because everything is going to be managed on the back end and then we're going to be styling out our website with tailwind css now i want to go a bit slower through the through this and make it more more in-depth so yeah i'm going to take my time with it it's probably going to take a few hours to uh to get this done i'm not going to focus too much on making the styling amazing um because you know that that will take um potentially weeks to make it you know absolutely amazing but we're just gonna do some some basic styling but actually cover cover it a bit more in depth than i usually would so the first thing that i'm gonna do is create my create my next guest application so let me just course so if we just do the usual npx create next app and then we're going to put in the name of our project which is just going to be portfolio let's just call it portfolio let's just leave it at that so now that we're doing that i want to um i want to start doing this we're going to have like three distinct sections to this overall video so the first one we're going to set up our model well models within graph cms and we're going to configure the the headless cms that's going to be what we're going to do all of that first the second stage we're going to get all of the data in our application setup on the front end get all the routes done get all the data done and then finally we can worry about the styling at the end once we've got the data into our pages so i'm just going to hit sign up for graph cms and then sign in sign up with github so we agree to the terms sign up with github and then we're going to authorize graph cms so basically we're just logging into graph cms with github and you can see we have a few different options so we're going to go with from scratch and do it from scratch so we're going to call it portfolio so you know it's just going to be a business portfolio website let's go with that and you can choose the the server with the lowest milliseconds to yourself or to your users more importantly but um we're going to go with the europe run and this is now creating our back end you can select the community plan and i think the community plan is quite generous certainly the way we're building out our website with static generation we're not going to be using a lot of these requests so you can see now we've got a relatively simple user interface and let's begin setting up our schema so the first one i'm going to add let's add our port folio schema like so and then so create model we've created the model portfolio and we can we can start get going so single line text for the title so we're going to just say title so we've got a display name the api id we're not going to we're not going to use descriptions or anything we can use this as a title field validations it needs to be required and that's it you can limit the character count on a title to something like 150 i think that is absolutely fine um let's go with 200 just in case so we've got a title i think another thing that we might need is like tags so we might want to say is this is this portfolio item in our instance it's going to be is it design is it brandon is it development so what we can do is we can do single line text let's call this tags and then we can allow multiple values and validations again they don't need to be unique or anything like that this this way of doing tags it will allow for kind of an endless amount of different tags so we could be we could be a lot stricter with this um and yeah we could just say you know you've got a a list of five different things to choose from but for now let's just do it this way we're going to want to have a image so main image so we'll call it a cover image like this we don't want multiple assets on this we want it to be required and no initial value and what that's going to allow it's just going to have the the asset picker on the the cms so title tags a cover image let's do multi-line text rich text i kind of want to do markdown oh mark down there we go so yeah our portfolio items and our blog posts are going to have markdown so we're consistent so let's just call this content validations we need some content that is fine and then we could just do a description because i'm just imagining on the on the where we're displaying all of our portfolio items we're going to have the title the description let's do description and again this can be required because it's part of going to be part of the front end it needs to be consistent so we got title tags cover image content description what else do we need yeah a date for the project so dead if you notice we do get um like published out and updated so we can just use those to be fair publish that i think is going to be absolutely fine yeah no actually let's just add a date so we can we can pick the date ourselves um so this is going to be required as well and i think for our portfolio there is nothing else that we need title tags image content we got a description a date yeah not really not really thinking of anything else and i guess you know if this was a real project you would clearly spend a lot of time thinking about this i like to just you know for these videos just you know i haven't made this we're not copying code from anywhere i'm just kind of doing it as we go um because i think that's the best learning learning experience for for you watching however yeah if this was a real project you would have the clearly defined content structure before you start so now that we've got our portfolio model let's add our post model so this is going to be for the blog again i think blogs are most businesses have a blog now um so this is a title field it's going to be required what we will need ah we need on our s we need a slug a slug field so display name is log api can i id can be slug it's look we're going to generate from other fields and we're going to choose tile like so what this is going to do is when you type in a title it's going to automatically generate the slug from that title field although if we didn't do this they would have to type in a slug themself and then this one needs to be required it needs to be unique and we limited the character count on the title so we don't need to worry about it for a slug okay so we've got that on our portfolio because we're gonna navigate to individual portfolio items um using that slug so we're going to need a slug for this as well slug generous look from template same thing like tail it's already unique we need this look let's go with that i'm going to do a multi-line text for an excerpt for the blog this is going to be required because again we're going to be showing this on on the front end so i want every every blog actually let's go with let's go with description because i think this is a bit more apt because we'll use it for our seo description as well when we get into that so it's required um fine we're going to want to have a image so if we choose asset picker um again let's just call it a cover image we don't want multiple assets it needs to be required all of our blog posts need an image in fact no let's let's let's have a blog without cover images let's do it this way um titles look description we want our markdown content as well so let's call this our content we need content we're going to need for a blog i'll be more inclined to do a day and time so you know if you imagine you're posting multiple blog posts a day then date and time is going to be better than just date but we'll just say a date that's fine oh let's call it date time like that it's required as well date time is this restricted word okay so we'll just go with that required so we got our title description content we've got a date again we're going to want those tags so if we just do tags here and then multiple values that's fine we can add our tags there what that's going to give us is it's going to give us like multiple strings of single line text okay i'm just trying to think what else we would want in a blog is there anything we're missing so we've got title dead we're gonna do the author model yeah i think that will be fine there's nothing really we're missing too much okay so let's make our author model and this is going to link to the post model so we've created our author so we want our name this one is required i'm gonna do a slug because we want um we're gonna want to again show the show the author's post for example find all posts from an author which will come from a a different it will have a dynamic route so yeah we need it it's required name slug we're gonna want an image on that um so just call it image whatever it's required and then we can just do multi-line text we can do for example by a biography um and again that's required and then we can do it so you know we don't want more than 500 characters in a bio for an author and then finally we can do the reference so we're going to define a relationship to the posts multiple posts for an author so authors one-to-many relationship with posts so what this means is you have you know one author can have multiple posts you know in theory you could set up so the posts can also have multiple authors and you can add a lot of authors per post but you know we're gonna go with you know we have one um one author per post um which is one author to many posts so multiple posts per author so the reference that is all good reverse field again the defaults are all good so we're saying we're linking here from our post model to the author of course as well so we can click create on this something wrong crap oh define relationship continue okay so you can see now we have got a relationship here and then we should also have a relationship here so let's um let's do let's do an author so let me add myself so if i say adam richardson we've got our slug for the image let me i think i've got an image somewhere on my desktop here we go so let me just add this image cool so the image is added we can publish the image you don't have to do it like this um let me just leave it in draft biography let me just copy from this website so we've added in a biography and yeah we can save and publish and then you can see we're gonna publish the image as well such saving and publishing then if we go to now add a post let's um can i just take something from here so i'm gonna do the title we've got that description you know how to use the youtube api to fetch channel statistics and videos content so this is markdown so what i can do is let me just have uh i think it's this so let me open that up in vs code and i will just copy um the blog post so you can see we're using a custom component here from nextgs so that's an mdx component we're not going to be going into mdx components or anything but um yeah let's keep going so what we will need to do is figure out where to um okay and you can see the markdown is all it's all displaying there in the content so that's great date so let's just pick now 1201 great and then tags we can do youtube development development can we do it like this api no so that would be like a nice improvement where we just hit enter and it refocuses back on this and then we add an author so i'm gonna add this author which is myself okay so save and publish ah we didn't i was gonna say we didn't do an image but that's because we didn't add one so if i go to the author now we should yeah we can see we've got posts that are linked to the author so we've got our portfolio items so let's make a few dummy portfolio items here as well so i don't know if we can just do a website um so let's just copy the image link um let's create an item here so what is this work hard anywhere work hard anywhere and then we can say you know design development uh branding as our tags cover image so what we can do is we can upload and we can do from a url like this and that's going to upload the image like so content-wise um let's just get some dummy markdown oh we'll just do markdown g sheet um and we can hopefully just copy a lot of mark down no okay let's just take i don't really want all of that yeah let's just take this stuff here and we can go with that to copy i don't want too much so content we've got that's working just fine description you know what was the work hard anywhere project date again let's just choose default now and we've got the slug for the for the portfolio item so we can save and publish that i'm going to publish the image along with it and yeah i'm going to do that a couple more times so you can create an item let's go back let's find a different image yeah it doesn't really matter copy image link call so let's upload this image hopefully you can see that this is um [Music] the the content itself is is quite easy to edit and then let me just try what's the what's the name of that i don't know we'll just take um take it anyway okay that's done wow facebook up landing page so we can do again design development that's cool content we've got that there facebook app landing page you know i'm not putting a high amount of effort into this but um yeah hopefully it will it will be good enough to get onto the front end of the website and you see i'm just adding you know random images they're not um you know we're not controlling the size or anything on these images so we're gonna have to handle that on the front end and then let's just do one more so we can have at least three i'm just trying to find another version another image that looks relatively like a website uh yeah whatever this'll do it's not website why is that is that slack so upload from link it's really handy to be able to do that into a cms like with unsplash where you we have that link you can see it's all my already formatted and cropped um and then we're just going to take it from that link so that's pretty handy so let's upload this one so title of this you know slack app design concept um and then this is just going to be design maybe say like brandon as well just trying to mimic like what this actually might look like in uh in one of your websites so let's just again take that take that content design proof of concept 12 slack application whatever okay cool so we've got three portfolio items that that should be enough for now yeah let me i have posts here so if i just for example take these posts so let's create the title do you have a description blog post that's fine content is there there's no mdx in there no no content date so let's back there this one let's say okay we did that one yesterday tags so next gs um i don't know eslint whatever that's fine and then author i'm gonna link myself save and publish and then let's do this tailwind toaster blog post as well so title and slug description i don't know let's just do this whatever doesn't really matter i suppose this is quite a long longer one so we add that in there let's backdate this to last a few days ago and then again we call this development react react.js and then let's add in add in the author okay so our back end now is pretty much done and hopefully you can see from a from a content perspective we've got portfolio items which are just going to be from from the business essentially and then we've got posts where we can have different authors which is which is linked to this author model so let me just demonstrate so if i go to settings we're going to do api access and then we're just going to make this public so content from published is going to be published uh it's going to be public so if i save that then if i click on this url we're going to get our graphical query so if you're not familiar with graphql graphql is basically um it's a it's a query query language like rest api is is another thing that it's compared to quite frequently i am not an expert in graphql i've built i think an online store with it which was really challenging um because that was the first thing i built in it and of course we were we were allowing users to upload upload products to the store so it was it was rather quite complex for for our use case here it gives you really good control over exactly what you are querying so whereas in a in a normal api you would if you have a rest api you would have lots of different endpoints for lots of lots of different things um with graphql you make different queries so i'm going to query for example our post model like this actually let's query post and then what i want is going to be you know title slog description we want that date um let's grab an id we don't want the content because we're just listing them out so we definitely want the the cover image what do we call it image oh no we didn't have an image on the post um and then let's do tags and let's do author and then because we have that connection we can say we want the author's name image like so and then with the image we want and you can see how we are explicitly defining everything that we want so the url and then with graph cms we get a width and a height which should integrate really well with next image so you can see now that we've got this data with a post and it's only bringing back the fields that we are requesting so that is brilliant is there anything else that we need description we don't actually need the id because the slug is unique you can see our tags we've got an array of single line strings um the author we've got the name and then this image and like i said it's giving us a url a width and height which is going to work great with with next image so yeah graphql is um i think it can be quite daunting at first when you um when you first start to use graphql however it works really really well especially with a simple use case like just displaying information from a headless cms i think your development will be a lot quicker using graphql rather than um you know rest apis and how the referencing um and and linking between models will will work with that so yeah i really really enjoy using it for projects like this one so that is um that is kind of and just on that note you know i'm certainly not an expert in graphql it's something i want to learn more um and i believe i'm going to be making a video series on you know graphql creating your own graphql api um obviously this one is generated for us through graph cms however you know when we when i do full stack development you know that's that's not going to be the case we're going to be building out our own graphql api the same way we would if we were using um a rest api with next api routes and things like that we can do exactly the same with the graphql api so yeah not going to dive too deep into it but just know that we'll we'll touch on it quite a bit we're going to be passing in some variables to find um to find slugs for the author and for the posts for the portfolio too but yeah just know i'm going to cover it more in depth um you know as my knowledge gets greater and greater as as well as um as well as we do the full stack projects with it okay i will stop rambling let's keep going so yeah our graph cms project now we've got public permissions for published content which is great what you could also do if you wanted to you could you know add a permanent auth token that you would pass from the from the server um but you know it's really not not necessary to be to be totally honest we're going to be calling this from the server side anyway okay so the next step is going to be actually fetching the data into our nextgs application okay so let's um let's get into building our front end so like i said i'm going to do the styling last let's just get the data into our let's get the data into our app and we can get going so what do we call it's just portfolio wasn't it so let's open that up in vs code and if we run our dev7 now you will see hopefully the next js default um default web page perfect so let's um what do we want to do yeah so let's let's install tailwind um and get that all set up so let's just do the the install stuff now so i'll just quickly run through this literally just copy in the commands so let's um in our tailwind config let's do our purge and then i want to just set the mode to just in time like so and then we can just import this into our app.js we don't need that anymore we can delete our styles folder and i think in our index page let's delete that you know let's get rid of both of those and we'll just keep this top level div like so so let's call this our awesome awesome portfolio as our title and we can add in a hedge one just saying welcome to our awesome portfolio and then let's run our dev server and then let me just reload this so that hopefully we can get to inside and then what i want to do as well let me just add all my eslint stuff sorry add all the eslint stuff as well so we get some consistent formatting across the project so dot eslint ic.js for this one let's place that in there and then we want a prettier pretty rc like this um and again you can go to the website and copy this stuff it's just adam richardson.dev let's reload our window once more to get our eslint config go in and yeah let's um save that and you can see that it's gonna auto fix everything for us we do need to import head from next head like so okay cool so yeah we've got um we've got a few nice things with eslint here that is set up you just need to make sure you have in your settings um so that it es lint is not pretty or is not format and unsafe instead we're fixing all all on save okay so we're good to go let's um let's take a look at what we need to do so we need to have this query we need to do this um for our pulse and our portfolio and we need to give access to this data within our index page um is there a different way oh here we go api playground yeah is there a different way to do this because the last time i was doing it we had a like a history and stuff so yeah so that's our posts query um can we do a nameless no and then we can do um we also want to query for our portfolios like so which we're gonna want to title the tags the slug the description the dead cover image and now we want the url the width and the height um oh let's go up here we don't want the content yeah so that's good i said if we do this query we can see we've got our portfolio items here so those are the queries that we need for now um we are going to need another query which um which we search for so how how do we do this i've forgotten it's been a while so query like portfolios and then is it like oh we want portfolio query part sorry from portfolio and then how do we search now is it here okay yeah where slug okay i'm gonna have to look this up query model portfolio where slug yeah so why isn't that what is the syntax for this hmm graphql slug query example slug query slug string yeah okay i see so if we do a query portfolio now let's back to this and plus where slug as they say it doesn't seem like it great portfolio wow so like this slug is this how we do it no syntax are expected where's the syntax error okay i will wait on this one let's let's uh let's figure that one out in a in a few minutes i um i'm just struggling with the syntax i thought i wasn't lying when i said graphql was not my strong suit right now um cruel okay so let's um let's start off with our portfolios query so we've got our portfolios here so what we're going to want to do is we use this um graphql request like so graphql requests where is it at so graphql request is a library that just allows us to make um graphql requests clearly um so we're going to add that library like so and then let's do [Music] movie okay so let's do we're not having authentication but let's take this code so let's just do it in our index page for now so let's do this and then we want to do this inside of um get static props so if we do export cons get static props equals it's going to be async like so and then from here we're going to return props and we want to return something like post and like portfolio and portfolio items like so so then let's look at i mean we can do we can do both of them in this query uh to be honest and then if we take pause like this and play that so you can see we've got portfolio and then post so let's just do i don't know let's just return data like this so let's um let's grab this query and well let's grab the code from our request so we're going to do yeah let's let's do it like this so end point let's paste in our let's go get our end point so let's just copy it from here so we've got our end point here like so and then we want to do we can do a graphql client like this um but we're not going to put in any headers so we could use a token we don't need this empty object we've got the graphql client that's our endpoint and then we can say like this query equals gql gql and then inside of there that's where we will paste our query where is it going here yeah so we can pass that query and do we need consequences no so i don't think we need to say query at all i think we just do this like so you can see the auto format there and then finally we will just say this so data equals away graphql client dot request and then we pass in this query um and then let's just in our home page let's take this data and then let's console.log that data like this and if we run our server now hopefully we're gonna have that data um where it needs to be if we didn't do anything wrong which to be honest would be surprising okay so let's see if we have it what do we do so we've got our portfolios and our posts so let's just um let's get these on screen so inside of here let's add a div and then inside the div let's say so we've got data dot portfolio dot is it portfolios yeah data.portfolios.map then we'll take we'll just call this an item like this so for each item let's return a div which let's give it a key is gonna be item.slug and inside the div let's do uh let's do a h3 um with the item dot and then what's it called item.title like so so we've got our titles there that's good and then let's copy that and then we've got data.post and then instead of item i'm just going to take post like so and then let's just make it look a bit more readable and separate those out and then this h3 let's just make these links so you want to import a link from from the next link like this and then those h3 tags can come link tags and then the href for this one is going to be select to forward slash portfolio forward slash um item.slug and we'll create the dynamic route for that soon so if you um if you're not familiar with this kind of you know syntax or next link essentially we're using next link instead of regular um regular old air tags just in order to do client-side routing um using javascript rather than a full sort of um like browser refresh kind of like that um and it will look more like um i don't know it will look like this so that's your clients out client-side routing that nextgest gives us through that link tag but it's good practice to also include an airtag as the first child of the of the link so that the browser knows you know this is actually an an anchor tag too okay okay so let's see what we've got a broken application yeah so we need the href and this link so with this one it's gonna be we'll do template literals again so this one is gonna be slash post let's do slash blog i think it's um a little bit more descriptive and then we won't post that slug so when we click on either of these links now it will take us to slash portfolio slash you know work hard anywhere because that was a slug so that is working just fine um again clearly it doesn't look good but like i said the focus for us right now is just to get the application working so we can we can abstract away this code so what i'm going to do is i'm going to make a lib folder and into here let's just call this um i don't know like data.js and then what i'm going to do is i'm going to export const get let's call this get there i should really call it something i get paused and portfolio um like this let's just do this and then we can take out this stuff and we can take out this and pop it into here so let's make this asynchronous and then instead of and away we just want to return that like so and because it's an asynchron asynchronous function um you know we don't need to return a weight um although you know we can do but it will automatically do that for us so now in our index page we can import and let's just copy that get person portfolio from lib forward slash data like this then we can say um const data equals a word get person portfolio and if we refresh exactly the same thing it's just a lot cleaner within our within our file here so i'm going to leave this console log for now um you know we might want to so we've got a link here so we've got a div with a link you know of course we're going to want to add on the the um time the date description and stuff like that but you know we'll get to that point soon so next up we're going to do the individual pages so we're going to have a different query for those
Info
Channel: Adam Richardson
Views: 3,113
Rating: 4.96 out of 5
Keywords: nextjs, graphql, graphcms, tailwindcss
Id: OWL40Z0Hb8s
Channel Id: undefined
Length: 52min 4sec (3124 seconds)
Published: Sun May 02 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.