PaoloJulian.dev - Article

go to article list

How to Integrate Contentful to Next 13

β€” Paolo Vincent Julian
How to Integrate Contentful to Next 13 banner

Banner - How to Integrate Contenful to Next 13

LAST UPDATEDΒ 

Hey there, content creators and tech enthusiasts! πŸš€ Imagine a world where managing your website's content is as smooth as a summer breeze. That's exactly what happens when you bring Contentful and Next.js together.

In this blog post, we're your guides to this exciting journey of integrating Contentful – your content management powerhouse – with Next.js – the magic wand for crafting web applications. No more hassle, no more headaches. Just pure content management bliss.

Whether you're a coding whiz or a content aficionado, we're here to break down the process step by step. Say goodbye to content chaos and hello to a harmonious collaboration between your content and your website. Ready to make your website a content paradise? Let's dive in! 🌟

Table of Contents

  1. Step 1: What is Contentful and Next.js SSG
  2. Step 2: Preparing Your Workspace
  3. Step 3: Integrate Contentful in Next.js
  4. Step 4: Displaying Content
  5. Step 5: Deployment to Vercel - Taking Your Site Live!
  6. Step 6: Dynamic Content Updates - Keeping Vercel in Sync
  7. Conclusion: Just the Beginning

Step 1: What is Contentful and Next.js SSG

Welcome to the exciting synergy of Contentful and the SSG magic of Next.js!

Contentful

Your reliable content manager facilitates effortless content creation and organization. It operates as a headless CMS, meaning content is retrieved through API calls, distinguishing it from traditional CMS platforms like WordPress and others.

Next.js

This is where the real magic happens. It's like the wizard behind the curtain, conjuring up speedy and super-responsive websites, thanks to its Server-Side Generation (SSG) charm. And it doesn't stop at speed – it's also your ticket to nailing SEO and giving users an unbeatable experience.

Why They Click?

Contentful crafts your content, while Next.js SSG elegantly delivers it. This dynamic duo breaks free from traditional CMS, embracing flexible creativity.

Intrigued? Let's dive into the steps of integrating Contentful with Next.js. Whether you're a coding maestro or a curious newcomer, you're in for an empowering journey. Head over to Step 2 and set up your workspace for this exciting adventure!

Step 2: Preparing Your Workspace

Now that you're acquainted with Contentful and Next.js SSG, let's get your digital playground ready. Don't worry, we're here to guide you, whether you're a seasoned developer or a curious newcomer.

Setting Up Contentful

1. Create a Contentful Account: Head to Contentful and create an account for efficient content management.

2. Set Up Your Space and Content Models: Organize content in spaces – your digital canvas for crafting content masterpieces.

Content Model Example

Picture of Content Model Example
Picture of Content Model Example

Setting up Next.js

1. Install and Create Next.js: Get the latest Next.js version on your machine – follow the installation guide here.

2. Set Up Your Project Structure: Craft an organized Next.js project structure for seamless content integration. Check out the standard folder structure here.

With a solid foundation, your Contentful and Next.js SSG playground is ready. Head to Step 3 and connect the dots between Contentful and Next.js.

Step 3: Integrate Contentful in Next.js

1. Setup environment variables: Secure Contentful credentials with environment variables in your Next.js project.

bash
# .env.local
CONTENTFUL_SPACE_ID=
CONTENTFUL_ACCESS_TOKEN=
CONTENTFUL_ENV=

2. Choosing your API path -Use GraphQL API with Fetch API. -Or employ the contentful npm package for Contentful's REST API.

Our Choice: Standard Fetch with GraphQL

typescript
// /src/_lib/contentful-graphql.ts

const ENV = process.env.CONTENTFUL_ENV;
const SPACE = process.env.CONTENTFUL_SPACE_ID;
const TOKEN = process.env.CONTENTFUL_ACCESS_TOKEN;
const URL = `https://graphql.contentful.com/content/v1/spaces/${SPACE}/environments/${ENV}`;
const headers = {
  Authorization: `Bearer ${TOKEN}`,
  'Content-Type': 'application/json'
}

