Environment variables are values your app needs that exist separately from the app's source code. They allow you to use sensitive information like API keys and database credentials without storing them in version control. During development, and at build time, variables defined in a `.env` or `.env.local` file will be added to the environment: ```env /// file: .env.local API_KEY=19f401ba-e8b0-48c4-8c77-b0ebb26d97fe ``` After following the setup below, they can be imported via the following modules: - [`$app/env/private`]($app-env-private) - [`$app/env/public`]($app-env-public) > [!LEGACY] > The `$env/*` modules, along with `$app/environment` were removed in SvelteKit 3 in favour of explicit environment variables that were added in SvelteKit 2.62 as an experimental option. ### Setup Add a `src/env.ts` (or `src/env.js`) file that exports a `variables` object: ```ts /// file: src/env.ts import { defineEnvVars } from '@sveltejs/kit/hooks'; export const variables = defineEnvVars({ // ... }); ``` Each value in the object passed to [`defineEnvVars`](@sveltejs-kit-hooks#defineEnvVars) is an [`EnvVarConfig`](@sveltejs-kit#EnvVarConfig) object that configures the environment variable. > [!NOTE] `defineEnvVars` returns its argument unaltered — it exists purely to help with type safety. ### Private variables By default, all variables are considered private. For example, you don't want to reveal your `API_KEY`: ```ts /// file: src/env.ts import { defineEnvVars } from '@sveltejs/kit/hooks'; export const variables = defineEnvVars({ +++API_KEY: {}+++ }); ``` > [!NOTE] Since no configuration is needed for this variable, we can use an empty object (`{}`). Now that `API_KEY` is defined, it can be imported into app code via `$app/env/private`: ```js import { API_KEY } from '$app/env/private'; ``` The `$app/env/private` module cannot be imported into code that runs in the browser, so that you can't accidentally reveal your secrets in a JavaScript bundle. ### Public variables Some variables are perfectly safe — necessary, even — to expose to the browser. For these, we can specify `public: true`: ```ts /// file: src/env.ts import { defineEnvVars } from '@sveltejs/kit/hooks'; export const variables = defineEnvVars({ GOOGLE_ANALYTICS_ID: { +++public: true+++ } }); ``` `GOOGLE_ANALYTICS_ID` can now be imported from `$app/env/public`, or used in your `app.html` template as `%sveltekit.env.GOOGLE_ANALYTICS_ID%`: ```html %sveltekit.head%
%sveltekit.body%
``` ### Validation You can specify a [Standard Schema](https://standardschema.dev/) validator such as [Zod](https://zod.dev/) or [Valibot](https://valibot.dev/) to check that an environment variable value is correct: ```ts /// file: src/env.ts import { defineEnvVars } from '@sveltejs/kit/hooks'; +++import * as v from 'valibot';+++ export const variables = defineEnvVars({ GOOGLE_ANALYTICS_ID: { public: true, +++schema: v.pipe(v.string(), v.regex(/G-[A-Z0-9]+/))+++ } }); ``` If a value is invalid, the app will fail to start (or build). If the variable is only available at run time (for example a secret that isn't set during the build), use `availability: 'runtime'` so that it is only validated when the app starts: ```ts /// file: src/env.ts import { defineEnvVars } from '@sveltejs/kit/hooks'; import * as v from 'valibot'; export const variables = defineEnvVars({ SECRET: { // required when the app starts, but not validated during the build +++availability: 'runtime',+++ schema: v.string() } }); ``` You can use validators to make values optional, or transform them (such as turning a string into a boolean, or parsing JSON) — see your validation library's documentation to learn how. ### Availability The `availability` property controls when a variable's value is available, and therefore when it is validated. It has three possible values: - `'dynamic'` (default) — the value is validated and used during runtime and build time. - `'inline'` — the value is inlined into your application code at build time, enabling optimisations like dead-code elimination. It is validated at build time. - `'runtime'` — the value is validated and used during runtime only. The value is `undefined` during the build, so the variable is typed as `T | undefined`. ```ts /// file: src/env.ts import { defineEnvVars } from '@sveltejs/kit/hooks'; import * as v from 'valibot'; export const variables = defineEnvVars({ SHOW_DEBUG_OVERLAY: { public: true, +++availability: 'inline',+++ // coerce to true/false schema: v.pipe( v.optional(v.string(), ''), v.transform((str) => str !== '') ) } }); ``` Because this variable is `inline`, the `` component shown here will be excluded from the JavaScript bundle unless `SHOW_DEBUG_OVERLAY` is truthy: ```svelte {#if SHOW_DEBUG_OVERLAY} {/if} ``` But if the variable is set before building the app... ```bash SHOW_DEBUG_OVERLAY=true npm run build ``` ...then the component will be included and shown. ### Documenting variables You can document the purpose of an environment variable by adding a `description`: ```ts /// file: src/env.ts import { defineEnvVars } from '@sveltejs/kit/hooks'; export const variables = defineEnvVars({ CACHE_TTL_SECONDS: { description: 'How long to cache responses, in seconds' } }); ``` Hovering over `CACHE_TTL_SECONDS` in your app code will show the description.