
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.
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
00:00:00Â Let's quickly check out the file and folder structure of our application.
00:00:03Â In the app, we currently have the layout and the page.
00:00:06Â That's it.
00:00:07Â But instead of having a single homepage, we'll create something known as group routes.
00:00:13Â In Next.js, you do it by creating a new folder and you wrap the name in parentheses, such as root.
00:00:19Â That means that this will not be an actual route in your application, such as forward slash root, forward slash home or something.
00:00:26Â It just acts as a regular folder in your file tree.
00:00:30Â So within here, we will have our homepage.
00:00:32Â So we can move the primary page to the root.
00:00:35Â Next, we can create a new route called Documents.
00:00:39Â And then within Documents, we can create a dynamic route.
00:00:42Â And in Next.js, you create dynamic routes by wrapping them in square brackets.
00:00:48Â And here we can give it a key.
00:00:50Â In this case, it'll be an ID.
00:00:53Â So we can create a new page.tsx for each specific document.
00:00:59Â Here, you can quickly run RAFCE and we can call it document.
00:01:04Â Very soon, we'll also have authentication pages.
00:01:07Â So let's add a new group route for auth.
00:01:11Â And within it, we can create a new sign-in folder.
00:01:15Â And we can also create a new sign-up folder as well.
00:01:19Â We'll leave those for later.
00:01:21Â Now, let's check out the other pages in the browser.
00:01:24Â Back on the homepage, we can still see the Click Me button.
00:01:27Â But if I go to Documents, what do you think we'll see?
00:01:30Â Try to think about it.
00:01:31Â Well, we won't be able to see anything because there is no page under Documents.
00:01:37Â There's only a page under Documents ID.
00:01:40Â So to visit that page, we can give a specific ID to these documents right here, and then we can get to the Documents page.
00:01:47Â And this is the page we'll be working on first, right?
00:01:49Â So let's begin.
00:01:51Â To get started implementing our editor, I prepared something special for you.
00:01:55Â It is a JSM editor MPM package.
00:01:58Â And I did this so that if you decide to build any kind of a collaborative tool later on or any kind of a markdown editor,
00:02:05Â you can very quickly and easily get started.
00:02:08Â This is built on top of the lexical editor, but I've extracted only the most important parts so we can focus on what matters.
00:02:17Â So let me walk you through it.
00:02:19Â I'll copy this command.
00:02:20Â Back in the code, we can run mpm i jsm-editor.
00:02:25Â After that, we'll have to use the CLI, mpx jsm editor, add editor, so that the editor code gets added to our application.
00:02:34Â So let's simply paste it right here and press enter.
00:02:38Â As you can see, editor components added to components editor, editor styles added to styles, and then assets get copied to source assets.
00:02:47Â So let's check it out in the file tree.
00:02:49Â Here, you can see that a new source folder was created.
00:02:54Â And now you can drag and drop the things from inside of the source folder to our own file and folder structure.
00:03:00Â For example, we already have the components, so we only need to grab the editor folder from the components folder and drag and drop it into our components.
00:03:09Â Styles can go into the root of the directory, so we can pull it right here to the bottom.
00:03:14Â And for now, we'll delete the source and the assets folder.
00:03:18Â Because if you go to the README, you can find the complete public assets for this project, including all sorts of icons needed for this project,
00:03:26Â not just the editor.
00:03:27Â I'm talking the logo, this edit icon here, the share icon, and so much more.
00:03:33Â So simply click here and click the download button at the top right.
00:03:37Â If it mentions any viruses, don't worry about that.
00:03:39Â That's not why I'm here for.
00:03:40Â I'm here to teach you how to code.
00:03:42Â Once you download it, delete the existing public folder.
00:03:46Â Unzip the one that you downloaded and drag and drop it to the root of your directory and select copy folder.
00:03:53Â Here, you can see all of the assets such as icons, images, even our favicon and more.
00:03:59Â So that means that we can delete our favicon from here, from the root.
00:04:04Â And we can move this one over right here to our app.
00:04:09Â And now back to globals.css, if you remember correctly, we can import the specific editor styles in here as well.
00:04:16Â So just uncomment this line.
00:04:19Â And for the time being, I'll still left the other two commented out.
00:04:22Â But as you can see, this style is pointing to the dark theme in our editor styles.
00:04:28Â Now let's check out the actual editor component.
00:04:32Â I'm using the command P keyword or control P that allows you to quickly open up the files.
00:04:37Â So simply press control or command P and then start typing the name of the component, press enter and you're there.
00:04:44Â Or you can just manually find it on the file explorer.
00:04:47Â You'll see that this is a longer component and we're using the lexical editor as the baseline.
00:04:52Â What I want you to focus on right now is taking a look at what this component does.
00:04:57Â So it's taking in the initial configuration and it's simply rendering out the editor.
00:05:03Â This is it.
00:05:05Â So let's use it as a component right within our document page.
00:05:09Â I'll do that by putting it right here within this div and start typing editor coming from components, editor, editor.
00:05:18Â It is a self-closing component.
00:05:20Â I'll save it and let's check it out in the browser.
00:05:23Â And as you can see, our entire screen just turned into a modern dark theme editor.
00:05:30Â So if I start typing something like test, you can already make it bold.
00:05:34Â You can make it italic.
00:05:36Â It supports all the key press events.
00:05:38Â So you can use the command or control B to bold it and do everything else.
00:05:42Â And we can even have different headings.
00:05:45Â It works amazingly well.
00:05:47Â So you might be thinking, but hey, what will I do here?
00:05:51Â Like we already have a fantastic editor.
00:05:54Â What do we do next?
00:05:56Â I mean, just check this out.
00:05:58Â We'll bring this app to a whole nother level and call it LiveDocs.
00:06:04Â First of all, there will be a homepage where you can see all of your different documents, which means that we'll have to store them somewhere.
00:06:11Â Not only that, each one of these documents will be a collaborative environment of its own where you can save the changes and see the changes that other
00:06:20Â people are making in real time.
00:06:22Â You'll have live cursors to track their work and overlay comments if you need to make any changes.
00:06:29Â Next, you'll be able to share your documents with everyone and invite them to your documents through an email address or just by sharing the link.
00:06:38Â You can find plenty of editors online, right?
00:06:40Â They're just MPM packages.
00:06:42Â But what I want you to do is to turn this editor into a complete live collaborative SaaS application with authentication,
00:06:51Â document storage, live collaborative features, enterprise ready application monitoring, and more.
00:06:58Â That's what we do at JSM.
00:06:59Â But you already know that, so I don't have to repeat myself.
00:07:03Â So let's go straight into the code.
00:07:05Â On the design, we have this simple navigation bar above the editor.
00:07:09Â So let's make it happen.
00:07:11Â I'll create a new header component inside of the components folder and call it header.tsx.
00:07:17Â We can run RAFCE inside of there.
00:07:21Â And I'll wrap everything in a div and give it a class name equal to.
00:07:26Â In this case, I'll just say header within it will render a link component.
00:07:32Â And this link will be coming from next forward slash link with an href of forward slash.
00:07:39Â and a class name equal to, on medium devices, flex-1.
00:07:44Â Since it's pointing to forward slash, we already know where it's going.
00:07:48Â It's going to be the homepage, so that means that we want to show our logo.
00:07:51Â Inside of the link, we'll create an image tag, which will come from next forward slash image.
00:07:58Â And it'll have a source of forward slash assets, forward slash icons, forward slash logo dot SVG.
00:08:05Â This will be a logo with the name of the application as well.
00:08:09Â So we can say alt will be something like logo with name.
00:08:14Â Next, we can give it a width of about 120 and a height of about 32 pixels with a class name equal to hidden on larger devices and on medium devices and
00:08:27Â larger block, which means that we'll show it.
00:08:29Â Now we want to duplicate this right below and we'll do a smaller logo.
00:08:34Â So we'll do icons, logo dash icon.
00:08:39Â This will be logo without a name, so just logo with a width of 32. And in this case, we'll say on medium devices, hide it,
00:08:48Â so hidden.
00:08:49Â And we'll also give it a margin right of two.
00:08:53Â Right below both of these images and below the link, we'll render the children.
00:08:58Â So everything else that we pass into this header.
00:09:02Â So let's accept that children as a prop right here.
00:09:06Â And we can give it a type of children.
00:09:09Â And we can specify that the type of this will be header props.
00:09:14Â Now, what is this header props?
00:09:18Â Well, you could go ahead and say type header props is equal to, and then say children will be of a type react.reactNode.
00:09:30Â You could do that.
00:09:31Â What I sometimes prefer is declaring all of the types in a different file.
00:09:37Â So if you go to the code snippets part of the readme, you'll see a file called types index.d.ts.
00:09:44Â Copy it and then back in the code, create a new folder in the root of the directory called types.
00:09:52Â And within it, create a new index.d.ts stands for declaration and paste everything you copied.
00:10:01Â If you want to find the header props, you can now see them here.
00:10:05Â We're just declaring a type for the header props.
00:10:08Â And from now on, you'll be able to use all of these types and interfaces without needing to import them.
00:10:15Â So if I go back and remove this header props, you can see that now the header knows exactly what it is accepting because it's inheriting it from its types.
00:10:25Â Great.
00:10:26Â Now let's use this header right here on our document page.
00:10:30Â Later on, we can use it on all the pages.
00:10:32Â For now, I'll simply put it right here.
00:10:36Â Header, and let's call it not as a self-closing component because we can still pass something into it.
00:10:42Â For example, let me just pass over a p tag that's going to say something like test and give it a class name equal to text-white.
00:10:52Â Now, if I go back to Localhost 3000 on the Documents page, you can see the Live Docs logo on the left side and test on the right side.
00:11:02Â But what else will our navbar have?
00:11:05Â Well, let's create a new div right within it.
00:11:08Â And this div will have a class name equal to flex, w-fit, so it fits the content width.
00:11:16Â items-center, so we center it vertically, and justify-center, so we center it horizontally, and a gap of two between the elements.
00:11:26Â Now within it, for now, we can render a p tag with a class name equal to document-title, and there we can render the title of our document.
00:11:39Â For now, I will say something like, this is a fake document title, because for now it's just hard coded, but soon enough we'll make it dynamic.
00:11:49Â If I save this back in here, you can see this new fake title.
00:11:54Â Now, if we compare this with a final design, you'll see that we're missing some things, such as the ability to change the actual title.
00:12:01Â Sure, that's going to come later, but even more importantly, the share button and the avatars of the people who are currently viewing this document to
00:12:10Â bring in that collaboration.
00:12:11Â So to make that happen, of course, we need to add authentication to our project.
00:12:16Â So let's do that next.