<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Deiring Andreas</title>
    <description>The latest articles on DEV Community by Deiring Andreas (@lacocoroco).</description>
    <link>https://dev.to/lacocoroco</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F831851%2Ff266d56d-70a4-4de0-8c1a-893d8eb9e4ca.png</url>
      <title>DEV Community: Deiring Andreas</title>
      <link>https://dev.to/lacocoroco</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lacocoroco"/>
    <language>en</language>
    <item>
      <title>NextJS - Get rid of DotENV</title>
      <dc:creator>Deiring Andreas</dc:creator>
      <pubDate>Thu, 31 Mar 2022 12:27:26 +0000</pubDate>
      <link>https://dev.to/lacocoroco/nextjs-get-rid-of-dotenv-5gol</link>
      <guid>https://dev.to/lacocoroco/nextjs-get-rid-of-dotenv-5gol</guid>
      <description>&lt;p&gt;I always disliked the &lt;strong&gt;.env&lt;/strong&gt; file. Almost every time I was forced to place it on the top level of my app directory. At some point i started to use the npm &lt;a href="https://www.npmjs.com/package/config"&gt;config&lt;/a&gt; package. This gives the application a consistent configuration interface and there is a formidable way to implement it into the NextJS environment. For people which prefer code over text, feel free to checkout the finished &lt;a href="https://github.com/LaCocoRoco/examples-nextjs/tree/master/nextjs-config"&gt;implementation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;As reference we usa a &lt;a href="https://nextjs.org/docs/basic-features/typescript"&gt;NextJS Typescript zero configuration&lt;/a&gt; setup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app@latest --ts
# or
yarn create next-app --typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First we have to install the necessary npm package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install config @types/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we create the config directory and configuration files. The &lt;strong&gt;default.yaml&lt;/strong&gt; will be used later as a type template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config
- default.yaml
- development.yaml
- production.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;NextJS has the possibility to define &lt;a href="https://nextjs.org/docs/api-reference/next.config.js/environment-variables"&gt;environment variables&lt;/a&gt; in the config file. To make full use of it, we will import the config package and set the environment variables to the configuration variables with &lt;strong&gt;config.util.toObject()&lt;/strong&gt;. By default NextJS creates a &lt;strong&gt;next.config.js&lt;/strong&gt; file in the root directory. Change the extension to &lt;strong&gt;.mjs&lt;/strong&gt; and replace the content with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// next.config.mjs&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;reactStrictMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;util&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toObject&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point we already replaced the &lt;strong&gt;.env&lt;/strong&gt; files. NextJS will load the configuration files from the config folder with the corresponding activ environment.&lt;/p&gt;

&lt;p&gt;To use it with typescript we have to do some additional work. First we will need a type declaration file for the config variables. Then we have to add it to the global process environment. &lt;/p&gt;

&lt;p&gt;From here on out we will work with an example for better traceability.&lt;br&gt;
Let us put some stuff into the &lt;strong&gt;default.yaml&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;firebase&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apiKey&lt;/span&gt;
  &lt;span class="na"&gt;appId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appId&lt;/span&gt;
  &lt;span class="na"&gt;projectId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;projectId&lt;/span&gt;
  &lt;span class="na"&gt;authDomain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;authDomain&lt;/span&gt;
  &lt;span class="na"&gt;databaseURL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;databaseURL&lt;/span&gt;
  &lt;span class="na"&gt;storageBucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;storageBucket&lt;/span&gt;
  &lt;span class="na"&gt;messagingSenderId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;messagingSenderId&lt;/span&gt;
  &lt;span class="na"&gt;measurementId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;measurementId&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we will have to reflect the configuration variables in typescript. In my native language there is a saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Viele Wege führen nach Rom&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In short it means there are many solutions for a problem. For example, we could do it manually or use a web based &lt;a href="https://jsonformatter.org/yaml-to-typescript"&gt;yaml to typescript&lt;/a&gt; converter. Unfortunately i could not find any npm package for this problem. But as many of us know: &lt;strong&gt;Why do something in 10 minutes when you can automate it in 10 hours?&lt;/strong&gt; Consequently, let us install an additional package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -D ymlts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can convert the configuration file to typescript from our console. With the following command we create the necessary type file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx ymlts config/default @types/config 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a &lt;strong&gt;config.d.ts&lt;/strong&gt; in the &lt;strong&gt;@types&lt;/strong&gt; directory. Its content should look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @types/config.d.ts&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Firebase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Firebase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;            &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;appId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;             &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;         &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;authDomain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;databaseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;       &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;storageBucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;messagingSenderId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;measurementId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last but not least, we have to add the new config type to the process environment. For this we create a &lt;strong&gt;global.d.ts&lt;/strong&gt; file in the &lt;strong&gt;@types&lt;/strong&gt; directory...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@types
- global.d.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and extend the process environment with the config type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// @types/global.d.ts&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;NodeJS&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ProcessEnv&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For future use, if you are really lazy: It is possible to add the ymlts command to the &lt;strong&gt;package.json&lt;/strong&gt; and start it with &lt;strong&gt;npm run env&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx ymlts config/default @types/config"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;So why? At first glance this looks like unnecessary work, but there is some neat stuff!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Better readability with a humanfriendly YAML file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Environment variables managed in an organized config folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normaly you have to prefix Environment Variables with &lt;strong&gt;NEXT_PUBLIC_&lt;/strong&gt; to expose them to the &lt;a href="https://nextjs.org/docs/basic-features/environment-variables#exposing-environment-variables-to-the-browser"&gt;browser&lt;/a&gt;. But NextJS replaces Environment Variables at &lt;a href="https://nextjs.org/docs/api-reference/next.config.js/environment-variables"&gt;buildtime&lt;/a&gt; which should make it obsolete.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By converting the config file to types we get the possibility to use intellisense with &lt;strong&gt;process.env&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The YAML configuration variables can be nested. Related to this blog as example it is possible to initialize  the Firebase app with &lt;code&gt;initializeApp(process.env.firebase);&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>typescript</category>
      <category>dotenv</category>
      <category>conf</category>
    </item>
  </channel>
</rss>
