Environment Variables

`astro:env` for Typed, Validated Configuration

Environment Variables

`astro:env` schemas declare which env vars exist, whether they're client-or-server, public-or-secret, and what type they are.

3 min read Level 2/5 #astro#env#configuration
What you'll learn
  • Declare an env var schema
  • Read server vs client env safely
  • Tell secrets from public values

astro:env lets you declare environment variables in astro.config.mjs with a schema. Astro validates them at build, types them, and protects you from accidentally exposing secrets.

Declare The Schema

// astro.config.mjs
import { defineConfig, envField } from "astro/config";

export default defineConfig({
  env: {
    schema: {
      // public (shipped to the client)
      PUBLIC_API_URL: envField.string({ context: "client", access: "public" }),

      // server-only (NEVER shipped to client)
      DATABASE_URL: envField.string({ context: "server", access: "secret" }),

      // server-public (server only, but not a secret)
      SITE_NAME: envField.string({ context: "server", access: "public", default: "My Site" }),
    },
  },
});

Read Server Vars

---
import { DATABASE_URL, SITE_NAME } from "astro:env/server";

const db = connect(DATABASE_URL);
---
<title>{SITE_NAME}</title>

If DATABASE_URL is missing at runtime, the build / page fails with a clear error — not a silent undefined.

Read Client Vars

import { PUBLIC_API_URL } from "astro:env/client";

export default function Search() {
  // Yes, this is shipped to the browser
  return <a href={`${PUBLIC_API_URL}/docs`}>Docs</a>;
}

Trying to import a server-only var from astro:env/client is a build error. Astro keeps secrets server-side automatically.

Setting Values

Same as any Vite project — .env, .env.local, host’s environment UI:

# .env
PUBLIC_API_URL=https://api.example.com
DATABASE_URL=postgres://...

Don’t commit .env. Most hosts have a per-environment env config.

The Old import.meta.env.PUBLIC_* Still Works

Pre-astro:env, you’d use import.meta.env.PUBLIC_API_URL. Still works, but astro:env gives you types and validation. New code should prefer it.

Up Next

Setting response headers and runtime redirects.

Headers and Redirects →