Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do I read from a .env file? #782

Closed
michrome opened this issue Nov 20, 2019 · 10 comments
Closed

How do I read from a .env file? #782

michrome opened this issue Nov 20, 2019 · 10 comments

Comments

@michrome
Copy link

I know I can pass local environment variables to 11ty by running it with a syntax like $ SECRET_TOKEN=xxxyyy npx @11ty/eleventy --serve but what's the best way to pick this up from a local .env file?

Failing that, what's a good way to inject a secret value into process.env without committing the secret to source control?

Thank you!

@DirtyF
Copy link
Contributor

DirtyF commented Nov 20, 2019

Take a look at https://www.npmjs.com/package/dotenv

@chrissy-dev
Copy link

chrissy-dev commented Nov 21, 2019

@michrome I'm using dotenv in my project as @DirtyF suggested. You can see how it's used here:

Sample env file:
.env.sample

Data file:
_data/webmentions.js

Links updated: 11/08/2021.

@michrome
Copy link
Author

michrome commented Nov 21, 2019

Thank you @DirtyF and @chrisssycollins 🤝 dotenv worked perfectly.

For anyone else coming to this later, it's as simple as:

  1. Install dotenv with $ npm install --save-dev dotenv.
  2. Add require('dotenv').config(); to your .eleventy.js file.

@davidrhoden
Copy link

@michrome I'm using dotenv in my project as @DirtyF suggested. You can see how it's used here:

Sample env file:
.env.sample

Data file:
_data/webmentions.js

These example links no longer work.

@pdehaan
Copy link
Contributor

pdehaan commented Aug 9, 2021

@davidrhoden There should be a few other references and examples using the dotenv library in this repo:
https://github.com/11ty/eleventy/search?q=dotenv+is%3Aissue&type=issues (for example, I think we discussed a few environment variable scenarios in #1886 recently).

Alternatively, I think you can check out an older branch to see those files now:
https://github.com/scottishstoater/chrissy.dev/blob/2020/.env.sample
https://github.com/scottishstoater/chrissy.dev/blob/2020/src/_data/webmentions.js#L2

@chrissy-dev
Copy link

@davidrhoden I've updated the links, thanks for flagging.

@patricknelson
Copy link

patricknelson commented Mar 13, 2022

Here's a little tutorial outlining what I did to access environment variables in *.njk files.

First, add dotenv to package.json

npm i --save dotenv

Initialize in .eleventy.js config callback

// Populates environment variables into process.env and makes it available in 11ty's global data.
require('dotenv').config();
eleventyConfig.addGlobalData('env', process.env);

In your .env, setup your vars, e.g.

FOO=BAR
BAZ=QUX

And in your templates, just access env var, like so:

Foo is {{ env.FOO }} and baz is {{ env.BAZ }}.

Folks googling will still land on this page, so I figured I'd drop this here (at least for my future self). 😄

@pdehaan
Copy link
Contributor

pdehaan commented Mar 13, 2022

Fun fact, if you're using v1, you can use the .addGlobalData() method and skip yourself the src/_data/env.js step:

const inspect = require("node:util").inspect;

require("dotenv").config();

module.exports = (eleventyConfig) => {
  eleventyConfig.addFilter("inspect", (value) => inspect(value, {sorted: true}));

  eleventyConfig.addGlobalData("env", process.env);

  return {
    dir: {
      input: "src",
      output: "www",
    }
  };
};

Then in your template it should still just be:

<!-- src/index.njk -->
<p>FOO={{ env.FOO }}</p>
<p>BAZ={{ env.BAZ }}</p>

OUTPUT

<p>FOO=BAR</p>
<p>BAZ=QUX</p>

Although this means ALL of your environment variables will end up in env (not just the files in your local .env file):

<pre data-debug>{{ env | keys | inspect | safe }}</pre>

OUTPUT

<pre data-debug>[
  'APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL',
  'BAZ',
  ...,
  'npm_package_name',
  'npm_package_version'
]</pre>

If you just want the environment variables from the .env file and not the entire system/universe, you can use the parsed property from dotenv.config(), a la:

eleventyConfig.addGlobalData("env", require("dotenv").config().parsed);

OUTPUT

<pre data-debug>[ 'BAZ', 'FOO' ]</pre>

Here's my "final" .eleventy.js file:

const inspect = require("node:util").inspect;

module.exports = (eleventyConfig) => {
  eleventyConfig.addFilter("inspect", (value) => inspect(value, {sorted: true}));
  eleventyConfig.addFilter("keys", obj => Object.keys(obj).sort());

  eleventyConfig.addGlobalData("env", require("dotenv").config().parsed);

  return {
    dir: {
      input: "src",
      output: "www",
    }
  };
};

@patricknelson
Copy link

Oh, nice! That is more elegant. Even though I only just started, I was still on 0.12.1 since I forked from another starter project.

Not sure if it's best practice per se (since I don't think those .env variables are used elsewhere) but in my case I'm just initializing it now inside the configuration callback, just to be concise. That's actually something I like about 11ty so far, since it's so clean and elegant (even extending it is super easy).

I think I'll tweak my mini tutorial, too.... thanks! 🚀

@brianzelip
Copy link

Just some feedback that this was a helpful thread for my related but different use case.

I assumed I could just require dotenv in my global JS data file, but the value outputted in the template was undefined. This thread pointed me to require dotenv in my 11ty config file, not in my JS data file, but still use the process.env.VAR in my JS data file, and it magically worked 🎉.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants