Vercel Logo

Managing Environment Variables on Vercel

The chat feature needs an API key to talk to the AI Gateway. We could hardcode it, but then it's sitting in your Git history forever. Vercel's environment variable system gives you scoped secrets (different values for development, preview, and production) without any of them touching source control.

Outcome

Configure the AI_GATEWAY_API_KEY across Vercel's three environment scopes and pull it locally with vercel env pull.

Fast Track

  1. Add AI_GATEWAY_API_KEY in the Vercel dashboard under Settings → Environment Variables
  2. Run vercel env pull to sync the variable to your local .env file
  3. Access it in server code with $env/static/private

Vercel's Three Scopes

Every environment variable on Vercel has one or more scopes:

ScopeWhen it's usedExample
ProductionDeployments from your main branchLive API key with billing alerts
PreviewDeployments from other branches (PRs)Shared team key for testing
DevelopmentLocal dev via vercel env pullPersonal key with low rate limits

This matters. You might want a test API key for preview deployments and a production key for your main branch. Or you might use the same key everywhere. The point is you choose explicitly.

Hands-on exercise 1.2

Add the AI Gateway API key to your Vercel project and access it in server code:

Requirements:

  1. Add AI_GATEWAY_API_KEY in the Vercel dashboard with all three scopes enabled
  2. Pull the variable locally with vercel env pull
  3. Verify the variable is accessible in a SvelteKit server endpoint using $env/static/private

Implementation hints:

  • Get an API key from the AI Gateway settings in your Vercel dashboard
  • The .env file is already in .gitignore, so never commit it
  • SvelteKit offers both $env/static/private (inlined at build time) and $env/dynamic/private (loaded at runtime). The SvelteKit team recommends $env/static/private as the default since it enables better optimization, and that's what the ski-alerts app uses
  • The chat endpoint has a TODO comment showing where this variable will be used. Check src/routes/api/chat/+server.ts

Try It

  1. Add the variable in Vercel:

    • Go to your project → SettingsEnvironment Variables
    • Name: AI_GATEWAY_API_KEY
    • Value: your gateway key
    • Check all three scopes: Production, Preview, Development
    • Click Save
  2. Pull locally:

    First time using vercel env pull?

    If you haven't connected your local directory to the Vercel project yet, run vercel link first. The CLI needs to know which project to pull variables from.

    $ vercel env pull
    Downloading Development Environment Variables for project ski-alerts
     Created .env file
  3. Verify the .env file exists:

    $ cat .env
    # Created by Vercel CLI
    AI_GATEWAY_API_KEY="your-gateway-key"
  4. Check that server code can access it:

    The chat endpoint in the starter shows the pattern you'll use in Section 2:

    src/routes/api/chat/+server.ts
    // You'll implement this in Section 2, but the import pattern is:
    import { AI_GATEWAY_API_KEY } from '$env/static/private';
     
    // Access directly: AI_GATEWAY_API_KEY

Commit

No code changes needed for this lesson. The environment variable lives in Vercel's dashboard and your local .env file (which is gitignored).

Done-When

  • AI_GATEWAY_API_KEY appears in your Vercel project's Environment Variables settings
  • Running vercel env pull creates a .env file locally
  • The .env file contains your API key
  • The .env file is listed in .gitignore

Solution

Step 1: Vercel Dashboard

Navigate to your project → Settings → Environment Variables. Add:

KeyValueScopes
AI_GATEWAY_API_KEYyour-gateway-keyProduction, Preview, Development

Step 2: Pull locally

vercel env pull

This creates .env in your project root with all Development-scoped variables.

Step 3: Access in SvelteKit

SvelteKit provides two ways to access environment variables:

// Static: inlined at build time (server-only) — recommended
import { AI_GATEWAY_API_KEY } from '$env/static/private';
 
// Dynamic: loaded at runtime (server-only)
import { env } from '$env/dynamic/private';
console.log(env.AI_GATEWAY_API_KEY);

Use $env/static/private as the default. It's the SvelteKit team's recommendation because the bundler can optimize the inlined values. That's what the ski-alerts app uses. Reach for $env/dynamic/private when you need to read values that change between serverless invocations or when you're building a library that shouldn't assume which variables exist.

Never use public env for secrets

SvelteKit also has $env/dynamic/public and $env/static/public. These are exposed to the browser. Only use private imports for API keys and secrets.

Troubleshooting

.env file is empty after pulling

Check that you enabled the Development scope when you added the variable. Production-only variables won't appear in your local .env file.

Advanced: Per-Scope Values

You can set different values per scope. A common pattern:

  • Development: A personal API key with low rate limits
  • Preview: A shared team key for testing
  • Production: A production key with higher limits and billing alerts

To set scope-specific values, uncheck "All Environments" in the dashboard and add the variable once per scope with different values.