Strict layout
Get the best security in Nuxt using strictly separated client and server schemas.
In this setup, you define your client, server, and shared schemas in separate files.
By importing env from ~/env/client in client-side code and ~/env/server in server-side code, you enforce a strict boundary where server variables and schemas never leak to the browser. If ~/env/server is accidentally imported on the client side, ArkEnv fails the build with a compilation error.
Setup
The easiest way to bootstrap the strict layout is with the ArkEnv CLI. It automatically configures @arkenv/nuxt for your existing Nuxt project using the strict layout option.
npx @arkenv/cli@latest init --strictpnpm dlx @arkenv/cli@latest init --strictyarn dlx @arkenv/cli@latest init --strictbunx @arkenv/cli@latest init --strictYour schema
When bootstrapping with the CLI, it generates three separate schema files under env/:
import { } from "@arkenv/nuxt/shared";
/**
* @internal 🛑 INTERNAL SCHEMA ONLY.
* Do not import this directly. Import `env` from `./client` or `./server` instead.
*/
export const = ({
: "'development' | 'production' | 'test' = 'development'",
});import from "@arkenv/nuxt/client";
import { } from "./internal/shared";
export const = (
{
: "string = 'https://api.example.com'",
},
{
: [],
},
);import from "@arkenv/nuxt/server";
import { as } from "./client";
export const = (
{
: "string",
},
{
: [],
},
);Usage
Both env/client.ts and env/server.ts export the resolved environment as env. This lets you use consistent env.MY_VAR imports depending on where the code executes.
In server code (server routes, middleware)
Import env from the server file. It contains all public, shared, and server-only variables:
import { } from "~~/env/server";
export default function (: unknown) {
// Access database URL and client API URL safely
const = .DATABASE_URL;
const = .NUXT_PUBLIC_API_URL;
return { };
}In client-side code
Import env from the client file (env/client.ts). The boundary protection works at two levels:
- TypeScript type safety: If you import
envfrom the client file and try to access a server-side variable (likeDATABASE_URL), you will get a TypeScript compilation error because it is not defined in the client-safe schema:
import { } from "~~/env/client";
const = .NUXT_PUBLIC_API_URL;
// @ts-expect-error DATABASE_URL is not defined in client env
const = .DATABASE_URL;- Compile-time isolation: If you accidentally import
envfrom the server file (env/server.ts) in client-side code, Nuxt's Vite bundler will fail the build with a compilation error. This is because@arkenv/nuxtregisters a custom Vite plugin that detects imports of the server module on the client side and blocks them at build time.