Build a Simple Next.js Interactive Web-Based Digital Business Card

Written by

in

In today’s digital age, the way we exchange contact information has evolved. Traditional business cards, while still relevant, can be easily lost or forgotten. A digital business card, on the other hand, offers a dynamic and easily shareable solution. Imagine being able to instantly share your contact details, social media profiles, and even a link to your portfolio with just a tap or a scan. This tutorial will guide you through building your own interactive digital business card using Next.js, a powerful React framework that’s perfect for this kind of project. We’ll cover everything from setting up your project to deploying it online, making it accessible to anyone, anywhere.

Why Build a Digital Business Card with Next.js?

Next.js provides several advantages that make it an excellent choice for this project:

  • Server-Side Rendering (SSR) and Static Site Generation (SSG): Next.js allows you to choose how your application renders. SSR and SSG are great for SEO, as search engines can easily crawl and index your content.
  • Fast Performance: Next.js optimizes performance by default, leading to faster loading times and a better user experience.
  • Easy Deployment: Deploying a Next.js application is straightforward, with many hosting options available.
  • React-Based: If you’re familiar with React, you’ll feel right at home with Next.js, as it builds upon React’s component-based architecture.
  • Built-in Features: Next.js includes features like routing, image optimization, and API routes out of the box, simplifying development.

Project Setup: Getting Started

Let’s start by setting up our Next.js project. Open your terminal and run the following command:

npx create-next-app digital-business-card

This command will create a new Next.js project named “digital-business-card” in a new directory. Navigate into the project directory:

cd digital-business-card

Now, let’s install some dependencies we’ll need for styling and potentially for social media icons:

npm install styled-components react-icons

We’ll use `styled-components` for styling our components and `react-icons` for adding social media icons. You can choose other styling solutions like CSS modules, Tailwind CSS, or plain CSS if you prefer.

Structuring the Application

Our digital business card will consist of several key components:

  • Header: Contains the name and optionally a professional title.
  • Profile Picture: A photo of yourself.
  • Contact Information: Includes phone number, email address, and potentially a physical address.
  • Social Media Links: Links to your social media profiles (LinkedIn, Twitter, etc.).
  • Portfolio/Website Link: A link to your online portfolio or personal website.

Let’s create these components within our `pages` directory. We will start by modifying the `pages/index.js` file.

Building the Components

1. Header Component

Create a `components` directory inside your project (if you don’t already have one) and then create a `Header.js` file within it. Here’s how you might structure the Header component:

// components/Header.js
import styled from 'styled-components';

const HeaderContainer = styled.header`
  text-align: center;
  padding: 20px;
  background-color: #f0f0f0;
  border-bottom: 1px solid #ccc;
`;

const Name = styled.h1`
  margin: 0;
  font-size: 2em;
`;

const Title = styled.p`
  margin: 5px 0 0;
  font-style: italic;
  color: #666;
`;

const Header = () => {
  return (
    
      Your Name
      <Title>Your Profession/Title</Title>
    
  );
};

export default Header;

This component uses `styled-components` to create styled elements. Feel free to customize the styles to your liking. We define a `HeaderContainer`, a `Name`, and a `Title` component and then render them within the `Header` function. Replace “Your Name” and “Your Profession/Title” with your actual information.

2. Profile Picture Component

Create a `ProfilePicture.js` component:


// components/ProfilePicture.js
import styled from 'styled-components';

const ProfileImage = styled.img`
  width: 150px;
  height: 150px;
  border-radius: 50%;
  object-fit: cover;
  margin: 20px auto;
  display: block;
`;

const ProfilePicture = ({ src, alt }) => {
  return ;
};

export default ProfilePicture;

This component accepts a `src` (image source) and `alt` (alternative text) prop. You’ll need to add your profile picture to the `public` directory of your Next.js project. You can name the image file something like `profile.jpg` and then reference it in the `src` prop. The `object-fit: cover` ensures the image fills the circle without distortion.

3. Contact Information Component

Create a `ContactInfo.js` component:


// components/ContactInfo.js
import styled from 'styled-components';

const ContactContainer = styled.div`
  text-align: center;
  padding: 10px 0;
`;

const ContactLink = styled.a`
  display: block;
  margin-bottom: 5px;
  text-decoration: none;
  color: #333;
  &:hover {
    text-decoration: underline;
  }
`;

const ContactInfo = () => {
  return (
    
      Phone: (555) 123-4567
      Email: your.email@example.com
    
  );
};

export default ContactInfo;

This component uses `a` tags with `href` attributes to create clickable links for phone and email. Replace the placeholder phone number and email address with your actual contact information.

4. Social Media Links Component

Create a `SocialLinks.js` component:


