Build a Simple Next.js Interactive Web-Based Portfolio

Written by

in

In today’s digital age, a personal portfolio website is more than just a nice-to-have; it’s a necessity. It’s your online resume, a showcase of your skills, and a direct line to potential clients or employers. But building one from scratch can seem daunting, especially if you’re not a seasoned web developer. That’s where Next.js comes in. With its powerful features and ease of use, Next.js provides an excellent framework for creating dynamic, SEO-friendly, and visually appealing portfolio websites. In this tutorial, we’ll walk you through building a simple, interactive portfolio using Next.js, suitable for showcasing your projects, skills, and contact information.

Why Next.js for Your Portfolio?

Next.js is a React framework that offers several advantages for building a portfolio:

  • Server-Side Rendering (SSR) and Static Site Generation (SSG): Next.js can pre-render your pages, improving SEO and initial load times. This is crucial for a portfolio, where you want to make a great first impression.
  • Easy Routing: Next.js simplifies routing, making it easy to create different sections for your portfolio, such as a home page, projects page, and contact page.
  • Built-in Image Optimization: Next.js automatically optimizes images, ensuring your portfolio looks great without sacrificing performance.
  • Fast Development: With features like hot module replacement and a streamlined development process, Next.js speeds up the development lifecycle.

Project Overview: What We’ll Build

Our goal is to create a simple, yet effective, portfolio website. It will include the following sections:

  • Home Page: A brief introduction about you, perhaps with a headshot and a call to action.
  • Projects Page: A showcase of your projects with descriptions and links.
  • Skills Section: A list of your skills.
  • Contact Page: A contact form or contact information.

We’ll keep the design clean and modern, focusing on showcasing your work effectively.

Prerequisites

Before we begin, make sure you have the following installed:

  • Node.js and npm (or yarn): You’ll need Node.js and npm (Node Package Manager) or yarn installed to manage project dependencies. You can download them from nodejs.org.
  • A Code Editor: A code editor like VS Code, Sublime Text, or Atom is recommended.
  • Basic Understanding of HTML, CSS, and JavaScript: Familiarity with these languages will be helpful.

Step-by-Step Tutorial

1. 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 my-portfolio

This command will create a new directory called my-portfolio with the basic structure of a Next.js project. Navigate into the project directory:

cd my-portfolio

2. Project Structure and File Overview

Your project directory will look something like this:

my-portfolio/
├── node_modules/
├── pages/
│   ├── _app.js
│   ├── index.js
│   └── api/
│       └── hello.js
├── public/
│   └── ...
├── styles/
│   └── globals.css
├── .gitignore
├── next.config.js
├── package-lock.json
├── package.json
└── README.md
  • pages/: This directory contains your pages. Each JavaScript file in this directory represents a route in your application. For example, pages/index.js will be the home page (/).
  • public/: This directory holds static assets like images, fonts, and other files.
  • styles/: This directory contains your CSS files.
  • _app.js: This is the root component of your application. You can use it to apply global styles or layouts.

3. Creating the Home Page (index.js)

Open pages/index.js. This is where we’ll build the home page. Replace the existing content with the following:

import Head from 'next/head';
import styles from '../styles/Home.module.css';

export default function Home() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Your Name | Portfolio</title>
        <meta name="description" content="Your Name's Portfolio - showcasing projects, skills, and contact information." />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>
          Welcome to My Portfolio!
        </h1>

        <p className={styles.description}>
          Hi, I'm [Your Name]. I'm a [Your Profession] with a passion for [Your Passion].
        </p>

        <div className={styles.grid}>
          <a href="/projects" className={styles.card}>
            <h2>Projects &rarr;</h2>
            <p>Check out my latest projects.</p>
          </a>

          <a href="/skills" className={styles.card}>
            <h2>Skills &rarr;</h2>
            <p>See my skills and expertise.</p>
          </a>

          <a href="/contact" className={styles.card}>
            <h2>Contact &rarr;</h2>
            <p>Get in touch with me.</p>
          </a>
        </div>
      </main>

      <footer className={styles.footer}>
        <a
          href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          Powered by{' '}
          <img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
        </a>
      </footer>
    </div>
  )
}

This code defines the basic structure of the home page. We’ve included a <Head> component for the page title and meta description (important for SEO), a main section with a welcome message and links to other sections of the portfolio, and a footer.

