Create a portfolio website | React, shadcn ui, Tailwind CSS, TypeScript, NextJS 14, MDX tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
how's it going so today I'm going to be showing you how to build this um fully customizable uh markdown git-based headless CMS um connected and enabled uh markdown blog SL portfolio site built with um Tailwind react and chat CN as well as Tina CMS so it's a going to be a nice um full feature tutorial hopefully and uh it's going to do some interesting things going to show you how to embed like things like uh tweets um and make it completely editable and nice thing about this um this blog site is everything in here is completely free you can um deploy this tover cell and because it uses your GitHub as a backend um there is no need for an API no need for a database and um yeah you can post your stuff over here make a nice little blog um or uh project showcase for your potential employers um and and you don't have to come into the like once you develop this you don't have to come into the code editor and change things manually you can just do everything from your uh you know from your from your browser from your phone if you want um so yeah and you know you have like nice little filtering for your blogs and um like I said all of this is editable from the browser so show you what that looks like if I come over here to say this is my resume I am Jo do or joh I'm clearly John Doe right so I am mmud the dude and you you can see things are being edited live in 4K HD as you see them um so we're going to be covering this and um yeah I I hope you uh hope you enjoy this tutorial and um if you uh if you're here for the first time subscription will mean a lot and if not then what are you doing there's a like button underneath that description uh box so thank you guys uh thank you guys in advance for watching and um yeah hope you enjoy this one so first things first let's go ahead and create a a new Next app so we're going to run yarn create next app and we're going to call this one um I don't know web dev portfolio and blog sure uh we're going to use typescript we're going to use eslint we are going to use tail when CSS uh we don't want to use a source directory and we do want to use the app router no we don't want to customize our default import Alias and let's go ahead and open this when it's done all righty so we'll say code web dev portfolio we go now once you get vs code open let's go ahead and open up our integrated terminal in here and we are first before we add um shadan which we are going to be using um for this tutorial we're going to first install some um Dev dependencies so I'm going to go ahead and install yarn or say yarn add uh- capital D eslint plugin Tailwind CSS prettier and prettier plugin Tailwind CSS okay and then I'm going to run npx Shad CN uy at latest in it all right and if you're wondering where I um I got that command let me just pull it over real quick so you can see the um at the uy. shen.com there's the installation uh docs and for nextjs um assuming you already created your next app which we just did you just run this and gives you a few options and you're good to go so yes we do want to install we're going to go with the default theme [Music] I not sure I think I want to go with neutral yeah I'll go with neutral and yes I do want to use CSS variables for colors all right there we go so now we have shadan installed I'm just going to go ahead and dock this over here real quick um and I believe we should be good to get started well actually no that's not even right let me first um first thing I need to do before we get started is uh update our es lint and our prettier config so which we don't even have a prier config so let's go ahead and dump one of these in here so I'm just going to paste this file in here and go ahead and copy these values um so this just us as the um the pretti plugin that we installed a few seconds ago and I'm also going to update our eslint to also use the eslint plugin so we'll say plugin wait what oh whoops um need to turn this into an array yikes all right we'll say comma then we'll say plugin Tailwind CSS slre recomended there we go yep I think that's good did I not spell till and CSS for oh we're good okay so there we go our es lint our prer config is set up and I think that's basically it for now so oh wait actually um no we have one more step left we actually have to um we have to start setting up ARA um uh well I I really don't know where I was going with that sentence so we'll go ahead and do that so we'll say npx Tena CMS CLI at latest and it and um this is just going to install Tina for us so yes we're using nextjs I'm using yarn and I do want to use uh typescript for our Tailwind what am I saying typescript for ARA configuration so now let's just update our scripts um tell you what I'm just going to grab the dev build and start script like that I'm going to head into our package Json there it is going to hi my terminal for a second and I'm just going to replace the contents of the scripts or just the dev build and start I'll just replace those because I don't know why they don't have the lint uh script in there but okay so that's that and they did um I don't know why the CLI always like shoves the pages uh like a Pages directory near with like a demo and we're not using the pages router so um okay so now that that's deleted um let's see I'm I I guess we are going to change this but before we do so we'll just go ahead and start up our server so we can see what this looks like so we'll say um yarn Dev and okay doing all its things there we go so it's running at Local Host 3000 that is over here and there we go so not not very overwhelming but um kind of underwhelming but uh we can check out the admin um view as well which does not work because um we need to update our um our next config to um to basically recognize the admin um end point so to do that we just head over to the next config like so um and inside of the next config object we'll say async think rewrites like that and then Open Bracket and then we'll say return um open um square bracket for front array then inside of here curly braces and we'll say Source admin and destination isadmin SL index.html so we save that and now just give this a hard refresh and there we go so yes want to enter edit mode and it's not really going to do anything because we don't actually have um like we can't edit anything over here because there's like we haven't configured our Tena CMS yet but um yeah so this is the admin View and then this is the regular view so go ahead and have both of these open so Local Host 3000 admin and Local Host 3000 that way we can jump back and forth between these and while we're going through this we can edit on the Fly and see how our edits look now let's go ahead and start configuring our um our Tina uh config so I'm just going to hide the sidebar real quick now the way this works is inside of your Tina config you have all the different um I guess config options for Tina and we're not going to worry about these right now uh actually we are going to worry about this this I'm going to remove the next public from this um environment variable because I I don't believe we want our client's ID to be um public so yeah we'll just you know get rid of that um for those who don't know next public this is a um this is a nextjs uh I guess um semantics thing where if you add next public to the beginning of an environment variable this will well it'll be a public environment variable so people will be able to see it and I don't know if we want that so um first thing we want to do is inside of our collections these are basically our like um our data types right so you have different collection ction types in this case they have set up a um posts collection type which would go with say blog post so this kind of defines like the structure of what um content or data would make up would comprise a blog post and that then gets used to um to be edited in or that gets used as uh as like the I guess point of reference for the admin to know what part of the site you're trying to edit and so forth and so on so um what we're going to do is we're actually going to like just blast this away uh well no we'll we'll overwrite it with what we want so we are going to get to the post later but for now we want to um we want to have our uh homepage and we want it to be something that we can edit from our um from our admin um admin view I'm I'm failing to I don't know what to call this um I guess like the contextual editing but the the CMS admin basically so that we don't always want to have to go into our source code to change things sometimes it's nice to just be able to go into an admin and modify things the way you would and say like a WordPress site for example so the um the first collection um because this is going to be a page we're going to call it page uh we're going to give it the label of pages and the path um AKA where this data um for this collection is going to be stored is in the content slash um page uh directory now I am going to add another field over here called format and this is just going to tell um Tina CMS what um what this data type is going to look like typically it's in markdown I believe that's a default um but we want to use MDX because we want to later on be able to um render our own custom some react components which is what MDX um is pretty much used for it's marked down with um react I'm pretty sure that's what it is but yeah so here's the different options um so we're choosing MDX and inside of the um inside of the fields this looks fine so um I I don't I don't like having the type first we'll put the name first then type and then label so the name is um title the type is string and the label is title uh we'll make it required um and we'll say his title is true so that's cool uh the next one is the body so again I do want to have the name um first so name it's uh going to be rich text and label is going to be body so this is just like the actual content and then is body is true okay so I think there's just maybe like one more thing yeah down here so for the router the UI router this is just telling it like um where to find the uh the file so this is not going to be demo blog rather we're going to say um I'm actually going to get rid of this right here um yeah and I'm going to open up a curly brace inside of here I'm going to say if the document doore CIS um under uh do file name so if the file name is home which is what our homepage is going to be called then um send us to oh I guess I got to use backtick send us to um the homepage um and then we might change this later but otherwise undefined so this will give us like a 404 um basically like if there's no file name uh the other thing we want to do is when we're editing the um when we're editing like uh file names or like when we're creating new files well actually this might not be relevant right now we'll come back to this part later so yeah because we are going to be adding like different like like you're going to be able to add new pages from the um admin so we'll take care of that in a little bit um so now we can actually go and create a um or modify the main page component inside of our app directory so we go to app page. TSX and in here we can basically get rid of like everything and start from scratch so we'll say um what we're going to be doing in here is export default um and we're going to be returning an async function so async function homepage okay and where's my bracket come on now there you are okay and inside here we're going to be querying TMS for the contents of that home. MDX file which we haven't created created yet so we're going to have to um go create that now actually so we'll say page and it's going to be home. MDX welcome to my blog now we want to fetch the content of that file so we'll say const result equals await client and this is going to be imported from Tina um. queries. p page and in here we're going to pass in relative path and the relative path is home home. MDX um so it's just telling it what the file uh that corresponds with this route is then we're going to want to return something now typically what we would do what what is going on return so I'm just going to return a div for now hi from home okay now uh this obviously isn't going to work right because wait hello um oh it says right there cannot return null for non-nullable field um so I guess we can modify this inside of our admin view real quick so I'll go to uh pages and um interesting no documents found huh could have swore okay um so let's do this I Wrong One let's do this let's get rid of home do MDX just delete that and um we'll add the page inside of our admin view real quick so we'll say um for this one we'll call it um I don't know um Welcome to My Oh huh we'll call it home then and in here we'll say um this is my blog thank you for looking at it and it's going to be saved as that so we hit save and there we go so there's home so hopefully that means that when I refresh um there we go hi from home so now it's working um so there was given us an error because we said that the title is required and we didn't provide it with the title um so let me see I'm going to change this title to Welcome to my blog and that'll make sense in a second um I think I have it where it's like literally naming the um the the entire file based on the title so like if we since we named the file or since we had the title of home just named the whole thing home so yeah it's it's a little funky but um like we we I'm still learning to so we we'll we'll get we'll get it um we'll get it strained out so let's see um the one thing we want to uh do now is the you might have noticed that I'm using like an a syn call and I'm not actually using this result the reason I'm not using this result is because we need to actually use a client's component um because we're going to have to use the Ed Tina uh hook which is essentially a US state and because we're using the app router we can't um we can't like have the get static props um function in the page anymore now we have to like create a client component and then like you know pass this down to the client component and do a whole bunch of funky stuff so we're going to go ahead and start doing that funky stuff so inside of our components let's add a new folder and we'll call it app and inside of this folder we're basically going to be like creating all the components that go along with our actual route components so the first one that we're going to create is page. TSX okay and this page. TSX is going to be a client component so um use client at the top and we're going to say export function page component so think of this as the actual like the actual part of the component that takes in whatever data is requested from the route component so this is the data that's being requested our um our page component is going to take that information and it's going to update the content like the actual template of the um of that component based on the results of that um of that query so in here we'll say props and open up a bracket and the prop types are going to be data and the data is going to be of type page query and this gets created um when Tina runs so this does not exist out of the box we have to create the config for the page and then Tina will create this um page query type for us to then use so the other one is um variables and the variables for the page component is going to be relative path and this is going to be of type string and then the last one is query and this is just going to be a typ string so um now let's open up the function body and we're going to destructure Da data from the Ed Tina hook which we will pass the props to so we pass the props to the use Tina hook and in return we get this data object now we're going to pull out the content of the data object so we're going to say const content equals data. page. body and while we're at it we'll say const title equals data. page. title yep that's what we called it so we're just saying like the page data which we've defined in the config as title uh and because it's required this will exist um because you can't create it as you saw earlier you can't create it without it not existing what you can't create create it without it existing I don't think that makes sense um so now that we got these two and we don't have to do this this is just like this is just for clean uh cleanliness sake um now we can actually return our template so we'll say return open up a parenthesis and we'll say article tic article jez okay this article is going to have an H1 which will contain the data well it's actually going to contain the title I was going to start typing in this again but we can just pass in the title now that we um declared it as a variable and underneath it we'll create a section um and the section is going to contain a Tina markdown um component which we will import um from the Tina CMS package and we'll pass in the content which we have defined here as content like that so we can save that and if we head back to our page. TSX doapp uh app page. TSX now we can say page component and import it like so and then pass in the um result like so so we can save and you'll see we have home at the top so this is the title and then this is my blog thank you for looking at it I do have to refresh because we actually there we go because we changed the the it's an xjs so it doesn't always update so we have have to do a hard refresh so control shift r or rightclick this I can't do it because I'm an incognito but you can right click empty cache and reload and it'll um it'll dump out whatever like exists and render it so um so yeah that's more or less what we wanted to do now the reason it looks like actual trash is because we need to add something to our tail one config so um let's head down to our Tailwind config and over here somewhere yep there we go the plugins we want to require and I learned this the other day so that's pretty cool um we want to require at um I think it was Tailwind CSS typography I always thought you had to install this package but it turns out it like comes built in which is pretty awesome um not entire oh wait hold up hold up I'm a silly goose because I forgot that we have to wrap this in a Pros which I guess we might as well take care of this now so inside of our layout. TSX so app layout. TSX let's change a few things over here so first thing we want to do is get rid of this nasty title so we're just going to call it Tina CMS blog um and in the description we'll say uh I don't know my web desk blog smiley face cool so um what we want to do here I do not want to use enter so I'll get rid of that and um we'll get rid of this body class name we are going to like introduce fonts later on like when we get to like the the real customization part um in here I am going to add something because you'll see there's probably like a screaming error at you or it will be screaming in a second so I'm going to um add the suppress if I can spell suppress no suppress hydration warning cuz this is going to start screaming at us in a little bit um once we start adding Styles over here for some reason and um inside the body right before the children or actually let me cut this because we're going to be putting stuff in here so um we'll say div. Pros so Pros is a is a Tailwind class that lets you essentially render um uh it lets you use the typography plugin for lack of a better way of explaining it but what this does is this just like gives default styling to things like um well to to basic markdown so you you'll see what it looks like so we'll say Pros XL um we'll give it MX of Auto uh my of 20 width of full Max width of 4 XL and padding X of four dark mode we'll give it pros inverts and this just makes sure that when it's dark mode it'll flip the colors and then when it's at the medium break point we'll give it a padding of X of zero like so and inside We'll add a main tag and inside here we'll pass in the children so we save and there we go so had we not added the typography it probably would have looked like garbage which let me actually verify that theory real quick I might just be like huffing paint right now let's see get rid of that yeah okay so I'm not crazy so that's what the tail and typography does it's um it's a pretty nifty like hack because it lets you like save a lot of time on styling if you don't feel like adding a bunch of styles so that's um oh wait let me show you how editing this looks so now we go to page we go to title uh sorry we go to the homepage so here you can start seeing um like some crazy some crazy things so we can say like okay I want to eat ramen noodles but only the good kinds and we'll I don't know do something crazy like we'll make this we'll make this italic um we'll add some code right here so we'll say um const D nuts and say if you want it and then you want it is type Boolean oh that's so cool I didn't even know that it doesn't sell it that is awesome oh this is this needs to be typescript change this to typescript there we go this is a Boolean so if you want it then console.log you you you can get it and uh that makes no sense and it's actually kind of gross but there you go so so now you have um like this nice little blog with you know just markdown you have like code auto code like linting in your that is crazy I didn't even know oh my God that is dope I did not even know it has like typescript Intellis and support okay so I just learned something new while I'm make this tutorial um so over here you can say uh I don't know if I have seen further than others is by standing on the should the shoulders of giants Isaac Newton yeah so there you go um and then when you save this you'll be able to head into um the home. MDX and there you go so you see like there's the typescript there's the um there's the it the italics I was about to say I was about to say intellisense and italics at the same time there's your uh quote field so yeah like it's it's just a it's it's a really Nifty way of like being able to modify your content and when you deploy it the nice thing about this is like let's say you want to modify your blog on the fly or you don't have access to your computer um where you write all your code or I don't know you just you want to do it on your phone right then when you deploy Dey it you can actually open up the admin page Log in using your GitHub credentials and just modify it and when you update it there's no backend there's no datab well there is a backend and there is a database but you don't have to pay for them you don't have to set up no like superbase database or or set up any rest API servers or anything like that it just makes commits to your GitHub rebuilds the site and you see the changes based on that get commit which is pretty awesome so um yeah it's a pretty nifty tool um and we are going to keep going and hopefully make it look really nice and give you a nice portfolio that you can show off to your um you know your potential employers and really like stand out so yeah um so I guess we can uh we can now start adding some more pages in here so the first thing well actually this is kind of unprofessional so I'm I'm going to replace this with some other content that I uh wrote up on the side so we'll say come to mood's blog cool um so that should have there we go so what we're going to do now is we're going to add an about page and um I tend to look at this page as like a place to kind of um you know just rant about yourself um show yourself off so uh like I'm probably going to trade it like a resume um not my resume though um I'm just going to pull like some blank content in there and um you know you can do whatever you want there uh it is your blog after all so let's see the in order to get another page in here we have to um add something to our app directory or our excuse me our app router so uh what we're going to add here is a folder called Slug and what this folder does is it basically says like if you have um anything that's after the the Home Route the home rout yeah the like the the the the root path I guess uh sorry words are hard um so anything after the root path that doesn't have a folder defined here will go into um or will be rendered by whatever page component is in here so if I say page. TSX here now whatever it is that I um whatever it is that I route like let's say admin um potato beans I don't know whatever um slash anything will default to what whatever it is that we have um in this slug um folder so but that it's also going to require there to be a um corresponding MDX file so it's going to give you a 404 if there isn't a um corresponding MDX file so what we're going to do is we're going to um probably sorry I'm breathing so hard into the mic I apologize uh we're actually going to repurpose um basically everything we wrote in here and just dump it into this file file with some extra steps what I mean by that is um it's not going to be it's not obviously it's not going to be looking for the home. MDX file rather we want to destructure or extract the um the current like um path I guess you could say or the current sub path so let me actually hide my um sidebar real quick so here I'm just going to call this um I don't know slug page Maybe or just page yeah page seems appropriate um I always have I never know what to name these like like whenever it's a slug page I never know what to call them to be honest like from the root but yeah my lack of experience is showing isn't it so um in here we're going to say we're going to take out the parameters of the um of the route and it's going to look like this so pams is going to have a type of params with another type of slug which is going to be of type string cool so um now we can uh instead of just like grabbing the result as is what we have to do is we have to say relative path is equal to and the relative path is going to be equal to whatever those pams do slugs are so pam. slug um and by the way this right here this comes from the bracket so because we named this slug the the pams SL whatever is named after this variable so it's basically like a um placeholder variable so if we had called it bracket um path this would have been pam. path um well maybe not path I don't I don't know about path I haven't tested that one yet but yeah so that's basically where this value comes from um so what we're basically saying is the relative path is whatever that slash whatever is so if this was the slash about page then the slug would be um about so we're saying here is um the relative path would be about MDX all right so what I'm going to do now is um to make sure that an error 4 or4 shows up if this uh if this route doesn't exist I'm going to then um because this is a promise I'm going to say do then um and then we're going to take the result and we're going to return the result so this then is going to be fulfilled this this part of the promise is going to be fulfilled if this MDX file exists but if it doesn't exist so I'm going to say. catch if it doesn't exist then I'm going to console. error the error and um I'm going to return not found and this is imported from the next SL navigation um package so now we can save that and back in okay that was weird back in um just like the normal deployment if I come here and I say uh Slash about it's going to give me a 404 right because we did that not found now here's what's going to happen if I don't do that it's going to give us errors because it's expecting it right um and we don't want it to expect it we want it to return a not found if it's not found so that's kind of a little neat little trick for you um so now that you have that we actually have to go and create the um create that about page so I am going to copy pasta a ton of stuff and I'll probably leave a link to um to my uh to my copy aasta site where I can like place all the stuff and have you all go and copy it if you want it um so yeah uh otherwise I don't know pause and try to copy as fast as you can um do not recommend or just you know like write up your own markdown I totally um recommend that to everybody so uh or not your own markdown use the admin page obviously so we come here this is the about. MDX inside of the content SL um SL page directory like so I'm going save that and now uh I have to re I have to do a hard refresh there we go so now you'll see theabout renders the or the slab renders the content in about. MDX so let's see um so that's that now I do want a better way of navigating back and forth between these pages so I'm going to create a new component called header and we're going to do that in the components directory and I'm just going to say um call this oh wait no no no I don't want to do it in app I want to do it in components so we're going to say header. TSX and uh you might have noticed I'm kind of indecisive on how to name my files uh what I'm using nextjs I typically tend to use camel case as much as I can but because like because NEX tends to use like file names as like path name sometimes path names are usually Kebab case I I tend to like mix and match so if it confuses you don't worry I'm right there with you so in the header what we're going to do is we're GNA export a my headphones are currently um entangled with my keyboard so that's fun so we're going to export default export default function header and this I don't know why I put a space there probably because I'm a genius um this is not going to actually do anything just going to return a um header with classes of MB margin bottom 20 uh margin top of 16 Flex content Center um items Center justify between font Sands text base I probably didn't need to do font sand but it is what it is um and in here we'll add a div it'll have a flex box and a gap of four love Gap and now we're going to do a link that should have imported it doesn't want to import it so that's cool so we're going to import it up here so we're going to say import link from next SL link like that and now we'll say um the link is going to go to the first link is going to go to home so like that and this is going to say home like that and then just going to alt shift down this and this one is going to go to about and we'll say about so now that's all fine and dandy but we need to actually use it um so we're going to go to our layout layout and what am I going to do with it I'm going to add it over here I'm going to say header like so well tell you what going do we're going to struggle a little bit that was supposed to import there we go and um now we can save it now we can refresh oh there it is okay so that's cool um and I guess now that this is there we have some Screaming invalid CSS class names why are they invalid okay that's funny it corrects it and then it goes back to what it was okay um so we actually can get rid of the my20 there we go um I don't know why it thinks there's invalid class oh it's because of Pros it always gets confused because of Pros okay so there you go um so now we have our little navigation so we can go to home go to about um yeah so now we can go in and add the blog posts um so similar to what we just did where we added the slug we're going to come into our uh let me close all these cuz that's way too much stuff um we're going to come into this uh app directory and we're going to create a new folder called posts uh posts with an S yeah that sounds good and inside of what this is going to do now is it this kind of like reserved posts so if I come over here and I say SL posts uh it's going to go to 404 because there's nothing there but if I come in here and hello if I come in here and add a page. TSX and I say um oh there you go see it's actually trying to do it so let me see RFC um I don't know what we can call this uh yeah that's fine so now be so it's just going to say page because that's all there is here um but we don't want it to say that and you probably guessed it we're not actually going to be rendering any templates over here because we're going to need to um to add the posts to our config and then we're going to need to like do basically the same thing that we were doing in this page where we uh render we we make an async call um we render that we pass that the result of that call to the um the client side component and then we render the template in the client side component so the first thing that we actually have to do is we have to go to Tina config.sys so like so and we're going to call it um I'm going show you a little trick so we're just going to control D this twice hit the right arrow key backspace three times and then write post so so now we have our um our post um uh config not really it's not done yet so well post collection I should say so um we need to Define so we have the title we we have the body but we also want to add a date over here so we'll say um the name is going to be the date and you know like I'm sure like you can have like a published date and a last edited date and stuff like that but we're not that fancy today we're just going to make it um nice and simple so this type is going to be type date time and we're going to give it a label now if in case you're wondering the label this shows up in the admin so this right here this is determined by this label property and I'll show you what that looks like in a second so um say date and I do want to make this required because um well I don't know doesn't make any sense to make the not required um if you're going to be well oh because we're going to be sorting by it so if it's not there it's going to be hard to sort by it right um unless you want like post to be like getting shoved all the way to the Bottom now because it's required we want to make things a little bit easier on ourselves so we're going to add a default item and this is going to be a function like so and it's going to return and basically in this default item we can make the defaults for everything so we can actually say title has a default um of new post and its date will be of new not Nate date like that okay let's add a comma over here and um yeah so I think that's about it well no no actually that's not right because this is going to be returning home this is confusing so let's see so the document is going to be we actually I don't even need typescript here it looks like so that's cool um so this is not going to have this conditional just going to have one return statement it doesn't seem to like what I'm doing let's try that again oh oh oh I an extra bracket there we go so in here we're going to return posts slash where is my dollar sign oh my God I clicked every single one except for dollar sign do there it is sorry I my keyboard is on my lap because it's more comfortable for my elbows and I but it makes me very inaccurate um so document doore system. file name so same cont concept to what we did with the home but this is going to be looking for um this going to be looking for the document in the posts um uh collection and we want to make sure that the um the file name is always going to have like a kebab case slug um uh format so go ahead and pause and copy this over here um we don't have to go into too much detail on this but if you want to learn more about what's going on here just look up regular expressions and um and you you'll understand why I didn't dive too deep into it so go and save that and um now we can go and start actually working on the template uh so let's see back in our components directory let me just close everything out like that and back in our components directory let's go into our app uh components app and let's add a posts folder and inside of posts we're going to have um well we're actually going to have two files we're going to have the post list page and this is going to be like when we go to the Post is going to have like all the list like the uh the list of all the posts excuse me and then we're going to have the post page and this is going to be a single post. TSX like that okay so the first one that we want to tackle is the um the the post list page right because that's the first one that we're going to run into so for this one let's actually grab um this page. TSX because we're going to be like manipulating or doing something similar to what's in there so it's easier to man manipulate what we have than to write it again from scratch so we're going to rename this to page sorry post list page component um and instead of taking in a page query this is actually going to take in a post connection query which now exists because we created the post config um this is not going to have a relative path just going to be an empty bracket for the variables and rather than um the well actually this isn't going to have a Content or a title rather this is going to have const post list which is going to be data. poost connection. edges okay um now down in this return statement we can actually wrap or we can get rid of that to be honest just open up a uh react fragment we're going to add an H an H1 which is going to say blog uh I would like it if my headphone cable stops getting CAU to my fingers cool um I already have such a hard time um typing accurately uh and then we're going to open up a div and we're going to say post list map and we're going to pass in an anonymous function did my ID just add that by itself that's awesome and people say VSS code sucks vs code is awesome um so now probably just created a whole lot of enemies by saying that um okay so now we're going to say div and this because this is a array we have to provide it with a key so key equals um post. node. and inside of this div we're going to add a link which is going to be imported from nextlink it's going to have an hre of a curly brace which will contain an interpolated string posts slash and then dollar sign got to write the second time not bad post node doore thee system file name like that close out the link and in here we're going to actually pass in the title so we're going to say post. node. tile for this particular um array element cool so we can save that and um just get rid of this page query up here and we're not using Tina mark down so we can get rid of that one here um like so cool so now let's actually use this so back in our appost page now we can actually uh use this there so what we're going to do is take this return statement and we're going to say oops we're going to say return post list page component but it needs to take in you guessed it a result but a result from what you might ask well as we did with the other page we'll say const result equals await oh I probably should Define the uh the function as a a syn asynchronous function so we'll say export default async function and we'll name this async function post list page I'm going to hide my sidebar there we go um so what we're going to await is the clients which we need to import do queries did I spell that right yes poost connection like that call that function and get rid of this export default we can save and now you see Blog shows up but no blogs actually show up and the reason no blogs show up is because we don't have any blogs so let's add some blogs so back in the admin view I'm going to go to this hamburger I'm going to go to posts and I'm going to create a new blog so let's see what are we going to put in this blog you might ask um I'm actually just going to copy pasta some stuff and uh I'll probably I'll probably like like with the last one I'll just leave a link um with uh whatever copy pastas I end up providing so I'm going to get rid of this posts uh directory because we're actually calling it post not like the the directory is being called is being referred to as post um I just like the singular um version of the word so we're going to delete um yeah I don't want to deal with that right now it's going to scream at me so we'll just say CD content slash hosts wait what did I no there we go rmrf posts I don't want to deal with the um the uh admin administrator permissions right now so just get rid of that and now in Contents I'll create a new folder call it post and in here I'll paste in these MDX files so now if I refresh I go back to posts interesting huh why is it doing this to me do I need to restart my server again maybe that's what it is let's give it a try okay that was yeah so sometimes you have to restart your Tina server if you do what I just did like adding a bunch of files um it's probably like whoa where did all that come from so there there you go um now it's given us a 44 because it doesn't actually recognize the post um because we didn't create that route yet but that's fine so now you can see the posts are showing up um so let's actually add the um well let's add the um the slug for the posts so let's head into I'm going close everything out and let's head into um which one do I want to do first uh I think it makes sense to do the the app first uh the sorry the component SLA first so in post we need to go to post page and post page is going to be structured pretty similarly to the normal page so I'm going to grab the normal page going to go to post page um and paste that there and here we just going to rename this to post page component um and let me think for a second so for this one we're taking in the same exact yeah the same exact props except it's going to be post query not page query there we go and data looks good these are supposed to be post that looks good um so now let's see down here we have an H1 where we're passing in the title and we have a um section where we're passing in the body so we can save that um I don't know if I want to make this a section or a div it doesn't really matter but uh there is something that I'm going to actually do now because might as well so something that's like pretty interesting about how um how Tina works is like uh you can pass in like when you're in the visual editor you can have um like that there's attributes that you can add to different parts of your HTML to basically indicate hey this thing that I'm going to click on in the UI it corresponds with this field that I would like to edit let me show you how to do that real quick so we're going to do it in this file first and then we're going to um go back and and do it in the other ones as well so to do that all you do is pass in a data Tina field attribute and in here you will open up this curly bracket and you'll say Tina field okay got to import that and you'll pass in um I think this one's just data yeah data post and the field is what hello the field is body like that okay so this is going to tell it that the um section that I'm that I'm hovering over is corresponds with the body um property and then I can do the same thing for the title so I do it like that but instead of body I say title save that and let me show you what that looks like so back in the app posts we'll add a slug uh folder in the slug folder we add a page. TSX and now I'm going to just yink all this from the app SL slug paste it in the appost slug and um in this one uh we're actually not going to have to like do this like not found nonsense um instead we're just going to like um well you know what actually it does make sense to have a not found for this one as well um but instead of page component we'll say post page component like that get rid of the page component and here we'll say post page and this is screaming at us a little bit um property data is incompatible page query where oh that's because I'm calling queries. page it's supposed to be queries. poost like that so we can save that and now let me head back to um the posts go to one of these and now you can see that data Tina field that I was talking about that lets us do this when I click on this part of the um actual editor or sorry not the editor the um the UI it'll take me to its correspond in editor box same thing goes for the heading see what I'm saying so it's actually really Nifty um so we can go back real quick and do it for the other ones um so let me do let me do that real quick so back in components we'll go to page um and because I'm way too lazy and cannot be bothered to type things over and over again I'm just going to yoink one of these like that I'm going to go back to the page and inside of the title paste that there just need to oh wait I didn't copy the whole thing um let me copy the whole thing actually so I need I forgot to copy the attribute like that so now in this H1 just paste that there and we just got to import Tina field and this is going to be Data Page title and just going to copy this go down to the section and we're going to do the same thing but for body like that so now if I um inside the source what am I saying oh there we go and if I go back to home and I open up the editor now you'll see that we have those editable boxes which is pretty dope so let's see I think there's one more place where I can do this so does this one need it well that one already has it this one doesn't need it right yeah yeah that's fine cool so there you go um I think there's just like one more thing we have to do which is um going to the uh header and adding the blog to the header so let's do that real quick let's go to components header. TSX and we'll just do an ALT shift down at the home and uh do I want the blog to be next to home or next to about actually we'll make it next to about so we'll say blog or not blog posts and blog and you can say posts if you want I don't know it just it looks nicer when it says blog but posts semantically makes more sense um so there you go plus I like something that can be turned into a plural easily I feel like blog is a plural um so there you go now I think it's a good time for us to start adding in some theming because I don't know about y'all but uh yikes there's way too much white on this screen I prefer dark mode myself as uh viewers of this channel probably already know so let's um yeah let's let's go ahead and fix that so there are um there are a couple of packages that we're going to need to install um the first one is yarn add react icons CU I love using icons as much as I can and the next one is next um is a next themes I think that's I think that's how it's spelled right no whoops what am I doing it's next D hyphen Dash themes you know what it is okay so excuse me um come on now okay so now that that's done learn Dev again hide my terminal and let's start adding these themes the First theme or not the first them the first thing that we're going to need to do is underneath the components we're going to add a few files uh let's say the first one is no not a folder a file theme provider. TSX we're also going to want a theme toggle. TSX and we're also going to want a footer. TSX and I know the footer doesn't seem like it fits in this um in this uh in this theme thing but figured we might as well get it out of the way now so let's go back to the Local Host 3000 and let's start adding these in so the first one the theme provider is pretty simple we're just going to make uh let me hide this side we're going to say use client and down here we're going to say um export function theme provider this is going to take in children props and it's going to be of type theme provider props like so like try to say like that and like so and I said like sat um you'd think English is not my first language so now um we're going to be importing the oh this isn't going to work okay so I need to import theme provider but we're calling this theme provider so we'll come up here and we'll say import um theme provider as next theme theme provider and this is from next theme so that's correct so now we'll come in here and we'll say next theme provider uh where we'll pass in whatever props um other than the children and then inside of here we'll say children like that cool so now we need to actually use this and to do so let's go into the app and into the app layout we will um maybe above the body no within the body say theme provide theme provider now remember make sure you import it from components not next themes like that we'll say attribute is class the default theme is going to be system and this is for um Freaks Like Me who always have everything in dark mode um I like I like whatever websites I come to to automatically have um my preference um in effect and if you don't want to do that you don't have to do that but after all this is your blog so if you want to enforce dark mode on people well this is the one place you can do it um so if we save that um interesting H maybe I have light mode enabled that would be crazy for me I'm not a light mode kind of guy well I guess there's only way one way to find out we need to go to our theme toggle and we need to um we need to create the theme toggle so this one's going to be fairly straightforward we're going to say export function theme toggle and if youall have seen my videos you've probably seen me do this a million times by now um well maybe not for next because this is actually my first um nextjs tutorial so in here we're going to return a react fragment that is going to contain a button like that the button is going to contain an onclick or click Handler which is going to take in an anonymous function or an inline function that uh uses set theme which I haven't even imported yet so not like that set theme light but we need to import this so we're going to say const set theme and we're going to destructure this from use theme which still haven't imported there we go so we're just going to grab the set theme um uh function from the use theme hook and we're going to say that the first button um is going to be the one that turns it to light mode and this one is going to be hidden um we'll give it a text of gray 300 and when it's dark mode it will not be hidden that's what dark Flex does um there is no like not hidden so or maybe there is and I'm just un like unaware of it so inside of this button will render the RX Sun icon like that from the react icons package and we'll save that so the second button is going to be for the dark mode so this one is going to be text gr 600 so we can actually see the dang thing and we're going to set the theme to dark when this one's clicked so we'll save that and um inside of the header let's first bring in that theme toggle just so that we can save our eyeballs so we'll add a um I think we can add another div in here we'll say Flex justify between Gap four like that and in here we will we're going to add some more icons but the first one that we're going to focus on for our poor little eyes is the theme toggle like that so we save that why isn't this showing oh oh thank God okay there it is so there 's our theme Toggler man that feels so much better okay so um I guess now that we're here let's start adding in some more things so I wanted to um I'm going to show you what this looks like in responsive mode you you might have noticed that like this right here is probably going to get a little unwieldy especially when we start adding more icons over here it's going to get really busy so I want to make it so that when um when you're in a smaller screen this text uh up top appears as um appears as icons and they become um text when you have a bigger screen so on mobile these will just be icons and on desktop they'll be um it'll be full text so it's pretty simple thing to do um what we're going to do to get that done is what we're going to do to get that done basically a wrapper at this point so we're going to add a class name of Max Small hidden so basically says hide this um until until you reach a Max small screen so if I save that you see the home disappeared um I'm just going to grab this like so and paste it into the about and the blog links but now we have to actually render the um the uh the icons so we're going to add another link href equals slash so it's the same exact link but this one is going to have a class name of when it's small hidden because this is only going to show up up until you reach the small break point so max small means um this uh like how how do I explain this so this means when you reach the small break point hide this means um uh hide it while you're in the small break point and then after you break out of the small breakpoint this is no longer applies I I feel like that that's even more confusing but you'll see what I mean so RX home so we import this icon like so so we save that so now you'll see the icon shows up now if I change this um to responsive you'll see when I resize home appears and then home disappears and the icon shows up so let's just copy PA to this down a few times we'll put it underneath about and underneath blog for the about um let say whoops say slab and for this one um I think I think for this one we'll say RX person and for the posts we'll say RX chat bubble save that and there you go so there's your blog there's your about and there's your home although the blog makes more sense if it's up front so I'm actually going to move the about down a bit so we'll move these underneath the blog like that cool um so let's see now I want to add some other links um down here before the theme toggle so we'll say link and this one's going to be R YouTube fill cuz always be plugin you know what I'm saying and this is going to be atra whoa well that was a lot atref https youtube.com M6 iio like comment and subscribe and then do these down twice and we'll say the next one is R Twitter Phil I officially have a Twitter for the first time in my life so go follow the uh Elon Musk doesn't like me so M6 iio is not long enough and mmud iio is already taken I don't know who mmud IO is coming for you I'm just kidding um so M6 codes is my Twitter handle um I don't know what Twitter is I don't really use it so feel free to go follow and maybe you'll never see me tweet um so the link down here is going to be r i uh GitHub Phill this is the only one that matters let's be honest um so we'll say get gig github.com iio where you can find a whole lot of code that probably won't get you a job now we'll say RX divider vertical just to add a little line just you know for funsies and um in here we'll add a class name of text Gray 300 but when it's dark out it's going to be text Gray 600 O So spooky look at that so now if we go back to our iPhone SE there you go it's nice and nice and busy but it's also like um you know a little bit easier on the eyes than uh having the full text everywhere and um if I get rid of this uh Dev inspector there we go so that's what it looks like like so there's our um yeah so there's our header we added our theming and the last thing we need to add is our footer so let's go back to the um components where we have footer and this one's going to be pretty straightforward we'll say export default why did I capitalize function function footer and this is going to return a div with a Y padding of 10 Center text and text small bruh there we go it's going to have a horizontal Rule and a P tag and in here we'll say n link that I need to import from there took me way too long to think about HR https mud. this is where I'm going to be dumping all of my copy pasta as soon as I have some time I know takes me forever to do it but I try my best um make sure to like comment and subscribe and share with all your friends so that way I'm more incentivized to do things on time underline offset 2 for the class name hover text Emerald because that is my favorite Tailwind color 500 and hover underline now we can close this m6 iio and then we'll add another spacer template save and I need to actually use it so Lego go back to you know what I shouldn't say that um cuz this is this is the text that I use for my actual template but what I'll say is the m6 iio blog save that so now in um in app layout um underneath the main I think underneath the main makes sense right maybe yeah we'll say almost said Hooter we'll say footer slash save that and there's our little footer so you know nice and cute clean elegant I if I do say so myself so uh there you go there's our there's our nice little theme um next thing we're going to do is uh well actually make this thing into an actual like proper portfolio the next thing that we're going to add to the site is a projects page it's going to operate some somewhat like the the posts the blog posts but instead of there being like individual Pages for projects it's going to just be basically like a grid of cards with information on all your projects that you can input um in in the CMS but um all of them will link out to uh the the Project's respective repos or whatever links that you have them um connected to and this is something that you can grow and expand as you as you like um I'm just showing you like an example of um a good way to get started with it so what we're going to do first is go into the Tina uh config and well before we do that let me close everything because there's way too many things open so we headed to the Tina config and um in here we're going to create a new schema um collection so let me just minimize the posts and actually let's see maybe maybe I can simplify this real quick um by copying the posts oh you know what while we're here there is something I forgot to add so we'll go ahead and take care of it real quick um I meant to actually have this file name um uh also applied up in the um the pages so I think that goes right there yeah okay so now let's just uh to make our lives a little easier we're just going to duplicate down this posts um collection like so and let me just minimize everything and go back into the schemas collections and open the third one so we're going to rename this one to projects um so we'll say projects like that and um I think for our Fields let's see what they are so the title yeah that looks good and then then um we don't really need the date but we can just replace this with um we can just replace this with description so we'll say the name would be description actually just going to do it the same way I did it earlier like that description the type would be string and the label would be description required we'll make it true um and the next one uh is body but we really don't need that um we can just have this be a string for the link so I'm going to duplicate down the dis the description and get rid of the body and like if you decide that you want to have like individual Pages for the projects um then I'll I'll leave that up to your discretion should be fairly simple to um to to implement since you have the basically most of that boiler plate done with the posts um anyways so we'll say this is going to be the link and I'll make make this required as well um I don't believe we're going to have a default item for this so I'll just get rid of this and I'll keep the the um actually we don't need the router either uh because this came for from the um the demo code from earlier so we don't need the uh the uh good lord I can't speak today we we don't need the router because we're not having like individual routes for every one of the projects cuz the projects are just linking out of the site to another site and you'll see what I mean in a second but if you want to keep it like if you want to have a similar ux to your um to uh to the post then you can do it that way and I believe for the format we can actually get rid of this MDX cuz we don't really need it to be MDX um you can if you want but uh since we don't have a body um we can just keep these as mark down since there's nothing really like crazy going on in there um okay so that's it for the projects uh config now we have to actually create the components so I guess the first thing we should do is create the actual um component since that's typically how we go about doing it um well we can't really show anything with the projects um with just the uh the the router since we need to like get uh fetch the data first so let's say uh inside of app we'll create a new folder we'll call it projects and inside of projects um we'll create a file and we'll call it project list page. TSX and I'm going to copy over the post uh list page just going to copy all this content and go into the projects list page paste that in there and let's start modifying this so let me just hit control B to hide that so for this one I'm just going to control D all the places where post appears and I'm going to hit right and then backspace three times and type project so now this isn't um this isn't really how we're going to go about doing this because this link for example should not send to a internal link this should actually send out out like um this should send us out to another um to another link like outside of the U of the project which would actually be um let me see we can get rid of yo it's way too much we can get rid of this and we can say project. node. link and it will link us there so let's just save this real quick head back into our app and create a new folder called projects and a file called page. TSX let's go to our posts and let's copy what we have in post SL page like so go back into project SL page and paste that there and now we're just going to replace like we did before replace every instance of post with project like that and we save and now we just need to add a header somewhere over here um like that and in the header we'll copy down the about like that and we'll just replace these three with projects like so just make sure to capitalize this one and instead of RX person we'll say RX code cool so we save that and now we have our projects um tab so I can click on that and it'll scream at me because uh I cannot return null for non-nullable Fields uh yeah that's probably because we haven't created a cont content SL projects link yet or uh projects file so let's do that so content SL project let's see so if we control shift R um non-null bles let's see let's see let's see let's see so if we go to Project list page and oh oh I see um so we say if no project list return could have swore that would work okay so for some reason I a had a restart my Tina server and um refresh a few times but now it's working uh I do got to replace blog with projects or I'll just say my projects like that so uh we don't have any projects so let's go ahead and create some um let me see if we head into our admin go to projects and let's create some new ones for my first one we'll say um I'll use my Json schema um autod do project and um we'll say for its description um you can tell I already wrote this in here so uh we'll say a sample app showcasing how one might generate Auto documentation and then in here uh oh nice it's actually kind of crazy that it say Sav all this in my auto fill um which one was it I think it was Jason schem autod do there it is cool so there we go have that one and I'll just autofill the other ones so um we had I think my uh react V uh what did I call it um react PL plus V plus Tailwind starter and um a quick starter template and for my link um I believe it was there we go save that and you know you can do this on your own as well so I'm just going to quickly go through these um so for this one I believe it was R JSF reactj scheme of form Tailwind um Tailwind implementation and for the link this one was R JSF tail Inver sale up cool you know some useful repos for you all to check out if you're uh into that kind of thing um and this one was the Shad CN V template for the description uh a react plus typescript there we go and for this one I think it was shet CN V template like that I'm going zoom in a little bit because I can't see and save that and then I have one more I think for this one so for this one I'll say um I think it was my yaml validator so yaml validator so this is a simple yaml editor and then for the link it was the uh there it is we'll save that cool so I don't know why I zoomed out so far okay so now if I go back to my um um um I was really hoping it would take me to the page okay can I just see this like without having to go all over the place yo let me see the thing okay there we go um I don't know why it was tripping so hard so if I go to my projects there we go so now I don't want them to look like this this kind of looks bad so I want to um I want to clean up the aesthetic a little bit back in Project list page page and as a matter of fact I'm going to um refresh real quick to see them there we go in Project list page we're going to um change up how we're doing this slightly so uh rather than have this div and these projects um be listed out in this way um what we're going to do is the following um I'm going to add some classes to this outer div over here um here I'll just enter over here and copy out whatever I need so we'll say div. MX auto. grid. grid calls one do Gap 4 medium breakpoint grid calls three and large breakpoint MX of Z zero okay and inside of this div we are going to contain three smaller divs so the divs are going to look like this div. grid. grid calls 1. Gap 4 like that and inside of here we're going to basically have this same projects list. map but before it do maps we're going to first dot filter and this filter is going to take an anonymous um not Anonymous a um uh how do I explain this so the when when you add an underscore basically means like I'm not actually going to use the component uh not the component the element rather I'm only going to use the index because that's all we really need for this um filter so it's basically saying like I'm not actually going to use the element that I'm mapping over that's it it's just to avoid the type error and um like I always say I always use thefn command and then end up deleting half of it so we'll we'll say I modulo where is my percentage there it is three so um this is going to show the first third of the things um of the projects and what that basically means is like the first third of the items will appear in the First Column the second third will appear in the second column and the third um the third um third third I don't know what I was saying so that that's kind of how we're going to do this um and we're g to add cards in a second so um for now this should be sufficient so there you go um let me just do the same thing twice more so we'll just um alt shift down this twice and I'm going to get rid of this div down here because we don't really need that anymore and we'll say um for here this is going to be for the second column so we'll do equal equal 1 and this one will be for the third column so we'll do equal equal equal 3 three and there you go so now um it'll always be three columns but we don't want to have them as links we want to have them as cards and um to do that we're going to create a new component um we don't have to but I this component is not going to require um the is not going to require is not going to require client side routing so that's why I'm splitting it out because its parent component is a client side routed component I want to separate this logic out so that way we minimize the amount of stuff that's being sent to the front end um for rendering so here we'll say at least that's how I think it works maybe I was misled I could be wrong TSX so this is going to be link card. TSX and it's going to look like this so we're going to say export const Link Card and if you if you've done some of my tutorials in the past you'll know like I have a affinity for Link cards these are um uh just like big boxes that when you you can click on the whole thing and it'll take take you to one page just a nice little um it's a different way to Show links in my um in my opinion uh I said a different way I in a better way but that's objective so here we'll say link is of type string title is of type string why oh it doesn't like it when I Define things like that description is of type string and this is going to be an arrow function and in the function body we're going to return the jsx template jsx template is going to be an outer um next link like so and in here we're going to pass in some classes um which I will actually paste in here because it is going to take me way too long to read all this out loud so go ahead and pause the video write these classes um into the link and um we're also going to have the href um be defined as the link that we that gets passed in so this means that the link is required so because all these things are required at at like when we Define the links then they should be available um should be not being like a um they should be but they cannot no like you can't even Define the things um unless these three um properties are defined so for the Target we'll saycore link and all this does is make it that when you click the link it opens up um the link in a new tab instead of um the current tab so inside of the link we'll we'll add an article tag um and this article is going to have a class name of P4 um and at the medium breakpoint it'll have padding of padding of eight eight there we go one of these days I'll learn how to type so the next thing we want to do is um we're going to have an H2 H2 that's going to have zindex of 20 um text of X you know what I'm just going to paste these in because the this is like this is not really um useful part of the tutorial so go ahead and pause it and copy these over and let me save this just so it looks clean so yeah please pause it copy it over because you're going to want these classes um for the next part and once you got that done we're going to head back to um where were we uh post list page like this and in the post list page instead of returning this div and this link like this wait sorry not post list page what am I saying projects list page yikes my bad so instead of um instead of returning this uh div and this link like so what we're going to do instead is we're going to pass in the Link Card which we will import like so and this link card um should probably close it like that this Link Card is going to take in a key because it is a iterable iterable um and we'll say project. node. ID for the key and and um for the link we'll say project. node. link and I'm just going to alt down this twice for the next one I'm going to swap out the link for title and for the link after that I'll swap out this one for description I'm getting an error um oh oh yeah it was that space Okay cool so now I'm just going to copy C this down um to the next two like that save that and there you go and then it is pretty responsive so when you go to mobile it's just like a stack of cards when I click on one of these take me to the new tab so this one's for my um uh V react Tailwind starter whatever this is my rsf Tailwind um repo so you know just nice little way to represent your projects um so I think that's it for the pro oh let's just clean some stuff up so we just remove that and I think um yeah I think that's it for the projects so yeah there you go so let's go back and start cleaning up the way our homepage and our blog Pages look we're going to start off with the homepage um it's looking a little sparse so I do want to add like a um I want to make this be like a more of a living blog so I want to add like the most recent posts um to the front uh to the front page that way when like you know someone that wants to see like what you're about they come to your uh your portfolio page and they see oh look at that um they have some latest posts um and like they'll be like in descending order by date and how we're going to go about doing this is in our components um we're actually going to change up how we're dealing with this uh page component previously this component was being shared by both the homage and like the I never know what to call it but like whatever uh slug is is like whatever slug page like the about page for example they both share the same um component but we want the hom page to be a little bit different because it's going to operate a little bit differently so in that vein we're going to do what we're going to do is create a new file called homepage uh in just in the app direct uh in the components slapp directory homepage. TSX and this homepage is going to contain essentially what's in the um page . TSX like so with a little bit of an extra twist so we're going to come up here we're going to rename this to Homage component and because this component is not really going to be taken a path anymore because it's going to be dedicated for the homepage we can actually get rid of that relative path variable um and in order to actually use this we're going to need to do something quickly to get this um work in the way we want because we're not going to be using the page query instead we're going to be doing something that we haven't done for which is creating a um a custom um uh graphql query um I think we can just call this query so this is like part of the tetina API we haven't dealt with this part yet so this is like new ground and to be honest with you my graph Q is not that strong so I'm essentially going off of examples um so in this query we're going to say uh we're going to call this home. gql like that and um in here we're going to create a query called homepage we are going to add a filter which will be of type post filter because we want to be um querying posts on the homepage um and in here we're going to say page relative path is going to be uh home. MDX um so this is the path that this page is going to um render on and we're going to um just expand out the page Parts here um I would I would encourage you to read the Tina docs on this cuz um to be honest I'm still learning this part myself so then we're going to say post connection is going to be um sorted by date whoa why did that come out green why did that come out like a comment that's strange um not sure what that's about is it because there's no space Oh it's because there's no space okay uh for the filter we'll just say filter and we want the last five um we want the last five posts to be the ones that come out um in this in this query so we're going to say edges oops um node title date ID hello date I ID D underscore systems these are all the parameters that we want back not the parameters the um the data points dude where is my underscore oh my God I'm dancing around the thing system and file name so these are the things that we want to query um from the from the post connection I think I'm saying that right so now we have our graphql um query set up so now to use that all we have to do is in the homepage component we just Swap this out with home page hello that should not be be giving me errors um I'm pretty sure this is right home P maybe I need to restart my server let's see um I probably do need to restart my server because it's a uh it's a new query that we're requesting so homepage yeah there it is okay sorry that was weird um so we have our homepage query uh let's see we don't care about the title do we care about the title yeah yeah we do care about the title what am I saying this the hom page nothing changes now we need to say const post list because we're actually going to have access to the post list now so we're going to say data. poost connection because now we have access to this edges so similar to what you've seen before so what I'm going to do um before I get rid of everything that's in here um we're going to kind of like redefine the return for the um for the homepage so we're going to say it's going to be a SE section with a C section um and well this is going to be a long one so I'm just going to paste these um styles in here real quick so we'll give it that pros and we'll also give it a um dark Pros like so and inside of the section we will grab this H1 throw that in there and um we're going to redefine this section as an article article and post that in there and we can get rid of this article then under here we will add a um we'll add a we u i I cannot speak We'll add some curly braces and we'll say post list so if the post list exists we'll say post list and and um post list. length is greater than zero like so so basically if there's a post list and if the length is greater than zero because I don't want to show this if there is no um if there are no posts so if that's all true then we're going to return a section this section is going to contain an H2 with the classes margin top of eight and text of three Excel like so and we're going to say latest posts save that real quick and um as a matter of fact I am going to quickly use this um in our homepage just so that we can see this happening live uh as we do it so in our app we'll go to page. TSX and instead of um oh we actually have to change this kind of significantly let me see so we got to change this query to homepage and because we are querying the relative path in the uh graphql query we don't actually need this anymore so we can just do it that way instead of using the page component we're using the homepage component like that so we can get rid of that import save that refresh real quick control shift R okay there we go and you see latest posts so uh even though it it might seem counterintuitive because what we were doing before we said if there's no posts then don't show latest posts but there are posts we just haven't decided to render them yet so down underneath this H2 um we'll add a unordered list and we'll say list Circle and that's just the uh styling for the um the bullet points okay I guess it doesn't like that we'll just do UL Dot and then I'll type it in like this uh sometimes I think it's EMT sometimes EMT doesn't know maybe it's not emit I don't I don't know which extension it is but sometimes it doesn't know like what characters constitute like um a class name um yeah intellisense problems remember how much I said I love vs code so post list. map edge of type any and um I know it's not of type any but I I don't really feel like looking into the type for that right now um I'll probably probably figure it out at some point I should and here we're going to return a list item why am I getting so many errors um oh this is supposed to be wrapped in a uh hello this wait a minute no that's right I just need to return this inside of a brace like that or a parenthesis like that so this list item is going to have a key of um edge. node. ID and we'll give it a class name of margin y of zero there we go and in here we'll use the link if we don't have it imported already um href equals the post so we'll say slash post slash dollar sign um curly braces edge. node doore system. file name and close that tag and now inside of here we'll say edge. node. tile so we'll use the title for this particular particular um post add a space and then we're going to add a span with a text small class and text Gray 400 in here we'll add another spacer like that and we'll say um ooh I need to add a package so we need to add moment um even though like you don't need to add moment but why not we're adding moment so you already add moment assuming I don't already have this added um come on buddy you can do it okay and we'll add the moment types so we'll say y-d at types SL moment um and before I get any angry customers in my DMs moment is still in maintenance mode so it's not technically deprecated so we can still use use it for things even though it's probably not the best package to use according to their own um docs so in here we'll say moment uh I think I need to actually import this up top so we'll say import moment from moment like so let me get rid of this page query while we're here cool so um inside of this moment we are going to pass in the edge. node. date and we're going to uh give it a format of Mama month the day year like that so I don't know why I just said it like that but there you go see look at it looks so much cleaner now um you know it's it's in descending order it's got dates assigned and um you know nice little nice little front page aesthetic of course I completely don't know how to spell circle so that's why the the bullet points aren't showing up as circles but there you go so now those are showing up properly um so I think that basically covers it for the changes that we wanted to make for the homepage now we can actually go ahead and apply these same changes to our um our blog in our here let's close some files real quick so we'll just get rid of all those um in our post list page um component what we'll do to uh sort the blog posts there I believe there's a way to do this with graphql but um I uh I don't know I I try to like dig through the Tina docs and I don't know if it's like I don't know what it is I wasn't able to figure it out so um and of course I'm way too lazy to actually post like a um uh anything on their docs or on the Discord like asking for clarification so instead we're going to do this a little bit of the um manual way uh so right underneath um where we're actually defining the post list we're going to say post list. sort and we want to sort from um uh uh by by descending dates so we'll say a of any B hello I don't know why I said that a of oh it's because I need to add another one there we go a of type any B of type any and I know these are dates but I I don't know I don't it is what it is so in here in our function block we'll say um say const date a type any equals new date a. node. and then that's supposed to be a space there we'll just duplicate this down it's really late here right now so I'm kind of just like doing things the not best way so forgive me for this so I mean it works it's just not the cleanest code return date B minus date a do not judge me by the code that I write at 10 p.m. um so goad and save that that and now you'll see that things are sort of um being sorted by date but you wouldn't really know would you because we're not actually providing the dates so we can address that real quick um by by actually adding some of these dates so let's see in our return right above yeah so right over here I'm actually going to change up how we're doing this so we're going to make this an unordered list um with class name of margin zero and padding left zero um like that and inside of this unordered list uh let's see where does this close closes right there cool so inside of this unordered list we'll say that the uh the posts are returning a list item instead of a div and we can keep the key the way it is but we do want to add some classes here so we'll say class name equals margin top zero every time I say margin top I feel like I'm about to say margin tayor green not to get political onal um so give that a margin top of zero padding bottom of two and then inside of here we're going to cut this link so don't delete it just cut it and we'll say div Flex inside of the div we'll say span text small text Gray 400 400 and if this starting to look familiar it's because we're basically recreating what we did in the other page here we'll say moment oh it let us import it this time nice post. node. dat and format of Mama month the day year a year like that okay um and you have to say it like that otherwise it doesn't work I'm just kidding sorry 10 pm coding shouldn't do it post node system file name that's right and then um I think the I think we going to save that and oo o o man that's nice all right so um I figured I would make this a little bit wait hello oops I clicked on a link I figured I'd make this a little bit cleaner like even more cleaner even more cleaner even cleaner than it already is um by adding a tags filtering mechanism so what I mean by that is I want to have it so that you can um so you can like assign tags to your different blog posts and then be able to filter by those tags so let me kind of show y'all what I mean um how how should I do this so what we'll do is we first got to head into our Tina config and down in the post collection we need to add a new field this is going to be we'll put it underneath the date and above the body so for this field dude come on now there we go um for this field it's going to be um we're going to name it tags and we're going to say um this is a type of string not a type of string tags are of typ string that's more correct way to say it and uh the label is going to be tags and we're going to say list is true because we want this to be an array um so we save that and the way we want this to work is we want us we want it to be like where when you click the tag like I I don't want to have to deal with um with a separate I guess data um point that has to be cross referenced like a tags uh collection or anything like that instead what I want to do is when you click the tag I want it to take you to a specific URL like post SL tags slash whatever tag you clicked on and it in in the actual like blog list it only shows the blogs that contain that tag so that means we're going to have to create a new route um in our app SL posts let's create a new folder and we'll call it tags right so this is going to be the this is going to be the sub route or the sub path of post so it's going to be post SL tags then similar to how we did it with the slug before we'll do tag so this going to be our our parameter name so inside of tag we'll say page. TSX like that and in page. TSX what we're going to do is is export a default async function called post Page by tag and this one is going to we're going to take the pams um I don't know if I need the comma there and this is going to be type prams which is of type tag that is of type string I don't even know if I'm saying that correctly in English is of type is of type um so here we'll say um we we want to basically get the posts so this is going to be just like the posts um uh the the the post routes but it's going to it's going to apply the filter right after the um the query and I I do agree to any descent where you might be saying hey just do this in the graphql and I agree with you but the docs are kind of not that great and graphql is not doesn't have a whole lot of typescript in it so I can't really make sense of the API uh the Tina implementation that well so we're freyling um it's not the best thing but you're getting this for free um so we're going to say the result is going to be um so what we're doing right now is we're kind of like modifying the structure of the result so in this case the result is going to be posts. query data is posts. dat variables are posts. variables so we're basically like destructuring all the contents of the posts but with an added parameter called Tags or property I should say params doag so after we've destructured the um the pams now we will assign them here um why are you screen oh I didn't import it that's why there we go so after that we're going to return post list page component and this will take in dot dot dot result now you might be wondering hey why don't you have a different component for this this is the post list page and to that I'll say it's because we're going to modify the post list page to take in an optional param called tag Okay so so what that means is in our um in our post list which I'm pretty sure is right here in our post list uh uh component or postless page component excuse me uh we're going to have to do a little bit of modification to our um to our props type definition so down here we're going to say tag question mark which means that this is an optional property or an optional prop and we're say this is of type string okay and down here where we're actually defining our post list we're going to have to change this so what this is going to now say is post list equals prop props doag so if props that tag is present then data. poost connection. edges did I spell that right yeah um do filter so we're going to filter out or yeah we're going to filter out any of the posts that contain the tag that was passed in so the tag that's passed in as a parameter in the URL will be used to filter out the posts that we actually show um so let's see post any Arrow function function blog so we'll say if post. node. tags so if the post actually has tags and post post. node. tags. includes props doag so first doesn't even have tags defined and then Does it include the props do tag then return post okay if none of this is true then just return post uh sorry data. poost connection do uh edges okay uh post list s sorting stays the same and down here because um yeah so down here we actually like um how how do I say this so one of the things that we want to show is not just like the tag not just the the things that are shown by tag but we also want to have the tags themselves and this is going to be a little tricky because we have to show all of the tags that exist ac across all the posts and we also want to show well how many of those tags exist that we can filter by so this is how we're going to do we're going to create a new variable called Tags and tags is going to be equal to data. poost connection. edges uh that isn't those are that's not a p let's try that again post connection. edges. ruce and we're going to say the the accumulator and this is going to be of type any and the post this is also going to be of type any um and we'll say uh inside of the function block uh first we want to check if the current post actually has any tags so we'll say if post. node. tags and if this is true then we're going to iterate over each of the tags so post. node. tags do4 each and we'll say nfn tag of type any um and then in the function body uh we're going to say if the tag already has uh sorry if the tag is already inside the accumulator then increment the count so if accumulator as the tag then oops there we go then ACC accumulator tag and where is my plus bruh oh my God okay we're having technical difficulties there we go just remove that P increment the tag um okay otherwise else um what we're going to do otherwise is add it um with a count so we'll say ACC tag equals 1 okay um and then uh let's see right over here we're going to return the accumulator so return the accumulator function like so and then after this we have to initialize the accumulator as an empty object so we'll do it like so so now tags is going to contain the count of every tag across all of the um posts so let's say data post connection edges there we go cool um so let me kind of show you what that looks like so if I come over here and I I say log tags like that and then I open up my Dev inspector you'll see there's an object that contains a whole lot of nothing all right and um well how do we get it to show stuff let's start adding some tags so let's head to our hello okay um hello let's re let's restart this that's weird okay yeah I don't know what that was about so let's go to to building a to-do list and let's start adding some tags so for the tags we'll say um I don't know v um react and typescript let me hide my terminal because it's bothering me okay and um we'll say I don't know um project okay save that and let's head nope wrong button let's head back to our posts and let's go to fast fasinating facts about CSS so here we'll say um CSS um informational and we'll say web dev and frontend cool save that let's head back to our posts and I know it's a little last nine but like you'll you'll get the you you'll get the point once you see it so for this one this is going to be react um next.js let's see did I have typescript in this I did not have typescript in it yeah there's a JavaScript so we'll say JavaScript for this one JavaScript web dev and I'll say tutorial save that all right so let's see this one's for remix so we'll say remix webdev um tutorial and typescript JavaScript JS uh I don't know we'll say JavaScript save and let's see one more understanding the re oh my God I cannot speak the react use effect to say uh react use effect explainer save okay so there was a point to this lesson so now when we refresh if I um if I control shift refresh there we go so I'll pull over my console my my my gez I cannot speak my um my Dev tools man that was really hard for me to get out and you'll see that we have all these tags so you'll see tutorial showed up twice JavaScript showed up twice next nextjs Once react three times so this is kind of what we wanted so now now that we have these um these tags we can actually go and start um like rendering them but like not just underneath the um not just underneath like each one of these but also as like a sidebar where we can click on and have it be a router um or have it be um have it be full of routes that point towards the um the the filter route so or the route that has the tag parameter so let's go ahead and start getting that done um so first one I guess the first one we can do is the actual sidebar so right under here where we uh have the H1 with the blog we um I'm actually going to paste some of these Styles in because this is this is a lot of styles so so uh the first one so we're first going to have these two outer divs um let me close these real quick okay so these divs are going to be like a nice little containment box so we'll save that and um actually I um I think this div needs to be closed outside of here like that there we go um because we want to have like the tags tip here at the left of um of uh all the Articles or all the block posts I should say so so inside of this uh left um this left div we're going to first have a um an anchor tag that when we click on it will basically take us to posts um and we're just going to call this all posts so go ahead and copy this over and this is what it's going to look like so when you click on this which you can't click on it now cuz um as you can see this right here says if props do tags is undefined then disable the pointer events and make it green which basically means this is the one that's currently active so you can't really click on it because uh there are no tags being passed um to the props uh being T being passed by the props excuse me and actually I made a mistake um this a tag has to be inside of a div so it's going to be div. PX 6. py4 like so and that yeah there we go gives it a little bit of space so the next thing we want to do is we want to add this um unordered list right underneath here so underneath the a tag we'll open up this unordered list and inside of this unordered list we're going to map over the tags Keys like so um and what's Happening Here is because our because our tags are defined as an array of key value pairs or a map we need to iterate over the object keys so remember um if you you look at this object over here let me just pull it over um like so so this is the actual object right so you have the key of CSS and you have the Val the the the key and the value being one right the count so we need to iterate over the keys as though they're array elements that's what object. keys does is it basically converts all of the keys into their own array and we iterate over them and then we can do funky things with them right so what we're saying here is we're iterating over the keys of the tags object and um we're going to say map tag whoops hello where' we go okay and inside of this array we're going to return a list item for each one of the tags with class name of margin y let me hide my sidebar and give us some more space margin y okay of three I can't tell if that's two or three it's late and we'll give it a key of tag um because the tags are going to be unique since they're um technically counts uh because like we're we're only going to have like one object that has CSS and the other value is going to be how many times CSS has shown up so logically speaking they're going to be um unique since they are the result of a count um so inside of the um inside of the list item we will um provide a link object so we'll say link well um not link object sorry link element um and this is going to have a uh actually tell you what I'm just going to I'm just going to copy these classes because this is going to be really confusing and it's a lot it's a lot of classes so we'll say class name equals um this all right so all this is is saying is if the tag that's being iterated over is the is identical to the props do tag meaning the tag that's being passed in from the URL then show the same Styles as before which is basically this is the active tag Styles um yeah uh so more or less and then we're going to give it a ara label of um view posts tag and I know this is the first time you saw me do an AIO label today this is supposed to be a back tick by the way like that um so in here we're going to say View Post tagged by tag close that and the hre in here will go to uh slost slags Slash uh dollar sign brackets tag like that okay so we can close that and inside of here we will show the tag and in parenthesis we will show how many of the tags um well what this is saying is like what is the value of the tag at the position of the tag so it's a little confusing but like if the tag is CSS for example then what this is saying is inside of the tags object at the value CSS that value would be the number that's associated with it so we can go ahead and save that and get a whole hell of a lot of Errors because we did not close our we didn't close this so let's let's close that so we owe this uh jsx to close dude where are my parentheses oh my God okay I'm having a stroke over here what the heck okay um and we can also I'm just going to close this with a curly brace and save that and there we go so now you see all of our tags so when we click on one of these you'll see it only shows the thing that has the tag of informational we click on webd and it breaks so that's good I love oh interesting I think it's because of the oh it's because of the space okay that's cool I didn't know that so um I'm going to have to figure out how to validate this so that it doesn't have the wow that's really interesting okay I I hadn't run into that before here let's fix that real quick so um what do you know you find bugs all the time so let's see this doesn't have it [Music] um this has it so we'll just say web-dev save that man that's crazy I didn't even think about the um spaces um I'm also going to change an xjs to one word just in case that has any impact so we'll say post um this one's fine post setting up a new thing web-dev save and I think that's it right so we have setting up a new yep I think that's it so let's head back over here give it a hard refresh and now we click on webd okay that's cool click on front end uh informational CSS tutorial JavaScript nextjs um so let me close my console inspect there we we go uh so I do want to actually sort these because there's like this funny thing that happens um where like they get reordered for some reason um and I think it has something to do with like uh it's showing the things that have the tags actually I have no idea I'm not even going to try so I'm going to sort them alphabetically um like that and we'll say uh the first type any the second is of type any and um we're going to say a. key. local compare b.key okay um interesting what any not Abby save that oh my God I forgot the e there we go cool so now we don't have that weird um issue where it's reordering them because now they're ordered alphabetically which is awesome so last thing we want to do is we want to show the tags underne underneath each one of the blog posts I know I know it's a lot but we are almost there um I think hopefully so let's see down underneath the link we're going to add a post. node. tag so if this exists or uh if this is true then and down here we're going to add a div with a flex Flex wrap Gap 2 font Sands text small uppercase text Emerald 600 dark text Emerald 400 enter and in here we'll say post. no. tags. map Ann ah they almost got me again I always mess up the Anns in this uh in these tutorials any that open a parenthesis found it the second time look at me I'm learning link like that I'm gonna sorry I'm making space because I realize I was at the bottom of the thing and yall probably have no idea what I'm doing um so in here we'll say HR equals curly braces um Tilda post tags um tag okay so it goes to that um link and we'll give it a class name of underline did I spell underline rightler under line offset 2 and on Hover we'll give it the underline um and then we'll say key equals tag and inside of the link we will say tag so we save and look at that so now these links operate the same way as these so if I'm over this and I want to say you know what let me filter by JavaScript what hold up no way get out of here okay interesting oh my God I sorry I said post not posts man that was underwhelming let's try that again okay that's working tutorial uh nextjs okay so now only the show is react and you'll see that it's actually updating it over over here too Isn't that cool there you go so now you got a nice little filtering mechanism oh my God let see what it looks like in day mode ah well everything looks like trash in day mode let's be honest okay so um yeah I mean that's uh hold on let me let me double check my notes I can't believe that's it if that's it I'm I'm G do a dance real quick oh my God that is it okay so the last thing that we want to do is we want to get this ready for deployment um so in order to do that no there is one more thing that we can do um and I think you'll appreciate this so there's a way for us to extend how like what contents we can render in our MDX by um essentially expanding the uh the the rich content blocks so we can add like if you come to the um if you come to these posts for example you see all these elements over here so these are all like um I guess custom like like components so like you have um you have your code block for example you have like I don't like like your image hyperlinks all that kind of stuff but you can also add your own custom components in there and I'm going to show you how to do that real quick so let's see I'm kind of going off the cuff here so hopefully um this this doesn't take too long so what we're going to need to do first is we're going to need to create this like Rich teex schema um so if we go to our Tina config tell you what we're going to add a new file and we're going to call it rich text schema. TS okay and in here we're going to have a few um definitions so we're going to say export const rich text components and this is going to be of type template which is a Tina CMS uh type and it's going to be an array of templates and in this array we are going to um did I open up an array to bracket or a curly brace no that that's that's an array and we're going to say Tina table template so we're going to first add the Tina table template um that one's like given at the box from Tina and the next one we're going to add is a video player so we'll say name video player label video play that was supposed to be in quotes like that and for the fields this one's so this is a custom block that takes in its own Fields so for these fields there's going to be the URL so we'll say name URL let me hide my sidebar give me more space uh um label video URL and type is going to be string like that um and then underneath here we'll give it a custom UI and we'll give it a default item and the URL the default item is going to be one of my YouTube videos cuz I am un original let me find one real quick since none of y'all watch my videos anyways I figured I'd go ahead and plug one over here so we'll say you have to go here this is the default um URL so if you add one it'll shove this video unless you change it um always be plugin next one we'll say name this is going to be a captioned image um I need to open up a bracket first it'll say name captioned and a lot of this is based on the examples provided by Tina CMS so I do want to like shout out the um uh Tina themselves because they be they be giving us a lot of examples and it's pretty awesome because I'm pretty sure they're like a like a 10 person team or something um they're grinding and I respect the grind okay so we'll open up an array and we'll say this bracket is going to have name image URL label image URL Type image and this is just going to be a custom little captioned image so an image that has a um caption underneath it um tell you what I'm just going to paste in the rest of these um cuz feel like saving you and me some time so go ahead and pause it copy them over there we go so there's the caption and then there's the image alt the next one is a tweet embed so paste that there it's got a nice little default um tweet for you definitely copy this over do not not copy this over um so next one is a text box this just like a rich text box that we can um put inside of the markdown text box cuz why not and the next one is the poll quote so we'll just paste that there so here I'll scroll up for youall to be able to copy that over there you go so it's just like a little quote box so we'll save that and let's go ahead and add these components so back in our um back in our repo or our directory let's go to components and we'll add a new file called Rich text. TSX and this is where we're going to dump in all of our Rich Text components so the first Rich the first Rich text component is going to be the text box like so and this is going to require Thea markdown um dependency the the one after that is the Tweet embed and this one is actually going to require us to import a um a package called react tweet so just go ahead and open up your terminal and say yarn add react tweet and I guess while we're at it I think we also need to import react player so we'll say react player like that okay so I'm going to kill this terminal and hide it wh I said hide it not show it there we go um so let's import tweet from react tweet like so cool um the next one is the pull quote so I'm just going to copy this from here paste that like so let's go ahead and copy this over and I'm going to scroll up real quick because I realized that I um I realized that when I was cut pasting these the first time they probably got like squished so there just take a second and copy them over um so the next one is the react player and this one's going to require us to use um the dynamic import because uh I don't know there there's some issue that like I found in the docs so this is the way it works as far as I was able to figure it out so it is going to require the dynamic package from next Dynamic so just paste that up there and go ahead and copy that over and the last one is the captioned image so paste that in there like so go and save and now we can actually use these but to use these we have to go back to our Tina configs cuz uh well I'm I'm not the most um I guess uh I guess I'm not the most thorough person in the world am I so here we'll just contrl p uh config cool so under post where's the text so under the rich text where it says is body we'll add a new property called templates and we just need to import the rich text components like so okay next one we want to do is the um the page so under Fields Rich Text there we go so now both of those are using the um the rich text components so we can go ahead and close the config I believe um yeah yeah we can close the config and now we just need to actually consume our hello uh I don't want to use image you guys always give me problems okay so let's I don't know why I just ranted out of nowhere um so now let's see so we actually need to import the rich t text and use them in all of the places where we're using um the rich text markdown uh so let me show you what that looks like um underneath the app uh page so app page. TSX um we want to pass in components here okay components if I can learn how to type equals that okay and in the components we can just import those um those components that we just created so text box like that and tweet embed like that uh maybe it needs to have another curly brace there we go okay we just save that to clean it up um so next one is pull quote I need to actually import it hello I said pull oh my gosh okay guess I'm going to do it here first pull quote captioned image video player and uh while we're here we'll create well no we have to do that we have to do that where it's consumed so we'll just copy those and paste them there sometimes my intence doesn't like to work so we can save that and um yeah there that's good enough so now I can just I'm just going to select these and then controll click these copy and go back to um let's see under posts uh I think it was yeah post page right here I'm just going to click here control click here space paste uh this one might need to be at slash components SLR text there we go add a space over there because that looks wonky all right so the last one I believe is just the slug so underneath [Music] um uh right there page. TSX oh wait I was oh I forgot to do it though I forgot to do the homepage so last one's the homepage sorry so here and there there let me do that again control click there control click there paste save and now let me actually show you what those look like so if we head into our Tina CMS and um let's say I want to modify here let me control shift R just to make sure refresh so now you can see there's this little embed button over here right so um up top I can actually come in here and say embed and I can embed a tweet and there's our default tweet uh Elon Musk um doing his thing right so and you can change this pretty easily so you can say um let me find another tweet uh let's see popular tweets oh gosh I'm probably going to find like a really terrible one um let's see man I forgot how toxic Twitter is all I'm getting is a bunch of inappropriate things okay here's a PG one there we go there's Mai caulin uh Mai mcau caulin I cannot say any I cannot say words and it's an embedded tweet so you can actually like do tweet actions which I'm not goingon to do because why would I do that um so let's see like there's the video player as well so um where did it go hello oh there it is okay and it does have a video oh it's at the bottom and there you go there's my accordian tutorial look at that so that's our default um so yeah it's um it's a pretty it's a pretty neat feature and you can do this across like the rest of your apps you can do this in the um you can do this in the homepage if you want like if you want to have I don't know one of your Banger tweets show up in the homepage hey you can do it um you can do it in your in your uh n no you can't do it in your projects because this is not a markdown uh this is not an MDX file but you can do it I mean if you want you can change it that it is and then you can do it that way um and like like I said like you can you can go back and you can customize those as much as you want so you can come into this Rich uh this Rich Text uh component and you can go buck wild like you can create whatever custom component you want that like it should work since they are react components and MDX renders react so yeah um I'm really excited to see what y'all build if you build anything exceptionally special please leave it down in the comments and um uh I did oh oh before I uh before I finish off I did actually create a um a guide on how to deploy this um the deployment stage is not too difficult it's just it's a little like uh there's just a few steps so instead of instead of actually um doing it for you what I did was I created a um site just like this one and one of the first blog posts that you'll see is a detailed guide on how to um on how to deploy U the Stell and get it hooked up with your GitHub so that you can get your portfolio um up and in front of your uh in front of your recruiters and your interviewers and wow and hopefully get that job that you've been fighting for so um so yeah um I want to just say thank you so much for watching and uh if you made it this far thank you so much um and as always I hope you learned something today
Info
Channel: m6io
Views: 11,368
Rating: undefined out of 5
Keywords:
Id: RpOsTUezCk8
Channel Id: undefined
Length: 154min 0sec (9240 seconds)
Published: Mon Jan 29 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.