Build a Next.js Interactive Web-Based Simple Markdown Editor

Written by

in

Markdown has become the go-to language for writing on the web. It’s simple, easy to learn, and allows you to format text without complex HTML. But what if you could see your Markdown transform in real-time? In this tutorial, we’ll build a simple, interactive Markdown editor using Next.js. This project is perfect for beginners and intermediate developers looking to learn Next.js, understand state management, and work with client-side rendering.

Why Build a Markdown Editor?

Creating a Markdown editor is a fantastic way to learn several key concepts in web development:

  • State Management: You’ll learn how to manage the content of your editor, which is crucial for any interactive application.
  • Client-Side Rendering: Next.js allows us to build applications that render on the client-side, which is ideal for a text editor.
  • User Interface (UI) Design: You’ll gain experience in creating a user-friendly interface with input fields and display areas.
  • Real-time Updates: The core functionality, updating the preview as the user types, will teach you about event handling and reactivity.

By building this project, you’ll not only learn Next.js but also solidify your understanding of fundamental web development principles. This project is also highly practical: you’ll have a functional Markdown editor you can use for your own writing needs.

Prerequisites

Before we begin, make sure you have the following:

  • Node.js and npm (or yarn): You’ll need these to install and manage project dependencies. Download and install Node.js from the official website: https://nodejs.org/
  • A Code Editor: Visual Studio Code, Sublime Text, or any other code editor you prefer.
  • Basic Understanding of HTML, CSS, and JavaScript: Familiarity with these languages will make the learning process smoother.

Setting Up Your Next.js Project

Let’s start by creating a new Next.js project. Open your terminal and run the following command:

npx create-next-app markdown-editor
cd markdown-editor

This command creates a new Next.js project named “markdown-editor” and navigates you into the project directory. Next.js will ask you a few questions during setup; you can usually accept the defaults for this project.

Installing Dependencies

We’ll need a library to convert Markdown to HTML. For this, we’ll use `marked`. Install it using npm or yarn:

npm install marked
# or
yarn add marked

The `marked` library will take our Markdown input and transform it into HTML that the browser can render.

Project Structure

Your project structure should look something like this:

markdown-editor/
├── node_modules/
├── pages/
│   └── index.js
├── public/
├── .gitignore
├── next.config.js
├── package-lock.json
├── package.json
└── README.md

The `pages/index.js` file is where we’ll build our Markdown editor.

Building the Markdown Editor

Let’s dive into the code! Open `pages/index.js` in your code editor. We’ll start by importing the necessary modules and setting up our component.

import { useState } from 'react';
import { marked } from 'marked';

export default function Home() {
  const [markdown, setMarkdown] = useState('');

  return (
    <div>
      <textarea
        onChange={(e) => setMarkdown(e.target.value)}
        value={markdown}
        rows={10}
        cols={80}
      />
      <div dangerouslySetInnerHTML={{ __html: marked(markdown) }} />
    </div>
  );
}

Let’s break down this code:

  • Import Statements: We import `useState` from React for managing the editor’s state and `marked` from the library we installed.
  • State Variable: `markdown` stores the text entered by the user. The `setMarkdown` function updates this state whenever the user types.
  • `textarea`: This is our input field. The `onChange` event updates the `markdown` state whenever the user types. The `value` prop binds the text area to the `markdown` state, ensuring it always displays the current value. The `rows` and `cols` attributes control the size of the text area.
  • `div dangerouslySetInnerHTML`: This is where the rendered HTML will be displayed. The `__html` prop accepts HTML as a string. We use `marked(markdown)` to convert the Markdown text into HTML. Using `dangerouslySetInnerHTML` is necessary because it allows us to inject HTML generated from our Markdown. However, it’s important to use it with caution, only when you are certain the content is safe, as it can be a potential security risk if you’re not careful.

Styling the Editor (Optional)

To make the editor more visually appealing, you can add some CSS. Create a `styles/Home.module.css` file (or use any other method for styling in Next.js) and add the following CSS:

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
}

