
No Comments Yet
Be the first to share your thoughts and start the conversation.
Be the first to share your thoughts and start the conversation.
Complete source code available till this point of lesson is available at
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
In this lesson, we focus on building a right sidebar for a web application using Next.js, highlighting various coding techniques and components necessary for implementation. The right sidebar is designed to be responsive and display popular questions and tags pertinent to user queries.
rightSidebar.tsx
and imported it into the main application layout.tagCard
component to display popular tags, incorporating properties for dynamic rendering based on user input.00:00:02 To start creating the right sidebar, I've put my browser right here to the right side, still expanded, and I have my code editor on the left,
00:00:09 so we can see the changes that we make on our right sidebar.
00:00:12 Now, let's head over to components, navigation, and create a new component called rightSidebar.tsx.
00:00:22 Run RAFCE right inside of it, and let's import it within our app, root, layout.
00:00:32 We want to add it right here below the section, so we have the left sidebar on the left side, and we have the right sidebar right here at the right side
00:00:40 of the section where we have our children, which is the primary part of our page.
00:00:44 Once you do that, you won't be able to see it yet because the navbar is hiding it.
00:00:49 So let's style it a bit by turning this div into a section.
00:00:54 Within it, we'll render another div.
00:00:56 And then within that div, we'll render an h3 that'll say top questions.
00:01:02 Because in the right sidebar, we want to show the top questions people are asking.
00:01:06 Next, let's give it a class name equal to h3-bold and text-dark200 underscore light 900. There's no dash before 200 right here.
00:01:19 And we still cannot see those top questions.
00:01:22 So let's style the section so we can actually see it by giving it a padding top of 36, and you can see now it dropped down.
00:01:31 Let's also give it a custom scroll bar so we don't show that ugly scroll bar.
00:01:37 We can give it a background light 900, underscore dark 200, a light-border property, sticky, specifically positioning it to the right side,
00:01:52 zero, and top side, zero, flex, h-screen, so it takes the full height of the screen, w-350 pixels for the width to give it some space,
00:02:03 flex-col, gap of six in between the elements, overflow, Y-Auto, same thing as in our left sidebar.
00:02:13 With a border of L for left side.
00:02:17 A padding of 6 to give it some breathing room.
00:02:21 Shadow of light 300. On dark mode, Shadow-None.
00:02:28 And on Mac's extra-large devices, it'll be hidden.
00:02:32 So this is for tablet devices, because we don't actually have enough space to show it.
00:02:37 So check this out.
00:02:38 If I go here and I collapse, notice how as soon as we start losing space for the main content, we're gonna actually collapse the right sidebar.
00:02:47 So in this case, we're not only making this mobile responsive, we're making it fully tablet responsive as well.
00:02:53 Now, let's go below this H3 and create a div.
00:02:56 We can expand our editor just a bit more.
00:02:59 And this div will act as the container for our top questions.
00:03:04 So let's give it a class name equal to margin top of 7 to divide it a bit from the top questions header, flex, w-full, flex-col,
00:03:16 and gap of 30 pixels in between the elements.
00:03:19 Within it, we want to actually map over some of the hot questions that we have.
00:03:24 So let's quickly generate a few.
00:03:27 I'll create a new object at the top, and I'll name it HotQuestions.
00:03:32 You can name it TopQuestions as well.
00:03:34 And it's going to be a series of objects with an underscore ID property, which is going to be a string of 1, and a title.
00:03:43 Like, we can say maybe, how to create a custom hook in React.
00:03:47 There we go.
00:03:47 That's something that GitHub Copilot was wondering.
00:03:50 And you can repeat this.
00:03:52 Like, again, you can see how nicely it's offering me these autocompletions.
00:03:57 How to use React Query, how to use Redux, how to use React Router.
00:04:01 And let's add one more.
00:04:02 That's going to be something like, how to use React Context.
00:04:06 Okay, it's all React-related for Copilot.
00:04:09 So now that we have these hot questions, we can actually map over them within this div by saying hot questions.
00:04:17 dot map, and for each one of these questions, we can automatically return a link because each one of these questions will actually be clickable and it'll
00:04:29 point to the details page of that question.
00:04:32 So let's say href is equal to forward slash question, forward slash question dot underscore ID.
00:04:41 And in this case, we can also just destructure this ID as well as the title from the question.
00:04:48 So we don't have to repeat ourselves.
00:04:50 So now what you can do is just say question forward slash underscore ID.
00:04:55 But Adrian.
00:04:56 Didn't you tell me that we're gonna use the routes constants, like these ones right here?
00:05:01 And if we're gonna use them, how are we gonna actually use them with a dynamic route like this, that accepts an ID?
00:05:08 Well, check this out.
00:05:09 We can go over to Routes and create a new route for the profile.
00:05:13 Since a profile is a dynamic route and is dynamic based on the parameter of id, which is of a type string, we can now dynamically form a forward slash
00:05:24 profile forward slash id string like this.
00:05:28 So this way we still get all the type checking and error handling, but we cannot make a mistake like this one.
00:05:35 Let me show you how we use it.
00:05:36 You just say routes dot profile, and you pass in what you have to pass.
00:05:43 In this case, an underscore ID.
00:05:47 Pretty cool, right?
00:05:48 Let's also give this link a key equal to underscore ID.
00:05:53 And let's give it a class name equal to flex cursor dash pointer, items dash center, justify dash between, and the gap of seven.
00:06:06 And within it, we can render a p tag that'll render the title.
00:06:11 So now you should be able to see four or five different titles.
00:06:15 We can also give it a class name of body-medium, text-dark 500, and light 700. Okay.
00:06:25 And finally, right after it, we can render an image coming from NextImage with a source equal to forward slash icons, forward slash chevron-write.svg.
00:06:38 with an alt tag equal to chevron.
00:06:43 with a width of 20, height of 20, and a class name of invert-colors.
00:06:51 If you do that, now they're going to appear clickable.
00:06:54 So you can just navigate over to that top question if you want to learn more about it.
00:06:58 If you check out the design, you can notice that we can even spice it up a bit.
00:07:01 So we have some of these exchanging red and blue circles, which also looks great.
00:07:06 But more importantly, below those questions, we have popular tags.
00:07:11 And before we go ahead and implement those tags, first, we need to create a tag card, which is this one right here, like a chip component.
00:07:19 So to create it, let's create a new component.
00:07:22 I'll create it within components, new folder called cards, And within cards, I'll create a new tagCard.tsx.
00:07:31 Run refce inside of there.
00:07:33 And to create it, we'll be using Shazien's badge component.
00:07:38 So we can run mpx shazien addLatest addBadge.
00:07:43 Let me show you how it works.
00:07:44 First things first, the tag needs to have some info inside of it, like an ID, name, question, and so on.
00:07:52 So let's think about different properties that each tag needs to have.
00:07:56 It has to have its ID and the name based off of which we'll generate the icon.
00:08:01 That's also a pretty cool thing that I want to teach you how to dynamically generate icons based on text.
00:08:07 Next, we can have the questions part, which is going to be a number of questions related to that tag, and then another boolean that's going to allow us
00:08:16 to choose whether we want to display the number of questions or not, because here we can show different tags, but we're not going to show the list of questions
00:08:25 near them.
00:08:26 and also we can have different versions of cards like a compact card or a larger card.
00:08:31 So let's actually accept all of these props by saying underscore ID, name, number of questions, show count, and whether it's compact or not.
00:08:43 That's going to be of a type props.
00:08:44 We can define those props right here by saying interface, props, where we have an ID of a type string, a name of a type string,
00:08:54 a list of questions of a type number, a show count, which is going to be a boolean, but it'll be optional, and compact, which will be optional and a boolean.
00:09:06 So now that we know which props does this tag card accept, we can go back to our right sidebar and actually map over some of the imaginary cards that we have.
00:09:17 So let's create them right here at the top, below our hot questions.
00:09:21 I'll say const popular tags is equal to an array, where each one is an object with an ID, name, and the number of questions.
00:09:31 And in this case, the name can be lower-cased.
00:09:34 We can also repeat this a couple more times, like ID JavaScript, TypeScript, Next.js, React query, whatever it is, with different numbers of questions.
00:09:44 Feel free to put your own technologies right here.
00:09:47 Once we have a list of popular tags, we can actually map over the tag cards.
00:09:52 So let's go below this link and below two more divs and I'll create another div right here with a class name equal to margin top of 16 to divide it a bit
00:10:04 from the top.
00:10:05 I'll give it an H3, which is going to say popular tags.
00:10:09 Going back to our page, this is how it looks like.
00:10:11 Let's give it a class name equal to H3 dash bold and text dash dark 200, light 900. There we go, that's better.
00:10:22 And right within it, let's create a div with a class name equal to margin top of 7, flex, flex dash col, and a gap of 4. And within it,
00:10:32 we can map over the popular tags Extract the ID, name, and the question.
00:10:37 And for each one of these cards, we can return a tag card, which we have created in our cards.
00:10:45 And to it, we can pass a key equal to underscore ID.
00:10:49 We can pass the underscore ID itself equal to underscore ID.
00:10:53 We can pass the name equal to name.
00:10:56 We can pass questions equal to questions.
00:10:59 We can pass show count in this case, because we do want to show it, and compact.
00:11:06 So now, you can see five different tag cards appear right here.
00:11:10 Now, it's our job to go into the tag card and actually make it look like a card and show that technology icon dynamically.
00:11:18 To do that, I'll turn this into a link because, yes, our tags will also be different links pointing to a special tag details page where you can see all
00:11:28 of the different questions with that tag.
00:11:30 This is quite a big app.
00:11:31 So as you can imagine, everything will be clickable.
00:11:34 going to the question details, tag details, profile details, everything will be there, as in every Enterprise application.
00:11:42 So each link will have an href pointing to forward slash tags, forward slash, and then underscore id.
00:11:52 And you know the drill.
00:11:52 We're going to turn this into an actual route constant.
00:11:56 So let's copy it.
00:11:57 Head over to routes and we can create one pointing to tags, which is going to be a function that's going to point to tags ID.
00:12:06 So now we can say routes dot.
00:12:11 tags, call it as a function and pass the other square ID.
00:12:14 To this link, I'll also provide a class name of flex justify between and a gap of two.
00:12:23 And I can try to render a name right within it.
00:12:26 And now we can see different tags appear right here.
00:12:28 Don't try to click the question details or the tag details because we haven't yet created the routes for those.
00:12:34 Instead of just rendering a name, I'll actually render a ShadCN badge component.
00:12:41 Within the badge, I'll render a div with a class name equal to flex-center and space-x-2.
00:12:50 Within it, I'll render i for italic.
00:12:53 And within here, we want to render the technology icon.
00:12:56 Right below it, we can render a span, inside of which we can render a name.
00:13:00 There we go.
00:13:01 That's looking nice.
00:13:02 Let's also style the badge itself by giving it a class name equal to subtle-medium, background-light 800, dark 300, text-light 400, light 500, rounded-md
00:13:14 for the corners, border-none, padding x of 4, padding y of 2, and uppercase.
00:13:31 There we go.
00:13:32 So now this is looking much more like an icon.
00:13:34 I even think we can make them a bit larger by removing this subtle medium.
00:13:39 There we go.
00:13:41 But then it's not the same as the questions, so I think I'm gonna keep it.
00:13:45 Finally, below the badge, if showCount is true, in that case, we want to render a p tag that's gonna render the number of questions.
00:13:56 And we can style it a bit by giving it a class name of small medium, text-dark 500, light 700. And we can fix this class name.
00:14:09 And now this is looking great.
00:14:11 The number of questions related to that tag.
00:14:13 But now the main question is, How are we going to generate a dynamic icon for each one of the technologies that the user enters?
00:14:21 Keep in mind that they can type in their own tags.
00:14:24 So we need to try to make it work for most of them.
00:14:26 But if it doesn't work, we can show some kind of a default option.
00:14:30 To make this work, we'll use Devicon or DevIcon.
00:14:34 That allows us to search for, what is this?
00:14:37 2.5 thousand different icons from JavaScript, to react, maybe even redux.
00:14:45 Yep, whatever you search for, it should be here.
00:14:48 So how does it work?
00:14:49 Well, we have to place this into our header of our HTML file.
00:14:54 So let's copy it, then head over to Layout.
00:14:58 This will be our primary layout because we want to show them everywhere.
00:15:01 And then where we have the HTML, we can add the head right here.
00:15:06 So if you ever need to add some links or scripts manually, then you can do it within the layout here.
00:15:11 And you can paste the link that we just copied.
00:15:14 This will give us access to all of those icons.
00:15:16 Now, to keep the logic of generating the icons separated from this file, we can create a new utility function by going to lib utils.
00:15:26 And then here we can say export const get dev icon class name.
00:15:33 And it's going to accept the tech name that we pass in of a type string.
00:15:38 Next, we need to fix up that name a bit.
00:15:41 We can say const normalized tech name is equal to tech name dot replace.
00:15:49 And we want to replace all the empty spaces or dots or stuff like that.
00:15:53 So we can use a regular expression to globally remove all the dots and spaces.
00:15:58 And we can also run to lowercase to lowercase it.
00:16:02 What do we want to replace those dots and empty spaces with?
00:16:05 Well, it's going to be just an empty string.
00:16:06 So that's going to look like this.
00:16:08 Now, what we can do is define some kind of a tech map that's gonna look like this, which is basically gonna be just an object where we can say that JavaScript
00:16:18 is gonna correspond to DeviCon JavaScript Plane.
00:16:22 Same thing for, for example, JS.
00:16:24 It's gonna correspond to the same, DeviCon JavaScript Plane, and we can even say, maybe not Plane, maybe we can go for the color,
00:16:32 so we can say colored, like this.
00:16:34 Let's give that a shot just to see how it looks like.
00:16:37 I'll add colored for this one and the other one can remain uncolored.
00:16:42 Now that we have this tech map, we can try to map over the tech name to the name of this icon.
00:16:49 So we can say return tech map and in the tech map we search for normalized tech name and actually we can make each one colored right here.
00:17:00 We don't necessarily have to say colored here.
00:17:02 And if we cannot find an icon, we can say devicon or devicon, one more time devicon, plain.
00:17:10 So then we'll show some kind of a default icon.
00:17:13 And let's actually fix this right here.
00:17:15 I think I have an extra ending string right here.
00:17:18 There we go.
00:17:19 And this tech is going to complain a bit saying that it doesn't know that we have access to whatever we're searching for.
00:17:26 So we have to fix the type for these icons by saying that this will be of a type key of a type string and then the value will be of a type string as well.
00:17:37 So now it's not going to complain.
00:17:39 So how exactly does this work?
00:17:41 Well, now we can try to call this utility function, getDevIconClassName.
00:17:48 We can call it right here where we have the icon.
00:17:50 By giving this element a class name and to it, we'll need to fetch the devIconClassName right here by saying const icon class is equal to getDevIconClassName
00:18:03 to which we can pass the name we're searching for and make sure to import this from libutils.
00:18:09 Once you do that, in the class name, we can pass this icon class.
00:18:14 And we can also just make it a bit smaller.
00:18:17 So we can say text-sm.
00:18:19 If you do this, you can see that now for JavaScript, we actually have a real icon.
00:18:24 But for other icons, we still cannot really see anything here.
00:18:29 So let's go back to our utils, and we can further improve our tech map.
00:18:35 I'm pretty sure that just Copilot could fill this out for me, which is pretty cool.
00:18:39 You can see that it knows and it can anticipate different people's desires like React, TypeScript, and so on.
00:18:45 But what I've done is I've took some time and I've actually mapped out a few more most commonly used icons.
00:18:53 I'll paste those in the lesson below, you can just copy them, and that should be good for now.
00:18:57 HTML, CSS, Git, PHP, C sharp, C++, Denno, Bun, Node.js, Next.js, React, and so on.
00:19:07 And the last one, React query, doesn't have any icon, or wait, maybe doesn't the light mode?
00:19:12 No, never mind, it doesn't.
00:19:14 So let's try to debug this.
00:19:16 What we're saying here is if you find the one in the tech map, then return that colored.
00:19:21 But I don't think this is a proper ternary.
00:19:23 Actually, what we should be doing is check right here before.
00:19:27 If TechMapNormalizeTechName exists, then return this, else return this.
00:19:34 And now you can see a default one appearing for React Query, because it couldn't find it in the database.
00:19:40 This is great.
00:19:41 And this is the type of situation that ChatGPT is perfect for, or even copilot.
00:19:47 Let me show you what I mean.
00:19:48 If we go to DevIcon, there should be a list of all the icons somewhere.
00:19:52 And even if there's not, you can see that you can scroll through all of them.
00:19:55 So if you just press Command-A or Control-A, you can copy all of them.
00:20:00 Then, you can paste all of these into ChatGPT and tell it to generate a structure looking like this for all of the icons.
00:20:08 So let me actually try that.
00:20:10 I'll create a new constants file and I'll call it techmap.ts.
00:20:17 I'll actually move over this techmap from here, just so we don't need to keep it here.
00:20:24 There we go.
00:20:25 Techmap.ts.
00:20:27 And I will nicely export it right at the top.
00:20:31 Export const techmap.
00:20:34 And then in the utils right here, we can import it from Constance.
00:20:38 Everything should still work normally.
00:20:41 But now, I'll use Copilot, or you can use ChatGPT as I've told you.
00:20:46 Select this entire part, press Cmd or Ctrl-Shift-I to open up the Ask Copilot dialog, and to it, I'll pass the entire list of icons that I copied from
00:20:59 DevIcon that looks something like this.
00:21:00 Now, I'll say something like, generate a tech map like the one in this file, but make it contain all of the icons from DevIcon.
00:21:16 Let's see if it'll do it.
00:21:19 You can see I just passed plain text that I copied from the website.
00:21:22 Now it's collecting a lot of info, filtering it, and returning it.
00:21:26 And check this out.
00:21:29 Containing all icons from DevIcon version 2.16, like this.
00:21:34 Isn't that pretty cool, right?
00:21:36 And it's gonna take some time to generate as it's just in the letter C.
00:21:39 So I'll pause this video and I'll be right back.
00:21:43 Okay, it's still going.
00:21:45 Maybe I should have used chat GPT.
00:21:47 It would have been a just a bit faster.
00:21:49 But okay, let's give it some more time.
00:21:51 There we go.
00:21:52 It tried to generate as much as possible, but it looks like we've hit a limit.
00:21:56 Doesn't matter, I'll take what we have so far.
00:21:59 So I'll just go ahead and copy this, and replace our current map with that.
00:22:05 So let me just select it, and I'll paste it, and I'll end it right here.
00:22:11 I think that should be more than enough.
00:22:12 We have about 600 lines worth of this.
00:22:15 We also have one warning right here.
00:22:17 It looks like it made a mistake right here, so I'll remove this.
00:22:20 And it looks like at one point, it actually just started duplicating all of the values.
00:22:24 So I'll remove the second half.
00:22:26 Yep, this wasn't that successful because it looks like it didn't get React, TypeScript, and all the other ones.
00:22:32 So in this case, I actually want to give it a shot with ChatGPT.
00:22:36 I'll take the same prompt that I gave to copilot, like this one right here.
00:22:41 Hopefully I can copy it.
00:22:43 Yep, I'll go right here and I'll copy the whole thing.
00:22:46 There we go.
00:22:47 And I'll paste that thing alongside our previous implementation of the tech map right here to ChatGPT.
00:22:55 Let's see what it comes up with.
00:22:57 Okay, so it actually provided some different variations.
00:23:00 Return a tech map of all the icons.
00:23:05 Sometimes it can be a hit or miss, but let's see what it comes up with.
00:23:08 It looks like it's following a nice structure and generating exactly the icons that we need.
00:23:14 And it even started with the most common web development ones.
00:23:18 MongoDB, Git, CSS, HTML.
00:23:20 It even included PHP there.
00:23:22 There we go.
00:23:23 So includes a wide range of popular web and software development tools.
00:23:27 We can copy it.
00:23:28 We can paste it here.
00:23:30 We have about 200 original ones.
00:23:32 So now you can see that most are covered, which is exactly what we need.
00:23:36 And it should also work with all of the other user input at once, at least if they're popular technologies.
00:23:42 I just wanted to take some time to show you how sometimes using ChatGBT or Copilot can be useful, although it can also be a hit or miss.
00:23:51 So with that in mind, great job on implementing the right sidebar.
00:23:55 It looks great on desktop devices.
00:23:58 It is even collapsible, so it gets hidden once we lose some space.
00:24:02 And it'll be super cool once we implement the question details and tag details pages so we can actually visit them.
00:24:09 When it comes to the code, we have added quite a few files.
00:24:12 We have modified the layout.
00:24:14 We have implemented the sidebar, the reusable tag card, the badge, I showed you how to use dynamic routes, and we learned a bit of how we can generate
00:24:23 this map that would allow us to match most user-generated tags.
00:24:28 So let's say implement, write sidebar, commit, and push.
00:24:36 Great work.