const contentfulGQLClient = {
  query: ({ query, variables = undefined }: { query: string, variables?: Record<string, string> }) => {
    return fetch(URL, {
      method: 'POST',
      headers,
      body: JSON.stringify({ query, variables })
    })
  }
}

export default contentfulGQLClient

With Contentful and Next.js SSG seamlessly connected, you're ready to fetch and display content. Dive into Step 4 and unleash captivating content displays!

Step 4: Displaying Content

Welcome to the heart of content integration! Display your fetched blog posts using captivating components and make your visitors spellbound.

Crafting Dynamic Content Templates

1. Creating the Blog List Page:

tsx
// /src/app/blogs/page.tsx
import React, { FunctionComponent } from 'react';

const BlogsPage: FunctionComponent = () => {
  return (
    <div className="flex flex-col space-y-8"></div>
  );
}

export default BlogsPage;

2. Crafting the Blog Post Component:

tsx
// /src/app/blogs/_components/blog-post-item.tsx
import Image from 'next/image';
import React, { FunctionComponent } from 'react';

export type BlogPostItemProps = {
  imageUrl: string;
  title: string;
  description: string;
  publishedDate: string;
};

const BlogPostItem: FunctionComponent<BlogPostItemProps> = ({
  imageUrl,
  title,
  description,
  publishedDate,
}) => {
  return (
    <div className='flex flex-row space-x-8 items-center'>
      <div className='relative w-[400px] h-[300px]'>
        <Image alt={title} src={imageUrl} layout='fill' />
      </div>
      <div>
        <p className='text-gray-700'>
          <time dateTime={publishedDate}>{publishedDate}</time>
        </p>
        <h3 className='text-gray-700 font-semibold text-xl'>{title}</h3>
        <p className='text-gray-600 line-clamp-3'>{description}</p>
      </div>
    </div>
  );
};

export default BlogPostItem;

Fetching Content

Now that you've set the stage, let's fetch your compelling blog content from Contentful.

1. Creating the Blog Post API: Craft an API that fetches the latest blog posts using the GraphQL library we built in Step 3.

typescript
// /src/_api/blog-post.ts

import contentfulGQLClient from "@/_lib/contentful-graphql";
import { IBlogPost } from "../_contentful";

export async function getLatestBlogPosts(): Promise<IBlogPost[]> {
  // initiate query params
  const query = `
    query GetBlogPostBySlug {
      blogPostCollection (limit: 5) {
        items {
          title
          description
          banner {
            url
          }
          sys {
            publishedAt
          }
        }
      }
    }
  `;

  // fetch data
  const res = await contentfulGQLClient.query({ query });
  const { data } = await res.json();

  return data.blogPostCollection.items;
}

2. Integrating the API in the Blog List Page: Integrate the API into your blog list page using the newly introduced API functionality in Next.js 13.

tsx
// /src/app/blogs/page.tsx
import React, { FunctionComponent } from 'react';
import { getLatestBlogPosts } from '@/_api/blog-post';

const BlogsPage: FunctionComponent = async () => {
  const blogPosts = await getLatestBlogPosts();
  console.log({ blogPosts });

  return (
    <div className="flex flex-col space-y-8"></div>
  );
}

export default BlogsPage;

Displaying Content

Now comes the exciting part – displaying your fetched blog posts for the world to see!

1. Displaying the Fetched Blog Posts: It's time to showcase your fetched blog posts using the BlogPostItem component.

tsx
// /src/app/blogs/page.tsx
import React, { FunctionComponent } from 'react';
import { getLatestBlogPosts } from '@/_api/blog-post';
import BlogPostItem from '@/app/blogs/_components/blog-post-item.tsx';

const BlogsPage: FunctionComponent = async () => {
  const blogPosts = await getLatestBlogPosts();

  return (
    <div className="flex flex-col space-y-8">
      {blogPosts.map((blogPost, i) => (
        <BlogPostItem
          key={i}
          title={blogPost.title}
          description={blogPost.description}
          imageUrl={blogPost.banner.url}
          publishedDate={blogPost.sys.publishedAt}
        />
      ))}
    </div>
  );
}