textarea {
  width: 80%;
  margin-bottom: 20px;
  padding: 10px;
  font-size: 16px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

div {
  width: 80%;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 16px;
  line-height: 1.6;
  overflow-x: auto; /* Allows horizontal scrolling for code blocks */
}

Then, import the CSS file into your `pages/index.js` file:

import styles from '../styles/Home.module.css';

And apply the styles to your components:


import { useState } from 'react';
import { marked } from 'marked';
import styles from '../styles/Home.module.css';

export default function Home() {
  const [markdown, setMarkdown] = useState('');

  return (
    <div className={styles.container}>
      <textarea
        onChange={(e) => setMarkdown(e.target.value)}
        value={markdown}
        rows={10}
        cols={80}
        className={styles.textarea}
      />
      <div className={styles.preview} dangerouslySetInnerHTML={{ __html: marked(markdown) }} />
    </div>
  );
}

This CSS provides basic styling for the text area and the preview area. You can customize the CSS to match your preferred design.

Running the Application

To run your application, execute the following command in your terminal:

npm run dev
# or
yarn dev

This will start the development server. Open your web browser and go to `http://localhost:3000`. You should now see your Markdown editor. As you type in the text area, the rendered HTML preview will update in real time.

Handling Common Mistakes

Here are some common mistakes and how to fix them:

  • Incorrect Installation of `marked`: Make sure you’ve installed `marked` correctly using `npm install marked` or `yarn add marked`.
  • Missing Import of `marked`: Double-check that you’ve imported `marked` at the top of your `index.js` file: `import { marked } from ‘marked’;`
  • Incorrect Use of `dangerouslySetInnerHTML`: Ensure you are using `dangerouslySetInnerHTML` correctly and only with content that you’ve processed (e.g., converted from Markdown).
  • State Not Updating: If the preview isn’t updating, verify that the `onChange` event is correctly updating the `markdown` state using `setMarkdown(e.target.value)`.
  • CSS Not Applying: Check the paths and class names. Make sure your CSS file is imported correctly and that the class names in your HTML match the class names in your CSS. Also, ensure that you are using the correct method of styling (e.g., CSS Modules as shown above).

Advanced Features and Enhancements

Once you’ve built the basic editor, you can add more features to make it even better:

  • Toolbar: Add a toolbar with buttons for common Markdown formatting options (bold, italic, headings, links, etc.).
  • Live Preview Styling: Style the preview area to match the appearance of your desired output.
  • Syntax Highlighting: Use a library like `highlight.js` to add syntax highlighting to code blocks.
  • File Uploads: Implement file upload capabilities for images and other assets.
  • Save and Load: Add functionality to save and load your Markdown content from local storage or a backend server.
  • Real-time Collaboration: For a more advanced project, explore integrating WebSockets for real-time collaborative editing.

Key Takeaways

In this tutorial, you’ve learned how to:

  • Set up a Next.js project.
  • Install and use the `marked` library to convert Markdown to HTML.
  • Manage state using React’s `useState` hook.
  • Create an interactive user interface with a `textarea` and a preview area.
  • Apply basic styling to improve the appearance of your editor.

FAQ

Here are some frequently asked questions about building a Markdown editor:

  1. Why use Next.js for a Markdown editor? Next.js provides excellent performance and SEO benefits, making it a great choice for web applications. Its server-side rendering and static site generation capabilities can enhance the user experience and improve search engine rankings.
  2. Can I use a different Markdown library? Yes, you can. There are several Markdown libraries available, such as `markdown-it`. The code will need to be adjusted to match the selected library’s API.
  3. How do I handle code blocks in Markdown? The `marked` library automatically handles code blocks if you use the correct Markdown syntax (e.g., using triple backticks: “`). You can enhance the display of code blocks using syntax highlighting libraries like `highlight.js`.
  4. How can I deploy this application? You can deploy your Next.js application to platforms like Vercel (which is recommended, as it’s built by the Next.js team), Netlify, or other hosting providers. Make sure you build the project before deploying by running `npm run build` or `yarn build`.

Building a Markdown editor is more than just a coding exercise; it’s a gateway to understanding the inner workings of modern web development. The interactive feedback loop, where your input instantly transforms into formatted text, exemplifies the power of reactive programming. This project is a solid foundation for further exploration into web development with Next.js and React. With the basic structure in place, the potential for expansion is vast. You can customize the editor with advanced features, refine its user interface, and even integrate it into a larger application. The ability to create, edit, and preview Markdown content in real-time offers a unique and valuable tool for writers, developers, and anyone who communicates through text. The skills you’ve acquired, from state management to UI design and event handling, are transferable and will serve you well in any future web development endeavors. As you continue to build and refine this project, you’ll discover more about the elegance and efficiency of Next.js, and the satisfaction of seeing your code come to life.