Best way to Handle Environment Variables

Best way to Handle Environment Variables

ยท

5 min read

In the past, I would add sensitive information directly to the code, which was easy but not recommended. As the application and team expanded, it became necessary to manage environment variables. However, it became challenging to handle application configurations across different environments (development, staging, production) without including sensitive information in the codebase.

Currently, I mainly work on VueJs projects, so the examples in this blog are based on Vue syntax and expressions.

Understanding .env Files

Vue CLI projects can use .env files to specify environment variables, which are stored in the root of the project. Different .env files can be used for various environments:

  • .env: Default

  • .env.local: Used in all cases except during testing.

  • .env.[mode]: Used for a specific mode.

  • .env.[mode].local: Used for a specific mode but not tracked by git.

Variables beginning with VUE_APP_ will be included in the client bundle with webpack.DefinePlugin, allowing you to access them in your application code.

console.log(process.env.VUE_APP_TITLE);

Creating Environment Variables

Lets create .env files in your project root.

For example,

For development, you might create a file named .env.development with the following content:

VUE_APP_API_URL=https://dev.api.example.com
VUE_APP_TITLE=My Vue App (Development)

For production, you might have a .env.production file:

VUE_APP_API_URL=https://api.example.com 
VUE_APP_TITLE=My Vue App

Accessing Environment Variables in Your Application

Anywhere in your Vue.js application, you can access these variables using process.env.VUE_APP_XXX, where XXX is your variable name.

For example:

created() {
  console.log(process.env.VUE_APP_API_URL); // Use the API URL based on the environment
}

Using Environment Variables in Static Files

Since environment variables are embedded into the build, using them in static files like HTML is not straightforward. However, you can access them in your Vue components and then bind them to the attributes you need in your templates.

Mode and Environment Loading

Vue CLI 3 and later support specifying the mode in which you're running the build or serve commands. Modes can be used to load specific .env files. For example, running vue-cli-service serve --mode development will prioritize loading .env.development and .env.development.local files.

Best Practices

  • Do Not Store Sensitive Information: Since the environment variables are embedded into the client-side bundle, they can be accessed by anyone using your application. Do not store sensitive information like passwords or secret keys in these variables.

  • Version Control: It's common practice to exclude local environment files (.env.local, .env.*.local) from version control by adding them to .gitignore. You might include example .env files (like .env.example) in your repository as a template for others.

  • Consistency Across Environments: Ensure that all the environments define the same set of variables, even if their values differ, to avoid runtime errors due to undefined variables.

By following these guidelines and practices, you can effectively manage and use environment variables in your Vue.js projects, keeping your application configurations flexible and secure across different environments.


Also, Let's delve into more scenarios where handling environment variables in Vue.js can be particularly beneficial, illustrating the flexibility and security they offer in application development and deployment.

Scenario 1: Different API Endpoints

Different API Endpoints Imagine you're developing a Vue.js application that interacts with a backend API. During development, you want your application to hit a development server. However, in production, it should use the production API. Environment variables allow you to switch these endpoints seamlessly without code changes:

.env.development

VUE_APP_API_ENDPOINT=https://dev.example.com/api

.env.production

VUE_APP_API_ENDPOINT=https://example.com/api

In your Vue.js application, you can access the API endpoint like so:

axios.get(process.env.VUE_APP_API_ENDPOINT + '/users')
     .then(response => { 
          // Handle response 
     });

Scenario 2: Feature Flags

You're rolling out a new feature in your application and want to enable it selectively across different environments or even toggle it for testing. Environment variables can act as feature flags:

.env.local

VUE_APP_NEW_FEATURE_ENABLED=false

.env.production

VUE_APP_NEW_FEATURE_ENABLED=true

In your application, you can conditionally render components or enable functionality based on this flag:

<template>
  <div>
    <NewFeature v-if="isNewFeatureEnabled" />
  </div>
</template>

<script>
export default {
  computed: {
    isNewFeatureEnabled() {
      return process.env.VUE_APP_NEW_FEATURE_ENABLED === 'true';
    }
  }
}
</script>

Scenario 3: Analytics and Third-party Integrations

Your application might use different keys or IDs for analytics and third-party services across environments to separate development and production data:

.env.development

VUE_APP_GOOGLE_ANALYTICS_ID=UA-XXXXXX-2

.env.production

VUE_APP_GOOGLE_ANALYTICS_ID=UA-XXXXXX-1

Initializing the analytics library with the appropriate ID is straightforward:

if (process.env.VUE_APP_GOOGLE_ANALYTICS_ID) { 
   initGoogleAnalytics(process.env.VUE_APP_GOOGLE_ANALYTICS_ID); 
}

Scenario 4: Application Theming or Branding

Suppose your Vue.js application needs to support multiple themes or branding options based on the client or deployment target. Environment variables can dynamically set these themes:

.env.clientA

VUE_APP_THEME=dark 
VUE_APP_LOGO_URL=/assets/logo-clientA.png

.env.clientB

VUE_APP_THEME=light
VUE_APP_LOGO_URL=/assets/logo-clientB.png

Then, use these variables in your components to adjust the theme or display the correct logo dynamically.

Scenario 5: Build Timestamps

For debugging or informational purposes, you might want to include a build timestamp in your application. This can be achieved by setting an environment variable in your build script:

In package.json scripts

"scripts": { "build": "VUE_APP_BUILD_TIME=$(date) vue-cli-service build" }

Then, you can display this build time somewhere in your application, such as in the footer or about page.


Conclusion

These scenarios illustrate the versatility of using environment variables in Vue.js applications. They enable you to manage different configurations and behaviors across environments efficiently, making your development process smoother and your applications more secure and adaptable.

Feel free to share your thoughts and opinions and leave me a comment if you have any problems or questions. ๐Ÿ˜Ž๐Ÿ˜Ž

Till then, Keep on Hacking, Cheers

Happy coding! ๐Ÿš€๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

ย