Important: Replace [Your Name] and [Your Profession] with your actual information.

4. Styling the Home Page (styles/Home.module.css)

Now, let’s add some basic styling. Open styles/Home.module.css and replace the existing styles with the following:

.container {
  min-height: 100vh;
  padding: 0 0.5rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: #f5f5f5;
}

.main {
  padding: 5rem 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.footer {
  width: 100%;
  height: 100px;
  border-top: 1px solid #eaeaea;
  display: flex;
  justify-content: center;
  align-items: center;
}

.footer img {
  margin-left: 0.5rem;
}

.footer a {
  display: flex;
  justify-content: center;
  align-items: center;
  text-decoration: none;
}

.title {
  margin: 0;
  line-height: 1.15;
  font-size: 4rem;
  text-align: center;
}

.description {
  text-align: center;
  font-size: 1.5rem;
  margin-bottom: 2rem;
}

.grid {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  max-width: 800px;
}

.card {
  margin: 1rem;
  padding: 1.5rem;
  text-align: left;
  color: inherit;
  text-decoration: none;
  border: 1px solid #eaeaea;
  border-radius: 10px;
  transition: color 0.15s ease, border-color 0.15s ease;
  width: 300px;
}

.card:hover,
.card:focus,
.card:active {
  color: #0070f3;
  border-color: #0070f3;
}

.card h2 {
  margin: 0 0 1rem 0;
  font-size: 1.5rem;
}

.card p {
  margin: 0;
  font-size: 1.25rem;
  line-height: 1.5;
}

.logo {
  height: 1em;
}

This CSS provides basic styling for the layout, headings, descriptions, and links. You can customize these styles to match your preferred design.

5. Creating the Projects Page (pages/projects.js)

Create a new file named pages/projects.js and add the following code:

import Head from 'next/head';
import styles from '../styles/Home.module.css'; // Reuse some styles

export default function Projects() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Your Name | Projects</title>
        <meta name="description" content="Your Name's Projects" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>Projects</h1>

        <div className={styles.grid}>
          <!-- Project Cards will go here -->
          <div className={styles.card}>
            <h2>Project 1 &rarr;</h2>
            <p>Brief description of project 1.</p>
            <a href="#">View Project</a>
          </div>

          <div className={styles.card}>
            <h2>Project 2 &rarr;</h2>
            <p>Brief description of project 2.</p>
            <a href="#">View Project</a>
          </div>
        </div>
      </main>
    </div>
  )
}

This creates a basic projects page. We’re reusing the styles/Home.module.css for consistent styling. Replace the placeholder project cards with your actual project details, including project names, descriptions, and links to live demos or GitHub repositories.

6. Creating the Skills Page (pages/skills.js)

Create a new file named pages/skills.js and add the following code:

import Head from 'next/head';
import styles from '../styles/Home.module.css';

export default function Skills() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Your Name | Skills</title>
        <meta name="description" content="Your Name's Skills" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>Skills</h1>

        <ul>
          <li>Skill 1</li>
          <li>Skill 2</li>
          <li>Skill 3</li>
          <!-- Add more skills here -->
        </ul>
      </main>
    </div>
  )
}

This creates a skills page with a simple unordered list. Replace the placeholder skills with your actual skills.

7. Creating the Contact Page (pages/contact.js)

Create a new file named pages/contact.js and add the following code:

import Head from 'next/head';
import styles from '../styles/Home.module.css';

export default function Contact() {
  return (
    <div className={styles.container}>
      <Head>
        <title>Your Name | Contact</title>
        <meta name="description" content="Contact Your Name" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <h1 className={styles.title}>Contact</h1>

        <p>Email: <a href="mailto:[your_email]">[your_email]</a></p>
        <p>LinkedIn: <a href="[your_linkedin_profile]">[Your LinkedIn]</a></p>
        <!-- Add other contact methods -->
      </main>
    </div>
  )
}

This creates a basic contact page with your email and LinkedIn profile. Replace [your_email], [your_linkedin_profile], and [Your LinkedIn] with your actual contact information.

8. Adding Navigation (components/Navbar.js)

To make navigation easier, let’s create a navigation component. Create a new directory called components in the root of your project. Inside the components directory, create a file named Navbar.js and add the following code:

