Integrating Sanity with Next.js: A Step-by-Step Guide

Introduction


Overview of Sanity and Next.js

Sanity is a powerful headless CMS that offers real-time collaboration, flexible content modeling, and a robust API for delivering content to various platforms. Next.js, on the other hand, is a React framework that supports server-side rendering (SSR) and static site generation (SSG), making it a perfect match for building high-performance web applications.

Purpose of Integration

Integrating Sanity with Next.js allows developers to manage content dynamically while leveraging Next.js’s performance optimizations. This integration is ideal for creating fast, SEO-friendly, and scalable web applications with a seamless content management experience.

1. Setting Up Sanity

Create a Sanity Project

  1. Install the Sanity CLI: Open your terminal and run:
    npm install -g @sanity/cli
  2. Initialize a New Project:
    sanity init
    

    Choose a project template: Select “Blog (schema + sample data)” for a quick start. Configure your project: Follow the prompts to configure your project, including the project name, dataset, and preferred features.

  3. Deploy Sanity Studio:
    sanity deploy
    

This command will deploy your Sanity Studio to the web, allowing you to manage content online.

Configure Your Schema
Sanity allows you to define custom schemas for your content. Here’s an example of a simple schema for a blog post:
				
					export default {
  name: 'post',
  title: 'Post',
  type: 'document',
  fields: [
    { name: 'title', title: 'Title', type: 'string' },
    { name: 'slug', title: 'Slug', type: 'slug', options: { source: 'title', maxLength: 96 } },
    { name: 'body', title: 'Body', type: 'blockContent' },
    { name: 'publishedAt', title: 'Published At', type: 'datetime' },
  ],
};

				
			

This schema defines a blog post with a title, slug, body content, and publication date.

Add Sample Data

To add initial content:

  1. Open Sanity Studio: Navigate to the URL provided after deploying.
  2. Add Content: Click on “Posts” and add sample blog posts. Fill in the fields as defined by your schema.

2. Setting Up Next.js


Create a New Next.js Project

Start by creating a new Next.js project:

npx create-next-app sanity-nextjs
cd sanity-nextjs

Install Dependencies
Install the necessary dependencies for integrating Sanity with Next.js:

npm install @sanity/client next-sanity-image
  • @sanity/client: This package allows you to interact with your Sanity content.
  • next-sanity-image: A helper library to optimize and render Sanity images in Next.js.

3. Configuring Sanity Client in Next.js

Install Sanity Client
In your Next.js project, create a file called sanity.js in the lib directory:
				
					import { createClient } from '@sanity/client';
export const sanityClient = createClient({
  projectId: 'yourProjectId',
  dataset: 'yourDatasetName',
  useCdn: true,
  apiVersion: '2023-01-01',
}
);

				
			

Replace yourProjectId and yourDatasetName with the values from your Sanity project settings.

Set Up Client Configuration

The configuration above connects your Next.js application to Sanity, using the Sanity Client to fetch and manage content.

4. Fetching Data from Sanity


Create a Sanity Query

Sanity uses GROQ (Graph-Relational Object Queries) for querying content. Here’s an example query to fetch all blog posts:

				
					export const allPostsQuery = `*[_type == "post"] | order(publishedAt desc){
  _id,
  title,
  slug,
  publishedAt,
  body
}`;

				
			
Fetch Data in Next.js Pages
Next.js provides two main methods for data fetching: getStaticProps and getServerSideProps.
				
					import { sanityClient } from '../lib/sanity';
import { allPostsQuery } from '../lib/queries';

export async function getStaticProps() {
  const posts = await sanityClient.fetch(allPostsQuery);
  return { props: { posts } };
}

export default function Home({ posts }) {
  return (
    <div>
      <h1>Blog Posts</h1>
      {posts.map((post) => (
        <div key={post._id}>
          <h2>{post.title}</h2>
          <p>{post.publishedAt}</p>
        </div>
      ))}
    </div>
  );
}

				
			

This example fetches blog posts from Sanity and passes them as props to the Home component.

5. Displaying Data in Next.js


Rendering Content

To display the fetched data, iterate over the posts array and render each post’s title and publication date.

Handling Rich Text and Media

Sanity stores rich text content in a structured format. Use a library like @portabletext/react to render rich text:

npm install @portabletext/react

Then, create a portable text component:

				
					import { PortableText } from '@portabletext/react';
export default function PortableTextComponent({ value }) {
  return <PortableText value={value} />;
}

				
			
Use this component to render the body field in your Next.js pages:
				
					import PortableTextComponent from '../../components/PortableText';
export default function Post({ post }) {
  return (
    <article>
      <h1>{post.title}</h1>
      <PortableTextComponent value={post.body} />
    </article>
  );}

				
			

6. Implementing Dynamic Routes


Create Dynamic Routes

To create dynamic routes, Next.js uses [param] syntax:

				
					import { sanityClient } from '../../lib/sanity';
import { postQuery } from '../../lib/queries';

export async function getStaticPaths() {
  const paths = await sanityClient.fetch(
    `*[_type == "post" && defined(slug.current)][].slug.current`
  );
  return { paths: paths.map((slug) => ({ params: { slug } })), fallback: false };
}
export async function getStaticProps({ params }) {
  const post = await sanityClient.fetch(postQuery, { slug: params.slug });
  return { props: { post } };
}

				
			
Fetch Data for Dynamic Routes

In the getStaticPaths function, you fetch all available slugs and generate paths dynamically. In getStaticProps, you fetch the specific post data based on the slug.

7. Optimizing and Caching

Static Generation vs. Server-Side Rendering

Use Static Generation (getStaticProps) for pages that don’t require frequent updates. It pre-renders the page at build time, providing faster load times.

Use Server-Side Rendering (getServerSideProps) for pages that need to display dynamic data on every request.

Caching Strategies
  • Revalidation: In Next.js, you can use Incremental Static Regeneration (ISR) by adding a revalidate property in getStaticProps to periodically update static pages.
  • API Caching: Implement caching layers for Sanity API responses to reduce load times.

8. Handling Images and Media

Integrate Sanity Image CDN

Sanity provides an Image CDN for optimized image delivery. Install the necessary package:

npm install next-sanity-image

Configure and use the Image component from the next-sanity-image package:

				
					import { useNextSanityImage } from 'next-sanity-image';
import Image from 'next/image';
import { sanityClient } from '../lib/sanity';

export default function BlogImage({ image }) {
  const imageProps = useNextSanityImage(sanityClient, image);
  return <Image {...imageProps} alt={image.alt || 'Blog image'} />;
}

				
			
Display Media in Next.js

To display media content, use the BlogImage component within your post template:

<BlogImage image={post.mainImage} />

9. Error Handling and Debugging


Common Issues
  • Invalid API configuration: Ensure that your project ID and dataset in the sanityClient configuration are correct.
  • Missing Slug: Ensure that all your documents have unique slugs for dynamic routing.
Debugging Tips
  • Console Logs: Use console.log() to inspect fetched data in getStaticProps or getServerSideProps.
  • Sanity Studio: Check your data directly in Sanity Studio to ensure it’s correctly structured and available.

CANADA

PAKISTAN

Copyright© 2023 DevPumas | Powered by DevPumas

Meeting with CTO

1-1 Meeting with Our
CTO & get
your quotation within 2 hours!

Please enable JavaScript in your browser to complete this form.
Scroll to Top