@bl0cka.de/nextjs-runtime-env (0.2.1)
Installation
@bl0cka.de:registry=npm install @bl0cka.de/nextjs-runtime-env@0.2.1"@bl0cka.de/nextjs-runtime-env": "0.2.1"About this package
nextjs-runtime-env
Runtime environment variable injection for Next.js 15+.
NEXT_PUBLIC_* variables are normally baked into the client bundle at build time by Webpack. This means a single Docker image cannot be reused across environments — you need a separate build per environment.
This package solves that by reading process.env at request time on the server and injecting the values into window.__ENV__ via an inline <script> tag before the client bundle hydrates. The result is a single image that works in staging and production by changing runtime env vars only.
How it works
<InlineEnvScript>is an async server component placed in the root layout.- It calls
await connection()(Next.js 15 API) to opt out of static prerendering, ensuringprocess.envis read fresh on every request. - It serialises all
NEXT_PUBLIC_*vars towindow.__ENV__via an inline<script>tag. - On the client,
env(key)reads fromwindow.__ENV__instead of the Webpack-inlined value.
Installation
The package is published to a Forgejo npm registry at https://git.bl0cka.de and is publicly accessible — no auth token is required to install it.
1. Configure the registry
Add a .npmrc file to the root of any project that consumes this package so npm knows where to resolve the @bl0cka.de scope:
@bl0cka.de:registry=https://git.bl0cka.de/api/packages/npm-registry/npm/
This line is safe to commit.
2. Install the package
npm install @bl0cka.de/nextjs-runtime-env
Publishing a new version
Bump version in package.json, then publish using a Forgejo personal access token with the write:package scope (create one at https://git.bl0cka.de/user/settings/applications):
NPM_TOKEN=<your-token> npm publish
Setup
Add <InlineEnvScript> to your root layout (server component):
// app/layout.tsx
import { InlineEnvScript } from '@bl0cka.de/nextjs-runtime-env/server'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<head>
<InlineEnvScript />
</head>
<body>{children}</body>
</html>
)
}
Usage
Read a single variable (works in both server and client components):
import { env } from '@bl0cka.de/nextjs-runtime-env'
const apiUrl = env('NEXT_PUBLIC_SERVER_URL')
Read all variables at once (client components only):
import { useEnv } from '@bl0cka.de/nextjs-runtime-env'
export function MyComponent() {
const vars = useEnv()
return <pre>{JSON.stringify(vars, null, 2)}</pre>
}
Custom prefix (optional, defaults to NEXT_PUBLIC_):
<InlineEnvScript prefix="MY_APP_" />
Notes
env()falls back toprocess.env[key]during SSR of client components. The dynamic key lookup (process.env[key]) prevents Webpack from inlining the value, so the fallback also reads at runtime.- Values are JSON-serialised with
</script>sequences escaped to prevent XSS. - This package ships as TypeScript source with no build step — it is intended to be consumed by a Next.js project that already runs TypeScript.
Dependencies
Development dependencies
| ID | Version |
|---|---|
| release-it | ^20.2.0 |
Peer dependencies
| ID | Version |
|---|---|
| next | >=15 |
| react | >=18 |