Integrating Sanity CMS with React Blog for the First Time
Welcome to Sanity! I checked out your blog site and it looks great - integrating Sanity will give you a powerful backend for managing your content. Let me walk you through the integration process step-by-step.
Step 1: Set Up Your Sanity Studio
First, you'll need to create a Sanity project and Studio. Open your terminal and run:
npm create sanity@latestThis will guide you through an interactive setup where you'll:
- Log in or create a Sanity account
- Choose a project name
- Select a dataset name (typically "production")
- Choose a template (I recommend "blog" for your use case, or "clean" for minimal setup)
- Decide whether to use TypeScript
You can also use flags for a quicker setup:
npm create sanity@latest -- --dataset production --template blog --typescript --output-path studioThis creates a separate studio folder for your content management interface. You can run it locally with npm run dev inside that folder.
Step 2: Define Your Content Schema
In your Studio folder, you'll define schemas for your blog content. Here's a basic post schema example (in studio/schemaTypes/post.ts):
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' },
},
{
name: 'publishedAt',
title: 'Published At',
type: 'datetime',
},
{
name: 'mainImage',
title: 'Main Image',
type: 'image',
},
{
name: 'body',
title: 'Body',
type: 'array',
of: [{ type: 'block' }], // This is Portable Text for rich text
},
],
}Step 3: Install Sanity Client in Your React App
In your React project directory, install the necessary packages:
npm install @sanity/client @sanity/image-url @portabletext/reactThese packages handle:
- @sanity/client: Fetching content from Sanity
- @sanity/image-url: Generating optimized image URLs
- @portabletext/react: Rendering rich text content
Step 4: Configure the Sanity Client
Create a sanity.js (or sanity.ts) file in your React app:
import { createClient } from "@sanity/client";
import imageUrlBuilder from "@sanity/image-url";
export const client = createClient({
projectId: "your-project-id", // Find this in sanity.json or studio/sanity.config.ts
dataset: "production",
apiVersion: "2025-01-01", // Use current date
useCdn: true, // Set to false for fresh data, true for faster cached data
});
// Helper function for generating image URLs
const builder = imageUrlBuilder(client);
export const urlFor = (source) => builder.image(source);Step 5: Fetch and Display Content
Here's how to fetch and display blog posts in your React components:
import { useEffect, useState } from "react";
import { client, urlFor } from "./sanity";
import { PortableText } from "@portabletext/react";
function BlogPosts() {
const [posts, setPosts] = useState([]);
useEffect(() => {
client
.fetch(
`*[_type == "post"] | order(publishedAt desc) {
_id,
title,
slug,
publishedAt,
mainImage,
body
}`
)
.then((data) => setPosts(data))
.catch(console.error);
}, []);
return (
<div>
{posts.map((post) => (
<article key={post._id}>
<h2>{post.title}</h2>
{post.mainImage && (
<img
src={urlFor(post.mainImage).width(800).url()}
alt={post.title}
/>
)}
<PortableText value={post.body} />
</article>
))}
</div>
);
}Step 6: Rendering Rich Text with PortableText
The @portabletext/react component handles Sanity's rich text format. You can customize how different elements render:
const ptComponents = {
types: {
image: ({value}) => (
<img src={urlFor(value).url()} alt={value.alt || ''} />
),
},
marks: {
link: ({value, children}) => (
<a href={value.href} target="_blank" rel="noopener">
{children}
</a>
),
},
};
// Use it like this:
<PortableText value={post.body} components={ptComponents} />Step 7: Deploy Your Studio
Once you're happy with your setup, deploy your Studio so you can access it from anywhere:
cd studio
npm run deployThis gives you a hosted URL like your-project.sanity.studio where you and your team can manage content.
Quick Tips for Success
GROQ queries: The query language
*[_type == "post"]is called GROQ. It's very powerful - check the docs for filtering, sorting, and joining data.Image optimization: Always use
urlFor()with width/height parameters to get optimized images from Sanity's CDN.API versioning: Use today's date as your
apiVersion- it locks in API behavior for consistency.useCdn setting: Set to
truefor production (faster, cached),falsefor development (fresh data).
The React Router quickstart guide has a complete walkthrough that closely matches what you'll need for your React app, even if you're not using React Router specifically - the content fetching patterns are the same.
Good luck with your first Sanity integration! Feel free to ask if you run into any specific issues.
Show original thread9 replies
Was this answer helpful?
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.