// components/SocialLinks.js
import styled from 'styled-components';
import { FaLinkedin, FaTwitter, FaGithub } from 'react-icons/fa'; // Import icons

const SocialContainer = styled.div`
  text-align: center;
  padding: 10px 0;
`;

const SocialLink = styled.a`
  display: inline-block;
  margin: 0 10px;
  color: #333;
  font-size: 1.5em;
  &:hover {
    color: #0077b5; /* LinkedIn Blue */
  }
`;

const SocialLinks = () => {
  return (
    
      
        
      
      
        
      
      
        
      
    
  );
};

export default SocialLinks;

This component uses `react-icons` to display social media icons. You’ll need to replace the placeholder URLs with your actual social media profile links. The `target=”_blank” rel=”noopener noreferrer”` attributes open the links in a new tab, which is generally good practice for external links.

5. Portfolio/Website Link Component (Optional)

Create a `PortfolioLink.js` component:


// components/PortfolioLink.js
import styled from 'styled-components';

const PortfolioContainer = styled.div`
  text-align: center;
  padding: 10px 0;
`;

const PortfolioLink = styled.a`
  display: inline-block;
  padding: 10px 20px;
  background-color: #007bff;
  color: white;
  text-decoration: none;
  border-radius: 5px;
  &:hover {
    background-color: #0056b3;
  }
`;

const Portfolio = () => {
  return (
    
      View My Portfolio
    
  );
};

export default Portfolio;

This is an optional component. If you have a portfolio website, include it here. Adjust the styles as needed. Replace “https://yourportfolio.com” with the URL of your portfolio.

Putting it All Together: The Index Page

Now, let’s assemble all these components in our `pages/index.js` file:


// pages/index.js
import Header from '../components/Header';
import ProfilePicture from '../components/ProfilePicture';
import ContactInfo from '../components/ContactInfo';
import SocialLinks from '../components/SocialLinks';
import PortfolioLink from '../components/PortfolioLink'; // Import the PortfolioLink component
import styled from 'styled-components';

const CardContainer = styled.div`
  max-width: 400px;
  margin: 20px auto;
  border: 1px solid #ccc;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
`;

const Index = () => {
  return (
    
      <Header />
      
      
      
       {/* Add the PortfolioLink component here */}
    
  );
};

export default Index;

In this file, we import all our components and arrange them within a `CardContainer` styled component. The `CardContainer` provides a basic layout and styling for the business card. Make sure you replace “/profile.jpg” with the correct path to your profile picture in the `public` directory.

Styling and Customization

The styling provided is a starting point. Here’s how you can customize your digital business card:

  • Colors: Modify the `background-color`, `color`, and other color-related properties in your styled components to match your brand or personal preferences.
  • Fonts: Change the `font-family` in the styled components to use different fonts. You can use web fonts from Google Fonts or other providers.
  • Layout: Adjust the `padding`, `margin`, and other layout properties to change the spacing and arrangement of the elements. Consider using `display: flex` and `flex-direction` for more advanced layout control.
  • Responsiveness: Use media queries (e.g., `@media (max-width: 600px)`) to make your business card responsive and adapt to different screen sizes.
  • Animations and Transitions: Add animations and transitions using CSS to make your card more visually appealing.

Experiment with different styles to create a unique and personalized digital business card.

Adding Metadata for SEO

To improve your digital business card’s visibility in search results, add meta tags to the “ section of your `pages/_app.js` file. This helps search engines understand what your page is about.


// pages/_app.js
import '../styles/globals.css';
import Head from 'next/head';