import Link from 'next/link';
import styles from '../styles/Navbar.module.css';

export default function Navbar() {
  return (
    <nav className={styles.navbar}>
      <Link href="/">
        <a className={styles.navlink}>Home</a>
      </Link>
      <Link href="/projects">
        <a className={styles.navlink}>Projects</a>
      </Link>
      <Link href="/skills">
        <a className={styles.navlink}>Skills</a>
      </Link>
      <Link href="/contact">
        <a className={styles.navlink}>Contact</a>
      </Link>
    </nav>
  );
}

Create a new file named styles/Navbar.module.css and add the following styles:


.navbar {
  background-color: #333;
  padding: 1rem 0;
  text-align: center;
}

.navlink {
  color: white;
  text-decoration: none;
  margin: 0 1rem;
  font-weight: bold;
}

.navlink:hover {
  color: #ccc;
}

Now, import and use the Navbar component in your pages/_app.js file to make it available on all pages:

import '../styles/globals.css';
import Navbar from '../components/Navbar';

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Navbar />
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

9. Running Your Portfolio

To run your portfolio, open your terminal, navigate to your project directory, and run the following command:

npm run dev  # or yarn dev

This will start the development server. Open your browser and go to http://localhost:3000 to see your portfolio.

Common Mistakes and How to Fix Them

As you build your portfolio, you might encounter some common issues. Here’s a look at some of them and how to resolve them:

  • Incorrect File Paths: Make sure your file paths (e.g., when importing styles or components) are correct. Double-check your imports and relative paths.
  • CSS Specificity Issues: If your styles aren’t applying as expected, you might have CSS specificity issues. Use the browser’s developer tools to inspect the elements and see which styles are overriding others. You can try increasing the specificity of your styles (e.g., by adding more specific selectors) or using the !important declaration (use this sparingly).
  • Routing Errors: If you’re having trouble with navigation, verify that your route paths in the Link components are correct and that the corresponding files exist in your pages directory.
  • Image Optimization Problems: Ensure that your images are in the public directory if you are using static image imports. For dynamic images, make sure you are using the next/image component correctly, and that your image paths are valid.
  • Missing Dependencies: If you encounter errors about missing modules, make sure you’ve installed all necessary dependencies using npm install or yarn install.

SEO Best Practices

Optimizing your portfolio for search engines is crucial for visibility. Here are some SEO best practices:

  • Use Relevant Keywords: Include relevant keywords in your page titles, meta descriptions, headings, and content. Think about what people might search for to find your portfolio (e.g., “web developer portfolio,” “[your city] web designer”).
  • Write Compelling Meta Descriptions: Craft concise and compelling meta descriptions for each page. These descriptions appear in search results and can influence click-through rates.
  • Optimize Image Alt Text: Add descriptive alt text to your images. This helps search engines understand the content of your images and improves accessibility.
  • Use Descriptive URLs: Make your URLs descriptive and easy to understand (e.g., /projects, /skills).
  • Ensure Mobile-Friendliness: Make sure your portfolio is responsive and looks good on all devices.
  • Submit a Sitemap: Create a sitemap and submit it to search engines like Google and Bing to help them crawl and index your site effectively. Next.js can help you generate a sitemap.
  • Use Heading Tags Correctly: Use heading tags (<h1> to <h6>) to structure your content logically and indicate the hierarchy of information. Use only one <h1> tag per page.

Key Takeaways and Next Steps

Building a portfolio website with Next.js is a rewarding project that can significantly boost your online presence. We’ve covered the essential steps to get you started, from setting up your project to creating pages for your projects, skills, and contact information. Remember to replace the placeholder content with your own information and projects. Customize the design to reflect your personal brand. You can expand your portfolio further by adding features like a blog, testimonials, a more advanced project showcase, and integration with social media. Consider deploying your portfolio to a platform like Vercel or Netlify for easy hosting and deployment.

By following this guide, you should now have a solid foundation for your personal portfolio. This website will not only serve as a digital storefront for your skills and experience but also as a testament to your ability to adapt and learn new technologies. Keep refining your portfolio, updating it with your latest projects, and using it to connect with potential clients and employers. The more you put into your portfolio, the more you will get out of it. Good luck, and happy coding!