9

I've been trying to get environment variables to work in my documentation build.
I've had some success with adding a dotenv-webpack plugin and substituting values that way. This has the downside of needing a .env file of some kind

I would like to have my build know of environment variables automatically ie. everything that is output from printenv

I've tried adding this to package.json: TEST_ENV_VAR=working docusaurus start" But when I log the process.env object there is nothing there.

How can I make this work?

dingdingding
  • 1,411
  • 1
  • 15
  • 23

6 Answers6

12

I created a plugin that adds the functionality of dotenv-webpack to Docusaurus2's webpack config.

https://www.npmjs.com/package/docusaurus2-dotenv

You should be able to npm install docusaurus2-dotenv, enable systemvar, and add it to your plugin section and your systemvar values will be accessible e.g. process.env.PATH.

This would allow you to make use of .env files (if you decide want to use them in the future), as well as any environment variables that get created during CI or that exist on the machine that is building the code.

docusaurus.config.js

module.exports = {
  ..., // other docusaurus2 config
  plugins: [
    [
      "docusaurus2-dotenv",
      {
        systemvars: true,
      },
    ],
  ],
}

Jonny Nabors
  • 300
  • 3
  • 11
7

Build time environment variables

There are two steps:

  • Run npm i --save-dev dotenv
  • In your docusaurus.config.js, just add:
require('dotenv').config()
  • Confirm your .env directory contains environment variables, e.g.
ENVIRONMENT_VARIABLE_1=hello_there

Your .env file will be loaded, and you can use process.env.ENVIRONMENT_VARIABLE_1 now.

Runtime environment variables:

To use process.env variables in React components for example, do the builtime environment variables steps above, then use the customFields field of the docusaurus config object:

const config = {
  ...
  customFields: {
    'ENVIRONMENT_VARIABLE_1': process.env.ENVIRONMENT_VARIABLE_1,
    'ENVIRONMENT_VARIABLE_2': process.env.ENVIRONMENT_VARIABLE_2,
  },
  ...
}

and in my typescript component, access them with:

const {siteConfig} = useDocusaurusContext();

  return <div>{`${siteConfig.ENVIRONMENT_VARIABLE_1}`}</div>;

Read Custom Configurations in the docusaurus documentation for more information.

Comment

Jonny Nabors's answer (and package) was unnecessary for me and actually confused me. If you want your build process to use your environment variables, use the extremely popular npm package that has been downloaded 22 million times this week (dotenv, rather than his package (docusaurus2-dotenv), which did not work for me.

Perhaps his package is more useful if you needed to use the environment variables at runtime whilst avoiding adding it to the configuration object like I did above? However, in that case, I also found another solution, which is to use environment variables beginning with REACT_APP_.

Ben Butterworth
  • 22,056
  • 10
  • 114
  • 167
3

The question I have is Why can't we use process.env.VARIABLE?

Reading how Docusaurus.useDocusaurusContext works, a developer can read the config variables using import siteConfig from '@generated/docusaurus.config';. So the solution looks like:

docusaurus.config.js

const config = {
  customFields: {
    // application environment (i.e. staging or prod)
    env: process.env.REACT_APP_ENV,
  },
  ...
}

myUtil.ts

import siteConfig from '@generated/docusaurus.config';

if (siteConfig.customFields.env === 'prod') {
 // do something for prod
}

Then, restart the server using

export REACT_APP_ENV="prod"
yarn start

Importing docusaurus.config.js directly into the application results in the error process is not defined. This requires a webpack configuration, which I didn't want to get into.

Note: This method is not documented so use with care.

Taku
  • 5,639
  • 2
  • 42
  • 31
0

We ran into this problem while developing jsPlumb Components, and we wrote a Docusaurus plugin to assist:

https://github.com/jsplumb/docusaurus-plugin-env-loader-json

With this plugin you manage your environment specific values in a JSON file:

{
    "production":{
        "SERVER_URL":"https://some.server.com/anEndpoint"
    },
    "development":{
        "SERVER_URL":"http://localhost:4200/anEndpoint"
    }
}

which you then access via the customFields of your site config:

import useDocusaurusContext from '@docusaurus/useDocusaurusContext';

export function MyApp {

    const {siteConfig} = useDocusaurusContext();
    const serverUrl = siteConfig.customFields.SERVER_URL

    ...

}

The selection of production vs development is made by inspecting the NODE_ENV environment variable.

The plugin is on npm:

npm i --save-dev @jsplumb/docusaurus-plugin-env-loader-json
jsPlumb Team
  • 247
  • 1
  • 3
0

Just as a future reference, there is now an official section in the docusaurus documentation addressing this issue: https://docusaurus.io/docs/deployment#using-environment-variables

0

Do not use docusaurus2-dotenv you will get his issue

[ERROR] TypeError: dep.getModuleEvaluationSideEffectsState is not a function?

Instead install docusaurus-plugin-dotenv and add it like this to your plugins config in daucusaurus.config.js

plugins: 
[
...
    [
      'docusaurus-plugin-dotenv',
      {
          path: "./.env", 
          systemvars: true, 
      }
    ]
....
]

Now in your app you can use env variable normally ex:

import React from "react";
import { Auth0Provider } from "@auth0/auth0-react";
import Login from "../auth/Login";

const DOMAIN = process.env.REACT_APP_AUTH0_DOMAIN;
const CLIENTID = process.env.REACT_APP_AUTH0_CLIENTID;
....

DINA TAKLIT
  • 7,074
  • 10
  • 69
  • 74