Matt
Matt

Reputation: 10392

How can I use Vite env variables in vite.config.js?

With the following .env in my Vite project:

# To prevent accidentally leaking env variables to the client, only
# variables prefixed with VITE_ are exposed to your Vite-processed code

VITE_NAME=Wheatgrass
VITE_PORT=8080

How can I use VITE_PORT in my vite.config.js?

Upvotes: 139

Views: 157592

Answers (9)

MiguelG
MiguelG

Reputation: 466

You have it documented right here:

https://vitejs.dev/config/#using-environment-variables-in-config

It worked for me as follow:

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, "../", "");
  return {
    plugins: [react()],
    envDir: "../",
    server: {
      port: env.VITE_CLIENT_PORT),
    },
  };
});

Upvotes: 3

Tharindu Jayasanka
Tharindu Jayasanka

Reputation: 359

I had exactly the same issue and found a solution.

import { defineConfig, loadEnv } from 'vite';

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd());

  const API_URL = `${env.VITE_API_URL ?? 'http://localhost:3000'}`;
  const PORT = `${env.VITE_PORT ?? '3000'}`;

  return {
    server: {
      proxy: {
        '/api': API_URL,
      },
      port: PORT,
    },
    build: {
      outDir: 'public',
    },
    plugins: [react()],
  };
});

In .env

VITE_API_URL='https://yourapiurl.com'
VITE_PORT=3000

Upvotes: 34

Ferdaus Zaman Polok
Ferdaus Zaman Polok

Reputation: 117

Anyone who is using Vite 4.0 and process.env = { ...process.env, ...loadEnv(mode, process.cwd()) }; is not working for you try this:

First Install dotenv using yarn add dotenv. Then go to your vite.config.js file write these:

import { defineConfig } from 'vite';
import dotenv from 'dotenv';
import react from '@vitejs/plugin-react'

dotenv.config();

console.log("hello", process.env.VITE_HOMEPAGE_URL) //when you run the frontend using yarn dev you will be able to see this on you cmd to know this works! :D

export default defineConfig({
  base: process.env.VITE_HOMEPAGE_URL,
  plugins: [react()],
})

Your environment variable file .env should look something like this:

VITE_HOMEPAGE_URL=https://abc.something.com/home/

If you face linter error like process is not defined go to your .eslintrc.cjs file and add node: true inside the env. So it will look something like below

module.exports = {
  env: { browser: true, es2020: true, node: true },
  //...other settings
}

Upvotes: 3

Samuurai
Samuurai

Reputation: 397

If anyone is using the firebase project name based env files like .env.yourapp-prod and .env.yourapp.dev, you can bring those runtime vars into vite to make them available for builds like this:

import { defineConfig } from 'vite';
import { sveltekit } from '@sveltejs/kit/vite';
import { resolve } from 'path';
import dotenv from 'dotenv';
import fs from 'fs';

export default defineConfig(() => {
  // Decide which .env file to load based on the mode

  const envFile = process.env.NODE_ENV === 'production' ? 'env.yourapp-prod' :'.env.yourapp-dev';
  // Load the environment variables using dotenv and assign to process.env
  const envConfig = dotenv.parse(fs.readFileSync(envFile));
  process.env = { ...process.env, ...envConfig };

  // Convert environment variables for Vite's define option
  const envVarsForDefine = Object.fromEntries(
    Object.entries(process.env).map(([key, value]) => [`process.env.${key}`, JSON.stringify(value)])
  );


  return {
    plugins: [sveltekit()],
    test: {
      include: ['src/**/*.{test,spec}.{js,ts}']
    },
    resolve: {
      alias: {
        $src: resolve('./src'),
        $stores: resolve('./src/lib/stores'),
        $assets: resolve('./src/assets'),
        $icon: resolve('./node_modules/svelte-bootstrap-icons/lib')
      }
    },
    define: envVarsForDefine
  };
});

Then deploy your app like this:

NODE_ENV=staging firebase deploy

or

NODE_ENV=production firebase deploy

Upvotes: 2

