Build a Next JS 13.3 App with Auto ChatGPT Content | Next 13.3, Prisma, TipTap, Typescript, Deploy

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys this is Ed Rowe so this has been a long time coming we have a very special app today and that is we are going to be building a complete next js13 application today we're going to be building this complete AI blog application and we're going to create this entire layout from scratch so we're going to go through and talk about CSS grid and flexbox and doing all of this for each of these layouts and we're also going to make it completely responsive so it looks good on both desktop and mobile screens and then from here we can go to each individual page and each individual page we're going to use next.js to make all of this performance optimized and we're going to make it Dynamic and then from here we're also going to talk about how we can write this content blog and the fact that we can edit this content information with some kind of text editor called Tip Tap and we can change our settings we can make it bold we can do italicized we can change all of these settings all for free and then from here we're also going to have generate AI content So based on this title we're going to generate this particular content and I can see I am a sarcastic writer for something like this we can generate our AI content and as you can see we have our blog content generation so I limited this to three sentences so it doesn't take too long but hey oh great can't wait for the future of space exploration so as you can see we are telling open AI that we want a sarcastic writer and we have content that's written in a sarcastic way so it's very very helpful and you can submit it and we save this information and finally I'm going to be telling you how we can deploy this application on versel all for free I'll show you all the process I'll show you all the performance optimizations what we can do and use all the new features of nexjs13 so in this application I'm excited to show you that we're going to be using next.js but not just standard next js12 with the Pages directory that most people are using we are going to be using the latest next.js 13.2 version with the app director and I'll be guiding you through every single new feature of Nexus 13 and optimizing performance everywhere I can while building this application for the tech unfortunately T3 stack is not yet compatible with the app directory but we'll be using every compatible Tech possible such as next year 13.2 Prisma hero icons Tip Tap typescript tailwind and versel and finally we are going to be utilizing the awesome power of Chachi PT to generate blog writing content that'll feel natural and engaging now speaking of chat gbt I want to introduce our sponsor for today's video brilliant.org which offers some incredible educational courses in neural networks machine learning and other computer science topics as someone passionate about Ai and deep learning models I found that Brilliance interactive content is an essential tool for professionals looking to stay ahead in this AI dominated world I personally love their courses on neural networks it's engaging Hands-On and it helps you truly understand the Core Concepts behind Ai and machine learning plus brilliant is designed for busy people so you can learn at your own pace on any device and even Master topics with just 15 minutes of learning a day what sets brilliant apart is their visual Hands-On approach which makes it easy to grasp complex ideas and truly understand the key Concepts behind today's Innovative technology their storytelling makes abstract ideas relatable and the Beautiful interactive visualizations lets you engage with Concepts so you actually understand you're curious about AI neural networks and machine learning and want to explore them like we're doing with chat gbt brilliant is the perfect place to start to get a 33 day free trial we'll see everything brilliant has to offer visit brilliant.org edrow or click on the link in the description and as a special bonus the first 200 of you will receive 20 off Brilliance annual premium subscription now with that let's explore what nexjs 13.2 has in store for us as we start building our app so the first thing we're going to do is we're going to be installing node.js so you can go to the description or the link in the description below to this website and you can download whatever is recommended for you for mine is Mac I've already had this installed so I'm not going to do that but node.js is basically it allows developers to build and run server-side applications using JavaScript which is traditionally used for client-side scripting and web browsers but we can use this for our server-side applications and then after that we're going to be installing npx so also the link in the description you can go here and you can do npmi-g npx so this is a package that will execute npm binaries for us and it's something we'll be using and finally if you don't have a code editor or like a text editor for writing code you can go to another Link in the description for vs code and you can go to this website download the vs code version that you will need and this will allow us to use our text editor so the next thing we're going to install is going to be next.js and by popular demand everyone has been asking me to build a project in next.js and we're going to be building a project in xjs13 today in version 3 13.2 specifically now if you're new to next.js next.js is an open source react-based framework for building server rendered web applications so it uses react under the hood but it provides a lot of opinions and the ability to simplify the process of building modern web applications by doing things like automatic server rendering and code splitting for you has a lot of default options a lot of those things all built in to next.js and we'll be covering that in this video all right so we're going to be installing this and we're going to be installing next.js 13.2 so we're going to go into our Visual Studio code I'm going to increase the side so you guys can see over here and what we're going to do is we're going to run npx create next app at latest and we're going to do dash dash experimental Dash app so this will install the latest version and it is in experimental mode so there is a lot of unstable features but I'll cover most of them and I'll cover what parts is still in production or still in testing basically and so after here I'm just going to say blog AI app that's the project name and I'm going to say we're going to use typescript we're going to use eslint we're not going to use the source directory so it's by default no and we want an import Alias of the basic default so we're just going to hit enter so that will set up our next JS project for us and by the way if you haven't noticed there's a lot of links to the description below about next js13 and installing it you have to go to the docs and there's the app router beta or next.js13 stable docs this is where you want to look at and you can see there's installation and all these types of instructions including the app router roadmap so basically it's all the road map items that they're trying to build into 13. so they have a lot of the things built in now they just have a few things that are still a work in progress so if you see anything like this that means those are a work in progress now we're going to open up vs code again and once next app has been installed we're going to open up our Explorer we're going to go into this folder so we're going to do CD blog AI app we're going to go into it and then here we're going to be installing at hero icons slash react so this is a library that's built by tailwind and it's used for using free icons that we can use for our application and we're going to be installing a lot of other packages but we're going to be doing it when the moment calls so we're going to be waiting for those and then from here we're going to go to extensions and I want you to install certain extensions from here so I want you to install this particular one es7 plus react Redux react native Snippets so this will give us some boilerplate code as needed then we're going to install eslint so this will allow us to show syntax errors automatically and help us debug a lot faster and if we go down over here we can go to prettier this will format our code automatically when we save it all right with those installed we're going to go back to our Explorer we're going to open up our folder and we're going to open up app and we're going to delete a few files so we're going to delete page module.css and we're actually going to keep everything we're going to go to globals.css I'm going to hit command a or select all depending on your Windows machine or OS machine basically and we're going to just delete everything in here and then over here we're going to go to page.tsx I'm going to remove everything inside the main jsx so I'm going to remove all of this guy just remove it we're going to be replacing it with our own code we're going to get rid of the class names we're going to get rid of everything up here so we have no Imports right now and then we're going to go to layout.tsx and we are going to modify our metadata and we're going to say blog AI app and we're going to say blog built in next j s dot uses AI so we're going to keep that and we're going to save that so the next thing we're going to be setting up is going to be the fonts so now normally we would just use a import from Google fonts but next JS has their own version of automatic self-hosting for any font files so it'll make it a lot easier and it will be much more optimized to use the fonts so if you can go to the link in the description you can see all of this font optimization that they have a lot of explanations for so for us it's going to be very simple so we're going to do import open underscore Sans so open underscore Sans is going to be the font that we're going to be using and we want to do next slash font slash Google so that will give us our particular font and we just do need to do a little bit of configuration for this case so we're going to do open Sans and we're going to say open underscore Sans and I'm going to do subsets and I'm going to set this to be Latin like this and once we have that I'm going to go over here into HTML and I'm going to pass in class name and we're going to say open Sans dot class name and basically once we have this set up we're going to be able to use open Sans for all our fonts so because we're placing it on the HTML we now have open signs as our font for our entire web page now there's a lot more configurations that you can set up for this having like different weights and different things like that but they do suggest using like this as a variable um variable version so that means it will use the font weight that it needs to and it'll optimize it automatically for you so I'm going to save that all right so the next thing we're going to install is going to be Tailwind CSS with next.js so next.js really works well with Tailwind CSS but material UI it's still not up to par it you can use client components but you cannot use the latest server components with material UI they are working on it so it will come in eventually with next.js but for now let's use Tailwind CSS to get this started and if you see the link in the description below you can go to this particular page install tail1css with next.js and we can set up Tailwind CSS in our next project so now they have some instructions over here for creating the project that we've already created the project and we want to just kind of do our own thing over here so all we have to do is Skip to step two and we can just follow these instructions over here so I'm going to open up my terminal over here that reduce the size of that and over here I'm going to do npm I Dash D and then I'm going to say Tailwind actually I could just copy I don't know why I didn't do that so let's copy and paste it over here let's wait for that to finish I'm going to go over here and then I'm going to copy and paste this particular value as well I'm going to copy and paste that as well so we created it we should be able to see certain files Tailwind config we should see post CSS and we should see all the installations over here all right so the next step is going to be configuring your template pass so we're going to go over here we're going to have majority of this so we're going to go over here Tailwind config and what we want to do is we can just actually copy the entire thing and just paste it over here so we'll have majority of that and then we just don't need to get rid of or we don't need the source directory because if you remember when we were configuring Tailwind or next.js it asks us if we want to use the source directory but we do not so we can keep it like this and we're actually not going to use the Pages directory so if I since we're using the experimental version we have app but we don't have pages so pages is the old way of next.js way of doing things so we're going to be using App instead everything is going to be based in the app and I'll explain everything as we go and then from here we're going to go down to the Tailwind directives so we're going to go to globals.css file and I'm just going to paste everything from here to over here I'm going to save it and now if you see this kind of annoying error says cannot find module next slash Babel that is mentioned over here all you have to do is go over to eslint RC and we're just going to create this into an array and I'm going to add over here next slash babble and I'm going to do a comma and once we save that we can go back to our tailwind.comfig and the error is now gone so I'm going to close all of this and we're going to be setting up our theme right away so over here we're going to do extend so now if you want you can go to the link in the description again and you can copy all of this into this particular page if you want to skip this but otherwise I'll just go and do this real quick and I'll explain everything as we go and now we have a few colors that we're going to be using and I'm going to use white and I'm going to use a 10. so the reason why I'm not using the like right here is because it's already reserved or if you can use gray 10 but those are already reserved so I want to create my own over here so I'm going to do F4 F4 I'm going to do wh 50 like so and I'm going to do Sharp fbfpfp I'm going to do white 100 colon number c 9 C9 C9 I'm going to just continue doing this over here until we get a few of these I'm going to say this is 300 and this is going to be 93 93 93 this is going to be 500 and we're going to do 59 59 59 and this one is going to be 900. and again these are like pre-configured colors that I decided would look good for this particular application so these are all the colors we're going to use and then we're going to have an accent of red I'm going to call this EA 9648 this is going to be accent Orange and we're going to have F 6 c f 6 8. and then this one's going to be accent green this is going to be c 2 e 9 B 4 I'm going to erase these two and over here I'm going to do background image make sure you spell that correctly and then we're going to pass in theme and I'm going to say we want a gradient gradual so this is the naming colon and I'm going to put linear Dash gradient so basically if you want to do a gradient color you're going to have to use background image to do so it's kind of a workaround but it works so we're just going to have to set this and we're going to say RGB a this is again colors that I've set I used figma to set these colors and these are the ones that kind of look good and it's automatically generated based in figma I need a comma zero zero zero zero zero zero I'm going to say a hundred percent set it like this and we're going to have our colors all set up we're also going to have to go over here make sure it's under the curly braces over here on line 21 I'm going to say screens colon and I'm going to say excess code or yeah colon 480 pixel SM colon 768 pixel and then MD 1060 pixels so we're setting up our own media queries so we're going to be using this in the code and that will set up our media queries that we can have like different colors or different CSS styling for different screen sizes and once we have that set up we have our theme configuration all set up for Tailwind all right from here we're going to be installing tailwind and uh extensions now Tailwind is very nice it just has a lot of configurations that you're going to have to kind of set up so if we go over here to the extensions we're going to go Tailwind intellisense which let me all right here so Tailwind CSS intelliser so this is this will provide syntax autocomplete and highlighting for your Tailwind CSS intellisense so it's very useful and then Tailwind documentation now you can use whichever Tailwind documentation you want but I prefer this one Tailwind dock let's see something like this there's two of them this one is way more popular I believe but I do let's say tell them I use this particular one and this one allows you to just bring it up inside vs code terminal so it's very fast so I can do command control T so if I go over here I do command control T like this and it brings it up and we can do like a search on let's say um Flex something like that we have flex and it will bring up the site inside your vs code the other one is pretty good so it's up to you whichever one you want all right so the next thing we're going to install so we're going to install all the Tailwind things that we're going to be using so I'm going to go out of this and we're going to be installing something called we're going to do npmi at Tailwind CSS slash line clamp so what this allows us to do is when we have text for example let's say let's take a look at this let's say we only want this particular text to be one line and at the very end of it if it's too long we want it to be a dot dot dot for the continuation this line clamp will help us set this up all we have to do is say line clamp one it's going to concatenate this to one line and you'll have three dots showing that this text is longer so it's very convenient library and we're going to be using this all right so the next thing we're going to be installing is going to be at Tailwind CSS typography so anytime we're going to be using HTML and let's say markdown coming from backend or something like that we cannot actually apply fonts or typography onto that like not using normal Tailwind CSS we cannot do that so for example in our completed application we cannot apply open Sans font and bold and things like that onto this guy so we cannot apply it the particular font without particularly using something like this so that's why we really need to install this so I'm going to do npmi-d and I'm going to say at Tailwind CSS typography so for development we're going to be using this for Tailwind CSS typography and then from there I'm going to go to the Tailwind config.js file and I need to just add this to as a plug-in oops that is not what I wanted so I'm going to do require like so and we're going to pass in at Tailwind CSS typography like so so this will set it up for us to use and also we actually I forgot to require our Tailwind CSS line clamp so you need to install this over here as a plug-in as well so once we have that we have our typography all set up for Tailwind to use and then finally the last thing we're going to do is we're going to go back to our file and we're going to go to app close all of that let's go to globals.css and now that we have Tailwind installed we can just do HTML body root dot app and we can set the height to be a hundred percent width to be a hundred percent at apply text SM so this is basically resetting it so that our entire HTML body they take up the full height and the width so we have everything set up like this and we want the width to be 100 and we want to make sure everything starts with the text of small instead of the regular default font size I'm going to go to page TSX and then make sure everything is working as expected yep all right so now that we have next.js pretty much set up and we have cleaned it and we installed Tailwind as well now I want to do some explanation of next js12 and next js13 and I'm going to explain the folder structure and I'm going to explain a lot of different things now just a heads up this video is going to include a little more explanation than usual just because I want to explain everything all the nuances about next js13 because there's a lot of changes there's a lot of things to note and there's a lot of important information that you really need to understand when you're using next.js 13. it's very complicated sometimes if you don't know what you're doing so anyway so this is our directory and we we're going to see dot vs code you can ignore that that's just vs code settings for myself I have vs code over here I'm just going to delete that because I don't need that over here we have the app directory so the app directory is a folder that's going to be required for next.js13 so this is going to be the new way of doing things in nexjs there used to be a folder called pages in the old version next.js12 and this is where you would have all your files folders your API folder as well you would have them all in here but next.js13 has moved it to app directory over here and in this app directory we can do route navigations again I'm referring to a lot of links in the description but this is another Link in the description it's about defining routes and how it basically works but let me explain so if I create a folder in the app directory let's call this testing and if I have a file called page.tsx and this is important there's a lot of opinionated abstractions in next js13 so for example page is a keyword so you have to make sure you use it wisely so over here essentially what this means is that if I go to localhost and in this here if I had a component here and I say slash testing then it would take me to this particular component over here now it's not going to show anything because there's nothing here but this will be represented by a folder over here called testing so that's how you would render out the routes of your website so it's not like react router where you identify and you have to use all the components you can just do this based on the folder directory and then let's say instead let's say I just want to create a folder though so like I don't want the navigation what you can do is just pass in parens like that by doing so now this will never be rendered as a particular route you can just store the files over here and we can just place any component in here and we're going to have like sharing components or whatever whatever we want without having a navigation all right and then from here I'm going to delete this so we don't have that we're not going to be using that don't see and then from here let's go back we have a folder called API so now if you are using nextgs now it is not mandatory but if you're using next.js you can use a backend with nexgs as well and you can have a folder called API in here and anytime you create it you have a route file it has to be called route by the way so you need to know that this is Route and in here this is where you can write the logic of your code for navigation now this has changed a lot if you used 12 or maybe even 13.1 this is has this has actually changed and you'll see in the code I won't do it right now but I'll explain everything as we go to show you how we can do it and it's pretty simple once you know what to do so we have our API directory over here and so for now what I want to do is I want to create a little bit of our architecture over here and we're going to keep it very simple so for our app we're going to create a new folder and we're going to call this home and this is going to be in Prince so we're going to keep files relevant to like the home page in here so we're going to have components over here we're also going to have a shared folder so these are components that will be shared across multiple pages so we want to keep that but we don't want this to be a separate route and then finally we're going to create a new folder called post so this one is actually going to be requiring a navigation and inside this folder post we're going to create another folder and we're going to call this ID so this is for dynamic routes inside the post ID that means if we have some route and we can have like a route that looks like something like this you have an ID at the end and it's Dynamic so we're going to be able to I'm going to explain this as we go but we're going to have this particular folder that will represent that I know there's a lot of information here we're going to be going through each one of these inside our app directory I'm going to create a new file I'm going to call this loading oops let me make sure I write it over here so I'm going to call this loading dot TSX and this particular file is another keyword so whenever you have a loading file this is the component that will be rendered when the page is loading so if I go back to my completed application so if I go home you saw there was for a second there was a loading screen you see that that is the loading component that will show up when the page hasn't loaded so we're going to be creating that so I'm going to say import react from react and over here I'm going to say function loading like so I'm going to return a div and we're going to say loading over here I'm going to say export default loading so this will happen anytime we are loading a file so if we just do that we'll have the loading now there's nothing to load over here so there's it's not going to pop up but if we have a lot more things to load it's going to show up and it will be our loading component and we're also going to have a loading component over here so I'm going to say a new file loading TSX and I'm just going to copy everything actually copy everything from the loading file and paste it to the other loading file so when you have that you should be able to get a loading component easily and then finally one more thing I want to explain is going to be the layout page so the layout page consists of a layout of the entire application so this is particularly shared across your component so if you have like a nav bar that's going to exist on every single page so this is where you write the code for that particular situation so over here I want to have basically a body we're going to have a nav bar let's see inside our body component we're going to have a nav bar up here so I can spell that correctly we haven't created this component yet and we're also going to have a footer component so if I do further this is where we can have shared components across the entire application so I'm going to comment out further and then we are going to be working on navbar and so before we work on that bar let me do a very brief summary of everything I just explained so we have grouped components grouped components that are in parenths so you would put any kind of component that you want over here without affecting navigation then we have regular navigation such as post so anytime you have a folder with posts over here you can do slash post and then you can go to that particular route and you also have Dynamic routes if you do a square bracket over here so you can put the ID in there and we'll show you I'll show you how to do that then we also have loading as well so this will display anytime the page is loading and we also have layout where this is universal to the entire application then we also have a folder called API where this is actually the back end so we can hit backend routes via this location and we can write the backend code in the same directory as the front end code so that this is basically essentially the back end that we have over here and then finally I want to explain one more thing is going to be the metadata so the metadata is going to represent what's at the top of this particular page so let's let me comment this out let me save it and I want to show you this title represents this guy over here in the tab it's a Blog AI app represents that and the description is going to be a description of what your website is about and this is particularly for Google search engine bots so if you want to do search engine optimization you're going to have to write good descriptions for this so Google can recognize your page and what it's about so you need these kind of descriptions now this metadata has changed this ability to write the search engine optimization has changed from 12 and in 13 quite a bit so now it's pretty simple we have metadata and there's a link in the description below about all this metadata information so you can provide all the information for Google via this particular object so one more thing about the metadata API so in next year is 13.3 we have a little bit of extra feature with the metadata but it's a very Niche case so in this situation so generally you have your config based metadata that applies to your entire website but now with next year 13.3 you can use the next JS metadata API to have different SEO and different metadata for each of the pages that you are doing so for example you can also have favicon for your main home page but you can also have it for your different post page for example like the post page that we created so we also have open graph image which is just an image for LinkedIn and Facebook what it shows when you create a social link with Twitter and then we also have icon sitemap robots and manifest so it's a lot of SC SEO metadata things that you can add if you want to and you just have to add it as a file into your folder system and also we have Dynamic open graph image generation again like open graph images for LinkedIn and Facebook when you share it you're going to see like a little image and metadata about that and that's what open graph images used for so now you can make it Dynamic so if you have a different image Generations or linked shared images this will allow us to do it dynamically so it's a very Niche case all right so this is a completed application and over here we gonna have we're going to be able to see our nav bar so the nav bar pretty simple and straightforward we're going to have this particular bar and we can go and navigate to some of these but these don't take you to too many places and then sign in is actually we're not going to be dealing with authentication in this particular application because there's a lot to cover and over here we have our Social Links and then we have our navigation items and basically if you take a look and if you want you can go to install this particular browser extension called toggle pesticide and you can see basically the div layout and it can show you and highlight you how everything looks so over here we have one big div surrounding the entire nav bar and then we have three divs over here so one div in the left one div in the middle one div on the right so we have these particular layouts and everything is kind of flexed between for these three layouts and then inside each of these this is also has a flex layout and we're spreading it across over here and over here so this is our layout for our navigation so let's go back to our code we're going to uncomment this and I'm going to import the nav bar from a file that we haven't created yet so we're going to import navbar R from so we're going to do app shared like so and we're going to say nav bar like this so we can if we're doing routes for next JS we can start from the app because that's how they configured it so it makes a lot of sense we have app then we go to shared and we're going to create a new file called navbar TSX so we're able to do that pretty simple and over here in our nav bar I'm going to do TS or afce so this is our extension and we're going to have our navbar component easily set up like so and in here we're going to be setting up our nav so over here I'm going to change this to a header because for nav bars we want to set that to be a header and then we're also going to set this to be a nav inside and Tailwind we can use class name and we can set a margin bottom of 5 like this so we have a margin bottom below and then in our nav I'm going to say class name I'm going to say Flex justify between and as you can see this is intellisense coming from tailwind and we can just easily select it and we're going to do items Center like so and then from here we can open up our Tailwind extension Docs with command control t or Control Alt T depending on your OS and if you go to Tailwind docs we can look at justify content and justify content represents us doing the flex positioning so justify between represents Justified content space between so it means items are spread out as far away from each other as possible evenly through Flex so that's what this particular just file between item Center is basically doing and over here let's actually take care of one thing I'm going to say this is nav you want to be able to see nav so now if you go over here and you can see that if we import navbar and this is highlighted underneath there's actually one configuration that we need to set up and we can go to tsconfig.json and I'm going to go over here maybe under path and we're going to do base URL and we want to put dot once we have that set up we should definitely be able to go through here and we can navigate now intellisense will yell at us now we'll be able to continue our navbar and then from here I'm going to say with a full so this it takes up the entire width I'm going to say a background of wh 900 so this is going to be close to a black color you never want full black or full white and so we do text white of 10. so we have a we have a color of text that's not full white either but close to it and we're going to have a padding in the X Direction meaning horizontally we can do PX of 10. so now these values right here they don't represent pixels so if you take a look let's say um let's do font size or actually let's let's look at padding have padding sometimes it starts to lag that's the only thing about this I don't know why we have a lot of lag over here but basically this size that we have of eight is basically their unit of elements for Tailwind that represents a specific amount they chose arbitrary values that actually that look good on depending on the padding and the width and the space between so it's they have their own version of it so they have options that you can use so in this case we have a padding X of 10. and I'm going to say p y oops I didn't have the 10. and then py of four so in the vertical direction we're going to give it a 4. and so now as you can see we have our nav over here and we have a padding on the top padding left and right and we have Justified between so we only have one item so that's why it's just slopped over here but we're going to be moving this across since we have that now we can go over here I'm going to create a div inside I'm going to say this should be the Social Links which I'll take care of in a little bit but not yet we're going to have the Social Links over here I'm going to say class name and we're going to say this is hidden when it's on let's say smaller screens because we don't want the Social Links to be blocking the navigation but when we are above a certain screen size which is SM so if you remember over here we go back to tailwind.config we have set this to be X or SM to be 768 pixel meaning anytime we're above 768 pixels we're going to set this to be block So This Is How We Do navigation depending on the width or like we're basically doing responsive design with this so if I open this up we have social link spread over here and when we're close it disappears so this is good for responsive navigation so we want to keep that all right inside our nav element but below our Social Links we're going to say div and this is where we're going to put all the navigation items over here so I'm going to say we want a link from next slash link so they provide us a way to navigate around the website using this link component so you have to use the link component to do that and for this we're just going to always set this to be slash because we're not going to have extra pages we're just going to keep this to be at the home location maybe in the future I can expand upon this project but for now we're going to keep this simple because there's a lot to cover especially with next js13 and in here I'm going to set this class name to be Flex justify between items Center and we're going to give it a gap of 10 so we have a spacing of 10 in between the items so now if you take a look we have home trending and about and they have a gap of 10 essentially and this is located on the left side so of course if we open this up we now have Social Links on the left side and our nav items on the right side so this provides a way of looking at this with responsive design and then finally we're going to have like the login or sign in item and we're just going to say P sign in over on the right so we'll have that and if we open this up we're going to see both Three Links so we have our layout of this particular navbar and it will be very convenient to use so this right here is going to be the nav bar that we're talking about however I also want to include this particular section as well as this image over here so that when we go to another page we have the top header also still existing so over here under the navigation I'm going to create a div and with this div we're going to have a class name and it's going to be Flex justify between with a gap of eight margin top five margin bottom of four margin X so horizontally 10. so this is margin Top This is margin bottom so we'll have those configurations and then from here I'm going to say div and I'm going to set this class name and this is going to be a width I can spell this correctly so class name with a width of two-thirds so that's 66 around 66 percent I believe and the way we do this is we do basis two-thirds so this is flex basis Flex bases is very good for when you're doing Flex instead of using a width and percentage you use basis and by doing basis it'll help you determine the width percentage that you want and it has more configuration so Flex bases instead of width gives you a lot more flexibility and options sometimes you can use it to just do a hundred percent so it'll take up as much space as it can if the other other items in that same Flex don't have any width so there's a lot more configurations you can read up on it it's a little complicated but it's much more nicer than just using regular width and by the way what I did was MD so this is above medium screens we are doing a media query for margin top of three so for desktop we have a margin top of three but on mobile screens we're just not doing that and in here I'm going to set the H1 we're going to set blog of the future which is the name of the website and I'm going to give this a class name a font bold text three excels so a larger font size and I could say for above medium screens we can say text 5xl so again if I look at Tailwind documentation and I do text s like uh let's do font size let me reopen this font size so when we have font size we can give it certain width or certain values so like text XS SM base large and then we can go all the way from XL to 9xl so these are very large font weights so basically they have a pre-configured values for those guys all right so from here on the next line I'm going to do a P tag I'm going to give this a class name of text small and the margin top of three and here I'm just going to write a gibberish blog dedicated towards Ai and generation and job automation so basically we have a P tag we're just going to have this as like our subtitle below so make sure you're using the right HTML tag so it helps with SEO if you have the correct elements below this div we can create another div over here and we can provide a class name with a basis of full and a relative of with Auto and a height of 32. so this is going to set a relative positioning so this is position relative essentially you can see what this little snippet is going to if you hover over it it's going to give you that and we're going to set this width to be Auto with a height of 32. so this is like one of the bigger Heights and we are going to set the spaces a full so it's going to take it take up as much space as we need so this is basically the image and this will be two-thirds blog of the future is going to be two-thirds of the information so but this will take us as much space as it wants so over here we are going to place an image tag so image component and this should come from let's say import image from next slash image so now image usually is pretty simple you just place the source and you would just place a value in there however this is going to be a very complicated so I want to explain later on once we have the image and I want to show you how you can use the image tag properly there is a lot to this so I don't want to cover this at the moment so I'm just going to say image right here and I'm going to just give this a background of let's say just White let's say 500 so we're going to keep that we're going to have an image over here but we're going to place the image component here later on and I will explain everything as we go because there's so much the image component and it can be can be quite the headache if you're using it the first time I've had a lot of issues with the image component but I will explain everything in this video all right and then from here I'm going to do a horizontal line and give it a class name of Border dash 1 mx-10 we're going to save that and then we'll see a little bit of a line right below and so the next thing we're going to be building is going to be the Social Links right here so before we create that component what we need is going to be the assets folder that's going to have our images now in the link in the description below I have a link to the assets folder in my finalize repo and you can go in and download all the images that are in there so I'm going to be adding that alright so now once you have the images over here you're going to see all these images we're going to have these social icons and we're going to be using this directly so if I go back to our nav bar I'm going to go to our shared components I'm going to create a new file called this Social Links dot TSX I'm going to call this TS rafce and we're going to have our Social Links component over here and what we're going to do is we're going to import a lot of the images we're going to import image from next image right here so we want to use that and then we want to import Twitter from our public assets folder so I'm actually going to probably do this manually so I'm going to do public assets social underscore Twitter PNG so that will link to this particular assets over here where we have Social Links and Twitter is right there so we're going to be doing that the same for all the Social Links so I'm going to just copy and paste this five times and over here I'm going to change this to Facebook this will be social Facebook same with over here this is going to be Instagram social Instagram like so same over here this is going to be Google like so and this would be social Google and then Discord right here from social Discord like that all right so over here in our div I'm just going to get rid of the Social Links and I'm going to write class name and I'm going to say Flex justify between as you can see I always use justify between it's very common as well as item Center so this is a very useful set of you know class names right here these three guys and then we're also going to give them a gap of seven so if we want images to have like a link so we can link them to a different page we want to surround the image tag with a link element so a and we're going to do we're just going to say we're not going to really link to a specific Twitter account but we're just going to link it to the main Twitter page I'm going to set this target to be a blink underscore bull link like this so when you click on it it's going to open up a new tab instead and I'm going to say Rel equals no refer so this is so it works properly on like Internet Explorer and those things so you need to set all of this and inside here I can say image so now like I said I'm not going to cover image in depth as of yet but I will just be using this for now I'm going to keep a class name of hover with an opacity of 50. so the one thing I really do like about Tailwind is that you can put your pseudo selectors directly so anytime we have something like hover or anything we can directly write the class name associated with it directly onto it and it's very convenient compared to just having to like always write the pseudo selector that's just kind of annoying and then with the name of Alt with Twitter so Bots can figure out what this is as well as for screen readers and then we have a source of Twitter and we're going to say with to be 20 as well as height to be 20. now again image is very confusing it can be very complex we want to set the width and the height directly over here but for now this is good enough we also want like a um a situation I'm going to make this conditional right here and I'm going to say if the Social Links is dark so meaning we have two variations so if you take a look at this is this is like the dark version and this is the light version so if it's on a lighter background we want this to be you know like black colors and the background is going to be white and then over here if the background is black we're going to have this as white so we just want two variations so all we have to do is change the color over here I'm just going to say if is dark which is a prop that we're going to be passing and creating I'm going to say brightness is going to be zero so if it is a dark background we are going to set the brightness to be zero so that means this is just going to automatically set this to be white you can't do color you can't just set text wh dot zero because of this like because this is PNG the only way to do this is by setting this brightness to be zero so this is the easiest way to do so and this is dark setting is going to come from the props and we need to set this for typescript so we're going to set this as a Boolean over here now again if you aren't familiar with typescript this is a prop section that we pass any kind of props over here we will need to type them prior to using them over here and by default we're going to have this as optional so it means you don't have to pass in the dark value so instead we're just going to have this set as default to be false so that's what this represents so if you don't pass this in that's why it's optional you can have this as false like this and then that gets passed down over here then we can use that and it seems like we have some kind of issue maybe it's the bracket curly braces all right oh yeah it seems like the issue is right here so this should not have double quotes so I'm going to close it like that and save it now everything is properly formatted so we have this is dark so anytime we're on the dark background we're going to have a light color and then if we hover over it's going to be opacity 550. otherwise by default these images are uh black color so it automatically is doing that so this is just a Twitter we're gonna have to do the same thing for Facebook Instagram Google and Discord so let's do that so I'm going to do all of this and I'm going to go up here we see Twitter I'm going to select all of them with command D or Ctrl D depending on your Mac so I'm going to say let's say this one is Facebook and this one needs to be capitalized over here we're going to do the same thing over here I'm going to say Instagram like so and this should be capitalized over here this should be Google so let's copy all of this I'm going to say Google and this should be capitalized this should be Discord right here Discord and this should be capitalized over here so I'm going to save it and let's double check everything is working so if I go back and open this oh yeah we have not imported the Social Links component so if I go back to navbar I'm going to go over here and let's actually see we want the Social Links to be inside here so I'm going to pass this in the Social Links and again you should use intellisense so anytime you're typing this in you'll want to be able to click on it so it Imports directly so it makes your life a lot easier so make sure to use that it also prevents you from making bugs so I'm going to save that and as you can see now if you open this you can see all of these so now if I click on one of them it's just going to take you to whatever location so that is perfect so everything is working let's make sure we open the dev tools make sure we don't have any errors coming in make sure everything works perfect we have everything as expected for our navbar all right with that we have our navbar set up now we're going to work on our footer so if I go back over here into our completed application we have our footer all the way at the bottom and we have basically three columns so we have Flex right here so we're just going to have items that are spread this particular section is longer than the rest so this should take up more space whereas these take up less so again if I turn off turn on my toggle pesticide you can see the div elements we just have a line of div elements going straight from the top to the bottom over here and then we have a main div over here that separates these out into three different boxes so we're going to be doing that so if we go back we're going to go and close a lot of these we're going to go back to our page file or actually layout file and we want to see our folder so if I don't close it would work so if I have a layout we have our footer I'm going to uncomment this out I'm going to import it over here so I'm going to import footer from app slash shared and we're going to create a component called footer like so let's save it and in our shared folder I'm going to create a new file called footer.tsx and I'm going to say TS rafc e and we're going to have our footer component over here inside here we're actually not going to have any props being passed down into footer because it's going to be the same we're going to do we're going to change this to actually be a footer tag so we're going to say footer I'm going to close that save it so we have that information and then say let's say footer like so and see we have our footer at the very bottom and inside our footer we're going to have a class name with a background of white 900 so it's a darker color so text white of 50 a padding y of 10 so padding top and bottom 10 and then vertically padding of 10 as well so now we have our black bar and inside here I'm going to say div I'm going to say class name with justify content actually justify between I'm going to say MX to be Auto with a gap of 16. I'm going to say Flex for wider screens so when it's responsive we want actually if this section is smaller we're going to stack them up like so so over here actually this is not small enough over here now you can see they get stacked when they're smaller now ignore these errors that's for something else so if I go back I'm going to close this and we're going to go back to our application so now that's why we have Flex only for larger screens above mobile screens and then here I'm going to say First Column so we have that section I'm going to say div and inside our div I'm going to say class name margin top of 16 with a basis of one half so this one is going to take 50 percent that's why you have one half over here and we're going to say a margin top of 0 for smaller screens all right for screens that are larger and smaller screens so you just always have to make sure you're aware of that and then from here I'm going to say H4 is going to be class name with a font of bold and I'm going to say blog of the future now for me it's a little confusing sometimes whether you do font bold versus text so sometimes I would think text bold or you know font white 50 or something like that so just be aware that certain ones have different class naming so it's a little bit confusing in those areas and then from here I'm going to just have a P tag and this is just going to be have gibberish um gibberish text so right here I'm just going to copy and paste it but you can write whatever you want over here you don't really need that much information but you can just copy this if you would like but it's just some random text so we have that and we also have and we want to do a little copyright text over here we're just going to say copyright by blog in the future All Rights Reserved so we can keep that so we have that for our first column and then we're going to do the same thing for our second column I'm just going to copy and paste this and we're going to adjust this to be second and we're going to modify some things so I'm going to say basis of 1 4. oh and by the way let me just clarify this section of margin top so this margin top 16 means that for smaller screen size we're going to have more than top of 16. but once we get past the small screen sized threshold we're going to give this a Marty top of zero so that's how you do responsive design over here so this is going to overwrite it once we get to a certain like width of the website in here we're going to keep the font bold and we're going to say links over here and I'm just going to add a bunch of gibberish text so I'm just going to get rid of this like so I'm going to just say Masa or C synec this whatever this is a bunch of gibberish text that I just copied from the internet and then we have we're just going to copy and paste this over here I'm just going to say some random link again and then finally I'm going to have one more this one doesn't have a class name of margin y of five so we don't want the bottom one to have any kind of padding and I'm just going to write this random text so we have this and if we open it up they are spaced between like that and then finally we're going to do the same thing with the third column just slightly different this is just more styling and simple styling so this is like this is good practice if you just want to learn Flex things like this is very common and you want to make sure you truly can Master using flexbox versus you know like positioning things absolutely I've seen some people position things absolutely and it can it's a it's an absolute nightmare all right so here we're just going to put a phone number you can try calling it it is not my number so you are not able to contact me through that make sure don't want to be spammed all right then we have the third column we have this and we have our footer so now everything is aligned perfectly we have everything we need let me make sure everything looks good yep that looks pretty accurate so we have our footer now now with the layout configured now we can work on our home page so in our page.tsx we'll be writing code for this so let's take a look at the final application and see what we have on our home page so we have a trending section over here with all these images laid out over here then we have our technology section over here then we have a Travel section and our other trending posts section so we have these three sections so we're gonna create the layout for this particular page so we're going to start with having main as our main tags and we're going to say class name and I'm going to say PX of 10 with leading 7. so leading seven essentially allows us to give us a line height if you can see over here if I hover over we get a line height of 1.75 REM so that means the text in this section is going to have a higher space between each line and then from here I'm going to create a trending component which I haven't created yet and then we're going to have a div of a class over here and we're going to have class name and it's going to be MD Flex so on larger screens we're going to have a flex for our display we're going to give it a gap of 10 with the margin bottom of 5. and in here I'm going to give it a div and this is going to have a class name of basis 3 4. so again this is going to be 75 percent of the width and we are going to have our components our sections that I mentioned so it's going to be the text section we're going to have a Travel section and the other section like so and then we'll have a section called subscribe so I'm going to do class name of hidden so if we're on larger screen we're going to hide this in this section and we're going to give it a block and I'm going to give it a subscribe component that we have not created just yet and then below this I'm going to have a div and in here I'm going to set this class name to be a basis of 1 4. and this section is going to have the sidebar right here so what I'm doing is I'm creating this section but we also have the sidebar on the right side and then we also talk about the Subscribe this is what this is so on smaller screens if I open the div tool you're going to see that it disappears because we already have the Subscribe in the sidebar so the sidebar gets pushed to the below and that's why we don't have this particular section in smaller screens so over here we're going to have the sidebar like so so we're going to be creating all of these components one at a time so I'm going to comment these out aside from the trending because that's going to be what we're going to be starting with and so let's go above our home section and I'm going to import trending from App slash home slash trending it is a component we have not created but we'll create this very shortly so if I go to home inside here I'm going to create a new file called trending so again I'm placing this component over here because this represents any component related to our home page and that's why we grouped this so over here I'm going to say TS or afce and we're going to have our trending component so inside our trending component we're going to have a few props that we're going to pass that press in here actually no we do not have any props so we're going to keep it like this for now and inside our div we're going to have we're going to change this to section and we're going to call this class name with a padding top at the three for the top and padding bottom of 10 for the bottom section and we're going to have some text inserted here so I'm going to say div and inside here this is going to be a class name of flex with items Dash center with a gap of three and in here I'm going to have a div I'm going to pass in trending with capitalized and I'm going to give this a few styling so this is a little box over here we're going to try and create this guy and then we're going to have text next to it so trending is going to have a background of white 900 so it's close to black with a padding of top or two from top and bottom with a px of 8 so left and right has a padding of eight text white 10 text SM font of bold and font of open sense so if I save that now we have this box I think we don't need font open Sans so let me just delete that so let me see yeah so we don't actually need font open says I don't know why I have that and then over here I'm going to say it paragraph tag with the class name with text SM and inside here I'm just going to have random gibberish text I'm just going to copy and paste it your feel free to pause and just like look at this if you want to write this it can just be any level of text whatever it doesn't matter and then next we are going to actually have this particular section oops didn't mean to click that we're going to have this particular section so this is actually it can be easy and complicated so now if you take a look at this we can use flexbox or grid and I'm going to go through this using both and I want to show you which one is better for this something like this can be both simple and hard depending on how good you are at this so something like that can be kind of tricky so what we're going to do we're going to try doing this with flex and I want to show you which one looks better afterwards so I'm going to say justify between we're going to give it a gap of three a margin y of three like so and actually I moved over here so we can see it better I mean this is Mobile screen but we want to look at the the desktop screen so we have this so what we want is going to be a flexbox so we can look at this if we wanted to this would be split into 50 like this and then we would have an item right here and then we would divide this with flex as well we can even divide the top and bottom with flex as well using Flex Direction column so if we do that we are going to have to have a lot of certain dips so let's start with the div on this left side representing this guy so div and we're going to have a class name of basis one half background white of 500 we're just going to have we're just going to have this color for the background just to see what it looks like and we're going to have a height of 96. so I'm going to save that we're going to take a look we have this particular box and then we can go over here and we can copy and paste it but we're going to modify this of course and I'm going to say I'm going to give this a flex and then Flex column so that this section we are doing flex but vertically that's what Flex column is going to do so we're going to be splitting the flex column into 50 from the top and I'm going to give it a gap of three by doing this we can split this into two different sections so actually we do not want the background just yet because we're going to create a div inside here we're still going to have a height of 96 but we're going to add a div like so and give the class name and then we're going to say basis one half with a background of white 500 so we're going to have this to be the top and then we're also going to have a bottom section and that's going to be split into Flex as well so the way we're going to do this this is going to be Flex with a basis of one half and a gap of three so this is going to be horizontally I'm going to say div and I'm going to say class name with the basis of one half with a background white 500 so if I save that we're going to have this section right there and I'm going to add another one so we're going to have this as well so now we have the layout that you would see over here I mean this is this is probably a little taller but we have this section and we have what we need for our layout but if you take a look now understanding it it's not too bad but if you take a look at the code this is kind of hard to really grasp your head around because there's a lot of flex there's some nesting going on and what I wanted to experiment was with flex versus Grid so this is the flex option but I want to try doing this with grid and I want to show you how that one looks like so if I do grid will be modifying a few things so I'm going to get rid of a lot of this actually aside from just one and I'm going to say let's completely modify this so on bigger screens I'm going to give it a grid with a gap of five grid columns of four so grid columns is grid template columns so basically we're separating this into four column sections so if you were to take a look at this this is four columns so one two three four so we're splitting that into four columns and then we also want to split this into two rows so one two so we have two rows from top and bottom and then what we want to do is we're going to set the height to be 600 pixel on bigger screens now I did a little bit so this is on bigger screens so we're setting it for bigger screens and a height of 600 pixel so you can sometimes when you want very specific values for your height you can set it directly using the square brackets so other if you don't want to use this unit sometimes you have a situation where you want something very specific this is how you would do it and then we're also going to give it a margin y of three so now I already have this let's actually comment this out because that's the old one so now right now we just have a big old box because this represents the entire thing but we want to make sure we want to try setting up our specific div for the grid so the way we do this is I'm going to get rid of this basis I'm going to say column span of 2 with the row span of two I'm going to get rid of the height 96. and if I open this up we now have this big old box so what it's doing is that this takes up two column spans and it's going to take up two rows and by default it'll provide us this look to it and then from here we want to look at this one so now this is one row column but two columns or two two columns and then one row that's what this represents so that's all we have to do so this is going to be column span of one but row or column span of two and then row span of one so that will give us that value and then we're going to do the same thing I'm going to copy and paste this two more times but we're going to change the column span for these two guys because this is one column one column and one row same with both of these so I'm going to change both of these to 1 like so and then now we have our perfect grid so now obviously this one looks higher than the other one that we saw just because I didn't set this to 600 pixel I set this to 600 pixel because I needed a bigger height than 96. so I set it to 600 so it gives us this particular grid now as you can see this is a lot cleaner to me than using the flex option because the flex can be kind of confusing if you're doing it this way so now if I take a look this is way cleaner now it's easier to identify which one's which so in this case grid wins out to me anytime we're doing two dimensional I really think grid is the better option although it has a steeper learning curve all right so with this we have our grid layout perfectly set up however if you take a look at the final application we have some text right here and a block of text right here as well so we're going to be using we're going to be creating a reusable component for each of these so let's actually go and do that so I'm gonna open this up we're actually going to create another component right above here so I'm going to call this const trending card and in this component I want to pass in class name here over here I'm going to pass an arrow function and we're going to have a return over here and inside this return I want to pass in the link component over here close this and we're going to have this like we're going to have it set up like this and Insider type props I want to pass in class name like so with an optional params right here so just in case if we don't want to pass in class name we can keep it like that but we're also going to call this trending card props we're going to have also props let's actually set up for props over here for this one but over here I want to pass in trending card props for our typescript so we know that this requires a or not requires but optionally can include a class name if we want to and then since each of these over here we can click on them we want to be able to have this link so we're gonna have it take us to the proper page so I'm going to set this as class name and what we're going to do is we're going to pass in the class name that we identified like so and then we're going to add our own so we're going to do SM margin top of 0 so when we're on bigger screens we're going to have a zero margin top I'm going to set margin top to be 7 if it's on smaller screens I'm going to give it a block we're going to give this a width of full a height of 96. and then if we're on bigger screens let's actually combine all of the bigger screen configurations so we're going to set a height of Auto if we're on bigger screens and we're going to set this to be a position of relative and over here I'm going to set hover if we hover over it we're going to set the opacity so it's going to become brighter to 70 or it doesn't be transparent a little bit so if I go over here I hover over it you can see that we have this opacity you can also make it smoother with the transition but we're just going to keep it simple so this is what we'll have so we'll also have class name and then we'll also set href so this will take us to the particular post page that we're going to want to talk about so right here if you click on it you go to this link let me open this up so you can see it's going to take us to the domain name plus post and then post ID so that's how the link will be categorized so over here as of right now you can see we have an error but we're going to be fixing that we're going to go over here and I'm going to set process.env dot next public URL so this is an environment variable that we have not set up and I'm going to set this to post with post question mark optional dot ID so we're going to have a link over here and we're going to have this to be post however this doesn't exist yet and we're going to be handling this a little later so I'm going to comment this out and let's just set this to href of home we're just going to keep it simple for now so we're going to keep this and we're going to have it set like this inside here I'm going to set a div tag and give this a class name with Z zero inside relative with the full and a height of full all right so the reason why we're doing this is that if you take a look back on our home page we go over here we want to be able to have the image in this section but also this text is over the image so it needs to exist above the image so the image is going to be placed below it so the image will be right here and for now we're just going to set this background to be white 900 or 500 so you can see this on our page and over here oh by the way you need to put the equal sign so we have that so we have proper formatting and over here below this div I'm going to add another div and we what we want what we want is this if you take a look at this image I have this subtle gradient that goes down there's like a black color at the bottom and it goes to be more transparent at the top so we're having a little bit of transparency at the top with a little bit of black so it makes it look a little bit nicer so we're going to add that so we're going to say class name and we're going to say absolute Z1 top 0 left 0 with the full height of full and we're going to give it the gradient color that we set so background gradient gradient gradual like so so if you remember we in our theme or Tailwind config we've actually set this gradient gradual which is a linear gradient so we are essentially using that and placing this in this particular div so that's kind of like a layer right above the image so the image exists right here below it and then this exists above and the reason why this is this will work when we set with the full a height of full is because the parent component is set to relative so when you set the parent component to relative you can set a child component to be absolute and that will position it by default at the top and we want it to extend the entire width and the full height so that will cover the entire thing that's what this absolute class is essentially doing and then from there we're going to grab this div and what we want to do is we're going to set this absolute to Z2 and I'm going to set this to be bottom zero left zero and we're going to give it a padding of three overall so this is for the text and I'm going to make it not self-closing so I'm going to close this div and inside this div I'm going to have an H4 tag with class name we're going to say inline block so we have it with this section so we don't have a full width we can say a padding X of 5 py of one font semi bold we're going to give it a background accent of Orange and then I'm going to set text with or white of 900. so that will essentially give us this text right here excuse so you see the yellow the tell the text is black right there with the background of yellow and we're just gonna for now we're just gonna say category we're going to be fixing it with the correct category later on but we'll just say category and over here I'm going to say div I'm going to close this I'm going to call this a class name with text of white 100 and the margin top of 2. so that will represent this text below and we're just going to say post title once we save it we are still not using the trending cards so we want to use that instead over here so I'm going to go down to these divs and I'm actually going to select all of them with command D or Ctrl D depending on your OS I'm going to say trending card and we are going to be saving that and once we have that set up you can see we have our grid with all the category post title and the hover opacity over here so we can see all the images we can see the text and we have the title below so perfect all right and then over here what I'm going to do I'm just going to select from here to the rest and I'm just going to make it closing so we have that say that just to make it a little cleaner so we have our trending card all set up we will do the images later like I mentioned I'll do all the images together and you'll be able to see what I'm doing with that and then finally if you go over here we can see right at the bottom we have just a text that just basically describes a random message so we're just going to add that so that's just going to be a P tag and we're going to say class name of text to be small and we're going to add a random set of text over here so again this could be whatever text you want I'm not going to go and type it out so it's up to you to add whatever you want and then over here I'm going to close the trending now we're going to be working on the text section so if I go down you can see the text section right here and we have our posts in kind of a weird layout but it's another situation where we have to decide should we use flex or we can we use grid for something like this and the answer is you can either use either one for this one this one is kind of complicated case so I will basically show you how to do both so if we go over here I'm going to uncomment out Tech and we're going to go over here we're going to import Tech from app slash home slash Tech I'm going to save it we're going to go over here I'm going to add a file called Tech TSX I'm going to do TS rafce and we'll have our component I'm going to save it and inside here I'm going to call this element section and inside this section I'm going to pass in HR so class name of Border one so we're going to have a horizontal line so I go down here we're going to have a horizontal line that splits it and the next thing I'm going to have is going to be a header and we're going to have a div with a class name of flex with items Center gap of three a margin y of eight and in here I'm going to do H4 I'm going to say class name I'm going to give it a background accent orange so this is going to be like the little box again so py of 2 PX of 5 text of white 900 so it's going to be a black color give it a small text and a font bold so now I'm going to going through like these stylings pretty quickly because it's just it's just styling like you can do you can do it whatever weight you want so paragraph tag I'm going to say latest news in technology oops I want to make sure I spelled that correctly I'm going to give this a class name with font of bold with text 2XL like so we're going to have this over here with the title and our category tag all right so for again this section right here I want to do it in two different ways so I can show you and really drive in that you know most likely you're going to use grid but this case we can really use flex if we wanted to it's just grid makes it much cleaner in the end just to like figure out what's going on so over here I'm going to add a section called Flex and I'm going to say div like this give it a class name of flex justify between items Center so like I said this is the most common Flex that I use and over here I'm going to say div and I'm going to call this class name of background white 500 h of 96 basis of one half and below this I'm going to copy and paste it over here and we're going to change a few things I'm going to change Flex Flex column and give it a gap of three and I'm going to get rid of the background white because inside our div that's where we'll create our boxes so I'm going to have a div over here I'm going to give this a class name BG White 500 with the basis of one-third so essentially we are splitting this vertically like this with 33 percent for each height so this is the 100 percent of height we're displaying this in one-thirds so if I go back I'm going to copy this two more times if I save it if you take a look now we have our setup like this so this is if you want to use flex we have this particular div that represents this section and then we have this div that represents these three guys however I want to show you grid as well and I prefer grid for even something like this because it's it's still a little bit cleaner so I'm going to copy this entire div as well as the closing one we're going to have grid over here so I'm going to say grid with grid calls to grid rows three gap of X of 5. and gap of Y of 3. so what that means is that we're doing a gap in the X Direction and a gap in the y direction and we're going to say height of 96 with a margin top and bottom of 5. and inside here I'm going to copy one of these div elements and we're just going to change this basis one-thirds so instead with the flex we are going to have this this is going to have a row of three and a column of 1. because this is two columns like I mentioned over here we have two columns and three rows so one two three so this particular box is one column and three rows so that means we do column span of one with row span of three so I'm going to duplicate that and save it and if we take a look we have this box and we're going to be doing the same thing with the other ones and copy it four three more times and these guys all of these are going to be one and once we do that we have the same layout we just used so this is perfect personally I like grid because you only have one level of divs you don't have to Nest them like in Flex you do or here so this is still to me a lot cleaner now still it doesn't look like this per se because I believe this is yeah this is a little bigger and this is kind of like small so we're going to make a few modifications so I'm going to give this if on on larger screens we want the grid we don't want this for smaller screens and we're gonna increase the Gap in the horizontal direction to 8 as well as the y direction to be eight as well and the height is going to be dependent on the image itself so we're going to get rid of the height so we're doing this after effect only because I wanted to show you guys both of these make a fair comparison but now I want to actually do it so now if you take a look I have all these divs but I want to be able to reuse these cards because we're going to be reusing a lot of these so if I take a look there's all these cards right here here here blah blah so we're going to be making a reusable card for all of these and there's slightly different variations for example like this one is slightly different from this and as well as this one this one's a lot bigger so we need to make some modifications specifically for that and we'll do this with the single reusable component for the card so if I go and since this is going to be shared across many components I'm going to create a new file over here I'm going to call this card TSX and inside this card I'm going to do TS rafce and we're going to be passing in props as we usually do so inside here I'm going to do top props and we're going to pass in a number of properties so I'm going to do class name of string and then I'm going to pass in image height of string we're going to pass in another Boolean we're going to say is small card so this is to determine if we're going to deal with this ball type of image and also is long form meaning we just have a longer set of text so that is what this Boolean represents so this is all going to be represented over here and so I want to pass in class name image height is small card and we're going to give this a default of false as well as is long form and we're going to say a default of false as well so if we save it we can see that we have our four props over there all right so in here we want to make sure we pass in class name so if we want custom class name from the outside of this component we want to make sure we pass them over here so we have the class name as the parent div element and then inside here I'm going to create a link tag with next I'm going to close it but in here I want to do class name with a basis of full so it takes up the entire width if we're in a flux situation because some of these cards we're going to use it for Flex and we also want to do hover of opacity 70. and by doing so we can say href is going to be the default route only because we are going to set up the post like the clicking of these cards at a later time inside the link I'm going to do a div and I'm going to give this a class name again and I want to set this to be a relative with width with the Vato margin bottom of three I'm going to pass in image height as well and I'm just going to call this image so right now we're not dealing with the image we'll be covering that later and then below this link I'm going to say div I'm going to pass in a class name with a basis of full and again I'm going to copy another link because we also want to be able to clink on the title so we have this we can also click on the title and it'll take us to the same location however we don't need the class name so I'm going to get rid of that for this one I'm going to change this to be different and I'm going to say this is an H4 tag I'm going to say title over here I'm going to pass in the class name and in here I'm going to say font bold and give it a hover of text accent green and when we have a small card this is going to be different so let me save this and over here on the next line I'm going to say is small card I'm going to give this a ternary operator I'm going to say text of Base so it's the default text size and then we're going to do text of large if it's not so depending on if it's a small card or not this is going to be different and actually I made a mistake this should be all in this bracket so is small card text based like this and then also I'm going to pass this over here and we're going to pass it if it's a small card we need to clamp the lines to be two length whereas on bigger we don't want that I'm Gonna Save it and it'll look like this now let me explain to you some of the things that are happening so if we have a line clap so if it's small card we're clamping it to two lines so over here you can see we have a clamp in the title so if we have any kind of long titles so let me let me see if we have any long titles it seems like we don't have any long titles we are definitely clamping the description but I haven't done that yet but if the title was long enough we're just going to clamp the length of it to be two lines and also for small cards like these are small cards we're having the regular text for these small cars whereas the large card the text will be larger in comparison all right and then from here I'm going to set a div I'm going to call this class name and I'm going to set this to be if it is a small card like so I'm going to do a ternary operator I'm going to say my of two I'm going to say Flex Flex of my of three and this should be a gap of three so again these are slightly different styling if it's a small card we're going to do a margin y of two otherwise we're doing a flex for non-small cards so some non-small cards are going to have a flex and then we're going to have an H5 we're going to say class name font semi-bold and we're going to give this text of X or small and this will represent the author so that will be these guys right here and then H6 we're going to have our date and it will be a class name of let's fix this we're going to call this text a white of 300 text of XS like so so again small cards this is going to be on two lines for large cards it's going to be on the same line that's what this Flex is doing and then finally we have a paragraph and this is going to represent the little snippet over here and as you can see on the small cards we have three dots and three lines clamped whereas the long form we're going to have this entire thing we're going to have a longer text so I'm going to say class class name and I'm going to say this is text of white 500 I'm going to say is long form like so I'm going to give this a line clamp of five colon line clamp of three and inside our paragraph tag I'm just going to say snippet for now so this will be our text and with that let's go back to Tech and we are now going to be able to paste the cards as well so I'm just going to call this let's just say this is the large card just to show you the difference and I'm going to Let's actually modify this and we're going to say card and we want to pass it in from the shared component so instead of it being shared like this let's started from app so over here we have our card but we're still missing some properties so we are going to go over here I'm going to say image height and I'm going to say height of 96. and we're going to say is long form to be true and let's make this love closing it's instead and let's actually see what we have all right so we have a background white with image a title an author and a date and this is the entire box so this is how it will look like and on bigger screens is going to split into two sections so it looks like that so these guys are going to be the same thing it's just going to have smaller different properties so I'm going to have I'm going to call these small cards and I'm going to give this different classes so I'm going to say or actually let's keep the columns man row span 3. actually this would be one for this and we're going to say over here margin top of 10 and for larger screens we're going to give it a margin top of zero we're going to say Flex justify between with the gap of three and then for the image height this should be height of 48 and we're going to call this is small card and we'll just keep it like that actually we need we can get rid of these equal true for the Islam form as well it's once I have that saved we have this image so if I go over here we can see that it's basically split with the image title author date and then we'll have a snippet over here and not exactly sure why the snippet text is not showing oh that's because it's the same color as the background so let's actually we do like a hundred yeah then you can see the color for now so let's go back to the tech page we're going to copy and then paste this two more times and then we should be able to see these three with the main large card over here so as you can see everything is snapping as expected and if you notice there should be something here which is going to be the sidebar that's why you see there's an open space whereas if you're right here the sidebar would drop to the bottom of everything so you're not seeing the sidebar here all right with that we have our Tech basically set up so this is perfect we're going to do the image later we're going to get rid of the background later if you take a look at the next section it's going to be about the Travel section so now this one you can see maybe we could do this in Grid but this one is actually good for Flex because you just have one dimensional layout right here so one direction we have a flex and then right here we can just do this as normal with flex horizontally so in this case it's better for Flex because there's no Grid in this situation so we're going to go back I'm going to close the or I'm going to go to page I'm gonna uncomment out travel and we're going to import that and I'm going to pass in home slash travel I'm going to save that and what we're going to do is we're going to create a new file over here I'm going to call this travel TSX and I'm going to say TS or afce and we have our travel component over here and in this travel component we're gonna make this into a section like so I'm going to say class name and we're going to give this a margin top of 10. let's save it let's actually see if we have this so we have our Travel section and a margin top of 10. perfect so in this section we want to go inside our section and we are going to do HR class name of border dash one and then I'm going to close this like that and then from here we can do we can reuse a lot of the code that we wrote so if I go back to Tech we have our header section so I'm going to copy and paste that over here right below the HR and we're just going to change a few things I'm going to call this uh let's say travel and we're going to say the title should be new travel experiences and instead of this being orange we're going to make this green so it's a little different and the text should be white like so I think that's good so if I save it let's go down we can see travel new travel experiences all right and then from here I'm going to go I'm going to go back to our grid section and we're just gonna grab this card and go over here in the Travel section and I'm going to call this card s row so this represents the the row of cards so I'm going to give this a div and inside this div I'm going to paste in the card that we got I'm going to erase the leather D and then make sure I retype it so intellisense pops up so I can import that and I want this to be App instead because it's a lot cleaner without the dots and over here in the div I'm going to say class name and I'm going to do SM Lex so on larger screens it's going to be a flex box I'm going to say this is Justified between with a gap of 8. and we are going to have this particular card and we're going to keep it background white of 500 we don't need the column span because this is just Flex I'm going to give this margin top of 5 with a for larger screens we're going to set this to be zero like this give this an image height of 80. and then I'm going to get rid of Islam form and we're going to set three of these like so I'm going to save it and we're going to see that we have these three things on smaller screens but if it's like this we have these cards now it is not taking up the entire space so instead what we're going to do for each of these we're going to do a basis of one third like that and I'm going to go down and then paste it sure you have all of that spaced and then save it so now if I go over here we can see that it takes up as much space as needed when it's on larger screens so you can see that and then finally we have one more card right below on the final section so this is going to be a little bit of a different layout but we have accounted for that so I'm going to grab the card again and then paste it over here and we're going to give it different classes so I'm going to just actually get rid of these classes over here and I'm going to say we're going to give this Flex by doing this we are flexing these two images and this one we're placing Flex on this parent component so you have these images right this is the image section and this is the rest so that's why it's going to be split into two we're going to have Flex I'm going to say justify between with items center with a gap of three margin top of seven and a margin bottom of 5. once I have that we are going to have our image right there so in this case we don't have the background white because we're not placing it over here but for now actually actually I can just do that and you can see we have our entire thing it's just the images over here on the left the text author date and the snippet is on the right so that is our Travel section and finally the last part we're going to deal with for the home page is going to be these other trending posts which is going to consist of these components over here and if you go on smaller screens it's going to be on all on one line so we're going to have this other section and we're going to be using grid for the this section when it's on larger screens so what I'm going to do I'm going to go back to page.tss TSX uncomment under and I'm going to import other from app and we are going to put it in shared this time because we may use this later so if I go over here we're going to go into shared create a new file call this other.tsx I'm going to call this TS or afce and this will be the other component and this one is pretty straightforward so we can use majority of what we had before so if I go up here I'm going to grab the section and the header and I'm going to change this to section and I'm going to pass in the header over here with the line with the Border one and then over here we actually don't want in this case we don't have a tag so I'm going to get rid of this tag right here and instead I'm just going to have this P tag right below and we're just going to keep that and call this something else we're going to say other trending posts make sure oops make sure I have that close it closed correctly so we have font bold text tol and we also want to do a margin y of eight all right and then from here we're going to create a div and this is going to represent the post and I'm going to say class name and I'm going to say on bigger screens we're going to set this to grid with grid of columns 2 with a gap of 16. and over here I'm going to paste in the cards so I'm going to grab one of these actually let's copy the large card so we're going to paste it over here and we're going to make sure we import that and it's in the same directory so we're not going to change that that's fine because this is obvious where it's located I'm going to change this to be margin top actually let's let's keep the background I'm just going to erase the columns I'm going to do margin top of 5 SM of margin top zero it's a different margin tops depending on like the screen size I'm going to give this an image height of 80. and we're just going to keep it like this so we're going to have this particular card and we want four of these guys so I'm going to paste it like so and we're going to save it and let's double check if everything is working as expected other trending posts we have four of these like so with the image at the top and the text at the bottom and if we open it up we can see our trending posts all separated cleanly depending on the size of the screen so perfect so that is basically responsive layout so this application actually has some tricky layouts and we've covered a lot of those so with the grid and the flex it covers a lot of these situations and how to do it with responsive styling all right and then from here we're going to do the final two layout type stuff which is like more CSS focused is going to be the Subscribe and we're also going to do the sidebar over here so we're just this this is all pretty straightforward so we're just going to go through this pretty quickly so over here when you have if you look at this this is the actual sidebar if you have a bigger screen you can see the Subscribe at the bottom where whereas this one also has a sidebar over here so this only exists on larger screens so we're going to do that so I'm going to create a component called subscribe and this is going to be in the shared file and we're going to say subscribe.tsx and over here we're going to go back I'm going to close everything we're going to go back to page or sorry we're going to go back to the page component and we're going to have our subscribe over here we're going to uncomment that out so we have that and we're going to import subscribe from app slash shared slash subscribe select here and over here we're going to do TS rafc e to make sure we have that correctly set this is not going to take any props so we're going to get rid of that and in the Subscribe we're going to add a number of elements but the parent component is apparent compare it parent element is going to have some classes we're going to say text Center BG white of 10 with PX of 5. a padding of Y in the the up and down Direction here I'm going to give it the H4 tag with class name and I'm going to give this font semi bold with text of Base I'm going to say subscribe to our newsletter with an H4 tag over here I'm going to do a P tag I'm going to do class name and I'm going to set text of white 500 my of 3 width of 5 6 MX of Auto so again this is just going to be 5 6 width so it's not the entire width but it's close to the entire width and we'll give it some styling we're going to say enter email address to get top news and great great deals like so I'm going to do an input tag and this input tag is not actually going to trigger any kind of functionality aside from being able to type and we're going to set this class name to be text to be center with a width of 5 6 what the Min width of 100 pixel PX of 5 p y of 2 and a border of two and I'm going to give this a placeholder with an enter email address and over here I'm going to give it a button make sure it's closed with subscribe as a text and this one is going to have a class name with a background accent red text of white 10 font semi bold width of 5 6 so I know there's a lot a lot of things a lot of class going on right here and then right here we're going to do Min width of a hundred 100 pixel py of 2 PX of 5 margin top of three so now there's a lot of class names this is just a lot of layout things that are going to give us our subscribe values so as you can see it doesn't exist but right here we have it exists when it is on larger screens so now we are missing some margin from the top and I believe if I go back I believe we did not add some margin to the bottom of the other we don't want to put margin top on the Subscribe because that will we are going to be reusing the Subscribe component elsewhere so we want to just go back to the other component and over here and over here I forgot a few class names so I'm going to do class name I'm going to say padding top of four and a margin bottom of 16. so if I do that we have some spacing now between that and the Subscribe as well as some Martin at the top so now it looks pretty good to me so that is our subscribe all right and the final thing we're going to do if we go back to our complete the application we're going to have this basic sidebar that will exist on both pages so it's pretty straightforward as well just a bunch of layout stuff we have our subscribe Social Links and some elements so that's why we made both subscribe and Social Links reusable because we're going to be reusing them in those locations so if you go back let's go to page.tsx we're going to uncomment out the sidebar and we are going to import our sidebar from app shared slash sidebar like so we're going to add that and I'm going to create a new file call this sidebar.tsx in here I'm going to call this TSA TS rafc e and we're going to start filling this out so this div should be a section and in here we're going to start with an H4 with subscribe and follow so let's do H4 actually we can go back to let's say Tech and we're just going to grab this guy over here or actually this H4 right here so we just want to grab that instead and that will give us a lot of the main styling we just want to change a few colors we're going to change this to White to be 900 so it's a black color this one is going to be a close to White so why the 50 I'm going to open this up a little more so you can see better so text should be XS font bold and we're going to do text Center so we're going to be Center centering our text and padding y should be three and we are just going to call this subscribe and follow below this H4 I'm going to do a div I'm going to give this a class name with my of 5 MX of 5. I'm going to call this Social Links we're passing that in I'm going to say is dark like so and then below this I'm going to do subscribe and we're going to pass that in and I'm going to have a div I'm going to do class name with background White of 900 so we can see this so this is going to be the advert image like so we're just going to keep that again we're going to do the images later and once again below this this is going to be a text so let me actually show you what we're doing so basically we have the Subscribe and follow then we're going to do the about the blog so that's why I copied this part to the Sim one because it's exact same styling so I'm going to say about the blog and then we're also going to have another image right below it and that's going to be the profile image over here now we're just going to keep that for placeholder and then I'm going to copy this one more time but this is we're going to have to modify this a little bit I'm going to get rid of the background I'm going to give her the background I'm going to change this to 500. then we have font bold text excess is not going to be there and over here I'm going to call this Jeffrey Epstein and then below this I'm going to do a paragraph tag and we're going to call this class name with text of white 500 text Center text SM and we're just going to add some text as well so over here let's paste that we're going to save that and we should be able to see if we have our sidebar set up and we do we have our about the blog and it seems like the black the images right here are getting merged with that so actually let's kind of add some padding or margin instead so let's just do margin y of eight over here and same with over here and then you'll be able to see that these are these black lines right here are going to be representing our images once we take care of that but there you go open we have our sidebar as well so our sidebar is fully complete but our home page layout is fully complete I know there was a lot of stuff a lot of layout complexities going on with it but we have a responsive design fully laid out and everything is working as expected I know it's kind of a lot of work sometimes with CSS styling and making sure it's responsive but if you want a nice Website Layout this is what you need to do so there we go we have everything as needed all right now with all of that lame stuff with the CSS styling and the layout out of the way now we can actually focus on creating server components and grabbing the list of posts so to do that we're going to have to get our database which we're going to be using Prisma to interface with our mySQL database that we're going to be hosting on planet scale so if you go to the link in the description below we're going to go to Planet scale and we're going to install the CLI if you go to this particular link we have the CLI over here and you have instructions depending on your machine I have a Mac so I would have to install Brew in this case but if you have Windows you can install it via these instructions so you're going to probably need scoop which I am not familiar with but once you install it we're going to have Planet scale so make sure you install that I'm not going to do this on screen because I already have it installed and it's not going to do anything so the next step after that installation I'm going to close our server and what I'm going to do over here is I'm going to write MPX Prisma in it and make sure you're in your app directory over here and it's going to ask you need to install the following packages and you're going to say yes and I'll give you a list of instructions so set the database URL in the EMV so we're going to have to do that we're going to set the provider of the data source in our schema then we're going to have to pull and generate so I'll do all these steps with you but before we do that let's actually install the Prisma extension so if you go to extension you can search for Prisma so this will add syntax highlighting for your Prisma logic so make sure you have that installed I already have it installed so I'm not doing it after that we're going to go to planetskill.com so this is we're gonna where we are going to be hosting our database of our website now this is not where we're going to be hosting our server we're going to be hosting basically just the mySQL database on planet scale and it's going to be free for us so if you haven't already I want you to sign up to Planet scale I've already signed in I have my GitHub on there so I'm going to be doing that instead but make sure you sign up for this all right once we're logged in you're going to be seeing this page you might it might be slightly different because you just created the account whereas I already had this account and you can just look through this these are just tutorials but we're just gonna skip this but we're gonna just create a new database I'm going to call this blog AI app and over here we want to choose a region that's closest to you I think Oregon might be closer so I'm going to create a database over here all right once your database is created I want to do a brief rundown of everything over here so I want to show you deploy request branches insights these are all extra information that for deploy requests and branches that's relevant to your GitHub insights is it relevant to just statistics or analytics if you want to see those and then console is an important one where you can connect and this is where you can make SQL queries so you can run queries on your database and get information on this particular database backups is backups obviously settings is just a bunch of things and you can like delete your database if you need on the free plan you can only use one database at a time so just make sure you cannot create more than one database for Planet scale unless you want to pick and over here we see the database what we want to do is click this connect button and be ready to copy a username and password so if I go click here this username and password only shows Once for this particular database so if I close this it's not going to be able to it's not going to be visible anymore so you want to make sure you have this copied down in a very safe place so now what I'm going to do I'm going to copy this for now and I'm going to go to the dot EnV file that was created when you created your Prisma so what I'm going to do over here is I'm going to just delete all the comments because I don't need those and I'm just going to paste those two guys over here and comment those out just for just for the Keepsake for now we're gonna have those just so we don't lose these guys and then also you want to click connect with node.js it starts with plan skill CLI but you want to click to node.js and you want to basically copy all of this down for the database URL and then you can paste it into your code so if I go over here I can paste the database URL in this particular section and we'll have all of these SSL reject authorization you want to make sure you have all this also this is something I mentioned this is post editing after I just want to mention if you have any issues with that SSL cert it might be different for depending on your OS I don't think I mentioned that so there is some links in the description below that will describe some of the SSL problems you might have and you might want to make sure you're doing the right certs over here so you can just see if this solves your problem in the location and there's a GitHub issue as well that I linked just in case you have any issues with the SSL cert so it might be different for you so I wanted to try that if you still have any issues I have a Discord that is specifically that has a Channel or discussion for each app so make sure you can find this current APP and you can go to that discussion section below and then you can ask questions there and one thing to note and this caught me too so if I go to the end of the URL string we actually need to add SSL certification this is to connect to Planet scale securely I don't know too much detail on what's Happening Here but you need this for connecting from a local server now if you are connecting when we are deploying on versel which would will do later this will be different and I'll show you what we need to set up but this is something you need to add to your database URL or else you'll get rejected all right then from here I'm going to open up Explorer we're going to go to Prisma I'm going to go to schema I'm going to erase this because we don't need the comments over here I'm going to change the provider to mySQL because Planet scale is offering MySQL not postgres and then I'm going to say relation mode over here and I have Prisma and by the way if you see all the linting that's from the Prisma extension if you didn't install that and follow the instructions on it you're not going to see all the linting going on and it's also going to like align things for you and then from here we're going to create our first table so the way we're going to do this is we're going to create a model and we're going to call this post so in this particular table we only need one model so we only have one table and that's going to be the post we're going to keep it very very simple and we're just going to grab this particular information so what I'm going to do is I'm going to say ID and I'm going to say string and I'm going to do at ID at default CU ID like that so what it does is going to generate a random ID based on the unique ID generator that they have and a lot of this information is in the Prisma schema file or Prisma schema URL in Prisma so you can look it through all of this and it gives you a lot of examples of how to set up your models so it's very close to the model posts we're going to be doing something similar to this but we're going to have our own little properties so I'm going to do created at so I actually can just copy this over here but you can just look at my filed just to see what's going on over here but basically created that default now and then it talks about updated so these are two nice properties that is already configured and then from here we're basically going to do all strings so the title is going to be a string category is going to be a string content is going to be a string but we're also going to do at DB dot text and the reason why we have to do that is this is for longer strings some longer strings cannot fit into these smaller ones so that's why we need to set at db.txt then we're going to do author we're going to say string again and then I'm going to say image which is also string we're going to say snippet which is string as well and I'm going to say at DB dot text I'm going to save that and it's going to automatically align so we have our model post and once we have completed our model we're going to do npx Prisma DB push and with that if we go to line and scale we're going to go back close that up I can go over here we can see that we have a table and to query our table we can go to the console and we can hit connect and once we're connected we're going to do show tables and now you should be able to see post right here now there's nothing inside the post and basically what I'm writing right now is SQL but right now we have nothing but we do have our properties you see ID created updated app title category content so our table is created now we just need to feed information into this database so now to feed our table I'm going to close both of these I'm going to go over to Prisma folder I'm going to create a new file I'm going to call this seed.ts this C dot TS is where we're gonna write or add our dummy data but we need to do a few things so we're going to import let's close this I'm going to import Prisma client from at Prisma client like this and I'm going to say Prisma I'm going to call this any because I'm not exactly sure what the typing is for the Prisma client but in this case we don't really need it but I don't exactly know how to get the Prisma type if you guys know let me know um but what I'm going to do is I'm going to link in the description below to the dummy data because I don't I'm not going to write all of this however you can go to the file and just copy all the posts or you can copy this entire file as needed but for now I'm going to only copy the post array so I have all of this copied over and below this I'm going to write this with you even though you can just probably just copy this the only reason just so you can see what the logic is to seat it so we need to create a main function and I'm going to say console log start seating so we start our seating of the database just so we can know when it actually does and what I'm going to do is do a const post of posts so this is looping through the array of posts and what I'm going to do is await prisma.post dot create and I'm going to pass data as the post so this will create our post for each of them and I'm going to say console.log and say seating finished so that creates our function but we did not invoke the function so we're going to invoke it I'm going to dot then I'm going to have an async function over here I'm going to say a weight Prisma Dot dollar sign disconnect and it's pretty self-explanatory what that's kind of doing and then we're also going to do dot catch so we're going to say async yeah e something like this with an arrow function and we're going to say console Dot error I'm going to pass to e in I'm going to say await Prisma Dot disconnect as well again but this time we're going to do process dot exit so what this is doing is basically we're invoking the function we're going to disconnect after whether we catch an error or not it's just in the error section we're console logging it and we're exiting it so this is our seating process so now we have our seed file with that we can go to the link in the description below where it talks about seeding your database and a lot of these steps we already did so I'm going to go down we're going to go to step three so I'm going to open this up I'm going to copy this and I'm going to paste it so we're going to be installing this to make sure everything works now I already had this installed so that's why you didn't see it taking that long and then from here we're going to go to package.json and I'm going to go over here and I'm going to copy this and paste it up here and then we're going to run over here as after we have that and actually no no this is incorrect make sure you don't do this one we want to make sure we have this second one because this is for next.js specifically so we want to paste that in so I'm going to save that I'm going to run npx Prisma DB seed and as you can see you can see the start seating message and then said seating finish the C command has been executed so hopefully we can go to the plant scale and we can see the database if we can see the table right now it doesn't show anything over here but we want to go to console we can hit connect we're going to do show tables make sure we have the post and then we can do select all from post like so and now as you can see we have all of this information being shown in our table so we have all of this and we can see everything that's going on we have the content which is super long author image snippet and all of this information so perfect so we have everything seated it's all in our database for MySQL I know there's a lot of steps to all of this but it is all worth it so we can see our console with our SQL query but if you go back over here instead we can do npx Prisma studio if you want an alternate view of this of the website so I'm going to move it over here place it over here now we can see we have our post and I'll show you in a better format so now it looks better over here you can see all of the content that you have and then it's being cut off for some stuff so you can see and open but this is a lot better so if you have npx Prisma Studio you have a server running and it'll show you all your database items it looks way better than just making SQL query so this is very nice and now with that I'm going to close out the Prisma Studio I'm going to close this terminal now we can actually finally write code for Prisma client in our actual code instead of just running it on the server because now we have our database now we just need to connect it into our code base so if I go to app API we're going to create a new file over here I'm going to call this client dot TS so I'm going to put this not in the folder right here but I'm just going to put it over here so this file we want to only start up our Prisma client once throughout our entire application it's possible that you can run all these Prisma clients for each route but we only want to use one of them so that's why we are going to have this particular file it's for setting up our Prisma client so I'm going to do import Prisma client from App Prisma clients over here and what I'm going to do is let prism be Prisma client and I didn't put an e on purpose now a lot of what I'm going to do is not typescript based because I have some enemies I know some people want to type everything but I am unable to figure out what the the typings for some of this is so let me know if you figured that out because I don't want to deal with it so sometimes it's just hard it's such a pain to find certain types so it's just not worth trying to look for it because sometimes it doesn't really help anyways so over here I'm going to say if we are in the production environment we're going to set Prisma client to be our regular Prisma client however in other environments we're going to set it like this so if Global doesn't exist but the problem with global is that it is I'm not exactly sure what the type for that is so that's what I'm not sure of so I'm going to keep that if this doesn't exist we're going to set Global as any.prisma is equal to new Prisma client like so and we're going to run that again however if none of that we're just going to say prism is equal to this value over here so it's just going to initialize if we need to otherwise we're going to have Prisma clients so it only initializes if needed and what I'm going to do is export const Prisma is equal to prism so now we can export Prisma that's why I just call this prism uh maybe a better maybe a better term is I'm just going to select all of these just for the sake of variable I'm going to select all the prisms I'm going to call this uh Prisma init it's just a better naming that makes sense but either way this is what we're going to be using to call our Prisma database so this is basically our initialization and from here now we can directly call our database anytime we want I know there is a lot of steps to setting up our Prisma or Planet scale but now we fully have a mySQL database that we can call and grab information from the back end and also make queries on there so now with our Prisma setup now we can actually use the power of next.js and next year is 13 with server components which is probably the biggest thing biggest upgrade to next JS so if I go to API this is our backend essentially so normally when you are calling the back end you would create an API point that will call our database it'll call Prisma in that route so we would have like a folder called posts however we don't need to do that because we can call this directly in a server component so if I go to page we can actually make our API call to the database in Prisma directly in this particular file and we can create a server component that will render our files so actually let's let's start writing some code and I'll explain everything and it'll make a lot more sense to you as we build it so over here what I'm going to do is I'm going to write some code called I'm going to create a function called get posts I'm gonna this is going to be an async function and I'm going to do an arrow component like this so in this function we're going to do posts and I'm going to do a weight Prisma and we want to make sure we grab it from the correct folder directory which is the API so I'm going to say this is app API instead to make it cleaner so we're going to have that and over here we're going to do Post and then find many so this is going to grab all the posts that are existing in our post database and it's all conveniently set up just for how you want it and so if you take a look typescript is able to figure out that this is a post an array of posts in here so it it's basically typed to be array of post and that comes from Prisma client now you can explicitly type it like that but this is already how it kind of works so I'm just going to erase this to keep it simple so Prisma client provides like the typing of the database and you can see all of this is already set up for us so now I can just basically return posts and how do we connect this to our front end so if I do that what I need to do is I'm going to make this component async so by doing this async we are creating server components and so to use this I would just use it like you normally would so you did posts and we would say await get post so this is essentially a server component so with this we actually have our posts now normally you would think oh okay if I do a get post you would typically do like a fetch call you would call your back end and you would grab your data from the server which would also call the backend database but in this case we directly call our database over here grab the information and then we can use it for our front end so let me console log this so you can see that it's basically working so I need to make sure I run the server so I'm going to do npm run Dev and we're going to go to our Local Host I'm going to refresh this and you can see the console log actually doesn't show up in the browser console log it shows up in our server terminal so the server that's running you can see that we just got our list of posts over here and it's kind of there's a lot to it or there's a lot of information so I'm not going to go through all of it but we have our post in our terminal so this is very different so we have we are essentially grabbing information in the back end and rendering those components on the front end so let me explain how this is essentially working because it's a little this is where you this is the biggest difference between nexjs 13 and 12 and then also all of react so what you're doing with these components is that on the server on the back end we are grabbing the information once we grab all the information we are pre-rendering the components on the back end not the front end we're rendering them on the back end and then we send the completed components to the front end so this has some performance benefits of always having like a rendered component and you can always render out certain parts of the page using server side rendering so in other words some parts of your website can render a lot quicker and other parts can render slower because some of them are more Dynamic if you have more Dynamic components if I'll show you later but we're going to have more Dynamic components where you can click and do a lot of interactions in those cases you cannot pre-render because it's Dynamic you have to have you know JavaScript running however for components like this where you're just displaying information you can pre-render that information because it's not Dynamic you can just send the compiled HTML CSS JavaScript and you can have it render on the front end by sending it and that allows for performance benefits in various locations you can also do caching you can do all these you know performance benefit type things that will make sites that require like SEO optimization or performance optimization it'll help those sites perform better and that's what next.js is all about or next js13 especially is about all right with that I'm going to close this terminal what I'm going to do is I'm going to format these posts over here so we have different posts for trending Tech travel other so trending is just going to be the first four now typically you would have some kind of algorithm that determines what is trending or you know you can just do some calculations but for us we're just going to do the first four posts and then after that we're just going to use different categories and we're going to categorize the other ones in different ways so we're going to do const format posts do an arrow function I'm going to say const trending posts and we're going to say this is an array of singular post so if you remember posts should come from the Prisma client so we can just pass that in and I can say an array like that and I'm just going to copy and paste this four times so we have four different arrays so I'm going to say Tech posts this one's going to be travel posts and this one's going to be other posts and below this I'm going to do Post dot for each I'm going to pass in post and make sure I have the typing of post as well I'm going to pass in the number for the index and I'm just going to do I'm just going to Loop through using if I is less than 4 so we have four trending posts we're going to do trending post dot push so we're going to push those particular posts in this and then we're also going to do if post and if post exists so post needs to exist first we're going to say category is equal to Tech because that's the category we set some of them to be so I'm going to say Tech posts dot push and I'm going to put push the post in there and I'm going to do else I'm going to paste what I just copied but this is going to be travel and this is going to be travel posts as well and then from here I'm going to do the same thing paste the if statement and this is going to be interior design and this is going to represent the other category so I'm going to just do other posts that push now this is not perfect this is just kind of like us organizing our data because this is not a real project but this is just to keep everything more simple so now we have our particular posts now we need to grab each of these posts for grab each of these array and we're going to destructure them so I'm going to const trending posts Tech posts travel post other posts I'm going to do format post like so and it seems like I forgot to do a return so if I do return over here I'm just going to copy this entire array that I just structured and so now this should not have an error so we have all of these posts being passed out and we're just going to pass in each of these to the correct component so I'm going to pass this over here it's going to look like that and right now trending doesn't account for these so let's actually go to trending component and I'm going to pass the trending posts over here I'm going to say array of post and make sure we import that using intellisense so we have our training post we need to make sure we destructure it to grab the trending post over here and I'm going to go down go over here in the trending card and we want to pass the data over here so I'm going to do post is equal to trending posts zero and I'm going to copy this over and we're going to modify our trending card don't worry so I'm going to paste three sections over there with one two and three so we're passing all four posts in there and we're going to go to our trending card now I'm going to say post is equal to post like that because now it's singular we're going to pass the post in and we're going to pass the post information over here and now we can actually pass this in to our href we do need to identify what this is so I'm going to go over here to our Explorer we're going to go to our DOT EnV and we're going to identify our public URL so we're going to say next public URL and it's going to be http colon slash localhost colon 3000 so this is for the development environment when we deployed on versel this will be different but we'll configure our environment variables in that situation later so I'm going to save this I'm going to go back to trending so now this should be able to go to that particular URL once we set up the routes and things like that but for now we're just going to keep it like this and then I'm going to go to our section where we have category so I'm going to go over here I'm going to pass in post and it has to be question mark just to make sure our post exists and then over here I'm going to do Post question mark dot title so and for now we're going to ignore the image because we have the image Art URL in the post so if you take a look we have the image string but we're not properly passing it in so we're going to wait for us to pass in all the posts first to get all the information and then we'll deal with the images so the image is its own huge topic so I'm going to save this and now as you can see after I refreshed it and saved it we can see we have the category we have the title over here especially in these trending cards now we haven't modified these so we'll do that next all right so now I'm going to go back to page.tsx I want to note one thing about this so if you go over here we have the get posts now typically when you use next.js12 you have this option of doing server side rendering or revalidation meaning we refetch the data every maybe like 60 seconds we can probably do that and that is for specifically for example the reason why you would do that is you want to make sure even if someone stayed on this page for a very long time they'll have the latest information at least every 60 seconds so because you don't want to do it every second because that's too much it's going to put a lot of strain on your your end and also their computer but you also want to make sure they have the latest data so revalidation which is what they call ISR increment incremental static regeneration you want that to happen every once in a while so you can probably do export const revalidate so this is a this is what's called server segment configs and I have a link in the description below to describe this now this is supposed to revalidate every 10 seconds or actually usually you want 60 because 10 is too much you want to revalidate every 60 seconds but I have not confirmed that this works I've seen some posts I have a link in the description below where they discuss this issue like I'm not exactly sure if I'm doing this correctly but I believe this is how you write this in this particular folder if you want to revalidate this particular information every 60 seconds but if you know the trick or if I'm doing this incorrectly please let me know but this is specifically for that scenario so anyways with that in mind I want to go to Tech posts and I want to pass that in as well so over here we're going to do the same thing pass that in to our Tech component so we're going to open that up I'm going to pass that in over here we're going to have an array of post make sure you import that over here and then we want Tech posts from here as well and we can go in and we can check and go down over to our cards so if I go over here I can say post is equal to Tech posts zero for the first one and we have not added the post yet for the card and over here I'm going to do Post is equal to text posts one and we're going to do the same thing for these two guys we're just going to change the numbers over here once I have that saved we're not going to see any changes yet because this is problematic so if you go to the card component I can go up here I can say post is going to be post again we're going to have to import that for our typescript I'm gonna pass in post over here and I'm going to use the post to grab information so I'm going to do Destruction for this one because we have a lot of information so I'm going to do ID title author created that image snippet and then post like so and what we need to do is add the date so I'm going to do date is equal to new date and created at so we need to format the date properly so to do that we create a new date object we're going to do options I'm going to pass in year colon numeric oops numberic change that I'm going to do month I'm going to switch this to be long I'm going to do day and I'm going to change this to numeric as well and we're just going to set this this as any because I couldn't find a way to get around this problem for Locale dates so I'm going to do formatted date is equal to date 1.2 local Locale date string and we need to format our date that comes from the back end to the proper format and formatting dates is not always easy so we're just going to pass in options over here yeah I was trying to figure out how to get this to be a different type that would work with this but I could not figure out the proper one so I'm going to go over here I'm going to go down we're going to check href and the href should be our proper URL so we're going to do href actually let me put this on the separate line so it's easier so href is going to be equal to we can actually probably it might be better to just go over here to the trending page or trending components I'm going to copy this guy over here should I go to the card component I'm going to paste it so now this should be identical because it should automatically take you to the correct URL and again like I said we're going to skip we're going to skip doing our image right here so I'm going to go to the title and the title has the same exact URL so I'm going to copy and paste it over there and then in here I'm going to put curly braces around this title because now we destructured it so we can grab it so I'm going to do the same thing for author and then as well as date and actually this should be formatted date now and then also the same for snippet so I'm going to save all this information and let's actually check everything is expected and with these cards we have our information now we have our title it has a URL the image has a URL as well and then we have our author we have our formatted date so it looks nice and then we have our Snippets so we have all this information everything is aligned we apparently have invalid date for these ones because we have not passed the information to these correct components but we did that for Tech so this is expected so now we're going to go to go back to our page and we're going to pass in travel posts and we're going to do the same thing for all of these so I'm going to go over here I know this is kind of tedious but we'll just make do so I'm going to go over here I'm going to put travel post and this should be an array of posts pass that in I'm going to grab the travel post over here and we're going to save it and now over here we can pass the post into these cards now it's screaming at us because we didn't pass it in so I'm going to say post is equal to travel post zero I'm going to copy and paste this for the other two so one and then two and then for the final one as well then this would be three so I'm going to save that and it seems like we don't have our travel post working properly and that's probably because I didn't save it over here yeah so once we have that we can go to our Travel section and we should see the same thing and then we'll do the same thing for other and we'll try to do this quickly so I'm going to go over here other paste it in here pass paste it over there we're going to go to our other component I'm going to paste other posts over here we're going to do array of posts make sure we import that grab the other post and then we're going to pass those posts in here so I'm going to post other post zero and then I'm gonna make sure we do the same thing for all of these so one two three and we should see everything for our trending posts or other perfect so we have all the information for all our posts and all our cards so now the next thing we're going to have to set up is going to be the actual images and now we can finally talk about our image and the image component from next JS now I wish I personally wish there was a little bit more examples in the next JS documentation I know versel does a puts a lot of work into their documentation but I wish they had a lot more complete examples they have like snippet of examples but they don't have complete examples of all the different scenarios that you might encounter for something like the image component and I was led into this Rabbit Hole of trying to understand what's happening with Nexus image components and how it optimizes your project so I will show you all the little details about the image component itself so if you take a look at this project right so what's happening with these image is that next.js with their image components will try to optimize your images depending on your screen size so for smaller screens you only need smaller images you don't need a huge 3800 pixel wide image otherwise it's going to slow down the website for smaller screens for mobile devices because they don't have as much processing power or maybe better they have worse internet connection than someone on like a desktop so if you take a look on what's happening on this particular website right now you're not going to see any calls but if you go over here the images depending on the screen size will go and show will have a smaller screen or a smaller image will be loading for a smaller screen size so if you open this up you would see an extra Network call for these images if you have a larger screen size so you would see this happening in real time and I'll show you how this happens because I don't have this is all cached so I don't have all of the available information to show you this but I'll show you when we're setting this up and that is part of our that is part of what the image component is going to be doing for us in next.js another thing is going to be a placeholder blur for when we load our images so if you can see briefly if I just do slow 3G it's going to load up slow so meaning I'm replicating internet slow so there is a placeholder that we can set to be blurred out before the real image comes so if your images are large it'll take some time for it to load on slower devices or slower screens but this placeholder makes it kind of look nice so I'll show you how to do that as well and then we're also going to take care of like the fill and how these kind of when you're dealing with media queries and responsive design the images are very hard to handle sometimes and we can see that they move in in a way that fills properly so like you have the image and it fills the size as we need depending on the width of the screen I'll also talk about a little about loaders and a few other things so this is all essentially image optimization and as you can see there's more net requests as we go down so the image only loads as needed it's already lazy loading only when it needs to so a lot of the image optimization from next.js13 image component is very nice but it's really really it's really complicated but I'll show you everything that you need to know so let's close this and let's actually get started so the first one so the first one we're going to handle is going to be the trending component and the trending cards so if I go to the trending component over here I can go to the trending card and this is where we have our image placeholder for now and what we want to do is we're going to change this so we're going to get rid of the background white 500 and in here I'm going to change this to an image component from next slash image so you need to make sure you import that correctly and then over here I'm going to close this and there are two ways to do the sizing so now there is the way that you can just set the width to be like 300 and then height 500 if you want to have like a very specific width or height so that's one way but another way is to do fill and you cannot do both you have to do either or so fill will fill the image to The Container size and we set this to relative with the width of full and height of full so we can make sure this is responsive so you need to do this you need to do this section if you want to use the fill otherwise it's going to complain to you that the parent component is not relative or width is full or height is not full so you need to make sure you have this fill option and then from here I want to set the style to be object fit so if you know how images work you can do object fit cover that's how I'm getting that it like crops when the screen size is dependent so the only thing the only issue with this method is that it depends on your image so you have if you have important image detail like if you have like another person right here on the left side let's say if I open this if you have an important uh person on the left side it's going to get cut off when you go to like smaller screens or adjust the screen size so it's possible that it might not be the best fit but it does it preserves a proper you know image size and you'll have the proper ratio otherwise you can do the other methods which will like stretch and Shrink depending on what you prefer so there's a lot of options but this is all more like vanilla CSS kind of thing but you need to set the style to be object fit there used to be in in the old image component before next year s13 they used to have an object fit like this but as you can see it's deprecated they have a cross mark making sure you don't do it that way so you want to make sure you have the style so don't get confused if you like search on stack Overflow how to do that and then we're also going to set the alts to the tech so this is just the description of the image so for this one we're just going to have it alt you want to be more descriptive of each particular item but for now we're going to keep it like that and also we're going to set the source to be post dot image so we can set set it like that and let's just save it and see we have our images and we do so we have our images everything is working as expected so let's yeah as you can see we have it cropped um but if you go to smaller screens as you can see what happened was it didn't it disappeared but why did it disappear let's actually open this up let me disable cache so we don't we can see that we have our image essentially loading and then we seem to have all right so what we're going to do is we're going to go and click the image over here we'll take care of the post and all of those other later but if you take a look we have an image right here so right now we have 828 width so if you take a look what next.js is doing by default is setting these pixels to the optimal one that it thinks this screen size might need but if I start opening it up you're going to see more image requests come in and this is going to be 1080 for this case and then 1200 for wider screens and we're going to continue and it's going to keep going up and up as the image size needs so we are going to 1920 for these scenarios and then for some reason we have 48 oh that's for the social media links but for this is 1920. so we can keep going and it's probably going to yeah get a few more so you can't see it but that's 20 48. so this is what next.js is doing by default however somehow sometimes this width setup is not ideal and you probably want to set up your own sizes directly so if you see this image with Source ignore these get files we'll take care of this as well but if you take a look at this image with Source assets something like this was detected as the largest contentful paint please add the priority you can add that if you want but most importantly is the fact that we have these images and we probably need to set up our own sizes as well so now we also want to do that placeholder blur I mentioned which is if we reload the page and the website is not up let's disable cache let's let's do fast 3G so if you take a look it's just empty and it just kind of goes in for slower computers or for fast computers or fast internets this is not a big deal but if you have a slower Internet it's just like a empty image for a very long time so one way of fixing this is to use placeholder blur so as you can see it kind of goes in very slowly so it's a little it's a bit ugly you don't have to have it but you can do it if you want like a more optimal experience for the user so what you can do is you can set the placeholder to be blur however we're going to run into a problem and we're going to be missing the blur data URL property so this is a URL if you want to import outside like a little smaller image and you would have to like manually downsize the image and blur it yourself or you can do an alternative way maybe like use a different website that will do this for you but there is a slightly better way that's kind of inherent that you can kind of do so if I go back to page.tsx the problem with what it normally does it won't ask you if you if to do the blur data URL if you're doing static image import so what that means is if I import my image like let's say like import image asset from earlier sorry import asset like five or one from like slash assets if I can find the file like I can do something like this and I can import it if you pass the image directly into here directly like that then placeholder blur will be fine however post dot image this is actually a string so what we're putting in here is a string not a static import like I mentioned over here so this is a static import however the problem with this is we cannot do it that way we cannot pass it directly in here because we're grabbing post information from the back end so that only happens when we are at runtime so before we get to that point we cannot do static import because we are grabbing the post information and we are using that as a string so there is an alternative way to do this and that is if you go to our get posts we can format the post to become a static import instead so the way we do this is a little all roundabout way but it works it might slow up slow it up a little bit but the blur image comes in right away so the way I do this is it await promise.all and what we're going to do is we're going to grab all the posts we're going to map it I'm going to grab each post like this sure I have posts like that and then I do Arrow function and what I'm going to do is create an image module variable and what I'm going to do is require and I'm going to do dot dot slash public dollar signpost dot image so we're passing the image string and we're requiring it so we're grabbing the static image import and we are returning it as the image so we're modifying our post to have a different value so this is no longer a string it is the static import instead so this is how we format it properly so that we can use for our posts so I'm going to set this to be formatted posts like this so now as you can see we have our placeholder blur that's coming in so that is essentially a very nice thing to have with our components so let me close all of this so again placeholder blur we no longer have an error because we changed this to a static image import I think this slows it down just a tad bit but I'm not entirely sure it feels like it's fine but either way we can see that we have the placeholder blur going in so if I do let's say fast 3G you can see the placeholder blur comes in very close so we have like a little bit of request with the width of eight so it's a very small URL and then we get the 1080 and then the bigger sizes now I know there is a lot about the images there's still one a few more things that I want to mention and they're a lot more quicker so here you can see it's automatically prepared for us and it's already set up to do the way it automatically optimizes it depending on the screen size however you can also set it so you are setting up the media queries itself so you can do sizes and you can set it up with your own media queries so if I do Max width of 480 pixel something like this and I do 100 viewport width you can set like the image sizes that it comes in I'm going to set this up for this project that was optimal so this is going to be a lot of trial and error to figure out the proper images but since we're kind of just mostly trying to get this website up to the optimized mode then we are just going to have to set this up pretty quickly so I'm going to do Max with I'm going to set this to 1060 pixel and we're going to set this viewport height to our viewport width to 50 and the default one is going to be 33 viewport width now I'm not fully sure how this fully works but it gets a little more optimization out of it so if you do this it's going to get a little better optimization so this is 1080 . if I go down we'll probably have a smaller one if we import it over here so this is like 384 we can do something like that and we can increase it as well we have 8 28 I'm not exactly sure why this one has issues but maybe because I increased the size too quickly but yeah so it's a little more optimized if you do it this way so as I saw it it was a little bit faster than from what we had before so I can change this to no throw along keep it to the default now there is also like the image loader so by default Purcell uses their own image loader so they have like something like a loader component property and then you can set up your own loader yourself for the image Optimizer so you know the thing that is changing all these images you would want to do that if you're loading up a lot of images because if you're using versel to do that they can start charging you and it's a lot pricier than some certain options if you use it too much so just be aware of that option all right hopefully that image component explanation was very helpful because this took me a long time to figure out what's happening and how it works and it's very very nice it's just I wish there was better explanations like I wish there was better examples for me documentation is all about examples I want a working fit example for these different scenarios but they do just like give a lot of words and explain a lot of those things and it's kind of tough to like figure out how you need to set these things up so image examples are just way better in my opinion so I wish I hope the verse cell team can like act on that make sure there's more examples so people can just right away use these images anyways let's go back we go to page and then we're gonna go to let's say let's go to navbar I'm going to go to our nav bar which is over here and we want to fix this particular image over here so I'm going to go down and again this is relative so we we can do fill for the image below and actually let's go back to trending and I want to just copy this image component so it makes our lives easier so if I just copy and paste it I'm going to import the image from next link let's see is it or yeah it's already imported so if I have the image component right here I'm going to place in advert image so in this case we don't need to do the static import we can just pass the image from directly using static image import like this assets add1.jpg so make sure you have that so now we can just import this directly and we don't have to really worry about it you just pass it add one in there directly like that and we're just going to call this advert one we're going to keep everything the same to keep it simple if we save it now you can see we have our image over there all right so now we're going to do the same thing for our card component so if I copy this from the image I'm going to go to my card component and inside this div I'm going to paste the image component and I believe the image component is not imported so we're going to import that and everything should be pretty much identical we can just get rid of the post because this one has a destructuring of the image so we have our sizes style object fit cover things like that so if we save it we're going to be able to see our image now we still have this background color so that is going to be in the text section I believe so if I go to the tech I'm going to find where we have a background like this so I want to get rid of this and save it and then our color for the snippet is not correct because I changed it so I'm going to say go to card we're going to go to snip it and this should be 500. in the snippet section so we save it now the color is very nice so now we should do the same thing for travel so if I go back and close all of this we're going to go to our travel component and this is why sometimes sometimes it's just nice to have it all in the same file even if you get like very long react components because sometimes if you encounter a situation where you're just bouncing back and forth between files it's it can be a pain so it's up to you and it's like a judgment call that you can make and there's no right or wrong answer at times just depends on your preference and your team so I'm going to save that and as you can see everything is good and we need to do the same thing for trending so if I go over to the other section I want to get rid of the BG white 500 once we save that now I can see we have our posts and everything is working as expected perfect so now the few things left is going to be the sidebar I believe there's an image and then yeah I think that covers all our image sections if we just do the sidebar so let's do that very quickly so we're going to go to our page go to our subscribe component and we are going to be actually not subscribed sidebar component so once we have it here we have our image placed over here so we're gonna go over here and I believe we need to import our image like this and we can go up here we're going to import at 2 from slash public slash assets slash add to dot PNG and I want to make sure we import that to our image and then over here we have another one right here with the profile image and we want to paste it here but this one we're not going to do all of this fancy stuff because this is just going to be we want this to be a have a specific width in the height so the way I'm going to do this one is I'm going to set this width to be 500 pixel a height of 250 pixel because this one doesn't look good if it's kind of stretched and it's trying to fill so I'm going to save this and I'm just specifically doing it for this case and I'm going to just import about profile from slash public slash assets I'm going to do about profile.jpg like so and I'm going to pass this in over here in the source right here make sure we have that we're going to have alt and this should be about profile and this one we don't we can keep the placeholder blur just get rid of the fill because this one's not going to be a fill based and because of that we're not going to need our sizes so we're going to keep just these guys and then I believe I forgot to change this so this is going to be advert Dash 2 and this one is actually with of 500 as you can see it's just taking up the entire screen so this is not properly set so we're just going to directly place our width and the height directly so we're not going to have a fill because this one is more of a just have a very specific width height type kind of deal and then also I want to add a class name for this specific one so I'm going to do class name and I'm going to do hidden MD colon block my8 with a width of full so this is just extra styling we don't want any of that as well so we can just keep it like this so if I take a look I'm going to see if we have our sidebar we have our advertisement we have our image so if I go and scroll this up the sidebar will go over here and it seems like we kind of have it messed up so let me see what's happening so this one at the bottom we actually need to set this to be flex and justify Center so that's what I kind of missed and then we also have the margin y of three and then everything else we don't have the advertisement because it'll kind of look weird if you have it on the small screen so we're just going to have the advertisement displayed when it's on the big screen so we have the ad we have the image everything is looking pretty good with our images so hopefully that clears up the image component I had a lot of problems when I was trying to set it up and I wasn't sure how to use it so hopefully you guys have a good understanding and if I did miss anything or if you know something about the image component that I do not know please leave a comment I want to know as much as possible about this image component to use for next.js all right so the next thing we're going to be building is going to be this individual post page and this individual post page will have breadcrumbs category title and basically this content over here underneath and we're also going to be able to edit and the edit is going to have a lot more functionality we can edit the title and then we can edit the content we also have this awesome editor for the text as well so we can do we can make this italicize we can bold things for example like this we can change all of this and we can save it as well if I hit submit is going to save it into our database however I stopped my database so it's not going to save so over here also I can say if I want to know what type of writer do you want so this is pretty cool with AI you can say or with openai you can set a type of writer and how you want them to write so if I click this we're going to generate AI content over here and we're going to have a little blog post about this so now there's only three lines and I'll tell you why I only have three lines and this is only because we are deploying on versel and we want to keep things free if it was if we upgraded to a different plan we can make this longer on versel the problem is versel not open AI so if we wanted a longer we would be capable of doing that but for now we're just going to have a three line you know generate AI content for this so this is very cool and you can see can't wait to book my first buy with all the money I don't have so this is written by a sarcastic witty individual so it's basically writing in that tone of voice and then we can also cancel the editing so we can keep the old one so it just depends on if you want to keep the information so that is how we are going to do this editing and I'll show you everything step by step all right so I'm gonna close this up we're going to go back to Arc code and we're going to go in we're going to look for post so now we're going to actually handle Dynamic IDs so if you take a look at this URL we have a dynamic ID so we have slash post slash ID so we can do that easily in next.js and the way we do this is we have a folder in here called ID in square brackets and I'm going to create a new file I'm going to call this page dot TSX and this page.tsx is going to call we're going to do TS rafce I'm going to call this post and with this post component we're going to be adding all the things that we need so first we're just going to set up the layout and the way we are going to do the layout is going to be very similar to what we had in the page so I'm going to go over here I'm actually just going to copy everything that we have over here and then we can make our modifications because most of the sidebar is going to be the same and some of the other aspects but we don't need like stuff like trending we can delete all of these guys over here and in here I'm just going to remove this we have basis 3 4 and I'm going to change this to a Content component and over here we'll have our sidebar and the way we do this for the dynamic ID we can give we can grab information from the params variable we're also going to make this async so this is going to be a server component and over here inside here I can say params colon curly braces ID to be string like so so this will be our type and what we're going to do over here is I'm going to grab the ID from the params and that's how we grab the ID of where the user is grabbing information from so basically if the user tries to go to this URL we're going to grab this particular ID over here and we are able to access it via this ID variable and we can pass that in with our server component logic that we can pass in over here so for example if I create our function so before we add get posts plural this is going to be post get post singular so we want information about a singular post and we can do this by doing passing it something like this and this is needs to be an arrow so what we're going to do is over here I'm going to say const post and we are going to await get post and we pass the ID up here and then we can use that ID to grab our post from the Prisma backend so the way I'm going to do that is going to be post is equal to a weight Prisma and make sure we import that from not the client but our file right here so we have our app and then we can do dot post dot find unique like this and we do where colon ID so we can grab the post the relevant Post in the right location and also we need a check just in case if post doesn't exist because it's possible that the user goes to a page where the ID does not exist we're just going to do console log post with ID not found just to make sure we have a console up for that and we just return null we can do like an error page or you can have your own thing over here depending on what you want to do with it so it's up to you but for now we're going to keep it like that and then we could just typically return posts like this however the only problem is when we passed post over here we need to modify the date object coming from get post because it'll give you a warning saying we cannot pass a date object which is something we're getting from the back end and we cannot pass it into the component over here so to do that it's pretty simple so I'm going to say formatted post with the curly braces object we're going to pass in all the post information I'm going to say created at and what I'm going to do is post comma or question mark dot created at question mark dot two ISO string so we're just converting it to a string that is useful and this should be a comma and we're going to do the same thing for updated at instead so let me grab both of these I'm going to just do updated at so now we have our formatted post and that's what we're going to be returning so with this we want to kind of make sure we have our typescript all in order so what I'm going to do is I'm going to import the post from Prisma client but we're also going to call it put as post type the reason why is because we don't want to conflict with this post naming so we need to change this to post type and this here we're going to say post type however we also need to make sure there's a possibility of it being null and that's why we have this error check just in case we cannot find it we have an error check otherwise we have our post type we can pass that in over here and then we will get formatted post that exists over here so now we know that formatted post exists and the way we have this particular type is that we're going to create a types file so we're going to go over here and in the app directory I'm going to create a types dot TS and what we're going to do is go over here you see where the post type is we're going to copy this entire guy we're going to paste it or copy it and we're going to go to our types file I'm going to paste it over here I'm going to call this formatted post instead and these should instead be string because we changed it prior and by doing so I'm going to close this and I'm going to import formatted post right here from at app types so now we have our post information so let's actually console log this out and we're most likely going to see if we go back let's click up here we're going to see our information it seems like oh yeah we do happen to have and then make sure we need to import that so we have these errors so let's save it and as you can see we have our post information perfect so our post information exists we have nothing on this page yet so we're going to be adding that very soon so here is our post this is all our information with our post perfect so I'm going to close that we're going to go up here and now we can work on our content actually before we go to the content I do want to explain one thing is that here let's say I'm just going to copy and paste this because I just want to show you what this is possible so let's say we're not using Prisma but let's say we need to call a third-party API so an external API instead instead of our Prisma database we want to call some other API call so we would have some kind of URL let's just say URL instead we're calling some outer URL and the way this works for fetch anytime we use a fetch fetch function we can use these things like cache or cash no store or next we validate so if you aren't familiar with these particular terminology SSG SSR ISR so these functionality is equivalent to getting static servers what was it static server generation static site generation sorry so you have Force cache that forces it to be a static site otherwise you can just do a no store and that will be server-side rendering otherwise you want a hybrid approach which is revalidate and you can do incremental static regeneration that's ISR so this is what it represents so these are the three options that you can use when you're using fetch for you know if you're actually using API calls so in this case we're just calling our database which is technically an API call but not in a traditional sense where we're using fetch so I just want to make sure you're aware of that and again like I mentioned before we always want to do export cons revalidate if you want it to revalidate every 60 seconds now again I'm not sure if this actually works maybe I'm not doing it correctly if someone actually knows how to fix this then please let me know but this is how we are revalidating our particular page so anyways with this information we can get rid of our console log and then we can now work on our content page so let's uncomment that out we're going to import content from at slash say app sorry it's going to be dot slash content so it'll be in the same file so we're just gonna our same folder so we're going to do that we haven't created it yet all right so from here I'm going to close this and we're going to be creating our content file so I'm going to create content dot TSX so this is where everything is going to be located over here so I'm going to call this TSA rafc e and then we're gonna write our content and then we're going to save it and we should be able to see content right here so in next js13 everything is a server component by default so right here this is a server component by default however there are occasions where you're going to have to use client components client components are when you have basically any kind of interaction so this entire component right here has this interaction right here and this cannot be a server component doing this so when you have all of these elements that are Dynamic and interactive we need to make this a client component so even if the parent component is this particular component right here that it's being a post the child component can still be a client component so this content component we're going to make this a client by saying use client like this so This essentially will be a client component over here so from here what I want to do is I'm going to start setting this up and I'll go through all the processes and steps to set setting everything so this being a Content or client component we're just gonna go through and I'll show you all the interactions so I'm going to start with is editable set is editable so we're going to start with setting up some State and we're going to set this as a Boolean type like this and we want to make sure we are importing use state from react like that so this is going to represent whether we are in editable state like or not so this interactivity is going to be based on this particular Boolean and then from here I want to have the state of title so since the title can change we want to make sure we have state for that so we're going to do use State string and we want to pass in the post title so the way we do this is we can go back to page.tsx because this is where we have our post information so I'm going to pass that in and content does not have post so over here I want to make sure we have post and it should be formatted post to type not the regular post and we want to make sure we pass that in over here so we can say post and now we can use post dot title like that so this is our Title by default it's going to be the title that we grab from the back end and then here we're also going to have validation so whenever you try to submit and if it's empty we're going to give it an error so we want to set that up so we need to set up our own error validation now if you've seen my other videos I do tend to use like the form library for these kind of things but because we're using the editor text editor we're going to be using a plugin for that that it makes it a lot easier to create our own validation and our own form especially for something that's as small as this it's better to do it handmade than rather than using a forum Library so in this case I'd prefer just to make our own so we have our title we have our title error and then we're also going to do content so this particular input has title and then the content itself and then we also have the role here but we're going to deal with that later so I'm going to set the content over here I'm going to set set content and I'm going to do use State and we're going to pass in string I'm going to say post dot content over here I'm going to copy all of this again I'm going to grab all the titles just the title sections actually yeah I'm just going to write it so set content error like this we have our content set content and then content error with an empty string so this is essentially the state we are going to start with but we're not going to do it just yet we're not going to hook it up we're going to set up our jsx first so the way we do that is we're going to do this to be class name and here because again like I said the editor doesn't allow to allow you to like modify the text directly because this is like rendering HTML we need to actually use Pros instead which comes from that Tailwind typography Library so that helps us to use and fix that problem and we are going to set all of these we want the max width to be full as well as the width to be full so we want to take the entire space I'm going to get rid of content I'm going to write H5 class name and we're this is going to be the bread comes we're going to give it a text of white 300 like so and in curly braces I'm going to say home with the arrow sign I'm going to do Post dot category close that with another arrow sign and I'm going to say post dot title close that and then close our template strings and close that now I'm going to say this is going to be the breadcrumbs like so so if we take a look we are going to see Home Tech and our title so our category and our title over there so that is our breadcrumbs essentially and then from here we're going to create this category and the edit button we're not going to do the functionality just yet but let's do that next so over here I'm going to say let's call this category and edit I'm going to do div I'm going to say class name and we're going to say Flex justify between items Center so we're going to have this particular div and over here I'm going to have an H4 I'm going to close this I'm going to say Tech in this case or actually we need to pass in the category sorry so we need to pass in this guy and we're going to pass in the class name and we're going to say background accent orange so this is going to be in orange background type with padding of 2 on the top padding of five horizontally and a text black color and I'm going to do text SM font and bold like that so we have our category over here and we're also going to have our editable button so we're going to say div class name Mt of 4. so we're going to have a margin top on the top of it and we're going to do this so I'm going to say is editable so if we are in the editable state we are going to show basically an input or an x mark right here so if I click on it we should see this should become an x mark versus if it's not edible we're going to see this edit icon so we're going to div class name and we're going to do Flex justify between with a gap of three and I'm going to close this div like so and over here I'm going to say a button should be on click and we are going to for now say console log cancel edit and we'll be fixing that as we go and what I want to pass is x mark icon so this is an icon from hero icons so again if you go to Hero icons.com you can see whatever icons that they have so if I do x mark you can see we could just grab this x mark and use that for our code so the way to do that is just after you've got the name of the icon that you want you can just import xmark icon and you want to do it from at hero icon slash react slash 24 solid so actually let me just clarify so you can choose whichever one you want because outline solid and then you have midi so it just depends on which one you want so you can import that and this is all for free for um from Tailwind all right so from here we can close the button we can finish writing our xmark icon and we can give it a height of six width of six so that determines the size and we want to give it a text accent of a reddish orange which is designated by text accent red so there we have our editable icon and we're going to do the same thing for the other version so I'm just going to basically crop uh grab this we don't need Flex Justified between we only need it for when we're not editing however when we're not editing we don't need it for editing we do and so here I'm going to do um make edit and keep everything the same this one is going to be pencil Square icon so I'm going to grab this I'm going to paste it over here and then we'll have our button so if I go back to my code and I click it nothing works because we did not handle the canceling but we'll handle that a little bit later because there's some other things to note when before we fix that all right so next on the list is going to be the header but inside our header we're going to have a form or a rounder header is going to be a form and we are going to have an on submit function and we are just going to say handle submit I'm going to close this form we don't have this particular function yet but let's just create the skeleton for it so I'm going to handle submit with an arrow function and we're just going to do we're just going to leave like that we don't need to do anything inside here I'm going to create our header and our header will just be basically our title and so the way I would do this is I'm going to do that and we basically need another is editable situation so I'm going to paste that over here and I'm going to have a div that will give us the text area inside so our title will involve a text area which is basically an input except it's multi-line and we're going to do border two rounded MD background white of 50. p dash 3 with a width of full so that is our styling for this and we're going to say placeholder should be title so basically if it's empty we're going to give it that placeholder we're going to give it on change again we are not going to initialize this just yet and we're just going to say change title every time next one we can just say this we can say change title and do e dot value dot Target oh e.target.value sorry so that will show you when we change it or someone types in it that's what's going to happen and the value itself should be the title state that we created and then we're going to go run into an error if we save it because we did not close our ternary and we still have a few things that we need to write if it's not in editable mode all we have to do is show an H3 with our title text and we just want to style this a little bit so we're going to say class name is equal to font bold text 3XL Martin top of three so I'm going to save that and there we go we have our title with our post title and then from here below this we're going to have a div and we're going to do the authors as well so I'm going to do class name with flex and a gap of three and inside here I'm going to say H5 class name font semi bold with text access and I'm going to say bye post dot author sure I spelled that correctly and then from here I'm going to do H6 so this is going to be the date I'm going to set this to text wh Dash 300 text s like so and I'm gonna just do pass in the post.date even though this is not formatted but we'll cover that um it seems like oh yeah I needed to create it out instead if I save it now we see we have our author and then we have our dates so the date is not formatted we'll take care of it in a little bit all right next part is going to be the image itself so I'm going to say image and we're going to do what we normally do with div we're going to say class name and we're going to set the parent to be relative like I mentioned before with the width of Auto so it's going to take up the entire width with margin top 2 modern bottom of 16 and a height of 96 so we're going to close that and inside here we're going to do our image component let's make sure image image was not imported correctly so I'm going to go up here image it and over here I'm going to close this Arrow close this component tag and what I'm going to do is I'm going to do fill so I'm going to do alt is equal to Tech and or actually sorry this should be post dot let's just set this to be title and it'll be better and then we're going to do source is going to be post dot image now if you know this is actually um this is just a regular image so we can modify it but we're not going to modify it this time so we're just not going to have a placeholder blur so instead we're just going to keep it like that and in this case I'm just going to copy and paste this so you can just see what's happening over here we have this set of sizes for the media queries so you can just fill this out this is just trial and error I just tried it that is what looked good it needed to be a little different from the previous one that we set and then over here I'm going to set this to be cover so I'm going to save it and then we have our image so if I open it up you'll see the image as it goes and it depending on the size and the responsive we have a nicely fitted image all right and then from here we're going to skip the content section which we'll handle because we're going to need a specific library for that but let's do the other part which is the save button so if we hit the edit button we don't we can see the save button the submit button over there so let's actually do that so the way we do this is we just do let's submit button and I'm going to do is editable and I'm going to set a div with class name of class name and it's going to be Flex with justify end and I'm going to set a button like so I'm going to say submit and I'm going to set type is equal to submit and I'm going to set the class name to be BG accent red with hover of BG white 500 text of white 10 font semi-bold py of 2 PX of 5 margin top of 5. so there's quite a bit of styling for that so we can't see it because we need to work on this editing which we'll do in just a bit but the last thing we want to add is going to be the Social Links over here on bigger screens so if you see there's the Social Links but on smaller screens we don't need Social Links because it would be redundant because the sidebar has visual settings so we're going to do that so down here outside the form we don't need to make it inside the form yeah so right here we're going to do social links yeah I'm just going to create a div around Social Links we're going to pass that in make sure you're using intellisense and we are going to pass this in as is dark so it's a dark color this time and we can say class name is going to be hidden by default for basically small screens but on big screens we are going to show it with a margin top of 10 with a width of one third so now if we take a look at our app if we open it up we can see we have our Social Links if we are on bigger screens so now I want to talk about the content section so here we are going to be using Tip Tap for our content section so this gives us a very nice interface so we can edit things as needed so we can have bold italicize things like that we can do like heading or H2 you can make bullet points things of this nature makes it very easy for this particular library and a lot of this is for free so now they have extension so if you go the price if you go to pricing they're going to show that you can use it for free but if you just want some extra extensions this doesn't mean that you have to pay for it but you can still use it without paying for the extension and you can still access a lot of what I showed you which is like H1 H2 bold italicized you can do all of that with this particular text editor so it's very nice so we're going to be using this and makes it very nice and easy to use so I want you to go to this Tip Top Dev installation so I have a link in the description below and we're going to run through these instructions so if I go up or if I go down we can go and we can go to step two since we're not using Create react app we just need to start with this particular one so install the dependencies so open up your terminal we're going to close this and we're going to install this Tip Tap over here and from there it's pretty simple after we install it I'm going to close the terminal we can just grab essentially right here let's grab the editor and use editor and we're just going to go up to our logic section and we are just gonna paste the editor and the use editor over here and make sure we import that so from Tip Tap react and we can just import the starter kit make sure we import it from Tip Top and we have our content so by doing that we have access now we need to create the editor content down below over here so we're going to do it above the submit and below the image so I'm going to create a div and inside this div we're going to be creating our editor component so I'm going to say over here we're going to say class name and I'm going to give I'm going to give it some styling so I'm going to say is editable and I'm going to say border Dash 2 with rounded MD BG 50 with P of 3. and I'm going to say with a full Max width of full like that and inside here I'm going to do is editable like so I'm going to do and and we're going to pass some stuff over here this is we're going to have our menu bar but let me add the editor content first so I'm going to import editor content and what I all I have to do is pass in the editor that we just created and make sure I close this and let's save it and I want to see what we have so far so let's open this up oh it seems like I turned off the server so I'm going to do npm run Dev so if you see we have our editor content it says hello world and we have this particular text so right now we don't see any of the uh like the styling of it but we can kind of do like some editing over here so we are going to adjust that however we need the little you know that the menu bar so if we want to do that we can go back we can go over here and we can see that there's a section with all the functionality right here however we can't use all of these complete setups because not everything is available so they have bold italic strike so they have all of these but either way let's go over here we're going to copy all of this pretty much and we're going to be using this so let's grab everything from here and we just want this particular component and I'm going to go over to our code and go in here and I'm actually going to create a new file and then we're going to call it editor menu bar so TSX and I did I'm just going to do TSA rafc e but instead I'm going to replace this with this entire guy and we're going to call this editor menu bar and then from here in the type props I'm going to say editor is going to be editor or null because it might not have existed yet and I'm going to give this to the props section of our editor menu bar and I'm also going to import editor from Tip Tap react so that is the typing and then let's make sure everything is working let's actually just copy all of this over here with the Imports paste it and we are going to see we can't do color or text Style I believe those are the ones we can't really use unless we want to upgrade so let's go through here and let's see which one see if there's any errors going down here so we have a set color we cannot do that so we're just going to get rid of that particular button and let's save it let's see if let's open up our terminal see if we have any errors okay we cannot find module content so I'm going to just call this at slash app slash post slash ID and then we're gonna have our content and then we have our content and this formatted post and also we should have a null check right here so I'm going to say if post does not exist yeah I think I missed this so if you have a div we're going to say post not found so we're just making sure we have no errors we're here so I'm going to close that as well so over here I'm going to close this we have our editor menu bar now we need to import that into our section so we're going to go over here you see where is editable this is where I left the space for this section so I'm going to go in if it is edible we're going to have our editor menu bar oops sure I imported that correctly and I'm going to pass in editor over here like so and it seems like we have some kind of issue let's see yeah we didn't close this so we have that and we should be okay and then also I'm just going to add a little horizontal line we're going to say class name is equal to border dash 1 mt2 mb-5 and we need to make sure we close this so we save it we have our editor menu bar only when it's editable so now if we want to see the editor menu bar let's actually set up or is editable function so the way we are going to do that I'm going to go up and I'm going to create a function over here I'm going to call this handle enable edit and we'll call this handle is editable all right so we have our editor menu bar and what we're going to do is we're going to create a function we're going to call this handle is editable to make sure we can edit this but we kind of need to do a little bit differently because we need to modify our state right here but also the editable inside the editor editor so if I go like this I have an error function I'm going to do set is editable like this I'm going to call this pool and I'm going to do editor question mark dot set editable so you need to modify the state inside this content over here but also the editor set editable so otherwise you're going to run into bugs because we're modifying both the state within the library itself and the state that we are using and the reason why we want to make sure we edit this state is because it might not update properly if we don't do it in both locations so I'm going to grab this and I'm going to go to our section with category and edit and I'm going to pass in our function over here and what I'm going to do is I'm going to set this one to be it should be a callback function like this handle is editable and we're going to make this is editable we're just going to flip it like that and we want to do the same thing for the opposite so now we can actually affect the state so if I go back to our code and I hit this we can see we have our styling over here now this is a little messed up we can say bold so now if we hit edit we can see we have all of this we can't type it yet and then we have all of this right now we cannot modify this right now because we still haven't configured some of the configurations that we need so if we take a look at our use editor we actually need to set this text to be our content State instead so this will allow us to modify our content and it'll give us the default information over here so as you can see it populated our post information over here but we also need to be able to change the content in both the Tip Tap editor but also keeping it in our state and the way we do this is we have an update on update function over here and we need to create a function for this so I'm going to crawl this handle on change content like so I'm going to create this function up here handle on change content and I'm going to pass in the editor over here and again I was not able to figure out the typescript I know it's not it's bad practice where I'm using a lot of Annie's but in this case I really couldn't figure it out spent a long time it's just not worth if you're spending so long and it has very minimal impact you can change it however we can set this editor over here as the editor type which we can import from Tip Tap react and we can grab the type this way so if you don't have type for this one we can actually set type for the child component of editor which is pretty obvious and here I'm going to set the content to be error of empty string so basically all this is doing is if the content inside Tip Tap is empty we are going to make sure there is no error here so if we don't have anything in the content we're not going to have an error so anytime we type we're going to remove the error that's essentially what we're doing and over here if we have editor we're going to set this as editor again and I'm going to say get HTML like like this so this is part of the Tip Tap editor so you want to be able to get the HTML text and we're going to be setting that to our content over here so the information over here is what we are basically setting in this content section so actually let's check if this is working I'm actually not sure but yeah it seems like it's okay and there we go we have bold but for whatever reason it doesn't seem to like and it just seems to refresh the entire page once we edit it so we're going to keep modifying this as well and I think maybe if we set the edible to is editable inside our editor so we have these two aligned like what I'm doing essentially I know this is a little confusing but I'm essentially aligning everything inside our editor with the state that we have up here in our content component we need to make sure they're aligned so the react component knows how to update things properly so I'm going to save it and let's see if this works uh and so the reason why it's canceling out when you try to click one of these buttons is because you need to set these as type is equal to button otherwise it's going to automatically assume it's going to be a submit and when you hit submit that's just going to cancel out any kind of logic you have so let's go through and add all of these for every single one so I'm gonna keep adding all the way down this is probably a faster way to do this actually so if I go it's quite quite a few I keep going down could block block quote horizontal rule I just need to add all of these so now if I go and click this I hit bold it should not be a problem so there you go we have all of these possible scenarios where we can add all of these information so horizontal rule hard break undo redo so we can add all of these however I'm just going to remove a lot of these so these are all free and you have all these opportunities to do a lot of different things like paragraph um and then you can do bullet list ordered list and this is all super cool so I want to go I'm just going to remove a lot of these so it's up to you if you want to include all of them I just don't want to style everything because I'll take forever so I'm going to remove most of these let's go all the way till each three probably gonna save that and then we have bold and italic I'm going to move all of the buttons for each one to the top I'm going to move it over here and let me just check I have H1 H2 H3 paragraph so where is paragraph so I'm going to clear these guys over here get rid of code get rid of strike and then we can keep italic we'll go up we'll move the button we'll have the paragraph over here bold italic we're saving it and it should be pretty good so now I just need to style this so the way I'm going to style is I'm going to keep everything with the on click over here which is fine we want to keep is active we can keep a lot of this and we can just say background white 500 text white 50 p-1 rounded MD so this is going to be for our active state and I believe we can keep we can do this for every single one so I'm just going to copy and paste all of this for every single one and save it and it should be a little bit different so we have all of that for the h tags if I go over here I'm going to set this to be H1 and over here I'm going to set span we should include the number one inside there I can say class name and it's going to be text s and we just make sure we have that and I'm going to copy this for H2 and H3 except I'm going to change this to 2 and then change this to 3. and I'm going to go down a paragraph I believe should be pretty good and let's just let's actually see how everything is looking so we have all of this I do want to style maybe this a little bit differently yeah so for italic it's just going to be we're just going to do an italic I like this we're going to keep it simple so it's up to you if you want to take the time to style this but I don't want to waste your time by just doing this so we have a bold and italic over there and then we also need to set some div over here outside so I'm going to set this to be div with class name Flex justify between and items Center so I'm going to close this div at the very bottom and also I'm going to add one more div and we are going to do class name a flex and we'll I'll show you why I'm adding a div over here so I'm going to item center with a gap of four and I'm going to encase all the buttons over here like so so now we have H1 H2 and we can use it as needed and I can also cancel out so we don't have this particular actually it is saving the information so we are going to have to handle how this is going to work so it's going to be a little complicated we'll make it work and I'll try and explain the best that I can of how this is going to properly work and only save this information when we hit the save button because right now it's saving even though we didn't hit the save button we hit the cancel it should have just you know went back to what it originally was so we are going to have to handle that so before we do that let's go back to content and we're going to handle the title so I'm going to go up here and I'm going to create another function I'm going to call this const handle on change title and I'm going to do e and what we're going to do is we're going to pass react dot change event and we want to pass in html text area elements so this is the proper type for handling our text since it's a text area element and we're going to do similar thing for handle on change content except we're just going to do if title like so we want to set the title error to be empty string so anytime we are typing and we know this that the title exists then we get rid of the error we always show the error when there's no information in there so I'm going to set this to be e.target dot value I'm going to move this actually below this because it makes more sense and then we have our handle on change title and handle on change content and where we pass it is going to be in the header over here so I'm going to just do e and then I'm going to do handle on change title area and then pass it like that and actually it's my mistake we could just actually pass and handle on change title like this and then we should be able to handle the title as well so if I do that we're going to keep it and again it doesn't save it based on when we submit it so the way we're going to do that is going to be a little complicated and I don't like doing this if I don't need to but in this case we kind of have to so what we're going to do the logic is this so whenever we hit the edit button we are going to be saving that information before we edit we're going to be saving that information into another state and then when we save that information in the other state we will either replace that we will use that information if we hit the cancel button so if it hit the cancel button we're going to go to the previous state so for example if I add hello after this we are going to have a temporary title that has this information and the current title information will be this so if they hit the X Mark it's going to look like this version so if we hit the X Mark we're going to get this information if we hit the submit button though it's going to use this information and we're going to save that one as the current title so we need to have a temporary state for both the title and the content that we need to store when we hit the edit button so that is why I'm going to create another state over here I'm going to call this temp title and I'm going to set set temp title like so and we're going to use State and we are going to have a string and we're going to do title like this and we're going to do the exact same thing over here but for the content so we're going to do set content like this and we need to set this to be the original content at first and we are going to be handling this in our header or a category and edit so what I want to do since this component is going to be quite long I'm going to start separating this out into a separate component so I'm going to create a new file call this category and edit TSX so I'm going to make sure we have all of this information and what I'm just going to do is I'm just going to cut this out and I'm going to paste it all in here and we're going to be missing a lot of things but we're going to make sure we edit this and we're going to pass in a lot of information into category and edit so that we know what to send to the child component and we're going to be sending a lot of things in here so I'm going to do is editable and I'm going to set is editable like so I generally don't like having to send so many props down because it's kind of a hassle to deal with it and it's kind of hard to manage in your head all the props going down so I try not to extract components unless I need to but this case this component is quite hairy anyways I'm passing all the titles like all the state titles that we have so I'm passing all of this in and then set temp title as well so I'm going to pass that in as well temp content so you're going to keep that and then set temp content over here like so then editor as well all right so we passed all of this in what I want to do is I'm going to copy this entire guy and we're going to pass it into category and edit so if I go over here I'm going to paste it all over here but we're just going to modify a few things so I'm just going to go so I'm going to select all the equals and the left bracket let's get rid of that so I'm selecting all of these with command d I'm going to hit alt shift or maybe option shift right arrow twice we're going to do that and hit erase the first one got messed up for whatever reason so I'm going to put a colon like this and then we're going to modify it from here so is editable is going to be a Boolean handle is editable actually before we do this let me just copy all of this so we can pass this into props over here because we need to do that as well just so we can do less work but either way let's start with here I'm going to pass in editor so that's from Tip Tap react and we are going to set this to be null like so handle is editable we're going to do is editable with the Boolean because we are defining what these types are we're going to set this to be um let's see title is a string set title is another function so this is going to be title string it's the one thing annoying about typescript sometimes it's kind of a pain just writing all this so temp title is going to be a string we're going to have a void like so set temp title is going to be the same thing temp Le colon string Arrow function void actually this is a mistake temp title is a string like this temp content is going to be a string set temp content is going to be similar to set temp title except this should be called temp content editor okay I'm making a lot of mistakes apologies so we have editor editor should be slash null is editable is going to be a Boolean right here so we have all our typing over here and what we're going to do down here is gonna we're gonna select all these colons and just change this to a string I don't know why that popped up so we have a string like that so now we have most of the properties being passed down so now what I want to do is I'm going to create a function actually cause handle enable edit and this one is going to include the handle is editable because we're going to edit so like when we click this button so we're going to be handling this situation we want to do a handle is editable like we did before but like I mentioned we need to save the the title and the content in our temporary state so I do this by the sent temp title and I'm going to set the title to be like this and we're going to do the same thing with temp content and here I'm going to do editor question mark dot get HTML because we'll get null errors and we need to set an empty string just in case if this doesn't exist or also start yelling this is going to be what this should be right here so when we are not clicked over here we want to make sure handle enable edit is the one that's being run because we need to set the temporary title and set temp content I know this is a little bit confusing but this is the only way to handle react with this particular Library because you need to modify the state so this is one of the situations where you can say oh react has limitations react like when it comes to this like you have to do all these funky things to make sure the state is updated in your content otherwise you know maybe there's other libraries that won't have this particular or other Frameworks that might not have this problem I think maybe I'm not exactly sure because I've never used sveld and it's felt might not have this issue of course it's not more the ecosystem of um react is just way bigger so who knows which one's better in in big applications anyways so when you want to cancel though we want to set the original title to be the temp title so anytime we are canceling we're going to use the temporary title and we're going to set the content to be what it needs to be so for the content we need to set it set the editor to be the right content type like so so by doing this this will adjust our content and that will affect our content information because the editor is the one controlling this content information so you need to make sure that you have so there's a few things we're missing we're missing post so unfortunately we have to pass in post so I'm going to do Post we're going to do a formatted post like so and then we're going to pass in post over here so we have that information so we have the post category and we can go back to our code and I'm going to go over here cut this out because now we're just going to put this over here in this particular component and then right here I'm going to say handle cancel edit and now since we have that if I hit the edit and I go over here and I type the text and I hit the cancel we now have information that it doesn't save it and I can do the same thing with the content I can change all of this make this bold tag right here and if I hit cancel it's not going to save so this is how you can make it so that it's not saving the state I know this is a little bit of like a convoluted way to do this but this is probably the best option that I can figure out using this Library it does add a lot of features so that's why I kind of like it so it's in this case the trade-off is essentially worth it so the next thing I will kind of want to change is going to be the header so the header the only thing we need to do is change the date so we have this date stamp so we're just going to essentially use the date logic that we had before and I believe it's on the page component let's say oh it's in the shared card component over here and we should have this date set up and I'm going to copy that and I'm going to go back to content and I'm going to copy and paste it right above here and we'll have our formatted date for our post so I'm going to say post question mark dot created that and then we can use formatted date and replace our header date down here yeah so I'm going to paste it over here in the H6 and then we should see our modified date all right and then the next thing I want to do is this section with the article or with the editor content I'm going to create this into a separate component I'm going to call this the article component because this is going to have some extra logic and I want this to be separate so I'm going to do article.tsx and we're going to have to import a number of things again so I'm just going to import all of the article I'm going to save this what I'm going to do is cut this out I'm going to paste this over here in this div and then I'm going to save it and then we're going to have to pass that into over here we're going to go over here and I'm going to pass in a lot of different things so I'm going to pass in content error like so with editor passed in is editable like so I'm going to pass and set content is equal to set content and then title is equal to title so I'm going to copy all of this again I'm going to create a comment over here article so we have that information and then I'm going to do go to our article component pass all of these grab all of those you know the equal sign and the left bracket command shift or command alt right twice we're going to grab all of these separately so we can pass that into props and then over here I'm going to do colon and we are going to start filling this in so I'm going to say string like so and there should be editor from Tip Tap react and it should be possibly null as well is editable is going to be a Boolean set content is going to be a function so content colon string it's gonna output a void and we're going to do a string over here and then I'm going to add a comment to each of these I'm going to say if editor does not exist so just in case we have a null check like so we're going to add some Logic for generating the AI content over here but let's fill this information out inside here what I want to do is I want to create a article section I'm going to say class name is equal to text white 500 with the leading of eight so this is again the pros like section so this gives us line height for our entire article so we can set it up so it has extra information we also need to import edit their content from Tip Tap react edit our menu bar from our other component make sure it's in there and then we also need to add the error section so if we have an error actually should be outside this div but inside the article I'm going to say content error exists then we say A P tag we're going to say class name is going to be mt1 text White 900. and we are going to say content error so we have an error message for this guy so now we can see that we have our editor so we can see it we have a little more line height we have our space we do have some undesirable outline and an easy way to fix is if we go back to content we can actually add editor props so we can add styling to our editor so we're going to edit our props like this and I'm going to do attributes colon curly braces class colon and I'm going to write Pros Pros SM so it's a smaller font Excel colon so on bigger screens we're going to set Pros to be 2XL so it's larger on bigger screens with a leading of eight we're going to set Focus outline none so that is the focus that the blue line that we saw so we're getting rid of that we're going to set width to be full a Max width of full and make sure I have a common or a comma over there if I save it so now if I select we don't see that blue outline we have this aligned a little better and we have smaller text so it looks a little better so we have our article perfectly styled with some of this so we still don't have this content or generate AI content button so let's actually do that next so what I want to do first is we're going to handle the submit function I know I just talked about the AI let's actually do that after what I want to do with the handle submit is that when we submit this code to the back end we can save this information so we update our post so now when we are dealing with mutating some value in the database we actually have to send a back end where we have to create our backend because this is a client component so we need to make an API call to a backend that we create so now it makes it they make it easy so if you go to our app and we go to API we can actually create our own route over here and the way we do this is going to be very similar to how the routes are set up so if I want to make an API call to slash post slash ID all I have to do is create a new folder I'm going to say post and inside this folder I'm going to create another one I'm going to call this ID like so in curly brace or square brackets and inside this one it needs to be called route TS so that is a keyword you need to make sure you have that proper keyword otherwise it wouldn't work that's why you have this one you have export function ASAP a get function for this particular route so I'm just going to delete this guy over here for hello because we don't need that but inside here I'm going to just do export async function and we're going to make this a patch so the get calls is just fully or not the get calls but like the API calls are fully dependent on the name so this is particularly represented of the method and this is actually a very new um new feature in next.js13 so it's actually quite new that we have this particular setup and so we have our request over here and then we can grab our params by setting up a prams type like this so now there is no prems object that you can use for the typescript so you kind of we kind of have to set up our own type params to be like this params colon ID colon string like so so that will be our type over here this should be plural so now we have our params type let me close this a little bit more so you can see better and then over here we're going to have a try catch block so I'm going to say const ID and we're grabbing it from the prams object and we're going to take title and content which is going to be what we're going to be sending from the front end so I'm going to say await request.json so if we are sending information from the front end in the body object this is how we grab the information from the request so we grab title and content so on the front end we're going to be sending title content the back end is going to receive it just like this and so here we're going to grab the post where we're going to create a variable called post and we're going to use Prisma so we're going to grab it from the client that we've created earlier and we are going to say Prisma dot post dot update and I'm going to say where ID colon ID and I'm going to say data is going to be colon title content like so because we are sending this information to the back end it seems like I have some kind of type or linting error let me just double check oh and that is because we don't have a catch block so let me just do a catch block real quick so we're going to have a catch we're going to catch the error I'm going to say console dot error I'm going to say request error if we have an error we're just gonna console error that and then I'm going to say next response from next server so we want to use next response to use so this is the recommended way of sending messages now so we're going to do error updating post and we're gonna give this a status of 500. so we're going to save that and then also in our try block we're going to do Rec return next response again dot Json and we're going to pass in post as well as status 200. and we're going to save that so this is how you make an API call so if I want to make an API call I'm going to have to set the base URL slash post slash ID so that is how you can grab it and then in here I'm going to send the title and the content to our backend in the body and grab it from this information so this is how we use next.js13 so now that we have the backend set up we can do the same thing on the front end and we can grab the information so if we go to our page component and this is where actually let's go to the content component this is where we can hit our API backend endpoint from the handle submit function so there's going to be a lot of things we actually need to handle over here but let's start step by step so we're going to say async we're going to do e and we're going to do react.form event let me close this so we have more space and I'm going to say HTML form element inside here I'm going to do e dot prevent default so we don't go to another page or it doesn't like refresh the page we don't want that we want some validation checks first so basically if title is empty we are going to set the title error so just in case if we if the user sends the empty title we want to make sure that they have some information in there so I'm going to say this field is required so I'm going to do that so I'm going to copy and I'm going to paste it over here I'm going to say editor question mark dot is empty and I'm going to say set content error like so and then from here I'm going to say if title is equal to empty string I'm going to say editor question mark dot is empty and we're going to return so basically if we don't have any or if we do have an error or if one of these is true we're just going to stop running this handle submit because we're going to have more logic over here so we're going to make sure we show the error and then return and do nothing if either of those are empty and then from here we're going to make our API call so in this case since this is a client component we still have to fetch and make an API call over here so we are going to do just that so what we're going to do is process.env dot next public URL so that is our base URL and we're going to set slash API slash post so I did forget to mention that it was Slash API to hit this slash API slash post slash ID so that is how we're going to hit our endpoint so post question mark dot ID so that is how we hit that particular endpoint and we need to set the method like we did to be patch because the function is batch and we're going to say headers colon and we're going to set content to be type with application slash Json and then finally we want to send the body so we are going to do oops didn't mean to do that so json.stringify and we are going to send the ID actually I don't know if we need to send that all right we do we do or do we no we we don't need to my bad we can just send the title like so and then the content does so like I said this is the body that aligns with this guy title content and the prams ID comes from this value over here and I did spell application wrong so make sure you spell that correctly so I have that saved and then after what we want is to grab the data and we're going to do response.json like so so now we have our response we grab the information from the back end and what we want to do is update the state as we need so here I'm going to say after we hit the submit button so when we hit the submit button we want to flip this so that it's no longer editable so I'm going to say handle is editable to be false we're going to set the temporary title select the saved value to be empty string because we don't we no longer want it and we're going to also reset set 10 content to be empty string so we're essentially resetting the values that we saved because we're not using it for cancel right there and then after that we want to set the title to be the data that we get from the back end we can just use the data that we get from you know like the current title we can just set set that information but it's better to be more explicit to grab the updated information that's coming from the back end so it's just a much more proper way to do it I would say even though the results are the same and plus we need to set the title we need to set the content and we also need to set the editor content as well I know it's kind of annoying we have to update both the states but it's the only way to keep track of what's Happening so with that we have our handle submit and let's actually test if this is going to be working so first off let's actually say let's just erase a lot of this and let's see if this gets saved so if I hit submit and as you can see we have it saved let's make sure we have a network call Let me refresh so I'm going to hit the fetch slash xhr because that's the fetch button so if I hit this I'm just going to copy paste multiple times let's just make sure it's working and if I hit submit we are going to see that it made an API call to our backend we're sending the content in the title and this needs more space so we have the content and the title and then we have preview this is what's being returned from the back end so we have all of this updated information and then we are replacing this information with the new updated values so this is perfect let's double check it works for the front uh the title as well hello and then let's say submit we're saving that and then we have hello but let's also delete all of this as well as this to see if that gets updated or actually if we cancel it we're going to go back to what we had before which is perfect that's expected and the last thing I want to check is if I hit the edit button and I hit or I delete the entire title and I hit submit we're going to get an error actually we're not displaying the error for that one but if I hit submit it says this field is required we actually need to set the disk field as required for the top one because it's not showing so let's go to the title over here in our header and I believe we need to set up an error message over there and to do that right below the text area I'm going to say title error I'm going to say and with the P tag class name like so margin top of one text primary of 500 I'm going to say that this is going to be title error make sure we have that let's see if everything is set up correctly so let's save that and let me check if I hit edit and I empty it out and I try to submit the field is required so everything is working as expected so once you type the error goes away and we still can't submit because this one is not required so I'm going to refresh it now we have our original so perfect everything is working with our editor and our changing of the editor I know it's a little complicated because of us having to update not only our state but the state of the editor as well because sometimes for libraries you're going to have to update their state and you're going to have you know sometimes State conflicts with those issues but you have to handle those but once we have that now we can just focus on open Ai and making sure we have the chat GPT content generator all right so now with all the editing out of the way now let's actually focus on getting our AI generator so the first thing we're going to do is we're going to actually set up our backend route to create and call openai but before we do that let's actually go to open AI API so this is the location where you can go and grab platform openai.com and by the way gbt4 as of uh March 16 2023 GPT 3.5 is available but gpt4 is on a wait list so you can sign this up if you want to so you can go and grab this information but after you sign up you can go to your personal account go to manage account and you can see I've used it I've used the open AI open AI API quite a bit like a lot nothing where I'm doing like bulk type editing but for just developer purposes as you can see even with that many posts like I'm still using I've only used eight cents so far eight cents for entire March and then three cents for the next February and I've used it quite a bit I've generated a number of things now I wouldn't say I use it excessively but it's still pretty cheap at some point Microsoft is gonna crank up the pricing but for now it's been cheap as of right now so the way to do this is once you sign up you create your account you can log into your personal account and it's pretty easy to set up so here you can go to your API Keys you can create as many API Keys as long as you want I'm going to create a new secret key and by the way if you generate a new key you can never grab this again so you can just copy it and if you're never going to use the previous one you can just delete them and I will delete this one so no one can use it so I'm going to go to my code and I'm going to go down go to my DOT EnV and this is where I'm going to be adding my openai API key and the way I'm going to do this is I'm going to do open AI API underscore key and I'm going to paste my code I'm going to do this a little off screen and once I have that saved I'm going to change this dot emv.local2.local because that's going to be ignored which is perfect because that's what we want we don't want to push this up to our GitHub repo or else people will be able to access your API key so make sure you do that and then from here we can go to this particular npm package which is in the link description below open AI node you want to go to this link and we're going to be installing open Ai and we're going to be configuring it with this configuration so I'm going to go to my code go over here open up my terminal close this and then paste npmi open AI there's a node package it helps easily easily connect to open AI and what I'm going to do is I'm going to go over here I'm going to copy I'm going to copy everything so I'm going to copy everything over here and we're going to make some modifications and once I have that I'm going to go to API I'm going to create a new folder I'm going to call this open Ai and again this is going to be a route dot TS so again if you wanted to call this API route it would just be the base URL slash API slash open Ai and that's how you can reach this endpoint now over here I'm going to paste everything I had and this is actually going to be an import instead and we're going to grab this from open AI like so we have our configuration this is the open AI API key that we just installed we have our API key over here now this is going to be in our logic and so what we're going to do is we're going to do the same thing that we did before from post a uh post ID route so I'm going to copy all of this paste it over here we don't really need majority of this so we're just going to erase a lot of that we can keep most of this the same so let's import next response because that's what we're going to be using we're going to include request we don't need the params this time because there's no params for this but we're going to keep the request what we're going to do is we're going to grab the title and the roll the roll will represent what the user is going to play so that or not the user but the system the bot is going to pretend like it's something else or you can tell it to write something in a specific way so if you go to the playground on open AI you can check this if I click let's say if I click chat we have a system this is a helpful by default you are a helpful assistant but you can tell them to be like sarcastic you can tell them to be witty and you can send a message and the system will respond as if they're a witty person so it's kind of like you give them a specific persona anyways over here what we're going to do is I'm going to say await response or request.json like we did before and we're going to make our API call and the way we do this is we're going to be using this information so let's cut that out paste it over here I'm going to call this AI response and what we're doing is we're going to be using axios or like this inherently uses axios under the hood so we need to type it the proper way so we're going to axios response make sure we can import that from axios so we're going to import axios response from axios like that then we'll have the type over here and then we can say create chat completion response and this comes from open AI so that's the typing and we also want comma any so that's that's how you type this and then from here open AI create chat completion is what we want and when we do that we're going to get this syntax because it's going to be different and when we want to set this to GPT 3.5 Dash Turbo so now if you're doing this with 3.5 if GPT 4 comes out you can replace this with GPT 4 or the equivalent but for now we have 3.5 we're going to be using that we're going to say messages like so and we're going to have an array so over here we're going to start with the role of being user so now typically they tell you to put the role let's see if they have it here okay I don't think they have it here but typically you can start with the role of the system and tell it what to be like The Helpful assistant but I was reading GitHub discussion and it says that if you put the system after at the very end of the array it has a much more higher impact on the message that you get because a lot of your content can be replaced by this particular user and let me show you so let's say we create let's actually uh but template string we can say create small blog post with HTML tags based on this title colon dollar sign and we can pass in the title we get from the front end so essentially for this AI response we're going to send the title from the front end so AI is eating humans for knowledge we can send that to the back end and it'll create a small blog post with this so this is the content and the command that we're sending to the system and then off after here we can set the role to be a system like this and we want the content to be a template string and we're going to say roll and if there's no rule provided and it's possible that the user didn't provide a role we can just say I I am a helpful assistant and we're going to do Dot and I'm going to say right with HTML tags like so so this is essentially our system now like I said if you put this at the beginning this can overwrite some of the the role that you've set and it's like hit or miss sometimes but if you put it after it has a much more High likelihood that this is the system and the role that the bot will play when writing the blog article so it's actually pretty cool and I'll demonstrate all of this so over here what I want is going to be similar to what we have here so I'm going to say AI let's actually create an object over here I'm going to say content it's going to be AI response dot data dot choices zero Dot message question mark dot content like so I'm going to remove that and then we're going to be sending this to the front end and I'll show you all the things that we just did and demonstrate it on the front end so let's go back so we're going to go to post ID and we're going to go to our page and in here we're going to go to content inside our content we are going to go to our article section because that's where we're going to have all the AI generator logic so inside here the first thing I want to do is create the code for the AI generator you know the UI basically so we have the button and the role they can type so I'm going to say if it is editable we are going to say div class name and we're going to give it a border of 2 rounded MD BG white 50 P3 and B3 so I'm going to go through all the styling pretty quick just because it's not as important right now so we're going to do class name we're going to set M 0 p 0. and we're going to say generate AI content and on the next side I'm going to say P tag I'm going to say class name we're going to give it a margin of 1 on the top and bottom P0 text access and I say what type of writer do you want so it essentially asks like what type of like how do you want it to write and we're going to say div I'm going to say over here I'm going to say class name give it a flex gap of 5 with justify between over here and inside here I'm going to give it an input like so give it a class name and I'm actually going to copy all of this because it's going to be very similar we're just going to modify a few things we're going to give this PX to B3 py of one and we're going to give it a width of full instead of the margin bottom and I'm going to say placeholder and this is going to be the roll that the bot will play I'm going to say on change and we are going to change this so right now I'm just going to console.log e.target.value because we have not created the state for this but we are going to and I'm going to set this to be roll so I believe we can just add the role over here so we can have roll Set Roll is equal to use state oops that is not what I meant pass that in and this is going to be a string and we are going to start with I am a helpful assistant so that's the role it's going to play and then we change this to be set roll like so so we're going to have that and then after here we're going to have a button and we are going to say type button this is important or else it'll just refresh the page and we're going to say on click and we are just going to add the empty function for now and this will be the rocket launch icon so I'm going to import rocket launch icon from at hero icons like so and then we're going to paste it over here and I'm going to say class name with height of 8 width of eight text accent Orange hover of text white of 300. and I'm going to make sure I close that and I save it so now we have the button when it's editable so if I go over here and it seems like we don't see it just yet and that's because we haven't run the server so let's do that all right so with our server running let's open this up and we have this we have our button the button doesn't really do anything but we can write and type for now and what we want to do is we want to create a function that's going to call our back end and generate our AI content so let's go and do that so right below over here with this null check I'm going to say oops const post AI content I'm going to say async like so I'm going to say editor chain so this is part of Tip Tap and what we want to do is while it's loading the AI content we are going to set the AI content to be generating AI content please wait because it does take some time for AI or open AI to come back with the response so we want to make sure we have a loading State over here I'm going to save that on the next line I'm going to say response and we're going to do a weight fetch and I'm going to pass in process.enb.next public URL slash API slash open AI so that's the URL like we mentioned before and we're going to add an object over here we're going to say method is going to be post we're going to give the headers of content Dash type give it an application slash Json and then let's add a comma so body is going to be Json Dot stringify and we're going to pass in title like so as well as the roll over here there we go and then what we want to do is we want to grab the response that we get back and use Json to parse it and what we want to do is make sure we can copy editor chain Focus so again what this is doing is this is just setting up a chain to make it very convenient it's going to help us Focus to it and then we're going to do set content like so and we are going to essentially set the content to the information that we get from the back end and again we need to set the content to be data content so so the content in the in our state and the Tip Tap content needs to be aligned so that's why we need to do both over here we're going to copy the post AI content and I'm going to just paste that over here on the rocket launch button and so let's see let's make sure we don't have any errors something strange is going on over here but let's just refresh and let's just see let me replace this AI is eating humans for knowledge so that is something we have I am a sarcastic and witty individual I'm going to hit Dot and we're going to hit that button oh and it seems like we do seem to have an error so let's actually let's actually click it again to see open AI seems like we are not method is not allowed so it seems like I did not set the correct route so this is oh okay so I did not change this to post so this needs to be post by the way so make sure this is a post I'm going to save it over here I'm going to click this button again and we are going to see let's see and see what it responds with and there you go look at this we have our text well well it seems like the tables have turned human and humans have always prided themselves on being at the top of the food chain but it looks like AI has other ideas and so on and so forth as you can see this is a sarcastic and winning individual if you don't have this it's not going to do it's not going to speak in that specific way so let's actually flip this and I want to show you that it doesn't work as well if you have this information like this so I'm going to do it again let's just wait for this okay this one is pretty sarcastic but I can keep doing it and keep trying it I will have better response of the system is below it unless they change that maybe it changed maybe it's already better so anyways probably better to have it probably better to have it on the bottom but either way that's pretty cool right like for me I think with the what type of writer do you want and then you can have a specific role for that writing style it can give you a much more personalized response for writing this particular article and after I have that information I can submit it and then I can save it and our information will be persisted on the the back end as well so I go back here I can go to this content and we already see that our article has persisted in our database and with that pretty much our entire website is fully complete we have open AI for editing right here we have all our entire posts one thing I want to mention is that when we use versel there is a time limit of how long the API can respond in and that's five seconds so open AI takes a considerable amount of time so it times out so unfortunately when we deploy it on versel which we will do for free we cannot have a small blog post that's why I have a shorter content and what I'm going to do is I create three Line blog post instead and this will shorten the time it responds otherwise it will you know have other problems and it seems like AI is really taking over I don't know why the image just became huge so let me double check what's happening yeah I don't know why I did that it seems like AI is really taking over um but yeah so we want to make sure we keep a three-line blog post to reduce the time and response it's unfortunate but we kind of have to do it if we want to keep things free when we deploy our application I just want to Note One Thing by the way is that with this you can do revalidation we can do if we add response over here this I'm going to just do any for now I just wanted to show you this we can do revalidate slash API slash posts so now if you see this you can see this as revalidating the list of posts so anytime I update people who are on the post page like the list of post they will get an updated version of all the posts that they're seeing and this is called On Demand revalidation so if you want to take a look at that you can have that information and then fortunately because versel has that time limit this is not going to work so we're going to comment that out and we just want to make sure that we know what this is for so I'm just going to save that so the next and final thing that we want to talk about is parallel routes and interceptions so this is a nexjs 13.3 feature that we are going to talk about so parallel routes allow you to render one or more pages in the same view or you can have it conditionally rendered depending on what your use case is now the idea is like why would you need this because you could just create a component that if someone clicks a button you can create a state so it changes to a different page on the same view however the problem with that is even if you change the page on the same view you would still be on the same URL which is a problem so in this case you can make it so you have parallel routes so you add user and at team or on the same page so for example at user and at Team could be on the same page but you can conditionally render it based on this type of logic so all you have to do is if user type is user then we would show them the user page right here otherwise we can show them the team page so this will actually navigate to different URLs so we can render them on the same view independently so we can have different Logics and we can render them based on what we need so to give you an example of this if we go to our app again and we could go to post ID we have our page and we have our content with our sidebar if we wanted to separate this for example into two different pages and have different conditional logic we can do something like this so instead of this content component we can just do at content like this and then go page dot TSX and by the way you don't have to copy this this is just for demonstration we're not going to use it because we don't need to so we're going to keep it like this so we're going to say at sidebar a new file we can say page.tsx and what we would do in this case instead of rendering out comment or content like so what we have to do is we create a new file we call it layout TSX and then you create a component where you can render it out based on children user and team so instead of user we would say content and then sidebar so that's how we can render those two pages as separate URLs if we want to and let's delete the layout as well and the final thing is about intercepting routes so intercepting routes is a way if you have some kind of image in our next JS app we have that image if we want a user to be able to click on it and that new image would take them to a modal but we want a new URL for that modal because we want to be able to share it with other people this will exactly solve your problem and the way you do this is you write add modal and then you would refer it to basically the relative path to where your photo actually exists so you would create a separate photo ID page just like this you would see here and we would do that for our particular article we can do that we can reference it and we can say this is at modal and that would give us a separate intercepted route or basically a route that we can share with other users but this also allows so if we go to this particular model we can still hit the back button and we're going to be taken to this page so it solves a very Niche problem that if you have like an image that you want to click on you can make it shared with other people now we're not going to do this but or we don't really need it and finally real quick we have a few things that I want to talk about static export for app rather so basically if you go to your config.js you can just set the output the export so that just means it'll automatically generate HTML file for every route so if you just want a strict single page app with individual HTML files we can just do this and it'll be basically a static entirely static site that you can use and upload it anywhere else so it's very a lot of times you're probably not going to use it because you want to use next year's applications but if you go to next config you can put output over here instead and then set it to export and then you'll be able to do that then you just do next build and it'll generate an ATM file file and now a link in the description there's like other improvements there but they're very minor so if you have a link right here the main thing you can probably take a look is Tailwind CSS for create next app so we didn't particularly do this but instead of setting up Tailwind like we did before we can just do npx create next app at latest and you can just do dash dash tailwind and it'll automatically set up most of Tailwinds so now I wasn't able to do this because this happened after I recorded a lot of this but if you want to try it you can do that you still need to configure things like next year yes font and line clamp and some of those things but this will make it a little bit easier and one thing one final thing about next year is 13.3 is that a lot of these are going to be Niche cases maybe parallel routes or maybe intercepted routes you might use but a lot of them are still very Niche use cases the cool thing about next year is 13.3 they finally said that they are approaching a very stable build so now with all of these updates you can pretty much do Nexus 13 with some sense of hope of stability so they don't change any updates that are going to be problematic so this version starting to be one where you can maybe start using it for your applications maybe not yet but very close to it all right so before we deploy our application since we have everything set up now I'm gonna make sure this is closed we want to go I'm going to close everything over here I'm going to create a new file I'm going to call this dot e and B dot production so now I don't know if there is a better way to do this but this is the best way I can possibly do it so our base URL is named next public URL so this is what we are calling so this is basically our next public URL and as we've seen before we have set this to http localhost 3000. now when we deploy it it's obviously not going to be at localhost 3000 what we need to do is we're going to have to change it to whatever URL that exists on versa so we are essentially calling the domain where we are deploying it and we're calling an API call to itself so we are calling the back end that exists at the same domain name what happens is though the domain name only exists when you deploy your application so you have to have a way of calling it calling the domain name even though the domain name might not exist so the way to do this is we're going to set next public URL and we're going to set https colon slash and we're going to set next public versus Cell URL so this is by default a versl URL is coming from like they have a system environment variable on their cell that will allow us to call the domain name and we also need to do https or else it wouldn't work so this is a way for us to provide versel the proper information to call itself and we can deploy this one on our GitHub because this is okay this is um this is not private information so we can just deploy this push it up to GitHub and we're okay so I'm going to save that all right from here now I'm going to go to GitHub I'm going to create a new repository I'm just going to call this next AI next AI blog app and I'm just going to keep it private for now and I will make this public when this video goes up so I'm going to create the Repository and over here we can follow these instructions but a little bit modified so I'm going to do get a knit and they re-initialize existing git Repository and then I'm going to do git add all git commit Dash M first commit and then we're going to do git push origin Main like so and actually it seems like I messed up so I need to do git remote add origin right like this first and then we can do git push origin make all right once that's completed I'm going to refresh my GitHub page just to make sure everything's there so we have dot EMV production we have dot vs code I think these are okay you can keep the settings public yeah that's that's fine too so a lot of this is perfectly fine just wanted to make sure our git ignore is correctly set so we have all of this information now we can go to versaille let's go to recelle.com and you want to make an account make an account is by default normal so we're going to do add new project so if you take a look you can you might see something a little different because it might be your first time setting this up if not you're going to have to do a just GitHub app permission so I'm going to add and add and import the GitHub repo I just created so once you have added the permission for your GitHub you want to do import for the one that you're wanting so I have this next I have block but I want this app one right now so I'm going to import that one so over here we're going to configure our project so build an output we can keep it the same because this is all the default next configuration we can go to the environment variables as well and then we can modify our database URLs and stuff so from before we have database URL in our DOT EMV file and we want to copy and then paste it over here so I'm going to paste that and we are going to change this SSL cert to be slightly different what we need we can change right here right here to be slash Etc slash p k i slash TLS slash certs slash CA Dash bundle dot CRT now this is fine for Mac I think this is different for but if you have any issues you can look at the links in the description below about these issues about SSL cert and you might need the proper one depending on your OS and I have a bunch of links in the description if you can try and see what which ones those work because I'm a little confused on where I'm supposed to find those information so I'm going to add that I'm also going to add open AI API underscore key I'm going to do this off screen to copy and paste it and once you have those pasted I'm going to hit deploy all right with enough luck hopefully you have deployed your project to yourself so let's actually see if everything's working as expected and we see our website oh that's great so if I go over here let's just make sure all our Network calls are basically working I'm just going to go all we have everything coming in we can go to this and it's loading and we can see our information as expected we can do edit we can add this let's say I am sarcastic I'm just going to do that and I'm going to hit that button let's just make sure our open AI icon or open I AI is working I'm just going to wait for it and as you can see we have this information we can hit submit and it saves it and we have our complete versel next.js App working now if you have any issues with deployment and some of the certs please go to my Discord because I have and Discord Channel dedicated to each app so you want to go there you can go and talk in that discussion because I know some people might have a lot of issues overall throughout especially something like this next year s13 is very new there might be a lot of problems you might have different OS different versionings it's hard for me to know what all those problems are so we can go you can go into that Discord discussion and you will be able to figure out what problems you might have or ask a question maybe I can help you out as well too and there you have it we've covered next js13 and we've covered the most recent features and the recent updates with 13 next.js 13.2 versioning we have all the routes we have you're using the app directory we are using image components we are using server components we are using Prisma along with it we are using typescript as well we are setting up our routes we are even using open Ai and using chat gbt to create our content in this blog style complete application now I hope you learned a lot from this because this was quite the challenge even for me there is a lot to nextjs and a lot to learn now hopefully you take something away and you can like comment and subscribe and be sure to check out my Discord I always have a discussion for each application now so if you go there you can ask questions if you have any kind of trouble hope you enjoyed I will see you next time
Info
Channel: EdRoh
Views: 30,438
Rating: undefined out of 5
Keywords: EdRoh, react, next js 13, tailwind, tiptap, blog, build an app
Id: pfHjxyeCHRs
Channel Id: undefined
Length: 313min 47sec (18827 seconds)
Published: Mon Apr 17 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.