How to allow multiple users to create and manage their own content in Sanity

7 replies
Last updated: Jan 20, 2023
Hi there, I recently started on a blog website project with nextjs that allows any user to sign up and publish blogs on the site/manage their own content (similar to Medium.com ). I'm working with Sanity as my CMS/publishing editor and have managed to set up a project to publish content I personally create to the site. Could someone please point me in the direction of docs that could help with the feature that allows others to independently create/manage their own content?
AI Update

Great question! Building a Medium-like platform where users can independently create and manage their own content with Sanity is definitely possible. Here's how to approach this:

Core Architecture

For a user-generated content platform, you'll need to handle authentication separately from Sanity, then use Sanity for content storage with proper access control. Here's the recommended approach:

1. Authentication Layer (NextAuth or Similar)

First, implement your own authentication system using something like NextAuth.js to handle user sign-ups and logins. This manages your user sessions in your Next.js application. Note that Sanity's built-in users and roles are designed for content editors/administrators, not end-users of your application.

2. Writing Content from the Frontend

To allow users to create content from your frontend, you'll use Sanity's JavaScript Client to perform mutations (create, update, delete operations). Here's the key pattern:

Never expose write tokens in frontend code. Instead, use Next.js API routes or Server Actions:

// app/api/posts/route.js (Server-side)
import { createClient } from '@sanity/client';

const client = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
  apiVersion: '2025-02-19',
  token: process.env.SANITY_WRITE_TOKEN, // Stored securely server-side
  useCdn: false
});

export async function POST(request) {
  const session = await getSession(request); // Your auth check
  if (!session) return Response.json({ error: 'Unauthorized' }, { status: 401 });
  
  const { title, content } = await request.json();
  
  const result = await client.create({
    _type: 'post',
    title,
    content,
    author: session.user.id, // Link to your authenticated user
    publishedAt: new Date().toISOString()
  });
  
  return Response.json(result);
}

Check out the Mutations API documentation for all available operations.

3. Access Control & Permissions

For a production app where users should only edit their own content, you have two main options:

Option A: Application-Level Security (Simpler)

  • Validate user ownership in your Next.js API routes before allowing mutations
  • Use read-only tokens for public content queries
  • Keep all write operations server-side with validation

Option B: Sanity Custom Roles (Enterprise) If you're on an Enterprise plan, you can use Custom Roles to define document-level permissions using GROQ filters. This allows you to restrict which documents users can access directly in Sanity based on field values (like author ID).

4. API Tokens Setup

You'll need to create API tokens in your Sanity project:

  1. Go to your project at sanity.io/manage or run npx sanity manage
  2. Navigate to the API section
  3. Create a robot token with Editor permissions for server-side writes
  4. Store it in your environment variables (never commit to git!)

For public read access, you can either use your project without authentication (for public datasets) or create a read-only token.

5. Schema Design

Design your schema to include user references:

// schemas/post.js
export default {
  name: 'post',
  type: 'document',
  fields: [
    {
      name: 'title',
      type: 'string',
      validation: Rule => Rule.required()
    },
    {
      name: 'content',
      type: 'array',
      of: [{ type: 'block' }]
    },
    {
      name: 'author',
      type: 'string', // Store your auth system's user ID
      validation: Rule => Rule.required()
    },
    {
      name: 'publishedAt',
      type: 'datetime'
    }
  ]
}

6. Image Uploads from Frontend

For user-uploaded images, use the Assets API through your server-side API routes:

// Server-side upload handler
const imageAsset = await client.assets.upload('image', fileBuffer, {
  filename: file.name
});

Key Resources

Alternative: Sanity Functions

For more complex workflows, consider Sanity Functions - serverless compute that runs within Sanity's infrastructure. These can handle content validation, notifications, or custom business logic when documents are created/modified.

The key takeaway: Sanity is your content backend, while NextAuth (or similar) handles your user authentication. Your Next.js API routes act as the secure bridge between them, validating users and performing authorized mutations on their behalf.

Show original thread
7 replies
Hey
user K
! We don’t have a guide that covers this specifically, however, you’ll use the JS client to write changes to your actual Sanity content from your frontend. This video will show you the basics of this as well. Your use case will be more complicated, though!
Thank you for the info
user M
! I will look at the links you provided before asking anything else implementation related but you think what I'm trying to do is possible with Sanity?
Definitely possible!
user M
the info was super helpful thank you! I can use the JS client to CRUD user content to the database from the frontend. I really like the embedded studio editor feature, is there an option to allow users to author their own content in the studio editor? So far my understanding is you can have unlimited admin under one project and control their roles and permissions. Maybe I could use roles to restrict their access to only viewing and editing content they own or have been invited to collaborate on?
If it’s a public facing app where anyone can sign up, you would not want to allow them to become members of the project. A project does have unlimited admin roles, but you can only customize the access of a user if you have the custom roles feature that comes with an Enterprise level plan. You could technically hack your way around this by controlling what shows up in the desk structure, but it would never be truly secure since all documents would be discoverable through search and the API.
user M
understood. It is a public facing app, so it's best to handle the content creation etc from the frontend and use the js client to update the backend, thank you so much
You’re welcome!

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?