Integrating Sanity CMS with React Blog for the First Time

9 replies
Last updated: Nov 29, 2025
Hello Junior developer here. I built a blog site using react Js and I am about to integrate it with Sanity but I am finding it difficult because this is my first time of doing something like this in Development state. Here is the link: https://objective-banach-d4d520.netlify.app/
AI Update

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@latest

This 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 studio

This 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/react

These 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 deploy

This gives you a hosted URL like your-project.sanity.studio where you and your team can manage content.

Quick Tips for Success

  1. GROQ queries: The query language *[_type == "post"] is called GROQ. It's very powerful - check the docs for filtering, sorting, and joining data.

  2. Image optimization: Always use urlFor() with width/height parameters to get optimized images from Sanity's CDN.

  3. API versioning: Use today's date as your apiVersion - it locks in API behavior for consistency.

  4. useCdn setting: Set to true for production (faster, cached), false for 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 thread
9 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.

Was this answer helpful?