How to use environment variables in SvelteKit (process.env)
It's easier than it used to be.
Published | Blog post
SvelteKit has recently changed how it brings environment variables into your code, whether from a .env
file or from Node’s process.env
. The new method is better. It allows you to bring private variables (secrets such as API keys) into server-side code without workarounds. Public variables can be imported into client-side code.
How
Four SvelteKit modules are at play to make this happen:
The dynamic
modules are for variables accessed at runtime—variables not necessarily known at build time. The static
modules for variables that can be injected as strings at build time. The public
modules expose variables that are prefixed by “PUBLIC_” or another prefix set in your config file. The private
modules expose variables not prefixed; trying to import them into client-side code will throw an error. That’s to keep you from accidentally exposing secrets to the front end. See the docs for more information.
In your DEV environment you can supply your public and private variables in a .env
file. That file shouldn’t be committed to source control, especially if it has private variables. In a STAGE or PROD environment you’ll want to supply your environment variables through process.env
by setting variables or secrets directly with your deployment service such as Vercel, Netlify, AWS Amplify, Azure Static Web Apps, or whatever yours is. This site, for instance, is hosted by GitHub Pages; its secrets are saved as repository secrets through the GitHub UI.
The docs show how to import the variables. For dynamic variables, you import env
as a named export of the $env/dynamic/*
module: import { dev } from '$env/dynamic/public';
, for instance. Your variables are properties of the env
object.
Static variables are imported directly as named exports from the $env/static/*
module. This site, for instance, fetches content from Contentful during its build process. That requires API keys and other secrets and looks like this:
Embedded content: https://gist.github.com/ostermanj/aaeb966d4de44eb2a0d9e96c27987ce5
The (relatively) old way
The method outlined above came into being in July 2022, according to SvelteKit’s changelog. Before that, as best I understand, in local development SvelteKit was exposing variables loaded by Vite from .env
, but only variables prefixed with “VITE_”. There was no straightforward way to import secrets into server-side code. One solution was to install env-cmd and add env-cmd
to the dev script in package.json
. That would expose the variables in .env
to your source code but would make a detour around SvelteKit’s failsafe to prevent exposing secrets to the client.