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
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.