Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

The Ultimate Guide to Integrating Sanity CMS with Next.js: Powering Your Content-Driven React.js Applications

In today’s digital landscape, creating dynamic, content-rich websites is more important than ever. As developers, we’re constantly seeking ways to streamline our workflow and improve the user experience. That’s where the powerful combination of Next.js and Sanity CMS comes into play. In this comprehensive guide, we’ll explore how to integrate these two technologies to create a robust, flexible, and high-performance content management system for your React.js applications.

Introduction to Next.js and Sanity CMS

Before we dive into the integration process, let’s briefly discuss why Next.js and Sanity CMS are such a powerful combination for building modern web applications.

Next.js: The React Framework for Production

Next.js is a popular React framework that provides a suite of developer-friendly features out of the box:

  • Server-side rendering (SSR) and static site generation (SSG)
  • Automatic code splitting
  • Built-in CSS support
  • API routes
  • Fast refresh for a smooth development experience

These features make Next.js an excellent choice for building high-performance, SEO-friendly React applications.

Sanity CMS: The Flexible Content Management System

Sanity is a headless CMS that offers:

  • A customizable content studio
  • Real-time collaboration
  • Powerful querying capabilities with GROQ (Graph-Relational Object Queries)
  • Flexible content modeling
  • Asset management

By combining Next.js with Sanity CMS, we can create a powerful content management system that offers both flexibility for content creators and performance for end-users.

Setting Up Your Next.js Project

Let’s start by setting up a new Next.js project. Open your terminal and run the following commands:

npx create-next-app@latest my-sanity-nextjs-app
cd my-sanity-nextjs-app

This will create a new Next.js project with the latest features. Now, let’s add the necessary dependencies for working with Sanity:

npm install @sanity/client @sanity/image-url react-query swr

Integrating Sanity CMS

To integrate Sanity CMS with your Next.js application, you’ll need to set up a Sanity project. If you haven’t already, install the Sanity CLI:

npm install -g @sanity/cli

Now, initialize a new Sanity project:

sanity init

Follow the prompts to set up your Sanity project. Once completed, you’ll have a Sanity studio that you can customize to fit your content needs.

Fetching Data with Sanity Client

The Sanity client is a powerful tool for fetching data from your Sanity CMS. Let’s create a utility file to set up the client:

Create a new file lib/sanity.js:

import sanityClient from '@sanity/client'
import imageUrlBuilder from '@sanity/image-url'

export const client = sanityClient({
  projectId: 'your-project-id',
  dataset: 'production',
  apiVersion: '2021-03-25',
  useCdn: true,
})

const builder = imageUrlBuilder(client)

export function urlFor(source) {
  return builder.image(source)
}

Now, let’s use this client to fetch data in a Next.js page. Create a new file pages/index.js:

import { client } from '../lib/sanity'

export default async function Home() {
const posts = await client.fetch(`*[_type == "post"]{
    _id,
    title,
    excerpt
  }`)
  return (
    <div>
      <h1>My Blog</h1>
      {posts.map((post) => (
        <div key={post._id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
        </div>
      ))}
    </div>
  )
}

Using React Query for Advanced Data Fetching

React Query is a powerful library for managing server state in React applications. It provides caching, automatic refetching, and more. Let’s see how we can use it with Sanity and Next.js.

First, we need to set up the React Query provider. Update your pages/_app.js:

import { QueryClient, QueryClientProvider } from 'react-query'

const queryClient = new QueryClient()

function MyApp({ Component, pageProps }) {
  return (
    <QueryClientProvider client={queryClient}>
      <Component {...pageProps} />
    </QueryClientProvider>
  )
}

export default MyApp

Now, let’s create a custom hook to fetch posts using React Query. Create a new file hooks/usePosts.js:

import { useQuery } from 'react-query'
import { client } from '../lib/sanity'

export function usePosts() {
  return useQuery('posts', async () => {
    const posts = await client.fetch(`*[_type == "post"]{
      _id,
      title,
      excerpt
    }`)
    return posts
  })
}

We can now use this hook in our components. Let’s update app/posts/page.js:

import { usePosts } from '../hooks/usePosts'

export default function Home() {
  const { data: posts, isLoading, error } = usePosts()

  if (isLoading) return <div>Loading...</div>
  if (error) return <div>Error: {error.message}</div>

  return (
    <div>
      <h1>My Blog</h1>
      {posts.map((post) => (
        <div key={post._id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
        </div>
      ))}
    </div>
  )
}

This approach gives us automatic caching, refetching, and loading states, making our application more responsive and user-friendly.

Implementing SWR for Real-Time Data

SWR (stale-while-revalidate) is another excellent library for data fetching, developed by the creators of Next.js. It’s particularly useful for real-time data. Let’s see how we can use it with Sanity.

Create a new hook hooks/usePostsSWR.js:

import useSWR from 'swr'
import { client } from '../lib/sanity'

const fetcher = (query) => client.fetch(query)

export function usePostsSWR() {
  return useSWR(`*[_type == "post"]{
    _id,
    title,
    excerpt
  }`, fetcher)
}

Now, let’s create a new page that uses this hook. Create pages/real-time.js:

import { usePostsSWR } from '../hooks/usePostsSWR'

export default function RealTimePosts() {
  const { data: posts, error } = usePostsSWR()

  if (error) return <div>Error: {error.message}</div>
  if (!posts) return <div>Loading...</div>

  return (
    <div>
      <h1>Real-Time Blog Posts</h1>
      {posts.map((post) => (
        <div key={post._id}>
          <h2>{post.title}</h2>
          <p>{post.excerpt}</p>
        </div>
      ))}
    </div>
  )
}

This page will automatically update when the data in Sanity changes, providing a real-time experience for your users.

Building Dynamic Pages with Sanity Content

One of the key benefits of using a CMS is the ability to create dynamic pages based on your content. Let’s create dynamic blog post pages using Sanity data.

Create a new file app/posts/[slug]/page.js:

import { client } from '../../lib/sanity'
import { notFound } from 'next/navigation'


async function getPost(slug: string) {
  const post = await client.fetch(
    `*[_type == "post" && slug.current == $slug][0]`,
    { slug }
  )

  if (!post) {
    notFound()
  }

  return post
}

export default async function Post({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug)

  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </article>
  )
}

Deploying Your Next.js and Sanity CMS Application

When you’re ready to deploy your application, you have several options:

  1. Vercel: As the creators of Next.js, Vercel offers seamless deployment for Next.js applications.
  2. Netlify: Another great option for static site hosting with easy setup.
  3. Custom server: For more control, you can deploy to your own server using a Node.js runtime.

Remember to set up proper environment variables for your Sanity project ID and dataset.

Conclusion and Next Steps

Integrating Sanity CMS with Next.js opens up a world of possibilities for creating dynamic, content-driven React.js applications. We’ve covered the basics of setting up your project, fetching data using various methods, and creating dynamic pages.

As next steps, consider exploring more advanced features of both Next.js and Sanity:

  1. Implement real-time previews of your Sanity content in Next.js.
  2. Use Sanity’s powerful GROQ language for more complex queries.
  3. Implement user authentication and personalized content.
  4. Explore Sanity’s webhooks for triggering builds when content changes.

Remember, the key to a successful CMS integration is finding the right balance between flexibility for content creators and performance for end-users. With Next.js and Sanity CMS, you have the tools to achieve both.

Happy coding, and may your content always be dynamically delightful!

Leave a Reply

Your email address will not be published. Required fields are marked *