Skip to content
Latchkey

SvelteKit "$env/static/private cannot be imported into client code" in CI

SvelteKit blocks $env/static/private and $env/dynamic/private from any module that can run in the browser, to keep secrets server-only. Importing it from a shared or client module fails the build.

What this error means

svelte-kit build fails with "Cannot import $env/static/private into client-side code" naming the module that pulled the private env in. Moving the import to a server-only file clears it.

sveltekit
Cannot import $env/static/private into client-side code:
src/lib/api.js
    imported by src/routes/+page.svelte

Common causes

A private env import in shared code

A module in $lib reads $env/static/private and is imported by a +page.svelte, so it would ship the secret to the browser.

Using private env where public was meant

A value safe for the client is read from the private module instead of $env/static/public, triggering the guard.

How to fix it

Move the private import to server-only code

Read private env in a .server.js module or a +page.server.js load, then pass only safe data to the client.

src/routes/+page.server.js
// src/routes/+page.server.js
import { API_SECRET } from '$env/static/private';
export const load = async () => ({ /* no secrets returned */ });

Use the public env module for client-safe values

Expose values intended for the browser via PUBLIC_ prefixed variables.

src/lib/api.js
import { PUBLIC_API_URL } from '$env/static/public';

How to prevent it

  • Read private env only in .server modules and server loads.
  • Use PUBLIC_-prefixed variables for client-safe config.
  • Keep secret-reading code out of $lib modules imported by components.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →