SaketSingh

Integrating Contentful CMS with Next.js Portfolio

👤Saket Singh
|
đź“…July 30, 2025
|
⏱️4 min read
Integrating Contentful CMS with Next.js Portfolio

Make your content dynamic without touching code again!

Want to update your portfolio without opening VS Code every time? That’s where Contentful CMS + Next.js becomes a powerful combo. In this post, I’ll show you how to connect your Contentful dashboard to your Next.js portfolio, step-by-step.


🧠 What’s the idea here?

Instead of hardcoding all your portfolio data (like projects, blogs, testimonials) into .tsx files, you can store and manage it in Contentful, a headless CMS. Then your Next.js site will fetch and display it automatically using Contentful’s APIs.

This setup means:
  • âś… No redeployment needed for every content change
  • âś… Non-techies can update content too
  • âś… Fast and flexible front-end with server-rendered content

đź”§ Tech stack used

  • Next.js (latest version, with App Router)
  • Contentful (Free tier works great)
  • TypeScript (Optional but recommended)
  • Incremental Static Regeneration (ISR) for best performance

🪜 Step-by-Step Guide

1. 🏗️ Create a Contentful account

  1. Go to https://contentful.com
  2. Sign up → Create a new Space (name it like “My Portfolio”)
  3. Under that space, create Content Models for what you want to display (e.g., Projects, Blogs, Testimonials)

Example Model: “Project”

  • title (Text)
  • slug (Text, unique identifier)
  • description (Long text or Rich Text)
  • image (Media → Image)
  • link (URL)

💡 You can later add more fields, like “technologies, experience, or about us.


2. đź§Ş Add some test content

  • Go to “Content” → Add a few projects manually.
  • Make sure to Publish them, or they won’t be fetched by your app.

3. 🔑 Get your Contentful API credentials

  • Go to:
    • Settings → API Keys → Create new API key
  • Note down:
    • Space ID
    • Content Delivery API - Access Token

4. 🤖 Setup your Next.js project

If you haven’t already:

npx create-next-app@latest my-portfolio
cd my-portfolio

Install Contentful SDK:

npm install contentful

Create a .env.local file in the root and add:

CONTENTFUL_SPACE_ID=your_space_id_here
CONTENTFUL_ACCESS_TOKEN=your_access_token_here

5. 📦 Create a Contentful client

Inside lib/contentful.ts:

import { createClient } from 'contentful';

export const contentfulClient = createClient({
  space: process.env.CONTENTFUL_SPACE_ID!,
  accessToken: process.env.CONTENTFUL_ACCESS_TOKEN!,
});

6. 📥 Fetch data from Contentful

Create a function like this in lib/projects.ts:

import { contentfulClient } from './contentful';

export async function getProjects() {
  const response = await contentfulClient.getEntries({ content_type: 'project' });

  return response.items.map((item: any) => ({
    title: item.fields.title,
    slug: item.fields.slug,
    description: item.fields.description,
    image: item.fields.image?.fields.file.url,
    link: item.fields.link,
  }));
}
Replace 'project' with your actual content type ID (you’ll find this in Content Model → Settings → API Identifier).

7. đź’» Show it in your Next.js page

For example, in app/projects/page.tsx:

import { getProjects } from '@/lib/projects';

export default async function ProjectsPage() {
  const projects = await getProjects();

  return (
    <div className="p-6">
      <h1 className="text-3xl font-bold mb-4">My Projects</h1>
      <ul className="grid grid-cols-1 md:grid-cols-2 gap-6">
        {projects.map((proj) => (
          <li key={proj.slug} className="border rounded-xl p-4 shadow-md">
            <img src={proj.image} alt={proj.title} className="rounded-lg mb-2" />
            <h2 className="text-xl font-semibold">{proj.title}</h2>
            <p className="text-gray-600">{proj.description}</p>
            <a href={proj.link} className="text-blue-500 mt-2 block" target="_blank">View Project</a>
          </li>
        ))}
      </ul>
    </div>
  );
}

8. ⚡ Use ISR for faster builds

You can use generateStaticParams and revalidate inside your Next.js App Router pages to cache and auto-update.

Inside app/projects/page.tsx:

export const revalidate = 60; // Revalidate every 60 seconds

9. đź§Ş Test it locally

Run your project:

npm run dev

Visit http://localhost:3000/projects – your dynamic Contentful data should now show up!


âś… Final Thoughts

Using Contentful with Next.js makes your portfolio super flexible and client-friendly. You just need to build the UI once, and from then on, you (or anyone else) can update the data from the CMS without touching the code.


📌 Bonus Tips

  • You can connect multiple models like Blogs, Testimonials, Services, etc.
  • Use Contentful’s Rich Text renderer if you want advanced formatting in content.
  • Set up webhooks from Contentful to Vercel for instant redeploys.

📎 Useful Links


Tags

#Contentful#Headless Cms#Nextjs
Share this post: