"Fixing 'Mutation' Issue Due to Insufficient Permissions in React and NextJs Web App with Sanity CMS"
This is a classic authentication issue! The error "Insufficient permissions; permission 'create' required" with a 403 status means your Sanity client in production doesn't have write access to your dataset.
Why it works locally but not on Vercel:
Locally, you're likely authenticated through sanity login, which gives your client write permissions. But in production on Vercel, your client has no authentication token, so it can't create documents.
The Solution:
You need to create an API token with write permissions and add it to your Vercel environment:
1. Create a write token in Sanity:
- Go to manage.sanity.io (or run
npx sanity@latest manage) - Select your project
- Navigate to API → Tokens
- Click Add API token
- Give it a name like "Production Write Token"
- Set permissions to Editor or Contributor (avoid Admin unless necessary)
- Copy the token immediately (you won't see it again!)
2. Add the token to Vercel:
- Go to your Vercel project settings
- Navigate to Environment Variables
- Add:
SANITY_API_TOKENwith your token value - Make sure it's enabled for Production
- Redeploy your application
3. Update your Sanity client:
import { createClient } from '@sanity/client'
export const client = createClient({
projectId: 'your-project-id',
dataset: 'production',
apiVersion: '2023-01-30',
useCdn: false, // Important for mutations!
token: process.env.SANITY_API_TOKEN, // Add this
})⚠️ CRITICAL SECURITY WARNING:
Never expose write tokens in client-side code! If you're creating comments from the browser, you MUST use a Next.js API route to keep the token server-side.
Proper implementation with API route:
Create /pages/api/comments.js (or /app/api/comments/route.js for App Router):
import { createClient } from '@sanity/client'
const client = createClient({
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
apiVersion: '2023-01-30',
useCdn: false,
token: process.env.SANITY_API_TOKEN, // Server-side only!
})
export default async function handler(req, res) {
if (req.method !== 'POST') {
return res.status(405).json({ message: 'Method not allowed' })
}
try {
const result = await client.create({
_type: 'comment',
...req.body, // Your comment data
})
res.status(200).json(result)
} catch (error) {
res.status(500).json({ error: error.message })
}
}Then call this API route from your frontend instead of using the Sanity client directly.
This keeps your write token secure on the server while allowing your comment functionality to work in production. For more details on token security, check out the Sanity documentation on API tokens.
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.