Gabriele Serra
Gabriele Serra

Reputation: 531

If you are searching for a simpler solution, you can do something like this:

import { defineConfig, loadEnv } from 'vite';

const env = loadEnv(
    'all',
    process.cwd()
);

let port = env.VITE_PORT;

The loadEnv type signature is detailed below:

function loadEnv(
  mode: string,
  envDir: string,
  prefixes: string | string[] = 'VITE_',
): Record<string, string>

By default, only env variables prefixed with VITE_ are loaded unless prefixes is changed.

Upvotes: 6

Thomas Foskolos
Thomas Foskolos

Reputation: 131

You can use dotenv

https://github.com/motdotla/dotenv#readme

in your vite.config.js

import dotenv from 'dotenv'

dotenv.config()

process.env.YOUR_ENV_VAR 

Upvotes: 13

Byron2017
Byron2017

Reputation: 1003

Maybe this can be usefull for someone that is working with react and vite

vite.config.js

import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
// export default defineConfig({
//   plugins: [react()],
// })

export default defineConfig(({ mode }) => {
  const env = loadEnv("mock", process.cwd(), "");
  const processEnvValues = {
    "process.env": Object.entries(env).reduce((prev, [key, val]) => {
      console.log(key, val);
      return {
        ...prev,
        [key]: val,
      };
    }, {}),
  };

  return {
    plugins: [react()],
    define: processEnvValues,
  };
});

How to TEST:

1.- Add these variables to a new .env or .env.local file

REACT_APP_MAILCHIMP_URL="https://gmail.xxxx.com/subscribe/post"
REACT_APP_MAILCHIMP_U="xxxxxxxxxxxxxxxxx"
REACT_APP_MAILCHIMP_ID="YYYYYYYYYYYY"

2.- Add a new component component/Test.js file

export const Test = () => {
  console.log(import.meta.env.REACT_APP_MAILCHIMP_URL); 
  console.log(import.meta.env.REACT_APP_MAILCHIMP_U); 
  console.log(import.meta.env.REACT_APP_MAILCHIMP_ID); 

  const a_var = `${process.env.REACT_APP_MAILCHIMP_URL}`;
  console.log(a_var);

  return (

    <div>
      <small> You are running this application in mode.: 
      <b>{process.env.NODE_ENV}</b>
      </small>

      <div>
        <small> REACT_APP_NOT_SECRET_CODE:  
        <b> {process.env.REACT_APP_MAILCHIMP_URL}</b>
        </small>
      </div>
    </div>
  );
};

3.- Add Test component to App.js file

import "./App.css";

import { Test } from "./components/Test";

function App() {
  return (
    <div className="App">
      <Test />
    </div>
  );
}

export default App;

Upvotes: 2

Matt
Matt

Reputation: 10392

You can load the app level env variables and add them to the Node level env variables:

import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';


export default ({ mode }) => {
    process.env = {...process.env, ...loadEnv(mode, process.cwd())};

    // import.meta.env.VITE_NAME available here with: process.env.VITE_NAME
    // import.meta.env.VITE_PORT available here with: process.env.VITE_PORT

    return defineConfig({
        plugins: [vue()],

        server: {
            port: parseInt(process.env.VITE_PORT),
        },
    });
}

Upvotes: 209

Goutham J.M
Goutham J.M

Reputation: 2194

If the above solution by @matt doesnt work for you then change the vite.config.ts/ vite.config.js like below

1st Solution

import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig(({ mode }) => {

const env = loadEnv(
  'mock', 
  process.cwd(),
  '' 
)
  const processEnvValues = {
    'process.env': Object.entries(env).reduce(
      (prev, [key, val]) => {
        return {
          ...prev,
          [key]: val,
        }
      },
      {},
    )
  }

  return {
    plugins: [vue()],
    define: processEnvValues
  }
}

2nd Solution

import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';


export default ({ mode }) => {
    process.env = Object.assign(process.env, loadEnv(mode, process.cwd(), ''));

    return defineConfig({
        plugins: [vue()],
    });
}

Upvotes: 15

Related Questions