Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to load environment variables at runtime, not build time #85

Open
timheerwagen opened this issue Jun 13, 2023 · 9 comments
Open
Labels
PRs Accepted Feel free to pick this up and make a PR

Comments

@timheerwagen
Copy link

I wonder if it is possible to load the environment variables at runtime, as with "https://github.com/expatfile/next-runtime-env". This is not possible in the example with nextjs.

@baptisteArno
Copy link

Yeah, I assumed t3-env already did this! 🥲

It's important for self-hostable applications that are packaged into a docker image, end users should be able to edit the runtime env

Would you accept PR for this? I could try to implement a solution

@baptisteArno
Copy link

I think we can make t3-env compatible with next-runtime-env at least! I'll take a look.

@timheerwagen
Copy link
Author

@baptisteArno I would be very happy if, if you find a solution, you share it here. I have been looking for something like this for some time. Thank you very much!

@baptisteArno
Copy link

baptisteArno commented Aug 15, 2023

This works:

// src/env.mjs
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

const readVariable = (key) =>  {
  if(typeof window === 'undefined') return process.env[key]
  return window.__ENV[key]
}

export const env = createEnv({
  server: {
    DATABASE_URL: z.string().url(),
    OPEN_AI_API_KEY: z.string().min(1),
  },
  client: {
    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1),
  },
  runtimeEnv: {
    DATABASE_URL: process.env.DATABASE_URL,
    OPEN_AI_API_KEY: process.env.OPEN_AI_API_KEY,
    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:
      readVariable(NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY),
  },
});

@juliusmarminge
Copy link
Member

Would you accept PR for this? I could try to implement a solution

Yes

@juliusmarminge juliusmarminge added the PRs Accepted Feel free to pick this up and make a PR label Aug 16, 2023
@psycho-baller
Copy link

Would love to hear of any updates on this issue🤔

@rochaalexandre
Copy link

In the project I'm working we adopted the t3-env lib with nextjs, to work around this validation problem in the build time I added an env var to skip the validation.
Package.json

{ 
  "scripts": {
      "dev": "yarn generate && NODE_OPTIONS='--inspect' next dev",
      "build": "yarn generate && SKIP_ENV_VALIDATIONS='true' next build",
      "start": "next start",
    }
 }

env.mjs:

export const env = createEnv({
  isServer: typeof window === 'undefined' || process.env.NODE_ENV === 'test',
  /*
   * Serverside Environment variables, not available on the client.
   * Will throw if you access these variables on the client.
   */
  server: {
    
  },
  /*
 * Environment variables available on the client and server.
 *
 */
  shared: {
    NODE_ENV: z.enum(['test', 'development', 'production'])
      .optional()
      .default('production'),
    STAGE: z.enum(['local', 'dev', 'stg', 'prod']).default('prod'),
    APP_LOG_LEVEL: z
      .string()
      .optional()
      .default('info')
      .transform((data) => data.toLowerCase()),
  },
  /*
   * Environment variables available on the client.
   *
   * 💡 You'll get type errors if these are not prefixed with NEXT_PUBLIC_.
   */
  client: {
  },

  /*
   * Due to how Next.js bundles environment variables on Edge and Client,
   * we need to manually destructure them to make sure all are included in bundle.
   *
   * 💡 You'll get type errors if not all variables from `server` & `client` are included here.
   * All the env vars must end with the suffix _ENV to avoid a cycle import on the env-nextjs that enters in loop
   */
  runtimeEnv: {
    NODE_ENV: process.env.NODE_ENV,
    STAGE: process.env.STAGE,
    APP_LOG_LEVEL: process.env.APP_LOG_LEVEL,

  },
  skipValidation: process.env.SKIP_ENV_VALIDATIONS === 'true'
});

In this way I'm able to skip the validation for the build

@SaadBazaz
Copy link

This works:

// src/env.mjs
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

const readVariable = (key) =>  {
  if(typeof window === 'undefined') return process.env[key]
  return window.__ENV[key]
}

export const env = createEnv({
  server: {
    DATABASE_URL: z.string().url(),
    OPEN_AI_API_KEY: z.string().min(1),
  },
  client: {
    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1),
  },
  runtimeEnv: {
    DATABASE_URL: process.env.DATABASE_URL,
    OPEN_AI_API_KEY: process.env.OPEN_AI_API_KEY,
    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:
      readVariable(NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY),
  },
});

I would like something like this, but for async functions. #146

@SunnyAureliusRichard
Copy link

The correct way is what @rochaalexandre posted but SKIP_ENV_VALIDATION instead of SKIP_ENV_VALIDATIONS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PRs Accepted Feel free to pick this up and make a PR
Projects
None yet
Development

No branches or pull requests

7 participants