Building a Modern Portfolio Website with Next.js and React

A practical guide to building a professional developer portfolio using Next.js App Router, React, Tailwind CSS, and Framer Motion — from project structure to deployment.

next.jsreactportfolioweb-developmenttailwind-css

By Keegan Kelly

Why Next.js for Your Portfolio

Your portfolio is often the first thing potential clients or employers see. It needs to be fast, look great, and rank well on Google. Next.js checks all these boxes with built-in server-side rendering, image optimization, and SEO-friendly metadata APIs.

I built the khkstudios portfolio you're currently reading with Next.js 16, React 19, and Tailwind CSS 4. Here's what I learned and how you can build your own.

Choosing the Right Stack

For a modern developer portfolio, here's the stack I recommend:

  • Next.js (App Router) — Server-side rendering, file-based routing, and built-in optimizations
  • React — Component-based UI with a massive ecosystem
  • Tailwind CSS — Utility-first styling that's fast to write and easy to maintain
  • Framer Motion — Smooth, performant animations
  • TypeScript — Type safety that catches bugs before they reach production

Project Structure

Organize your project for clarity and scalability:

app/
  page.tsx          # Homepage
  about/page.tsx    # About page
  work/page.tsx     # Portfolio/projects
  blog/page.tsx     # Blog (optional but great for SEO)
  layout.tsx        # Root layout with nav, footer, analytics
components/
  Navigation.tsx
  Footer.tsx
  ContactForm.tsx
  ...
lib/
  constants.ts      # Centralized config
  blog.ts          # Blog utilities (if using MDX)
content/
  blog/            # MDX blog posts
public/
  fonts/           # Custom typography
  image/           # Optimized images
  logo/            # Brand assets

Key Architecture Decisions

Server vs Client Components

One critical lesson: keep your page files as server components and extract animated/interactive content into separate client components. This enables:

  • Per-page metadata exports (critical for SEO)
  • Server-side rendering for faster initial loads
  • JSON-LD structured data injection
// app/page.tsx (server component)
export const metadata = { title: '...' }
export default function Home() {
  return <HomePageClient />
}

// components/HomePageClient.tsx (client component)
'use client'
export default function HomePageClient() {
  // Animations, interactions, etc.
}

SEO from Day One

Don't leave SEO as an afterthought. Set up these essentials before launching:

  • Per-page metadata with targeted title tags and descriptions
  • Sitemap using Next.js's sitemap.ts convention
  • Robots.txt via robots.ts
  • JSON-LD structured data for Person/Organization schemas
  • Canonical URLs on every page
  • Open Graph and Twitter cards for social sharing

Contact Form with Validation

A portfolio without a contact form is leaving conversions on the table. Use React Hook Form with Zod for schema validation, and Resend for email delivery:

  • Client-side validation with real-time error messages
  • Server-side validation in the API route
  • Rate limiting to prevent spam
  • GTM event tracking for conversion analytics

Design Tips for Developer Portfolios

  1. Keep it clean — Let your work speak for itself. Avoid cluttered layouts.
  2. Show, don't just tell — Link to live projects, not just descriptions.
  3. Include a tech stack — Clients want to know what you work with.
  4. Make contact easy — CTA buttons, contact form, phone, email, WhatsApp — give visitors options.
  5. Performance matters — A slow portfolio site is a bad first impression. Target 90+ Lighthouse scores.

Deployment

For Next.js, your best options are:

  • Vercel — Zero-config deployment, built by the Next.js team
  • Self-hosted — Docker container on a VPS for full control
  • Coolify — Self-hosted PaaS alternative to Vercel

Performance Optimization

  • Use Next.js Image component for automatic image optimization
  • Load fonts with @font-face and font-display: swap
  • Use afterInteractive strategy for analytics scripts
  • Enable response compression in next.config.ts
  • Lazy load below-the-fold content with Framer Motion's whileInView

Building a portfolio is an ongoing process. Start with the essentials, ship it, and iterate. Check out my portfolio for inspiration, or browse the tools I use for development.

Let's Build Something Together

Whether you need a web application, analytics dashboard, or data pipeline — I'm here to help. Fill out the form below, or reach out directly via WhatsApp or phone.