Giridhar Chettiar

Full Stack Developer and AI enthusiast with a passion for creating intuitive, high-performance applications.

Quick Links

  • Home
  • About
  • Projects
  • Blogs
  • Contact

Let's Connect

  • GitHub
  • LinkedIn
  • Instagram
  • Email

Contact

  • giri.chettiar@gmail.com
  • Adelaide, Australia

© 2026 Giridhar Chettiar. All rights reserved.

Privacy PolicyTerms of ServiceSitemap
Logo
CONTACT
Logo
HOMEABOUTPROJECTSREVIEWSBLOGSIDEAS
CONTACT
Logo
HOMEABOUTPROJECTSREVIEWSBLOGSIDEASCONTACT
Web Development
Apr 15, 2024
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

Giridhar Chettiar
Giridhar Chettiar
Author
Configuring a Next.js website with Sanity CMS with blogs and Dynamic Page rendering
Contents9 sections
  1. 1Getting Started with Next.js and Sanity
  2. 2Setting Up Sanity Studio
  3. 3Creating Schema Types
  4. 4Creating Dynamic Page Types
  5. 5Setting Up the Sanity Client in Next.js
  6. 6Fetching Blog Posts in Next.js
  7. Creating Dynamic Pages

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

Related articles

AI & ML

Agent Harnesses — The Model Was Never the Bottleneck

Tejas Kumar took one of the worst models you can still rent — gpt-3.5-turbo — gave it one fixed prompt and one task (upvote a story on Hacker News), and made it reliable without ever touching the prompt or swapping the model. He did it across five git branches by engineering everything around the model: tools, context, guardrails, a verify step, a login handler. This is a hands-on, build-it-with-me walk through that repo and the idea underneath it — an AI harness is everything except the model weights.

AI & ML

Agent BattleGround — Claude Code vs Codex

I gave Claude Code (Fable 5) and Codex (gpt-5.5) the exact same six creative-coding tasks — an arcade game, a generative-art CLI, a bug hunt, an ASCII aquarium, a messy-data dashboard, and a 120-line demoscene — one shot each, zero interventions, blind judges, instrumented re-tests. This is the full fight card: every prompt, the actual screen recordings, the parameter-by-parameter scorecards, and what the judges said. Final tally: 6–0, but the story is closer than the headline.

Read More Articles
  • Getting Started with Next.js and Sanity
  • Setting Up Sanity Studio
  • Creating Schema Types
  • Creating Dynamic Page Types
  • Setting Up the Sanity Client in Next.js
  • Fetching Blog Posts in Next.js
  • Creating Dynamic Pages
  • Creating the PageBuilder Component
  • Conclusion
7
  • 8Creating the PageBuilder Component
  • 9Conclusion