Next.js: Build a Simple Interactive Code Snippet App

Written by

in

In the world of web development, sharing code snippets is a daily occurrence. Whether you’re collaborating with colleagues, helping out on Stack Overflow, or documenting your own projects, the ability to present code clearly and concisely is invaluable. But let’s face it: plain text code snippets can be, well, a bit dull. They lack the visual appeal and interactive elements that make code easier to understand and use. That’s where a code snippet app comes in. This tutorial will guide you through building a simple, yet effective, interactive code snippet application using Next.js, a powerful React framework.

Why Build a Code Snippet App?

Think about the last time you saw a code snippet online. Was it easy to read? Could you quickly copy it? Did it highlight the key parts? A good code snippet app solves these problems. It provides syntax highlighting, makes it easy to copy code, and often includes features like line numbers and the ability to expand or collapse sections. Building your own app not only gives you these features but also lets you customize the experience to your exact needs. This project is ideal for beginners because it introduces fundamental concepts of Next.js, such as components, state management, and basic styling, while providing a practical, real-world application.

What We’ll Build

We’re going to create a simple web application where users can input code snippets, view them with syntax highlighting, and copy them with a single click. The app will have a clean, user-friendly interface. We’ll use the following technologies:

  • Next.js: The React framework we’ll be using.
  • React Syntax Highlighter: A library for syntax highlighting.
  • Clipboard.js: A library for copying text to the clipboard.
  • CSS (or your preferred styling method): To make the app look good.

Setting Up Your Next.js Project

First, let’s create a new Next.js project. Open your terminal and run the following command:

npx create-next-app code-snippet-app

This command sets up a new Next.js project named “code-snippet-app”. Navigate into your project directory:

cd code-snippet-app

Now, let’s install the necessary dependencies:

npm install react-syntax-highlighter clipboard

We’ve installed `react-syntax-highlighter` for syntax highlighting and `clipboard` for the copy-to-clipboard functionality.

Creating the CodeSnippet Component

The heart of our application will be the `CodeSnippet` component. This component will take a code snippet as input (a prop), render it with syntax highlighting, and provide a button to copy the code to the clipboard. Create a new file named `components/CodeSnippet.js` (or similar) inside your project’s `components` directory. Add the following code:

import React, { useState, useRef } from 'react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dark } from 'react-syntax-highlighter/dist/cjs/styles/prism'; // Or any other theme
import ClipboardJS from 'clipboard';

const CodeSnippet = ({ code, language = 'javascript' }) => {
  const [isCopied, setIsCopied] = useState(false);
  const codeRef = useRef(null);

  // Initialize Clipboard.js
  React.useEffect(() => {
    if (codeRef.current) {
      const clipboard = new ClipboardJS(codeRef.current, {
        text: () => code,
      });

      clipboard.on('success', () => {
        setIsCopied(true);
        setTimeout(() => setIsCopied(false), 2000);
      });

      clipboard.on('error', (e) => {
        console.error('Action:', e.action);
        console.error('Trigger:', e.trigger);
      });

      return () => {
        clipboard.destroy();
      };
    }
  }, [code]);

  return (
    <div className="code-snippet-container">
      <div className="code-snippet-header">
        <button className="copy-button" ref={codeRef} data-clipboard-text={code}>
          {isCopied ? 'Copied!' : 'Copy'}
        </button>
      </div>
      <SyntaxHighlighter language={language} style={dark} showLineNumbers={true} wrapLines={true}>
        {code}
      </SyntaxHighlighter>
    </div>
  );
};

export default CodeSnippet;

Let’s break down this code:

  • We import `useState` and `useRef` from React to manage the component’s state and create a reference to the copy button.
  • We import `SyntaxHighlighter` from `react-syntax-highlighter` and a theme (e.g., `dark`).
  • We import `ClipboardJS` from `clipboard`.
  • The `CodeSnippet` component accepts two props: `code` (the code snippet itself) and `language` (the programming language, defaulting to ‘javascript’).
  • `isCopied` state variable tracks whether the code has been copied.
  • `codeRef` is a ref to the copy button element, which we will use to initialize ClipboardJS.
  • `React.useEffect` hook initializes ClipboardJS when the component mounts. It sets up event listeners for `success` and `error` events. The `success` event changes the button text to “Copied!” for a short duration.
  • The component renders a container with a copy button and the code snippet, rendered with syntax highlighting using `SyntaxHighlighter`.

Styling the Component

To make our component look good, let’s add some CSS. Create a file named `components/CodeSnippet.css` (or similar) and add the following styles:

.code-snippet-container {
  border: 1px solid #ccc;
  border-radius: 4px;
  margin-bottom: 20px;
  overflow: hidden;
}

.code-snippet-header {
  background-color: #f0f0f0;
  padding: 10px;
  text-align: right;
}

.copy-button {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 5px 10px;
  border-radius: 4px;
  cursor: pointer;
}

.copy-button:hover {
  background-color: #0056b3;
}

.copy-button:focus {
  outline: none;
}

.copy-button:active {
  transform: translateY(1px);
}

.code-snippet-container pre {
  margin: 0;
  padding: 10px;
  overflow-x: auto;
}

Import this CSS file into your `CodeSnippet.js` component:

import React, { useState, useRef } from 'react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dark } from 'react-syntax-highlighter/dist/cjs/styles/prism'; // Or any other theme
import ClipboardJS from 'clipboard';
import './CodeSnippet.css'; // Import the CSS file

