DEV Community

Cover image for How to inject runtime env vars to your Next.js app
Michał Wrzosek
Michał Wrzosek

Posted on

How to inject runtime env vars to your Next.js app

It is very often beneficial to load environment variables during runtime to your client side, for example, when you want a single Docker image to use in different environments. This would not be possible when using build-time environments (NEXT_PUBLIC_...). Surprisingly, it may not be that obvious how to do so...

Here's one way you can do it:

You have your dynamic layout that will be executed on the server side that injects the env vars config to the client side. You can't use the "use client" clause here.

/src/app/layout.tsx

import { PropsWithChildren } from 'react';
import { unstable_noStore } from 'next/cache';
import { LayoutClient } from './layout-client';

export default function Layout({ children }: PropsWithChildren) {
  // This is important!
  unstable_noStore();

  // some example config to be injected to the client side
  const config = {
    apiEndpoint: process.env.API_ENDPOINT!,
    appEnvironment: process.env.APP_ENVIRONMENT!,
  };

  return (
    <html lang="en">
      <head>
        <link rel="icon" href="favicon.ico" />
      </head>
      <body>
        <LayoutClient config={config}>{children}</LayoutClient>
      </body>
    </html>
  )
}
Enter fullscreen mode Exit fullscreen mode

Then you have your "client" layout:

/src/app/layout-client.tsx

'use client';

import { PropsWithChildren } from 'react';

export const LayoutClient = ({ config, children }: PropsWithChildren<{
  apiEndpoint: string;
  appEnvironment: string;
}>) => {
  // and here you are now on the "client" and basically,
  // you can do whatever you want with your config
}
Enter fullscreen mode Exit fullscreen mode

I split the layout into "server" and "client" because I like to push the config through the React Context so that it will be available to all the components and this of course requires you to be within the "use client" clause.

In short, to make this work you need "unstable_noStore" and careful "use client" clause placement.

Top comments (0)