Back to all blogs
Web Development
12 min read

Configuring a Next.js website with Sanity CMS with blogs and Dynamic Page rendering

Learn how to integrate Sanity CMS with Next.js for dynamic content management, blog creation, and flexible page rendering

Configuring a Next.js website with Sanity CMS with blogs and Dynamic Page rendering

Configuring a Next.js website with Sanity CMS

Next.js and Sanity CMS make a powerful combination for building modern, content-driven websites. This guide will walk you through setting up a Next.js project with Sanity CMS integration, focusing on blog functionality and dynamic page rendering.

Getting Started with Next.js and Sanity

First, let's set up a new Next.js project:

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

Next, install the Sanity client packages:

npm install @sanity/client @sanity/image-url

Setting Up Sanity Studio

Sanity Studio is the content management interface where editors will create and manage content:

npm install -g @sanity/cli
sanity init

Follow the prompts to set up your Sanity project. When asked about the schema, choose "Blog" as a starting point.

Creating Schema Types

In your Sanity project, define schema types for your content. Here's an example for blog posts:

// schemas/post.js
export default {
  name: 'post',
  title: 'Blog Post',
  type: 'document',
  fields: [
    {
      name: 'title',
      title: 'Title',
      type: 'string',
      validation: Rule => Rule.required()
    },
    {
      name: 'slug',
      title: 'Slug',
      type: 'slug',
      options: {
        source: 'title',
        maxLength: 96
      },
      validation: Rule => Rule.required()
    },
    {
      name: 'publishedAt',
      title: 'Published at',
      type: 'datetime'
    },
    {
      name: 'mainImage',
      title: 'Main image',
      type: 'image',
      options: {
        hotspot: true
      }
    },
    {
      name: 'excerpt',
      title: 'Excerpt',
      type: 'text',
      rows: 3
    },
    {
      name: 'body',
      title: 'Body',
      type: 'array',
      of: [
        {
          type: 'block'
        },
        {
          type: 'image',
          options: {
            hotspot: true
          }
        }
      ]
    }
  ]
}

Creating Dynamic Page Types

For dynamic page rendering, create a flexible page schema:

// schemas/page.js
export default {
  name: 'page',
  title: 'Page',
  type: 'document',
  fields: [
    {
      name: 'title',
      title: 'Title',
      type: 'string',
      validation: Rule => Rule.required()
    },
    {
      name: 'slug',
      title: 'Slug',
      type: 'slug',
      options: {
        source: 'title',
        maxLength: 96
      },
      validation: Rule => Rule.required()
    },
    {
      name: 'pageBuilder',
      title: 'Page Builder',
      type: 'array',
      of: [
        { type: 'hero' },
        { type: 'textSection' },
        { type: 'imageGallery' },
        { type: 'ctaSection' }
      ]
    }
  ]
}

Setting Up the Sanity Client in Next.js

Create a client configuration file:

// lib/sanity.js
import { createClient } from '@sanity/client'
import imageUrlBuilder from '@sanity/image-url'

export const client = createClient({
  projectId: 'your-project-id',
  dataset: 'production',
  apiVersion: '2023-05-03',
  useCdn: true
})

const builder = imageUrlBuilder(client)

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

Fetching Blog Posts in Next.js

Create a page to display blog posts:

// app/blog/page.js
import { client } from '@/lib/sanity'

export async function generateStaticParams() {
  const posts = await client.fetch('*[_type == "post"]{ slug }')
  return posts.map(post => ({ slug: post.slug.current }))
}

export default async function BlogPage() {
  const posts = await client.fetch('*[_type == "post"] | order(publishedAt desc) {
    _id,
    title,
    slug,
    publishedAt,
    excerpt,
    mainImage
  }')

  return (
    <div>
      <h1>Blog</h1>
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
        {posts.map(post => (
          <BlogPostCard key={post._id} post={post} />
        ))}
      </div>
    </div>
  )
}

Creating Dynamic Pages

For dynamic page rendering:

// app/[slug]/page.js
import { client } from '@/lib/sanity'
import PageBuilder from '@/components/PageBuilder'

export async function generateStaticParams() {
  const pages = await client.fetch('*[_type == "page"]{ slug }')
  return pages.map(page => ({ slug: page.slug.current }))
}

export default async function Page({ params }) {
  const { slug } = params
  const page = await client.fetch(`*[_type == "page" && slug.current == $slug][0]`, { slug })

  if (!page) return <div>Page not found</div>

  return (
    <div>
      <h1>{page.title}</h1>
      <PageBuilder sections={page.pageBuilder} />
    </div>
  )
}

Creating the PageBuilder Component

// components/PageBuilder.js
import Hero from './sections/Hero'
import TextSection from './sections/TextSection'
import ImageGallery from './sections/ImageGallery'
import CtaSection from './sections/CtaSection'

export default function PageBuilder({ sections }) {
  return sections.map((section, index) => {
    switch (section._type) {
      case 'hero':
        return <Hero key={index} data={section} />
      case 'textSection':
        return <TextSection key={index} data={section} />
      case 'imageGallery':
        return <ImageGallery key={index} data={section} />
      case 'ctaSection':
        return <CtaSection key={index} data={section} />
      default:
        return null
    }
  })
}

Conclusion

By integrating Next.js with Sanity CMS, you've created a powerful, flexible system for content management. The combination allows for:

  1. Structured content with a customizable schema
  2. Dynamic page building with reusable components
  3. Optimized performance with static generation
  4. Real-time content updates
  5. Image optimization and asset management

This setup provides a solid foundation for building content-rich websites with excellent developer and editor experiences.

Tags

Next.js
Sanity CMS
Content Management
Web Development