10

Is it possible to set environment variables in the manifest.json file of a Chrome Extension?

Isabella Lopes
  • 526
  • 6
  • 9
  • 2
    The final manifest.json can only use [locale variables](https://developer.chrome.com/extensions/i18n). If you use webpack or other bundler you can write a hook to process the source manifest.json and resolve the environment variables there. – wOxxOm Nov 07 '19 at 17:16
  • Did you figure this out Isabella? I have the same problem and am about to explore wOxxOm's suggestion of using webpack hooks. – Paul Watson Feb 11 '20 at 10:06
  • @PaulWatson I used wOxxOm's suggestion – Isabella Lopes Mar 18 '20 at 12:30
  • Thanks Isabella, I also came across the CopyWebpackPlugin method; https://stackoverflow.com/a/60188143/484337 – Paul Watson Mar 20 '20 at 08:42

2 Answers2

6

Like wOxxOm said, I used webpack to proccess manifest.json.

In my case, I needed to set version automatically on manifest file.

I added to webpack script:

plugins: [
    new CopyWebpackPlugin([
        {
            from: "public/manifest.json", 
            to: "manifest.json",
            transform(content, path) {
                return modify(content)
            }
        }
    ]),
]

And the modify function replaces version on file for the parameter:

function modify(buffer) {
  var manifest = JSON.parse(buffer.toString());
  let argv = process.argv[2];
  if (argv) manifest.version = argv.split("=")[1];
  let manifest_JSON = JSON.stringify(manifest, null, 2);
  return manifest_JSON;
}

So, I build like "yarn build --version=x.x" and webpack do what I need.

PS: if you're going to use this, remember to change:

  • the manifest.json directory, if necessary;

  • the value in the modify function, in my case it was version

Isabella Lopes
  • 526
  • 6
  • 9
6

As the OP has mentioned in her answer, using the copy-webpack-plugin in the webpack.config.js file is the way to go if you're building your Chrome Extension with React. However, if your React app is based on create-react-app, directly editing the webpack.config.js file (which is located in node_modules/react-scripts/config) is not recommended.

In such a case, use craco, which is an npm package that can be used to customize an app based on create-react-app. Here's how you do it:

  • Install craco into your project using npm i @craco/craco.
  • Install copy-webpack-plugin as a dev-dependency in your project using npm i --save-dev copy-webpack-plugin.
  • Let's suppose we're creating a development and a production build of our Chrome Extension. Let's also suppose we've already assigned "version": "0.1.0" in our Chrome Extension's manifest.json. Depending on the build type, we'd like to assign accordingly the version_name field in our Chrome Extension's manifest.json, e.g., "version_name": "0.1.0 dev" for development and "version_name": "0.1.0" for production. In your React app's package.json, introduce two fields (the script names can be whatever you wish) as follows:
    "scripts": {
      ...
      "build-dev": "CRX_ENV=dev craco build", // or "set CRX_ENV=dev&& craco build" in the case of Windows
      "build-prod": "CRX_ENV=prod craco build", // or "set CRX_ENV=prod&& craco build" in the case of Windows
      ...
    }
    
  • Create a new file called craco.config.js in the root of your project. As per your need, do something similar to the following in the craco.config.js file:
    const CopyPlugin = require("copy-webpack-plugin")
    
    module.exports = {
      webpack: {
        plugins: [
          new CopyPlugin({
            patterns: [
              {
                from: "public/manifest.json",
                to: "manifest.json",
                transform(content, path) {
                  return modifyManifest(content)
                },
              },
            ],
          }),
        ],
      },
    }
    
    function modifyManifest(buffer) {
      const manifest = JSON.parse(buffer.toString())
      if (process.env.CRX_ENV === "dev") {
        manifest.version_name = `${manifest.version} dev`
      } else if (process.env.CRX_ENV === "prod") {
        manifest.version_name = `${manifest.version}`
      }
      const manifestJson = JSON.stringify(manifest, null, 2)
      return manifestJson
    }
    
  • Run npm run build-dev. It will create a folder called build in your project root. This build folder is your unpacked Chrome Extension, which you can load into Chrome using the "Load unpacked" button on the chrome://extensions page. Once loaded, you should be able to see 0.1.0 dev as the version name of your Chrome Extension.
  • Delete the build folder created from the previous step and run npm run build-prod, and repeat the same steps. You should be able to see 0.1.0 as the version name of your Chrome Extension on the chrome://extensions page.
Nikhil Sinha
  • 481
  • 7
  • 5