How to fix Vercel rewrite rules for Sanity Studio?

4 replies
Last updated: May 5, 2021
Hi, how do you fix the Vercel rewrite rules for Sanity? I lifted this line from their blog, but it doesn’t actually work:
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
AI Update

The rewrite rule you've got is actually correct for a basic SPA setup, but there's a key detail: Vercel automatically serves static files before applying rewrites. So the issue likely isn't the rewrite rule itself—it's probably something else in your configuration.

Here's what you need for a standalone Sanity Studio deployment to Vercel:

{
  "rewrites": [
    { "source": "/(.*)", "destination": "/index.html" }
  ]
}

But wait—if this isn't working, here's what's likely wrong:

1. Wrong Output Directory

Make sure your vercel.json specifies where your built Studio files are. Sanity Studio builds to dist/ by default:

{
  "buildCommand": "npm run build",
  "outputDirectory": "dist",
  "rewrites": [
    { "source": "/(.*)", "destination": "/index.html" }
  ]
}

2. Studio at a Subpath (like /studio)

If your Studio lives at a route like /studio instead of the root, you need to:

a) Configure the basePath in your Sanity config:

// sanity.config.js
export default defineConfig({
  basePath: '/studio',
  // ... rest of config
})

b) Update your rewrite to match:

{
  "rewrites": [
    { "source": "/studio/(.*)", "destination": "/studio/index.html" }
  ]
}

3. Deploying Studio with a Next.js App

If you're embedding Studio in a Next.js app, you don't need rewrites at all—Next.js handles client-side routing automatically. The rewrite rule is only for standalone Studio deployments as SPAs.

4. Build Not Producing index.html

Check your Vercel build logs to confirm that dist/index.html actually exists after the build runs. Run sanity build locally and verify the output.

Common Gotcha: Vercel's Order of Operations

Vercel checks for static files first, then applies rewrites. So your rewrite won't break CSS/JS files—those will be served directly. The rewrite only kicks in for paths that don't match actual files, which is exactly what you want for client-side routing in a single-page application.

If you're still stuck, double-check that your CORS origins are configured correctly in sanity.io/manage for both your Vercel deployment URL and localhost (for development). Also verify that your Vercel integration is set up properly if you're using visual editing features.

Show original thread
4 replies
this works for me in vercel.json

{
  "routes": [
    { "handle": "filesystem" },
    { "src": "/(.*)", "dest": "/index.html" }
  ]
}
or when hosting the sanity spa inside a next project I use this in next.config.js


async rewrites() {
  return [
    { source: "/cms", destination: "/cms/index.html" },
    { source: "/cms/:path*", destination: "/cms/index.html" },
  ];
},
Thanks, for some reason I can’t seem to get
routes
to work either. I’m thinking maybe I’ll try wrapping it in a next app if the next few deploys don’t take.
Some thoughts: Is the sanity index.html there at all (the file is created with
sanity build
and in the right directory)? No conflicting routes (now.json / vercel.json, next.config)? Have you tried using the vercel cli locally?
Those are good ideas. After I came back with fresh eyes, I realized
"cleanUrls": true
was the culprit. Though I’m really not sure how that could get in the way of
/desk
. Anyway, thanks again for the help! 🙂

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?