Accessibility

Handling Environment Variables in Vue

Vue uses the widely adopted dotenv module to load build configuration from the following files in your environment directory:

Fotis Adamakis
Fotis Adamakis
Senior Software Engineer / Technical Writer
1 min read
February 19, 2024

Handling Environment Variables in Vue

Handling Environment Variables in Vue

Vue uses the widely adopted dotenv module to load build configuration from the following files in your environment directory:

.env                \# loaded in all cases
.env.local          \# loaded in all cases, ignored by git
.env.[mode]         \# only loaded in specified mode
.env.[mode].local   \# only loaded in specified mode, ignored by git

Each file has the following format

VITE\_SOME\_KEY=123
DB\_PASSWORD=secret

Everything that has the VITE_ prefix will automatically be available in the client application inside import.meta.env

<script setup>
console.log(import.meta.env.VITE\_SOME\_KEY) // "123"
</script>

In case you are using [vue-cli](https://cli.vuejs.org/guide/mode-and-env.html#environment-variables) instead the prefix is _VUE__

Other parts of the application can securely use the .dotenv file without the VITE_ prefix so variables will not leak to the client.

That was easy so far. In a real-life scenario, you will have multiple config files for each environment.

For example locally

\# .env.local
VITE\_BACKEND\_URL=http://localhost:3000/
VITE\_PUBLIC\_URL=http://localhost:3000/uploads/

And for production

\# .env.production
VITE\_BACKEND\_URL=http://example.com/
VITE\_PUBLIC\_URL=http://example.cloudflare.com/uploads/

On the client side, we can use these variables directly since they are globally available

// /lib/fetch.ts

import axios from "axios";

const instance = axios.create({
  baseURL: import.meta.env.VITE\_BACKEND\_URL,
});

In case you are using typescript (you should, right?) you might see a not-that-helpful error

Property 'env' does not exist on type 'ImportMeta'.ts(2339)

To make TS happy create the file src/types/vite-env.d.ts with the following content.

/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE\_PUBLIC\_URL: string;
  readonly VITE\_BACKEND\_URL: string;
}

interface ImportMeta {
  readonly env: ImportMetaEnv;
}

Lastly, I find it a bit verbose to refer to import.meta.env.VITE_BACKEND_URL in my code. I usually create an intermediate appSettings.ts file to encapsulate it.

// src/config/appSetings.ts

export default {
  baseURL: import.meta.env.VITE\_BACKEND\_URL,
  publicUrl: import.meta.env.VITE\_PUBLIC\_URL,
};

which makes our original code simpler.

import axios from "axios";
import { baseUrl } from "@/config/appSetings";

const instance = axios.create({
  baseURL,
});
Fotis Adamakis

Fotis Adamakis

Senior Software Engineer / Technical Writer

Experienced software engineer writing about front end architecture, accessibility, system design, and developer productivity. Lessons from building and maintaining large-scale frontend applications, with a focus on practical patterns that make codebases easier to understand, scale, and evolve.

Barcelona, Spain