const CodeSnippet = ({ code, language = 'javascript' }) => {
  const [isCopied, setIsCopied] = useState(false);
  const codeRef = useRef(null);

  // Initialize Clipboard.js
  React.useEffect(() => {
    if (codeRef.current) {
      const clipboard = new ClipboardJS(codeRef.current, {
        text: () => code,
      });

      clipboard.on('success', () => {
        setIsCopied(true);
        setTimeout(() => setIsCopied(false), 2000);
      });

      clipboard.on('error', (e) => {
        console.error('Action:', e.action);
        console.error('Trigger:', e.trigger);
      });

      return () => {
        clipboard.destroy();
      };
    }
  }, [code]);

  return (
    <div className="code-snippet-container">
      <div className="code-snippet-header">
        <button className="copy-button" ref={codeRef} data-clipboard-text={code}>
          {isCopied ? 'Copied!' : 'Copy'}
        </button>
      </div>
      <SyntaxHighlighter language={language} style={dark} showLineNumbers={true} wrapLines={true}>
        {code}
      </SyntaxHighlighter>
    </div>
  );
};

export default CodeSnippet;

Integrating the Component in Your Page

Now, let’s use the `CodeSnippet` component in your main page. Open `pages/index.js` and modify it as follows:

import CodeSnippet from '../components/CodeSnippet';

const IndexPage = () => {
  const code = `function greet(name) {
  console.log(`Hello, ${name}!`);
}

greet('World');`;

  return (
    <div style={{ padding: '20px' }}>
      <h2>Interactive Code Snippet App</h2>
      <p>Here's a sample code snippet:</p>
      <CodeSnippet code={code} />
    </div>
  );
};

export default IndexPage;

In this code:

  • We import the `CodeSnippet` component.
  • We define a sample code snippet in a multiline string.
  • We render the `CodeSnippet` component, passing the code as a prop.

That’s it! Now, run your Next.js development server:

npm run dev

Open your browser and navigate to `http://localhost:3000`. You should see your code snippet with syntax highlighting and a copy button.

Common Mistakes and How to Fix Them

Here are some common mistakes and how to avoid them:

  • Syntax Highlighting Not Working: Make sure you’ve installed `react-syntax-highlighter` correctly and that you’re importing a theme. Double-check that you’re using the correct language prop for the `SyntaxHighlighter` component (e.g., `language=”javascript”`).
  • Copy Button Not Working: Ensure you’ve installed `clipboard` and that you’re initializing it correctly within a `useEffect` hook to prevent issues during server-side rendering. Also, make sure your button has the `data-clipboard-text` attribute set to the code you want to copy.
  • Styling Issues: Make sure your CSS file is imported correctly into your component. Check for any CSS specificity issues that might be overriding your styles. Use your browser’s developer tools to inspect the elements and see if your styles are being applied.
  • Clipboard.js Initialization Errors: Make sure the reference to the button element (`codeRef`) is correctly set, and that you’re initializing ClipboardJS *after* the component has mounted (using `useEffect`).

Enhancements and Next Steps

This is a basic implementation, but there are many ways to enhance it:

  • Add a Form: Allow users to input their own code snippets through a form.
  • Language Selection: Add a dropdown or other UI element to allow users to select the programming language.
  • Theme Selection: Allow users to choose different syntax highlighting themes.
  • Save Snippets: Implement a backend (using Next.js API routes) to save and retrieve code snippets.
  • Code Folding: Add functionality to collapse and expand sections of code.
  • Error Handling: Implement more robust error handling for the copy functionality.
  • Responsive Design: Make the app responsive to different screen sizes.

Key Takeaways

You’ve successfully built a simple, interactive code snippet app using Next.js. You’ve learned how to integrate syntax highlighting, implement a copy-to-clipboard feature, and manage component state. This project provides a solid foundation for understanding Next.js and frontend development concepts. By adding new features, you can enhance your understanding of React and Next.js and create a more powerful and versatile application.

FAQ

Q: How do I change the syntax highlighting theme?

A: When importing `SyntaxHighlighter`, you also import a theme (e.g., `dark`, `light`, `atom-one-dark`). Change the `style` prop of the `SyntaxHighlighter` component to use a different theme. You can find more themes in the `react-syntax-highlighter` documentation.

Q: Why is the copy button not working?

A: The most common causes are incorrect installation of the `clipboard` library, incorrect initialization of ClipboardJS (make sure it’s inside a `useEffect` hook), or a missing `data-clipboard-text` attribute on the copy button. Double-check these points.

Q: Can I use this app with different programming languages?

A: Yes! The `language` prop of the `SyntaxHighlighter` component determines the language. You can set this prop to any language supported by `react-syntax-highlighter` (e.g., “javascript”, “python”, “java”, “html”).

Q: How can I deploy this app?

A: Next.js apps are easy to deploy. You can deploy them to platforms like Vercel (which is recommended for Next.js), Netlify, or other hosting providers. Simply push your code to a Git repository, and the deployment platform will handle the rest.

Building this app is a great starting point for anyone looking to understand the fundamentals of Next.js and frontend development. From here, you can explore more advanced concepts, experiment with different features, and create something truly unique. Remember that the best way to learn is by doing. So, keep coding, keep experimenting, and don’t be afraid to try new things.

” ,
“aigenerated_tags”: “Next.js, React, Code Snippet, Tutorial, Web Development, JavaScript, Frontend