Build A Twitter Sidebar using Next.js 14, React, shadcn/ui, and Tailwind CSS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey there everybody welcome back to another video and in this video let's build a sidebar in NEX js14 so this is how the sidebar is going to look like um it's the exact same one as Twitter has and if I show you the Twitter one this is how it looks this is how it works and our sidebar this is how it looks and works now we are using Shar CN UI for this you're using nextjs 14 with the app router of course and I think it's a really good example to show something that already exists and then you can expand upon this sidebar to make it your own so let's get started with this all right so very first of all what I'm going to do is I'm going to create a new nextjs project and I'm going to use pnpm you can use npm or yarn if you want to so I'll just go ahead and say pnpm um DLX create next app and I'm going to use dot because I'm going I I want this directory itself you want to use typescript yes yes L yes Tailwind yes SRC directory let's go with yes app router yes and change the default LS no now while that's getting installed I will go ahead and set up shat CN UI as well so let's go installation nextjs and we already did this let's go ahead and copy this command all right so once this is done let's go ahead and paste this for initialization of Shad CN UI now I'm doing all this speed run because I I hope you already know what shat CN UI is if you don't just go ahead check their website it's really nice it's just a component library that you don't have to install right instead of putting everything inside of the node modules folder it installs the components locally sort of so let's go ahead and set that up default and we'll select the theme anyone it doesn't matter for now let's go CSS variables yes and let's go over to themes over here on this tab themes and you can choose any theme you want any color you want because we are building something like Twitter I chose the blue color and I customized um the radius to be one right so that makes sense what you can do is you can just copy all this code let's copy it and once this initialization is done let's open it up in nvs code here it is and let's go ahead and change the theme that we just installed so if I go to Source app global. CSS over here what we can do is we can just go ahead and modify all of these except the the bottom one bottom one we can paste the code that we copied from Shad CN UI and one thing that I would like to change here is this radius that you see radius is one REM we chose one REM we did not have other options but I'm going to keep it two REM because that's what suits Twitter more okay so once we are done with this set up let's go ahead and run the app to see how it looks like so I'm just going to open up the terminal over here let me expand this let's do a pnpm Dev running the pnpm dev our app starts up let's close that tab that we had earlier and let's go to shat CNU homepage all right this is how it looks like very basic does not matter because we are going to take all of this out anyways so coming back over here let's close this let's go inside of page. TSX and we don't really want any of this so let's collapse this let's take this out all we need in this page. TSX is a dip and let's add an H1 called homepage and over here let's just add some class name like text 3XL and font semibold right hit save let's get rid of this import now we see homepage one more thing that I would like to change is go inside of the layout file and go to the HTML and set a class name to Doc just Doc and what that will do is that will tell Tailwind CSS and Shard CN UI to use the dark mode we go back you see we got homepage and everything is in dark mode of course now let's start working on the sidebar itself so for the sidebar we need a couple of components from shat cnii that we have to get and I have made a list of all these components so what I'm going to do is just show you how it actually works and let's see if I were to let's say I want the button component all I have to do is run this command and that's going to install the butt component in my project not in the node modules in my project and that gives us the ability to customize it and whatnot so going over to our project again if I open up the terminal a new terminal and all I'm going to do is I'm going to run pnpm DLX Shad CN UI add and we're going to add a bunch of components so let's start with Avatar uh Avatar we need the button we need pop over and we also need the separator now there are other components that we need but that's for the responsive version that we are going to work on in the next video so in the next video I'm going to show you how to make this same sidebar but responsive on mobile it will show sort of a drawer and on desktop it will be a static fixed sidebar so let's first off all go ahead and just install or sorry add all these components now they will be added inside the components folder um there will be a UI folder created all right so you see component UI we've got Avatar now let's go inside the components folder itself not the UI folder make sure not the UI and going inside of the components I'm going to create a sidebar Das desktop. TSX file this will essentially be just our sidebar so I'll just say export function sidebar desktop oops sidebar desktop that's going to return some jsx so we are going to return an aside tag because it's a sidebar then we need an aside tag and let's give some classes to the aside tag I'll just go ahead and say class name the width is going to be a fixed width then I'll just give it like 270 pixels which is sort of a Convention of width for the sidebar then we're going to give it a Max width of XS so it will not exceed this Max width which is 320 pixels then we're going to set the height to screen which is of course full height we need it to be fixed so position fixed so that it stays on the left hand side and for that we set the left to zero and top to zero and then let's add a z index of 40 and yeah that's it let's also add a border right so it adds some level of separation between the sidebar and the non sidebar content once that is done let's create another div and in here let's just set the height to full the padding X to three and the padding y to four this will basically hold all of our content ins inside of the sidebar so that's why we're giving it the padding then let's add an H3 tag and in this H3 I'm just going to give it a few Styles first this is going to hold a margin X of three a text of large font of semi bold and text foreground so it will give it a foreground color that is built into shat CN UI and we're just going to call it let's just say it's going to be Twitter right fairly straightforward we go back we see nothing of course because we made this component but we are not using it anywhere so let's go over here in the layout file not in the page right we're using it in the layout because we want it to be uh on each and every page so coming into the layout in the body tag what I'm going to do is go ahead and create a main tag like wrap the children in the main tag let's do that so we just wrap the children in the main tag and just right before the main tag I can add the sidebar desktop component like so that is imported from components sidebar desktop when we go back we see this is how the sidebar looks like now this is the page content that is right below the sidebar we can see it because the sidebar does not have any background color we can still see it but if I try to select it we cannot select the page content right now what we can do in that case is go to the main tag over here and we can add some margin so right over here you see we added width of 270 pixels we can similarly go ahead and say instead of width is going to be margin left of instead of 270 pixels let's say 280 pixels hit save you see this is a little bit more far from the sidebar now this is 10 pixels far I like to keep it let's say 300 maybe uh with trial and error you can choose a value that you want also there is no margin on the top so I can add either add it here so let's just add it here margin top of three maybe that that makes the content a little bit better all right so we have this heading now let's work on the other links so going back to the side by desktop let's go right after this H3 and I'm going to add a div a div and I'll set the I'll set some margin top of five so that it's a little bit far away from the div oh sorry from the H3 then let's add another div that will hold all the links that we add uh that we add it's going to be Flex Flex column it's going to have a gap of one and a width of w and here's where we're going to add some links now the Links that we are going to add are going to come from a different component so I am going to create a reusable component called uh called sidebar button so let's go over here in the components again let's create a sidebar dasb button. TSX over here we're going to export function sidebar button that is going to to return to us um sorry that's going to return a button component that you see this comes from UI button this is basically the button by Shad CN UI that we recently installed all right so this button we use this same button over here but we apply some styles to it by default all right so by default all of these sidebar buttons are going to have a variant of ghost and then they're also going to have a class name of Gap 2 because this these buttons are already Flex box so we are going to add an icon so let's say there is a sun icon I'll just say sun and let's just say any text dark mode for example right inside of the span tag so we have gap of two which basically add some gap between the Inner Elements let's go ahead and use it for real I'll just say sidebar button like so nothing fancy go back you see this is how it looks like it looks perfect but first off we don't want the text to to be centered we want it on the left hand side and uh because we are going to reuse this component again and again we want it to be dynamic so that I don't want the same content again and again let's go back to the button and let's accept some props but yeah before accepting the props let's make this go to the left and for that what we can do is we can just add justify start which is a tailin class and you see now they are on the left hand side all right so now coming to the props what we can do is we can create an interface called sidebar button props now if you are not using typescript then you can skip this part of interface because interfaces are not part of JavaScript they are a typescript thing so what you can do is you can just skip this part and move along now these sidebar button props what we're going to do is we're going to take in one prop specifically which is going to be the icon and that's going to be of type loose side icon now because we are using you know icons from lcde react we have a type provided by lucide itself where you can use the lucide icon type to just tell typescript that hey this is going to be a Sun or a moon whatever whatever icon lose site provides from this big list so we are going to accept the loose side icon props and we're going to also make it optional so that if we don't want an icon in the button that's possible as well now let's go ahead and destructure the props so what we want is sidebar button props again if you are using typescript then only do this part else you can just skip to the restructuring thing and we got the icon now how about we use this icon well in loose side what we can do is we can just use the icon like this inside of jsx but this does not work because this is lowercase we have to make it uppercase somehow so what you can do is in JavaScript you can just add a colon right in in an object you can add a colon and you can say well hey I want it to be be icon with an uppercase i now so now this icon is gone but this icon exists so we can just use it like this now typescript throws as an error because this is also optional so it can also be undefined what we can do in that case is just say well hey if icon exists only then show or render the icon like this and let's get rid of this so if the user passes in this prop called icon we then rename it to icon with an uppercase i and if that exist only then we show this component all right so once we got this icon done now let's accept the other props I don't want only the icon prop what if I want to customize the button from outside the component so when I use this button over here I want to customize it as well in that case what I can do is I can accept more props right all of the all of the props that this button takes and I can do that using the extend keyword so we can extend this this sidebar button props we can extend it with the button props now we import the button props from the same place we import the button from now this this is again a typescript thing if you're using JavaScript skip this part so we got the button props and what we can do is we can get the rest of the props like this with the rest operator now this is basically an object with all of these props that a button accepts basically this this interface that we see and what we can do is we can just go ahead and say well hey spread out these props in the button itself all right so if now I pass in a variant let's go over here and I'm just going to say variant you see we get autocomplete as well this variant for example is going to be outline hit save we go back you see this one is outline if you cannot see it I set it to default and now you see this is the default variant so that way you can also customize the button from outside but one problem is that if I say pass in a class name which is let's say margin X of two that overrides the original class name so so this original class name is now overridden by this class name we can easily fix that by simply taking out the class name so let's take out the class name from this props so now the class name is no longer part of this props object and what we can do is we can manually append this class name to here we can do that by just passing in an object and we can say CN which is a helper function from Shad CN so right over here it cannot find it let's add this import so this is basically a helper function that helps us merge all the Tailwind classes so we can import this function we can use it and we can pass in a number of classes that we want which is in here this prop that we are getting so we can just add this class name prop and that does the job you see we have some margin but the original class name is also there coming back let's let's take this out now let's work on this text so this text Will basically be the children of the button what we can do in that case is again we can take out the children from these props and we can just set it like so children in here it say you see there is nothing in our button because we did not pass in anything so let's just go ahead and add some children I'm going to take out these two buttons for now let's just say this sidebar button will have a children of home right the text of home and let's also add an icon of home and this home comes from Lo side react hit save go back you see this is how the home looks like one change that I would like to make is if we go back to the sidebar button this icon actually want the size of this icon to be 20 so that the icon is a little bit close to the text in terms of sizing okay now that's our sidebar button component we don't want this input let's get rid of it and now we can reuse this button so let's say home let's say we want an about and you can add an icon or you can skip an icon and let's get rid of this you see we got the about button now I don't want to repeat this button again and again so what I can do is I can accept a prop from here as well so let's just go ahead and create an interface sidebar sidebar desktop props and in here we're going to take in sidebar items now this sidebar items is going to be like this sidebar items this type and this is a custom type that we are going to create so let's go ahead and in the root right in the SRC folder I'm going to create a types. TS file and I'm going to export an interface called sidebar items and this interface is going to include first of all it's going to include links which will be an array which will be an array of objects so we can do we can make it something like this it will include a label which will be of type string it will include an href which will be of type string and it will option Al include an icon so let's make it optional that will be loose side icon so basically the almost the same thing as we had in the props almost the same thing so we got the icon and basically this is where we're going to pass in the links let's go over here and let's import this from types and now let's go ahead and use it so we got props props are going to be sidebar desktop props something like this and let's go ahead and use it over here in the layout so say sidebar items is going to be an object that we just set the type this is an object includes links so let's go ahead and set links is we already got some autoc complete perfect so the icon is going to be home but not like this let's just say home like this and actually you know what I'm just going to comment this out for now let's just keep this part hit save and let's go in the sidebar desktop where we actually receive these props and all I'm going to do is just so let's go ahead and use these props so we can say props do sidebar items. links. map and for each link link we also get the index and the link itself and we can just use the sidebar button component with the key of index now this is not usually recommended but we can use it for now the key is index and the icon is we can just go ahead and say link do I like this and let's just go ahead and say link. label all right now this is not a link this is still just a button but we are going to make it a link don't worry about that going back we see just this about now to make it a link all we can do is we can wrap this inside the link component that comes from next SL link so let's import that let's make it like this and because link is now the parent element let's take this key out and let's pass it in here and we on the href which is link. hre hit save go back now this is a clickable link as well but it's not full width so what we can do is we can just go ahead and go to the sidebar button and let's add a class name of width full hit save go back you see it's now full width perfect now let me show you what happens if I were to add an icon over here so let's let's get rid of this one and let's just add this home so label is home perfect H is Slash and the icon is home and this home comes from lde react now if I were to hit save go back to the app this works just fine what so right now it works perfectly fine if you look at this we get the icon but it works fine because our sidebar if you look closely it's not a client component it's a server component in nexts we have client components that are hydrated on the client side there are somewhat rendered on the server side and all that stuff but basically this is a server component this component will be rendered on the server on build time so there is nothing client side related so let's do it right now if I'm going to make it a client component by just adding use client at the top of the file you'll notice something weird I'll hit save and we go back you see we get an error functions cannot be passed directly to client components unless you explicitly expose it by marking it with use server what does this mean this basically means that in the layout you see layout is a server component right and this sidebar desktop is a client component what next just tells to us is that you cannot pass in functions to a client component from a server component but if you look closely we are not passing in an function we just have this object that contains an array that contains another object if you look closely we have a function which is this icon home home right over here is a functional component right it's not just an SVG it's a a component and in the end it is a function so we cannot just pass in home like this I mean practically we can but nexts won't allow us to do that for that comes a little weird hack what you can do is you can create a sidebar. TSX so basically a component right and we mark this as your client and we say export function sidebar and all it's going to do is just return the sidebar desktop component like so basically this same thing so let's cut this out and let's paste it over here and let's import home from blue side react so all we are doing over here is keeping the layout of server component still while we are making this sidebar component as a client component all right so let's just use this sidebar right sidebar like this and let's get rid of this home let's get rid of sidebar desktop now let's see what we did all I did was just take this sidebar desktop component and move it into another client component all right layout is a server component by default so we make another component which is a client component and we pass in the home icon through that and what that allows us to do is just use this as a client component so now we are not passing in a function from server component to another client component but all we are doing is passing in a function which is the home icon from a client component to another client component if all of this is confusing don't worry about it just use a client component like this just use this way and try to understanding by analyzing the code and trial and error stuff now let's go ahead and create instead of passing it in directly over here I'm going to create another separate object so let's copy this go back over here I'm going to say const sidebar items is going to be of this is going to be this value and we can just use the type of sidebar items right so this type comes from the types that we created and what we can do is we can just pass in this sidebar items like so hit save and we have links which is the home we go back this works perfectly fine let's add some more links all right so let's go ahead and uh expand this a little bit and I'm going to copy this and paste it again let's copy and paste it similar to Twitter we can make a notifications we got notifications the h is going to be item SL notifications this is basically going to be a page that we're going to make later on and then we have the Bell icon for this one so let's get Bell hit save go back it looks perfectly fine let's add the other ones so the other ones are messages and let me just paste out the other ones so we got lists which is which uses the list component uh sorry list icon then we got bookmarks which uses the bookmark icon we got communities which uses the users icon and we got the profile which uses the user icon as simple as that hit save and go back this is how it looks like perfectly fine and we had another and we had another button over here which was not a link so if you look at all of these all of these are links now all of these are perfectly fine but on Twitter you see we have this and this so we have two more sort of buttons that we want but they're not links all of them all of these are links but these two are not exactly links so in that case what we can do is we can go back to the sidebar items interface that I created and we can say extras so let's add extras which will be an optional um item I should say it will be a react node so all we are going to do is we're going to render out the extras like anything else so let's go back to the sidebar and let's collapse all these links and we can say extras is going to be a let's just say it's going to be a at div like so and in this div we are going to add the sidebar sidebar button which will have an icon of more horizontal it will have a class name of WID P yes it's going to be called more and and I guess that's it so let's close this up now we go back you see we don't get anything because we have to use this so let's go back into the sidebar desktop where we are actually getting the sidebar items so coming back over here what we can do is right after this we can just say props do sidebar items. extras this might not be the perfect approach this might not be the perfect API design but for this demo I thought this is the right way let's go back you see more is here and it's not a link all of these are links if you hover over them you know it's a link but this is not a link finally let's also add the other button that we had so let's copy and paste this sidebar button and this will not hold an icon and let's just say it's going to be tweak go back this is what it looks like let's make it proper like a tweet button for that first off we don't want it to be justify start right if you remember we added justify start to this sidebar button we can modify it over here so we can say justify Center that adds the text to the center and now we want it to have a blue background color and for that we can just modify the variant so variant is going to be the default one go back you see this is it looks like everything is very sticky right now you see Everything is Everything sticks to each other except for these links and that's why we can go inside of this div let's add a class name of flex Flex column sorry Flex column and a gap of two for example and now there is some gap between these two things also we want the text color to be white so we can go right over here in the button itself and we can say text white and this is it looks like okay now finally when all of this is done we can actually collapse this whole sidebar items and let's go to the sidebar desktop itself because here what we want now is is a pop over like this one all right so this one I showed you in the demo we want to pop over like this one what we can do now is go outside of this one so let's go outside of this div where we contain all of these links and Extras we can go over here we can make another div now this div is going to be positioned absolute with a left of zero a bottom of three so it's it goes to the bottom and a little bit upwards from the bottom we can set the width to full and a padding X of three let's add some content I'll just say content nothing nothing fancy go back over here you see it's at the bottom perfect now let's add a separator so this separator comes from UI separator let's import it and the separator is going to be of position absolute as well with a minus top of three now what this means it's going to have a top of minus 3 which is min - 12 pixels so it's going to move a little bit up instead of moving a little bit down then we got a left of zero and we say width of P it save you see we get a line over here now let's use the pop over by shad and UI so we've got pop over and let's say pop over trigger and this will be let just go ahead and add a button a normal button component this will be of a v this let's set the variant to Ghost and let's set the class name to with full and justify start which is almost justify start this is almost the same as the sidebar button but I want to use a noble button over here then let's just add the Avatar component we got Avatar let's set a width and height for this one so class name there will be height of five width of five we can set the Avatar image which will have n SRC of HPS github.com Max dprogram PNG which basically points to my profile picture then we can use the Avatar fallback so if there is no Avatar then we just go ahead and say Max programming like so and let's go right below the Avatar let's add a span tag with a name so I'll just say Max programming again this is different this is different and we go back we see this is how it looks like not so good so let's make it better and we can do that by simply wrapping this inside of a div all of this and we can add some Flex box so let's say flex and a gap of two maybe now now it has a gap in between now let's add the three dots icon over here we can do that by adding another div let's just wrap everything inside another div and in this div just right after our image and name we can set more horizontal so this icon we can set the size to be 20 hit save go back this is how it looks like let's make it better and in this div I'm just going to set Flex with a justify between so there is some space in between like they are far away let's set the items Center and let's hit save let's take a look this is how it looks like but it's still not full width so we can set the width to full that does not work either because this pop over trigger has the width so what we can do is go ahead and let's set this to as child what this does is it sets the button as the main element right so this basically this as child prop moves the button over here something like that all right you see now it's full width perfect let's add a pop over let's add the popover content now which is like this let's go outside of the trigger let's say pop over content let's add a div and a link component and in this link I'll add a sidebar button with a text of account settings and all this is going to do is HF is going to be slash for now the size of this is going to be SM which is small the icon will be settings like this that comes from L side react and let's say the class name with full let's do the same thing with another button copy let's go right outside this link and I'll paste it over here because we don't want this other one to be a link let's just set it to log out this will be a normal button with everything and yeah this is going to be log out icon just like that hit save go back when you click open it this is how it looks like looks fine but let's make some adjustments so we can go over to the pop over content let's say class name is going to be margin bot bom of two so it moves a little bit upwards we got width of 56 we can say padding of three and let's set the rounded will be just one R hit save go back this is what it looks like but everything is sticky so let's go to the div let's set a class name of space y1 hit save and you see now both of them look perfectly fine now that's it with the sidebar let's add Final Touch by adding all these pages so we can quickly do that in nextjs what I'm going to do is inside the app directory I'm going to create an item folder in here I'm going to create another folder and I'm going to call this item like this inside of square brackets I'll explain why and then I will add a page. TSX so all this is is a dynamic route so we can say item SL anything we want and let's just say export default function item sorry item page return return a div let's go back to the previous page. TSX let's copy this return this and I'll I'll just call this item page and a P tag with a lot of lurm ipsum hit save now go back if I were to click on notifications and you'll see we get the item page perfect if I go to list we get the same page now what I want is just a different name on this one and for that we get over here in the props we get param all right what we can do is we can just go ahead and say we want params do item so basically this corresponds to the name of this folder in the square brackets all right hit save go back you see we get profile page we get let refresh ones so you get notifications messages you get a dynamic page like so we can just add capitalize over here as a Tailwind class that will capitalize the first word of all of these all of the words inside of this string finally let's just use typescript over here so I'll just go ahead and say well hey it will have params which will include which will be an object with item of type string that removes our type error and now we are good to go and finally let's add the active highlight for example so if I were to be on a link I want it to be highlighted what we can do in that case is we can just go ahead and say const path name is equal to use path name we get the path name from next navigation right over here next / navigation so we get the current path name and over here what we can do is go to the sidebar button we can say hey what I want is the variant to be different right so if the path name if the path name is equal to the link. hre so if the path name above is the same thing as the link right over here I want it to be I want it to be secondary right which is which looks like the hover effect and otherwise I want it to be ghost it's save go back you see messages is highlighted notifications is highlighted home is highlighted as simple as that I hope this video helped you out it was a little long video but I hope this was insightful in the next video we are going to make a responsive version of this same sidebar because currently if you were to go ahead and view in the responsive version it looks terrible it looks like this on mobile version so we're going to make a responsive version of this sidebar which will be a hamburger menu and all that stuff stay tuned for that if you have any questions anything let me know in the comments below suggest me what else would you like to see in upcoming videos and finally thanks for [Music] watching
Info
Channel: Max Programming
Views: 3,595
Rating: undefined out of 5
Keywords: javascript, typescript, react, js, web development, node js, nodejs, javascript tutorial, javascript course, learn javascript, web development full course, web development course, web development roadmap, next js, next js tutorial, next js project, next js 14, shadcn ui, shadcn ui nextjs, shadcn ui react, nextjs shadcn ui, tailwind css, javascript mastery, tailwind nextjs, tailwind nextjs 13, tailwind next js sidebar, sidebar shadcn, sidebar shadcn ui, nextjs shadcn sidebar
Id: -vD8DAEEEWE
Channel Id: undefined
Length: 36min 56sec (2216 seconds)
Published: Wed Feb 28 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.