Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
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.
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 is a popular React framework that provides a suite of developer-friendly features out of the box:
These features make Next.js an excellent choice for building high-performance, SEO-friendly React applications.
Sanity is a headless CMS that offers:
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.
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
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.
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>
)
}
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.
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.
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>
)
}
When you’re ready to deploy your application, you have several options:
Remember to set up proper environment variables for your Sanity project ID and dataset.
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:
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!