function MyApp({ Component, pageProps }) {
  return (
    
      
        Your Name - Digital Business Card
        
        
        
      
      
    

In this code:

  • We import the `Head` component from `next/head`.
  • We set the `` tag to a descriptive title for your card. Keep it under 70 characters.</li> <li>We add a `` tag with a concise description of your card. Keep it under 160 characters.</li> <li>We include a `` tag for responsive design.</li> <li>We link a favicon.</li> </ul> <p>Remember to replace "Your Name" and the description with your actual information and a compelling description.</p> <h2>Deploying Your Digital Business Card</h2> <p>Next.js makes deployment easy. Here are a few common options:</p> <ul> <li><b>Vercel:</b> Vercel is the easiest and recommended way to deploy Next.js apps. It's built by the same company that created Next.js, and it's optimized for performance and ease of use. Simply push your code to a Git repository (GitHub, GitLab, or Bitbucket), and Vercel will automatically build and deploy your application.</li> <li><b>Netlify:</b> Netlify is another excellent option for deploying static sites and web applications. It also offers automatic builds and deployments from Git repositories.</li> <li><b>Other Hosting Platforms:</b> You can deploy your Next.js application to other platforms like AWS, Google Cloud, or Azure. However, these options often require more configuration.</li> </ul> <p><b>Deploying to Vercel (Recommended):</b></p> <ol> <li><b>Create a Vercel Account:</b> If you don't already have one, sign up for a free Vercel account at <a href="https://vercel.com/" target="_blank" rel="noopener">vercel.com</a>.</li> <li><b>Connect Your Git Repository:</b> In your Vercel dashboard, click "Add New Project" and connect your Git repository (e.g., GitHub) where your code is stored.</li> <li><b>Import Your Project:</b> Vercel will automatically detect that it's a Next.js project. You may need to configure the build command (usually `npm run build` or `yarn build`) and the output directory (usually `.next`). However, Vercel often detects these settings automatically.</li> <li><b>Deploy:</b> Click "Deploy" to deploy your application. Vercel will build and deploy your application, and provide you with a unique URL.</li> <li><b>Customize Your Domain (Optional):</b> You can connect a custom domain to your digital business card from the Vercel dashboard.</li> </ol> <p>After deployment, your digital business card will be live and accessible via the provided URL.</p> <h2>Common Mistakes and Troubleshooting</h2> <ul> <li><b>Image Paths:</b> Double-check the image paths in your `ProfilePicture` component. Make sure the path is relative to the `public` directory (e.g., `/profile.jpg`).</li> <li><b>Spelling and Typos:</b> Carefully review your code for spelling errors and typos, especially in component names, variable names, and URLs.</li> <li><b>CSS Issues:</b> Use your browser's developer tools (right-click and select "Inspect") to identify any CSS-related issues. Check for conflicting styles or incorrect selectors.</li> <li><b>Missing Dependencies:</b> Make sure you've installed all the necessary dependencies (e.g., `styled-components`, `react-icons`) using `npm install` or `yarn install`.</li> <li><b>CORS Errors:</b> If you're fetching data from an external API, you might encounter CORS (Cross-Origin Resource Sharing) errors. This is a browser security feature. You'll need to configure your API server to allow requests from your domain or use a proxy. Since this project does not involve external API calls, this is less of a concern.</li> <li><b>Deployment Errors:</b> If you encounter deployment errors, carefully review the build logs provided by your hosting platform (Vercel, Netlify, etc.). The logs will often provide clues about what went wrong. Common issues include incorrect environment variables or missing dependencies.</li> </ul> <h2>Key Takeaways and Summary</h2> <p>You've now built a functional and shareable digital business card using Next.js. Here's a recap of what we've covered:</p> <ul> <li>We set up a new Next.js project.</li> <li>We created reusable components for the header, profile picture, contact information, social media links, and portfolio link.</li> <li>We used `styled-components` to style our components, but you can choose any styling method you prefer.</li> <li>We added meta tags for SEO.</li> <li>We learned how to deploy the application to Vercel (or other platforms).</li> </ul> <h2>Frequently Asked Questions (FAQ)</h2> <ol> <li><b>Can I use this digital business card on my phone?</b> Yes, the business card is designed to be responsive and work seamlessly on mobile devices.</li> <li><b>How do I share my digital business card?</b> You can share the URL of your deployed application. You can also generate a QR code that links to your digital business card for easy sharing.</li> <li><b>Can I add more information to my digital business card?</b> Yes, you can customize your card by adding more components or information, such as a short bio, testimonials, or a contact form.</li> <li><b>Is it possible to track the views of my digital business card?</b> Yes, you can add analytics tools (e.g., Google Analytics) to your Next.js application to track views, clicks, and other user interactions.</li> <li><b>How can I update my digital business card?</b> You can update your card by modifying the code, committing the changes to your Git repository, and redeploying the application. Platforms like Vercel automatically redeploy when they detect changes in your repository.</li> </ol> <p>Building a digital business card with Next.js is a practical project that showcases your skills in web development. The ability to create a professional online presence is more important than ever. With the knowledge you've gained, you can now create a digital business card that not only looks great but also helps you make a lasting impression. As you continue to refine your card, consider adding more features, experimenting with different designs, and ensuring it represents your personal brand effectively. Your digital business card is a dynamic, evolving representation of you, ready to be shared with the world.</p> <div class="wpzoom-social-sharing-buttons-bottom"><div class="wp-block-wpzoom-blocks-social-sharing align-none"><ul class="social-sharing-icons"><li class="social-sharing-icon-li"><a class="social-sharing-icon social-sharing-icon-facebook" style="padding:5px 15px;margin:5px 5px;border-radius:50px;font-size:20px;color:#ffffff;background-color:#0866FF;" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fjavascriptdebugged.com%2Fbuild-a-simple-next-js-interactive-web-based-digital-business-card%2F&t=Build+a+Simple+Next.js+Interactive+Web-Based+Digital+Business+Card" title="Facebook" target="_blank" rel="noopener noreferrer" data-platform="facebook"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" style="fill:#ffffff;" aria-hidden="true" focusable="false"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z" /></svg><span class="social-sharing-icon-label" style="font-size:16px;color:inherit;">Facebook</span></a></li><li class="social-sharing-icon-li"><a class="social-sharing-icon social-sharing-icon-x" style="padding:5px 15px;margin:5px 5px;border-radius:50px;font-size:20px;color:#ffffff;background-color:#000000;" href="https://x.com/intent/tweet?url=https%3A%2F%2Fjavascriptdebugged.com%2Fbuild-a-simple-next-js-interactive-web-based-digital-business-card%2F&text=Build+a+Simple+Next.js+Interactive+Web-Based+Digital+Business+Card" title="Share on X" target="_blank" rel="noopener noreferrer" data-platform="x"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" style="fill:#ffffff;" aria-hidden="true" focusable="false"><path d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z" /></svg><span class="social-sharing-icon-label" style="font-size:16px;color:inherit;">Share on X</span></a></li><li class="social-sharing-icon-li"><a class="social-sharing-icon social-sharing-icon-linkedin" style="padding:5px 15px;margin:5px 5px;border-radius:50px;font-size:20px;color:#ffffff;background-color:#0966c2;" href="https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fjavascriptdebugged.com%2Fbuild-a-simple-next-js-interactive-web-based-digital-business-card%2F" title="LinkedIn" target="_blank" rel="noopener noreferrer" data-platform="linkedin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" style="fill:#ffffff;" aria-hidden="true" focusable="false"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" /></svg><span class="social-sharing-icon-label" style="font-size:16px;color:inherit;">LinkedIn</span></a></li><li class="social-sharing-icon-li"><a class="social-sharing-icon social-sharing-icon-whatsapp" style="padding:5px 15px;margin:5px 5px;border-radius:50px;font-size:20px;color:#ffffff;background-color:#25D366;" href="https://api.whatsapp.com/send?text=Build+a+Simple+Next.js+Interactive+Web-Based+Digital+Business+Card+https%3A%2F%2Fjavascriptdebugged.com%2Fbuild-a-simple-next-js-interactive-web-based-digital-business-card%2F" title="WhatsApp" target="_blank" rel="noopener noreferrer" data-platform="whatsapp"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" style="fill:#ffffff;" aria-hidden="true" focusable="false"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" /></svg><span class="social-sharing-icon-label" style="font-size:16px;color:inherit;">WhatsApp</span></a></li><li class="social-sharing-icon-li"><a class="social-sharing-icon social-sharing-icon-email" style="padding:5px 15px;margin:5px 5px;border-radius:50px;font-size:20px;color:#ffffff;background-color:#333333;" href="mailto:?subject=Build+a+Simple+Next.js+Interactive+Web-Based+Digital+Business+Card&body=https%3A%2F%2Fjavascriptdebugged.com%2Fbuild-a-simple-next-js-interactive-web-based-digital-business-card%2F" title="Email" target="_blank" rel="noopener noreferrer" data-platform="email"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" style="fill:#ffffff;" aria-hidden="true" focusable="false"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-.4 4.25l-7.07 4.42c-.32.2-.74.2-1.06 0L4.4 8.25c-.25-.16-.4-.43-.4-.72 0-.67.73-1.07 1.3-.72L12 11l6.7-4.19c.57-.35 1.3.05 1.3.72 0 .29-.15.56-.4.72z" /></svg><span class="social-sharing-icon-label" style="font-size:16px;color:inherit;">Email</span></a></li><li class="social-sharing-icon-li"><a class="social-sharing-icon social-sharing-icon-copy-link" style="padding:5px 15px;margin:5px 5px;border-radius:50px;font-size:20px;color:#ffffff;background-color:#333333;" href="#copy-link" title="Copy Link" data-platform="copy-link"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" style="fill:#ffffff;" aria-hidden="true" focusable="false"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" /></svg><span class="social-sharing-icon-label" style="font-size:16px;color:inherit;">Copy Link</span></a></li></ul><script> document.addEventListener("DOMContentLoaded", function() { var copyLinks = document.querySelectorAll("a[data-platform='copy-link']"); copyLinks.forEach(function(link) { if (link.hasAttribute("data-listener-added")) return; link.setAttribute("data-listener-added", "true"); link.addEventListener("click", function(e) { e.preventDefault(); var tempInput = document.createElement("input"); tempInput.value = window.location.href; document.body.appendChild(tempInput); tempInput.select(); document.execCommand("copy"); document.body.removeChild(tempInput); var originalText = this.querySelector(".social-sharing-icon-label")?.textContent || ""; var originalTitle = this.getAttribute("title"); var originalIcon = this.querySelector("svg").outerHTML; // Show success feedback this.setAttribute("title", "Copied!"); this.classList.add("copied"); if (this.querySelector(".social-sharing-icon-label")) { this.querySelector(".social-sharing-icon-label").textContent = "Copied!"; } else { this.querySelector("svg").outerHTML = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" style="fill:#ffffff;" aria-hidden="true" focusable="false"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z" /></svg>'; } var self = this; setTimeout(function() { self.setAttribute("title", originalTitle); self.classList.remove("copied"); if (self.querySelector(".social-sharing-icon-label")) { self.querySelector(".social-sharing-icon-label").textContent = originalText; } else { self.querySelector("svg").outerHTML = originalIcon; } }, 2000); }); }); }); </script></div></div></div> <div class="wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60)"> <div class="taxonomy-post_tag is-style-post-terms-1 is-style-post-terms-1--2 wp-block-post-terms"><a href="https://javascriptdebugged.com/tag/deployment/" rel="tag">Deployment</a><span class="wp-block-post-terms__separator"> </span><a href="https://javascriptdebugged.com/tag/digital-business-card/" rel="tag">Digital Business Card</a><span class="wp-block-post-terms__separator"> </span><a href="https://javascriptdebugged.com/tag/frontend/" rel="tag">Frontend</a><span class="wp-block-post-terms__separator"> </span><a href="https://javascriptdebugged.com/tag/next-js/" rel="tag">Next.js</a><span class="wp-block-post-terms__separator"> </span><a href="https://javascriptdebugged.com/tag/react/" rel="tag">React</a><span class="wp-block-post-terms__separator"> </span><a href="https://javascriptdebugged.com/tag/seo/" rel="tag">SEO</a><span class="wp-block-post-terms__separator"> </span><a href="https://javascriptdebugged.com/tag/styled-components/" rel="tag">Styled Components</a><span class="wp-block-post-terms__separator"> </span><a href="https://javascriptdebugged.com/tag/tutorial/" rel="tag">Tutorial</a><span class="wp-block-post-terms__separator"> </span><a href="https://javascriptdebugged.com/tag/vercel/" rel="tag">Vercel</a><span class="wp-block-post-terms__separator"> </span><a href="https://javascriptdebugged.com/tag/web-development/" rel="tag">Web Development</a></div> </div> <div class="wp-block-group alignwide is-layout-flow wp-block-group-is-layout-flow" style="margin-top:var(--wp--preset--spacing--60);margin-bottom:var(--wp--preset--spacing--60);"> <nav class="wp-block-group alignwide is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-878fe601 wp-block-group-is-layout-flex" aria-label="Post navigation" style="border-top-color:var(--wp--preset--color--accent-6);border-top-width:1px;padding-top:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40)"> <div class="post-navigation-link-previous wp-block-post-navigation-link"><span class="wp-block-post-navigation-link__arrow-previous is-arrow-arrow" aria-hidden="true">←</span><a href="https://javascriptdebugged.com/build-a-simple-next-js-interactive-web-based-markdown-editor/" rel="prev">Build a Simple Next.js Interactive Web-Based Markdown Editor</a></div> <div class="post-navigation-link-next wp-block-post-navigation-link"><a href="https://javascriptdebugged.com/build-a-simple-next-js-interactive-web-based-podcast-player/" rel="next">Build a Simple Next.js Interactive Web-Based Podcast Player</a><span class="wp-block-post-navigation-link__arrow-next is-arrow-arrow" aria-hidden="true">→</span></div> </nav> </div> </div> <div class="wp-block-group alignwide has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60)"> <h2 class="wp-block-heading alignwide has-small-font-size" style="font-style:normal;font-weight:700;letter-spacing:1.4px;text-transform:uppercase">More posts</h2> <div class="wp-block-query alignwide is-layout-flow wp-block-query-is-layout-flow"> <ul class="alignfull wp-block-post-template is-layout-flow wp-container-core-post-template-is-layout-b4d04ffe wp-block-post-template-is-layout-flow"><li class="wp-block-post post-1754 post type-post status-publish format-standard hentry category-node-js tag-api tag-backend tag-beginner tag-express-js tag-frontend tag-intermediate tag-javascript tag-node-js tag-tutorial tag-url-analyzer tag-web-development"> <div class="wp-block-group alignfull is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-cba70755 wp-block-group-is-layout-flex" style="border-bottom-color:var(--wp--preset--color--accent-6);border-bottom-width:1px;padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)"> <h3 class="wp-block-post-title has-large-font-size"><a href="https://javascriptdebugged.com/build-a-simple-node-js-interactive-web-based-url-analyzer/" target="_self" >Build a Simple Node.js Interactive Web-Based URL Analyzer</a></h3> <div class="has-text-align-right wp-block-post-date"><a href="https://javascriptdebugged.com/build-a-simple-node-js-interactive-web-based-url-analyzer/"><time datetime="2026-02-23T10:21:24+00:00">February 23, 2026</time></a></div> </div> </li><li class="wp-block-post post-1749 post type-post status-publish format-standard hentry category-node-js tag-beginner tag-code-review tag-diff tag-express tag-intermediate tag-javascript tag-node-js tag-software-engineering tag-syntax-highlighting tag-tutorial tag-web-development"> <div class="wp-block-group alignfull is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-cba70755 wp-block-group-is-layout-flex" style="border-bottom-color:var(--wp--preset--color--accent-6);border-bottom-width:1px;padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)"> <h3 class="wp-block-post-title has-large-font-size"><a href="https://javascriptdebugged.com/build-a-node-js-interactive-web-based-simple-code-review-tool/" target="_self" >Build a Node.js Interactive Web-Based Simple Code Review Tool</a></h3> <div class="has-text-align-right wp-block-post-date"><a href="https://javascriptdebugged.com/build-a-node-js-interactive-web-based-simple-code-review-tool/"><time datetime="2026-02-23T10:15:04+00:00">February 23, 2026</time></a></div> </div> </li><li class="wp-block-post post-1748 post type-post status-publish format-standard hentry category-node-js tag-code-diff tag-ejs tag-express-js tag-javascript tag-node-js tag-tutorial tag-web-development"> <div class="wp-block-group alignfull is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-cba70755 wp-block-group-is-layout-flex" style="border-bottom-color:var(--wp--preset--color--accent-6);border-bottom-width:1px;padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)"> <h3 class="wp-block-post-title has-large-font-size"><a href="https://javascriptdebugged.com/build-a-node-js-interactive-web-based-simple-code-diff-tool/" target="_self" >Build a Node.js Interactive Web-Based Simple Code Diff Tool</a></h3> <div class="has-text-align-right wp-block-post-date"><a href="https://javascriptdebugged.com/build-a-node-js-interactive-web-based-simple-code-diff-tool/"><time datetime="2026-02-23T10:10:48+00:00">February 23, 2026</time></a></div> </div> </li><li class="wp-block-post post-1747 post type-post status-publish format-standard hentry category-node-js tag-beginner tag-code-playground tag-coding tag-express tag-intermediate tag-javascript tag-node-js tag-tutorial tag-web-development"> <div class="wp-block-group alignfull is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-cba70755 wp-block-group-is-layout-flex" style="border-bottom-color:var(--wp--preset--color--accent-6);border-bottom-width:1px;padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)"> <h3 class="wp-block-post-title has-large-font-size"><a href="https://javascriptdebugged.com/build-a-node-js-interactive-web-based-simple-code-playground/" target="_self" >Build a Node.js Interactive Web-Based Simple Code Playground</a></h3> <div class="has-text-align-right wp-block-post-date"><a href="https://javascriptdebugged.com/build-a-node-js-interactive-web-based-simple-code-playground/"><time datetime="2026-02-23T09:59:35+00:00">February 23, 2026</time></a></div> </div> </li></ul> </div> </div> </main> <footer class="wp-block-template-part"> <div class="wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--50)"> <div class="wp-block-group alignwide is-layout-flow wp-block-group-is-layout-flow"><div class="is-default-size wp-block-site-logo"><a href="https://javascriptdebugged.com/" class="custom-logo-link" rel="home"><img width="434" height="289" src="https://javascriptdebugged.com/wp-content/uploads/2026/02/ChatGPT_Image_Feb_6__2026__02_59_52_PM-removebg-preview-edited.png" class="custom-logo" alt="Javascriptdebugged" decoding="async" fetchpriority="high" srcset="https://javascriptdebugged.com/wp-content/uploads/2026/02/ChatGPT_Image_Feb_6__2026__02_59_52_PM-removebg-preview-edited.png 434w, https://javascriptdebugged.com/wp-content/uploads/2026/02/ChatGPT_Image_Feb_6__2026__02_59_52_PM-removebg-preview-edited-300x200.png 300w" sizes="(max-width: 434px) 100vw, 434px" /></a></div> <div class="wp-block-group alignfull is-content-justification-space-between is-layout-flex wp-container-core-group-is-layout-cf54d0a6 wp-block-group-is-layout-flex"> <div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-794e3cfa wp-block-columns-is-layout-flex"> <div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:100%"><p class="wp-block-site-tagline">Making JavaScript Clear and Practical</p></div> <div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"> <div style="height:var(--wp--preset--spacing--40);width:0px" aria-hidden="true" class="wp-block-spacer"></div> </div> </div> </div> <div class="wp-block-group alignfull is-content-justification-space-between is-layout-flex wp-container-core-group-is-layout-2ab8c7fb wp-block-group-is-layout-flex"> <p class="has-small-font-size wp-block-paragraph">© 2026 • JavascriptDebugged</p> <p class="has-small-font-size wp-block-paragraph">Inquiries: <strong><a href="mailto:admin@codingeasypeasy.com">admin@javascriptdebugged.com</a></strong></p> </div> </div> </div> </footer> </div> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/twentytwentyfive/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <div class="wp-dark-mode-floating-switch wp-dark-mode-ignore wp-dark-mode-animation wp-dark-mode-animation-bounce " style="right: 10px; bottom: 10px;"> <!-- call to action --> <div class="wp-dark-mode-switch wp-dark-mode-ignore " tabindex="0" role="switch" aria-label="Dark Mode Toggle" aria-checked="false" data-style="1" data-size="1" data-text-light="" data-text-dark="" data-icon-light="" data-icon-dark=""></div></div><script data-wp-router-options="{"loadOnClientNavigation":true}" fetchpriority="low" id="@wordpress/block-library/navigation/view-js-module" src="https://javascriptdebugged.com/wp-includes/js/dist/script-modules/block-library/navigation/view.min.js?ver=96a846e1d7b789c39ab9" type="module"></script> <!-- Koko Analytics v2.5.1 - https://www.kokoanalytics.com/ --> <script> (()=>{var e=window.koko_analytics,c=["utm_source","utm_medium","utm_campaign"],d=/bot|crawl|spider|seo|lighthouse|facebookexternalhit|preview|prerender|headless|phantom|scrapy|python|curl|wget|go-http|okhttp|node-fetch|axios|java\/|libwww|http[-_]?client|monitor|uptime|pingdom|statuscake|validator|scanner/i;function u(){let t={},a=new URLSearchParams(window.location.search),s=new URLSearchParams(window.location.hash.substring(1));return c.forEach(n=>{let r=a.get(n)||s.get(n);r&&(t[n]=r)}),t}e.trackPageview=function(t,a){if(d.test(navigator.userAgent)||window._phantom||window.__nightmare||window.navigator.webdriver||window.Cypress){console.debug("Koko Analytics: Ignoring call to trackPageview because user agent is a bot or this is a headless browser.");return}navigator.sendBeacon(e.url,new URLSearchParams({action:"koko_analytics_collect",pa:t,po:a,r:document.referrer.indexOf(e.site_url)==0?"":document.referrer,m:e.use_cookie?"c":e.method[0],...u()}))};function o(){e.trackPageview(e.path,e.post_id)}function i(){e.autotracked||(o(),e.autotracked=!0)}document.prerendering?document.addEventListener("prerenderingchange",i,{once:!0}):document.visibilityState==="hidden"||document.visibilityState==="prerender"?document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&i()}):i();window.addEventListener("pageshow",t=>{t.persisted&&o()});})(); </script> <script id="prismatic-prism-js" src="https://javascriptdebugged.com/wp-content/plugins/prismatic/lib/prism/js/prism-core.js?ver=3.7.5"></script> <script id="prismatic-prism-toolbar-js" src="https://javascriptdebugged.com/wp-content/plugins/prismatic/lib/prism/js/plugin-toolbar.js?ver=3.7.5"></script> <script id="prismatic-prism-line-highlight-js" src="https://javascriptdebugged.com/wp-content/plugins/prismatic/lib/prism/js/plugin-line-highlight.js?ver=3.7.5"></script> <script id="prismatic-prism-line-numbers-js" src="https://javascriptdebugged.com/wp-content/plugins/prismatic/lib/prism/js/plugin-line-numbers.js?ver=3.7.5"></script> <script id="prismatic-copy-clipboard-js" src="https://javascriptdebugged.com/wp-content/plugins/prismatic/lib/prism/js/plugin-copy-clipboard.js?ver=3.7.5"></script> <script id="prismatic-command-line-js" src="https://javascriptdebugged.com/wp-content/plugins/prismatic/lib/prism/js/plugin-command-line.js?ver=3.7.5"></script> <script id="prismatic-prism-bash-js" src="https://javascriptdebugged.com/wp-content/plugins/prismatic/lib/prism/js/lang-bash.js?ver=3.7.5"></script> <script id="prismatic-prism-jsx-js" src="https://javascriptdebugged.com/wp-content/plugins/prismatic/lib/prism/js/lang-jsx.js?ver=3.7.5"></script> <script id="zoom-social-icons-widget-frontend-js" src="https://javascriptdebugged.com/wp-content/plugins/social-icons-widget-by-wpzoom/assets/js/social-icons-widget-frontend.js?ver=1780124671"></script> <script id="wp-emoji-settings" type="application/json"> {"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://javascriptdebugged.com/wp-includes/js/wp-emoji-release.min.js?ver=7.0.2"}} </script> <script type="module"> /*! This file is auto-generated */ const a=JSON.parse(document.getElementById("wp-emoji-settings").textContent),o=(window._wpemojiSettings=a,"wpEmojiSettingsSupports"),s=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(o,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const a=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===a[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e<n.data.length;e++)if(0!==n.data[e])return!1;return!0}function u(e,t,n,a){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\udde8\ud83c\uddf6","\ud83c\udde8\u200b\ud83c\uddf6")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!a(e,"\ud83e\u1fac8")}return!1}function f(e,t,n,a){let r;const o=(r="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):document.createElement("canvas")).getContext("2d",{willReadFrequently:!0}),s=(o.textBaseline="top",o.font="600 32px Arial",{});return e.forEach(e=>{s[e]=t(o,e,n,a)}),s}function r(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}a.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(o));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(s),u.toString(),c.toString(),p.toString()].join(",")+"));",a=new Blob([e],{type:"text/javascript"});const r=new Worker(URL.createObjectURL(a),{name:"wpTestEmojiSupports"});return void(r.onmessage=e=>{i(n=e.data),r.terminate(),t(n)})}catch(e){}i(n=f(s,u,c,p))}t(n)}).then(e=>{for(const n in e)a.supports[n]=e[n],a.supports.everything=a.supports.everything&&a.supports[n],"flag"!==n&&(a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&a.supports[n]);var t;a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&!a.supports.flag,a.supports.everything||((t=a.source||{}).concatemoji?r(t.concatemoji):t.wpemoji&&t.twemoji&&(r(t.twemoji),r(t.wpemoji)))}); //# sourceURL=https://javascriptdebugged.com/wp-includes/js/wp-emoji-loader.min.js </script> <script> (function() { function applyScrollbarStyles() { if (!document.documentElement.hasAttribute('data-wp-dark-mode-active')) { document.documentElement.style.removeProperty('scrollbar-color'); return; } document.documentElement.style.setProperty('scrollbar-color', '#2E334D #1D2033', 'important'); // Find and remove dark mode engine scrollbar styles. var styles = document.querySelectorAll('style'); styles.forEach(function(style) { if (style.id === 'wp-dark-mode-scrollbar-custom') return; if (style.textContent && style.textContent.indexOf('::-webkit-scrollbar') !== -1 && style.textContent.indexOf('#1D2033') === -1) { style.textContent = style.textContent.replace(/::-webkit-scrollbar[^}]*\{[^}]*\}/g, ''); style.textContent = style.textContent.replace(/::-webkit-scrollbar-track[^}]*\{[^}]*\}/g, ''); style.textContent = style.textContent.replace(/::-webkit-scrollbar-thumb[^{]*\{[^}]*\}/g, ''); style.textContent = style.textContent.replace(/::-webkit-scrollbar-corner[^}]*\{[^}]*\}/g, ''); } }); // Inject our styles. var existing = document.getElementById('wp-dark-mode-scrollbar-custom'); if (!existing) { var customStyle = document.createElement('style'); customStyle.id = 'wp-dark-mode-scrollbar-custom'; customStyle.textContent = '::-webkit-scrollbar { width: 12px !important; height: 12px !important; background: #1D2033 !important; }' + '::-webkit-scrollbar-track { background: #1D2033 !important; }' + '::-webkit-scrollbar-thumb { background: #2E334D !important; border-radius: 6px; }' + '::-webkit-scrollbar-thumb:hover { filter: brightness(1.2); }' + '::-webkit-scrollbar-corner { background: #1D2033 !important; }'; document.body.appendChild(customStyle); } } // Listen for dark mode changes. document.addEventListener('wp_dark_mode', function(e) { setTimeout(applyScrollbarStyles, 100); setTimeout(applyScrollbarStyles, 500); setTimeout(applyScrollbarStyles, 1000); }); // Observe attribute changes. var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.attributeName === 'data-wp-dark-mode-active') { var existing = document.getElementById('wp-dark-mode-scrollbar-custom'); if (existing && !document.documentElement.hasAttribute('data-wp-dark-mode-active')) { existing.remove(); } setTimeout(applyScrollbarStyles, 100); setTimeout(applyScrollbarStyles, 500); } }); }); observer.observe(document.documentElement, { attributes: true }); // Initial apply. setTimeout(applyScrollbarStyles, 100); setTimeout(applyScrollbarStyles, 500); setTimeout(applyScrollbarStyles, 1000); })(); </script> </body> </html>