Using system environment variables in Vercel to set preview URL for Sanity Studio.

7 replies
Last updated: Jan 26, 2022
has anyone hosting their studio on Vercel figured out a way to use its system environment variables ? i want to use the
VERCEL_URL
to set my studio's preview URL but can't find a way to add the
SANITY_STUDIO_
prefix. (i know this is more of a Vercel question, but my question there didn't get answered. hoping someone here has already figured this out!)
AI Update

I've been in a similar situation! Unfortunately, there isn't a straightforward built-in way to reference Vercel's system environment variables like VERCEL_URL with a different prefix directly in Vercel's dashboard.

The Reality of Vercel System Variables

Vercel's system environment variables (VERCEL_URL, VERCEL_BRANCH_URL, etc.) are automatically available at build time, but they can't be easily "aliased" with a different prefix through Vercel's UI alone. The challenge is that Sanity Studio requires the SANITY_STUDIO_ prefix for environment variables to be accessible in your Studio code.

Working Solutions

Here are the approaches that actually work:

1. Manual Environment Variable (Simplest)

In your Vercel project settings → Environment Variables, create:

  • Name: SANITY_STUDIO_VERCEL_URL
  • Value: Manually copy your production domain (e.g., your-project.vercel.app)

Downside: This is static and won't automatically update for preview deployments.

2. Build Script Approach (Most Flexible)

Create a build script that reads Vercel's system variables and makes them available with the correct prefix. In your package.json:

{
  "scripts": {
    "build": "node scripts/set-env.js && sanity build",
    "dev": "sanity dev"
  }
}

Then create scripts/set-env.js:

// scripts/set-env.js
const fs = require('fs');

// Vercel system variables are available as regular env vars
const vercelUrl = process.env.VERCEL_URL;
const vercelEnv = process.env.VERCEL_ENV;

if (vercelUrl) {
  // Set it for the current process
  process.env.SANITY_STUDIO_VERCEL_URL = vercelUrl;
  process.env.SANITY_STUDIO_VERCEL_ENV = vercelEnv;
  
  // Optionally write to .env.production for the build
  const envContent = `SANITY_STUDIO_VERCEL_URL=${vercelUrl}\nSANITY_STUDIO_VERCEL_ENV=${vercelEnv}\n`;
  fs.writeFileSync('.env.production', envContent);
}

Since VERCEL_URL is available at build time, you can access it directly in your config without the prefix:

// sanity.config.ts
export default defineConfig({
  // ... other config
  document: {
    productionUrl: async (prev, context) => {
      // Access Vercel's system variable directly (no SANITY_STUDIO_ needed here)
      const vercelUrl = process.env.VERCEL_URL || 'localhost:3000';
      const protocol = process.env.VERCEL_ENV === 'production' ? 'https' : 'http';
      
      return `${protocol}://${vercelUrl}/api/preview?slug=${context.document.slug?.current}`;
    }
  }
})

This is the cleanest approach - you don't need the SANITY_STUDIO_ prefix when accessing variables directly in your config file at build time. The prefix is only required for variables you want to access in your Studio's runtime code (like custom plugins or components).

Which Vercel Variable to Use

  • VERCEL_URL - Current deployment URL (works for production and preview)
  • VERCEL_PROJECT_PRODUCTION_URL - Always your production domain
  • VERCEL_BRANCH_URL - Branch-specific URL
  • VERCEL_ENV - Environment type ("production", "preview", or "development")

Remember that VERCEL_URL doesn't include the protocol, so you'll need to prepend https:// (or http:// for local development).

Summary

The third approach (accessing process.env.VERCEL_URL directly in your config) is usually the best solution since it requires no extra setup and works automatically for both production and preview deployments. You only need the SANITY_STUDIO_ prefix for variables you're accessing in React components or Studio plugins, not in the config file itself.

For one off env, perhaps you can do it with a npm prebuild script?

{
  "build": "sanity build",
  "prebuild": "touch .env.production && echo \"SANITY_STUDIO_VERCEL_URL=$VERCEL_URL\" >> .env.production"
}
Could you use a plugin to insert a custom configuration option?
user U
: please share how that goes! i’m considering a similar approach but using a Node script to make sure it works
cross-env
i got a reply from a Vercel maintainer , but neither suggested approach worked for me. (the first one just did nothing, & the second was irrelevant since it’s not a Next.js project.)
ok, i think i got something working! thanks
user G
, the prebuild approach seemed to do the trick. i tweaked it a bit, & did
{
  "prebuild": "cross-env NODE_ENV=production node ./scripts/prebuild.js"
}
& then that
prebuild.js
is the attached. so i’m actually making all the system variables available this way.(note that i’m on Node 14, & i had to add
"type": "module"
to my
package.json
. also, i had already added the
SANITY_ACTIVE_ENV
variable to each of my environments.)
i still feel like Vercel should support custom prefixes in the Environment Variables UI, but this should do the trick for now.
I attempted some tests on my own using sanity/node custom env values per https://www.sanity.io/docs/studio-environment-variables , hoping that vercel would have an easier time with those. I took a look at their suggestions, and didn’t have luck with that either. Hopefully this prebuild suggestion does the trick for you!

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?