export default BlogsPage;

Fetching and displaying content is a breeze! Dive into Step 5 for the exciting journey of deploying your masterpiece to Vercel.

Step 5: Deployment to Vercel - Taking Your Site Live!

Step 5 introduces the exciting journey of deploying your Next.js SSG site integrated with Contentful to Vercel, where your creation will shine brightly on the web.

Preparing for Deployment

1. Create a New Vercel Account: Head to Vercel and create an account for seamless deployment and hosting.

2. Connect Your GitHub Repository: In Vercel dashboard, connect your GitHub repository for automatic build and deployment.

Import Git Repository
Import Git Repository

3. Create a New Deployment: Initiate a new deployment on Vercel. The powerful CI/CD pipeline will handle the process.

4. Configure Environment Variables: Secure sensitive information by configuring environment variables on Vercel. Add the same variables you used in previous steps, including CONTENTFUL_SPACE_ID, CONTENTFUL_ACCESS_TOKEN, CONTENTFUL_ENV

Add Environment Variables
Add Environment Variables
.

5. Deploy! Hit the deploy button! Vercel will build and deploy your Next.js SSG site enriched with Contentful integration.

Ready to showcase your masterpiece to the world? Move to Step 6, where real-time magic awaits!

Step 6: Dynamic Content Updates - Keeping Vercel in Sync

Prepare to dive into real-time content management! Step 6 unravels the magic of dynamic updates, ensuring your Next.js SSG site stays in sync with Contentful changes.

On-demand Revalidation

Next.js has a blog post about this, you can also check it out.

Add a revalidate route

typescript
import { NextRequest, NextResponse } from 'next/server'
import { revalidateTag } from 'next/cache'

const allowedOrigins = [
  'https://app.contentful.com'
]

export async function POST(request: NextRequest) {
  const secret = request.nextUrl.searchParams.get('secret')
  const tag = request.nextUrl.searchParams.get('tag')

  if (secret !== process.env.CONTENTFUL_REVALIDATE_SECRET) {
    return NextResponse.json({ message: 'Invalid secret' }, { status: 401 })
  }

  if (!tag) {
    return NextResponse.json({ message: 'Missing tags' }, { status: 400 })
  }

  revalidateTag(tag)

  return NextResponse.json({ revalidated: true, date: Date.now() }, { status: 200 })
}

export async function OPTIONS(request: NextRequest) {
  let origin: string = '*'
  if (process.env.NODE_ENV === 'production') {
    origin = request.headers.get('Origin') || '';
    if (origin && !allowedOrigins.includes(origin)) {
      return NextResponse.json({ message: 'Bad Request' }, { status: 400 })
    }
  }

  return new Response(null, {
    status: 200,
    headers: {
      'Access-Control-Allow-Origin': origin,
      'Access-Control-Allow-Methods': 'POST',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
    },
  })
}

Be sure to add in a CONTENTFUL_REVALIDATE_SECRET so that your webhook URL is secure.

Contentful Webhooks: Next, connect your Vercel hook to trigger a deploy whenever content is updated in Contentful. -Open your Contentful space. -Access Settings and select Webhooks. -Create a new webhook and enter your revalidate route https://(your-domain)/api/revalidate?tag=blogPost&secret=(your-secret).

Here is my example.
Here is my example.

That's it! Your content will now seamlessly sync in real time.

Automatic Revalidation

Allow data to be revalidated at set intervals. Use the next.revalidate option with fetch to establish cache lifetimes.

Read more at Next.js revalidation strategies

javascript
fetch('https://...', { next: { revalidate: 3600 } })

Conclusion: Just the Beginning

Congratulations, you've journeyed through the core aspects of integrating Contentful with Next.js SSG! You've crafted a dynamic content powerhouse, ready to captivate your audience. But remember, this is just the tip of the iceberg. Stay tuned for upcoming advanced blogs, where we'll dive into specific topics like Preview API, Remark integration, and more. Your path to content excellence is an ongoing adventure – happy coding!

TAGS:

#nextjs

#nextjs13

#contentful

#preview

#auto-sync

go to article list