<?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: Emmanuel Gautier</title>
    <description>The latest articles on DEV Community by Emmanuel Gautier (@emmanuelgautier).</description>
    <link>https://dev.to/emmanuelgautier</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%2F355929%2F7b9e399b-900d-4fc2-91db-fd538aedfeac.png</url>
      <title>DEV Community: Emmanuel Gautier</title>
      <link>https://dev.to/emmanuelgautier</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emmanuelgautier"/>
    <language>en</language>
    <item>
      <title>Introducing new blog on OAuth, OpenID Connect, and IAM Solutions</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Thu, 30 Mar 2023 21:10:34 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/introducing-new-blog-on-oauth-openid-connect-and-iam-solutions-2b7e</link>
      <guid>https://dev.to/emmanuelgautier/introducing-new-blog-on-oauth-openid-connect-and-iam-solutions-2b7e</guid>
      <description>&lt;p&gt;I'm excited to announce the launch of a new blog named &lt;a href="https://www.cerberauth.com/"&gt;CerberAuth&lt;/a&gt;, where I'll be exploring the world of OAuth, OpenID Connect, and IAM solutions for modern security. As a developer and security enthusiast, I've spent countless hours researching and experimenting with various IAM and OpenID Connect providers. With this blog, I hope to share some knowledge and experience with others who are interested in learning more about these topics.&lt;/p&gt;

&lt;p&gt;In addition to sharing some thoughts and insights, I'll also be developing tools to make it easier for developers to implement and work with these technologies. I'm particularly excited about a new tool I've been working on that automatically generates secure OAuth2 rules from an OpenAPI contract (available on &lt;a href="https://github.com/cerberauth/openapi-oathkeeper/"&gt;Github&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Whether you're a seasoned security expert or just getting started with these technologies, I hope you'll find the &lt;a href="https://www.cerberauth.com/"&gt;CerberAuth blog&lt;/a&gt; informative and helpful. Stay tuned for more posts and updates.&lt;/p&gt;

</description>
      <category>security</category>
      <category>authentication</category>
      <category>authorization</category>
    </item>
    <item>
      <title>How to fix DNS Internal Resolution inside the Nginx docker container</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Sat, 19 Nov 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/how-to-fix-dns-internal-resolution-inside-the-nginx-docker-container-2338</link>
      <guid>https://dev.to/emmanuelgautier/how-to-fix-dns-internal-resolution-inside-the-nginx-docker-container-2338</guid>
      <description>&lt;p&gt;Sometimes, errors with Docker and some containers can become cryptic when it is about networking. Today, it was Nginx that was not able to reach another container. Here is the docker-compose used:&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;containername&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;...&lt;/span&gt;
    &lt;span class="s"&gt;container_name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;containername&lt;/span&gt;
    &lt;span class="s"&gt;networks&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;intranet&lt;/span&gt;

  &lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:8080"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./.docker/nginx/conf.d:/etc/nginx/conf.d&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;intranet&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;intranet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the Nginx configuration used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt;       &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt;  &lt;span class="s"&gt;[::]:8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt;  &lt;span class="s"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://containername:3000&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;Even after defining a container name and ensuring that the two containers can communicate inside the same docker network, Nginx continues throwing the following error: &lt;code&gt;no resolver defined to resolve container_name&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Thanks for this Stack Overflow &lt;a href="https://stackoverflow.com/a/37656784"&gt;answer&lt;/a&gt; for helping me figure out what was the root cause. The problem is that Nginx's default behavior is not to make a DNS resolution with Docker's internal DNS so he can not resolve a container by name. To fix this issue, you need to make possible the resolution with the Docker internal DNS. Just add this line in the Nginx configuration and you should be OK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;http&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;resolver&lt;/span&gt; &lt;span class="mi"&gt;127&lt;/span&gt;&lt;span class="s"&gt;.0.0.11&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;Hope this quick post helps you fix a similar issue.&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>docker</category>
      <category>dns</category>
    </item>
    <item>
      <title>Keep the same Node.js version between local environment and Github Actions</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Sun, 30 Oct 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/keep-the-same-nodejs-version-between-local-environment-and-github-actions-1gj7</link>
      <guid>https://dev.to/emmanuelgautier/keep-the-same-nodejs-version-between-local-environment-and-github-actions-1gj7</guid>
      <description>&lt;p&gt;It can be complicated to have the same Node version between the local environment and the CI/CD. The latest Node.js version or the latest lts is released recently and if you want to upgrade to the Node version, usually you can forget to configure one environment. For that reason, it can be important to have only one source of truth to define the Node version, so you change in one place it impacts every environment.&lt;/p&gt;

&lt;p&gt;Here we will use nvm and have the CI/CD example with Github Actions. Some other CI/CD solutions can exist elsewhere using a similar configuration and reproduce the common configuration.&lt;/p&gt;

&lt;p&gt;First of all, you should configure a &lt;code&gt;.nvmrc&lt;/code&gt; file defining the version you want to use. This version will be used in your local environment. To use it, you can either make an &lt;code&gt;nvm use&lt;/code&gt; each time you go to the project's local directory or configure your bash to use it automatically.&lt;/p&gt;

&lt;p&gt;Here is an example of a &lt;code&gt;.nvmrc&lt;/code&gt; file content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lts/hydrogen

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, you can configure the Github Action so to use the same .nvmrc file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup node env
        uses: actions/setup-node@v3
        with:
          node-version-file: '.nvmrc'
          cache: 'yarn'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you change the .nvmrc file, it changes the version used for your local environment, the Node environment for all your team, and the CI/CD running on Github.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>github</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Extends Express session SessionData type</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Sun, 30 Oct 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/extends-express-session-sessiondata-type-53ic</link>
      <guid>https://dev.to/emmanuelgautier/extends-express-session-sessiondata-type-53ic</guid>
      <description>&lt;p&gt;It can be complicated to have the same Node version between the local environment and the CI/CD. The latest Node.js version or the latest lts is released recently and if you want to upgrade to the Node version, usually you can forget to configure one environment. For that reason, it can be important to have only one source of truth to define the Node version, so you change in one place it impacts every environment.&lt;/p&gt;

&lt;p&gt;Here we will use nvm and have the CI/CD example with Github Actions. Some other CI/CD solutions can exist elsewhere using a similar configuration and reproduce the common configuration.&lt;/p&gt;

&lt;p&gt;First of all, you should configure a &lt;code&gt;.nvmrc&lt;/code&gt; file defining the version you want to use. This version will be used in your local environment. To use it, you can either make an &lt;code&gt;nvm use&lt;/code&gt; each time you go to the project's local directory or configure your bash to use it automatically.&lt;/p&gt;

&lt;p&gt;Here is an example of a &lt;code&gt;.nvmrc&lt;/code&gt; file content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lts/hydrogen

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, you can configure the Github Action so to use the same .nvmrc file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup node env
        uses: actions/setup-node@v3
        with:
          node-version-file: '.nvmrc'
          cache: 'yarn'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you change the .nvmrc file, it changes the version used for your local environment, the Node environment for all your team, and the CI/CD running on Github.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>github</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Convert a JavaScript object to queryparams string</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Mon, 16 May 2022 21:33:24 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/convert-a-javascript-object-to-queryparams-string-ck3</link>
      <guid>https://dev.to/emmanuelgautier/convert-a-javascript-object-to-queryparams-string-ck3</guid>
      <description>&lt;p&gt;Converting a JS object to parameters in a URL is a common task for web developers but there are different ways to do it in depending on the context. Let's see two options depending whether your code is running in a browser or on a NodeJS server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser Side Using URLSearchParams API
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams"&gt;URLSearchParams&lt;/a&gt; interface is available in the browser. It is used to manipulate the query string of a URL. This API is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams#browser_compatibility"&gt;compatible&lt;/a&gt; with all modern browsers including the latest browser versions and excluding Internet Explorer.&lt;/p&gt;

&lt;p&gt;Here is an example:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&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;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;URLSearchParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are in the case you need to support Internet Explorer 11 or lower, you can use a URLSearchParams &lt;a href="https://github.com/zloirock/core-js#url-and-urlsearchparams"&gt;polyfill&lt;/a&gt; or the &lt;a href="https://www.npmjs.com/package/querystringify"&gt;querystringify&lt;/a&gt; npm package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server Side Using querystring
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://nodejs.org/api/querystring.html"&gt;querystring&lt;/a&gt; module is part of NodeJS built-in modules. It is used to manipulate the query string of a URL as well.&lt;/p&gt;

&lt;p&gt;Here is an example:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;querystring&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;querystring&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;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&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;qs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;querystring&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;qs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>ESLint Global Variables</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Sat, 27 Nov 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/eslint-global-variables-17d3</link>
      <guid>https://dev.to/emmanuelgautier/eslint-global-variables-17d3</guid>
      <description>&lt;p&gt;Sometimes, we need to access some globally defined variables, especially the browser side when we use third-party libraries, and can also be the case server side. Because the variables are not referenced in the code, eslint throws an error saying the variable is not defined.&lt;/p&gt;

&lt;p&gt;Eslint let us specify the global variable. This configuration allows eslint to know that a variable exists even if it is not referenced in the code. Here is an example:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"globals"&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;"dataLayer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to specifying it, you can declare the variable as writable or not. Here is an example:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"globals"&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;"dataLayer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"writable"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or only declare it as read-only:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"globals"&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;"dataLayer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"readonly"&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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find more documentation on the &lt;a href="https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals"&gt;Eslint doc page&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>eslint</category>
    </item>
    <item>
      <title>Extend Window type with Typescript</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Sat, 27 Nov 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/extend-window-type-with-typescript-p9d</link>
      <guid>https://dev.to/emmanuelgautier/extend-window-type-with-typescript-p9d</guid>
      <description>&lt;p&gt;During typescript app development, sometime you need to access properties or functions of the &lt;code&gt;Window&lt;/code&gt; object. Some of these properties or functions are not available in the &lt;code&gt;window&lt;/code&gt; object defined by the browser. Those may be defined by Third-party libraries you can add to your pages like Google Tag Manager for example. Because of this, you need to extend the Window type with the properties or functions you need to access.&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeScript Window type
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Window&lt;/code&gt; type is defined in the &lt;code&gt;lib.dom&lt;/code&gt; typescript module. You can find the definition of the &lt;code&gt;Window&lt;/code&gt; type at the following &lt;a href="https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.window.html"&gt;TSDoc&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When can you have new properties not defined by your code in the &lt;code&gt;Window&lt;/code&gt; object? An example is when you want to add Google Tag Manager or Google Analytics to your page. Those scripts are not loaded by your code directly but you may communicate with them through some window object properties. For Google Tag Manager, the &lt;code&gt;datalayer&lt;/code&gt; property is added and some of the functions are also added.&lt;/p&gt;

&lt;p&gt;In this case, you will have the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Property does not exist on type 'window &amp;amp; typeof globalthis'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extend Window type with the missing properties
&lt;/h2&gt;

&lt;p&gt;In order to extend the Window type, you need to add the missing properties or functions.&lt;/p&gt;

&lt;p&gt;The following code snippet will extend the &lt;code&gt;Window&lt;/code&gt; type with the missing properties or functions.&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="kr"&gt;declare&lt;/span&gt; &lt;span class="nb"&gt;global&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;Window&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;gtag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
    &lt;span class="nx"&gt;dataLayer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;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;Do not forget to add the file containing this snippet to the list of project files for the Typescript compilation.&lt;/p&gt;

&lt;p&gt;For example, in a NextJS project, you can add the snippet in the &lt;code&gt;globals.d.ts&lt;/code&gt; file 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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Window&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;gtag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
  &lt;span class="nx"&gt;dataLayer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope this article helps you to avoid this Typescript error.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>react</category>
      <category>vue</category>
    </item>
    <item>
      <title>Gatsby + Netlify CMS + TailwindCSS Starter</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Sun, 17 Oct 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/gatsby-netlify-cms-tailwindcss-starter-2fko</link>
      <guid>https://dev.to/emmanuelgautier/gatsby-netlify-cms-tailwindcss-starter-2fko</guid>
      <description>&lt;p&gt;With the number of websites generated with the same tools, I tend to mutualize as much as we can the effort to maintain the common technical stack. Following this principle, I just created a new starter coming from some of my website development and powered with Gatsby.&lt;/p&gt;

&lt;p&gt;You can find this starter on this &lt;a href="https://github.com/emmanuelgautier/gatsby-starter-netlify-tailwind"&gt;Github Repository&lt;/a&gt;. This repo contains an example business website that is built with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gatsbyjs.org/"&gt;Gatsby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.netlifycms.org"&gt;Netlify CMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/"&gt;TailwindCSS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It follows the &lt;a href="https://jamstack.org"&gt;JAMstack principles&lt;/a&gt; with Git as a single source of truth for pages and blog posts, deployed and delivered thanks to the solution &lt;a href="https://www.netlify.com"&gt;Netlify&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This starter is not strongly linked with Netlify so you can choose the hosting provider you want but, since this starter is using the Netlify CMS solution, the integration is simpler with Netlify.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the main features?
&lt;/h2&gt;

&lt;p&gt;This starter brings the following set of features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pages and Blog posts content model&lt;/li&gt;
&lt;li&gt;Performance optimized with good Web Vitals scores&lt;/li&gt;
&lt;li&gt;SEO optimized&lt;/li&gt;
&lt;li&gt;Twitter Cards and Open Graph support&lt;/li&gt;
&lt;li&gt;RSS Feed&lt;/li&gt;
&lt;li&gt;Sitemap&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since this starter comes from my other websites developments, this list should bring most of the features you will need to build a website. If your think some features are missing or can be improved, feel free to contribute by making a PR or create an issue to ask about new features.&lt;/p&gt;

&lt;p&gt;To see how it looks, please go to the deployed &lt;strong&gt;&lt;a href="https://gatsby-starter-netlify-tailwind.netlify.app/"&gt;Demo Page&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>gatsby</category>
      <category>jamstack</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Enable Python type checking in VSCode</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Wed, 18 Aug 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/enable-python-type-checking-in-vscode-3j5i</link>
      <guid>https://dev.to/emmanuelgautier/enable-python-type-checking-in-vscode-3j5i</guid>
      <description>&lt;p&gt;Since version 3.5, Python now has &lt;a href="https://docs.python.org/3/library/typing.html"&gt;support for type hints&lt;/a&gt;. This typing is a cool new feature allowing type checking across your code for more quality and also help when you are using some packages or call some functions your colleague did in a large codebase. In this article, we will see how to enable type IntelliSense and type checking analysis in Visual Studio Code editor.&lt;/p&gt;

&lt;p&gt;First of all, you need to install the Microsoft extension &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance"&gt;Pylance&lt;/a&gt;. This extension provides a set of useful features powered with &lt;a href="https://github.com/microsoft/pyright"&gt;Pyright&lt;/a&gt;, the Microsoft static type checking tool.&lt;/p&gt;

&lt;p&gt;With the extension installed and enabled, you should now have better IntelliSense with typing information when you are calling some package function for example. For the type checking analysis, it is not enabled by default, you need to configure it by yourself.&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;settings.json&lt;/code&gt; file, add a new line with the following setting:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"python.analysis.typeCheckingMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"basic"&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;p&gt;The default value for this line is &lt;code&gt;off&lt;/code&gt; meaning the static analysis is disabled. You have two other possible values which are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;basic&lt;/code&gt;: basic type checking rules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;strict&lt;/code&gt;: All type checking rules at the highest error severity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you test on the code below you should have a type error in VSCode now&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Wrong type between expected return type and the value type really returned by this function
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrong_return_type&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>python</category>
      <category>vscode</category>
      <category>typing</category>
    </item>
    <item>
      <title>How to get a React element as an HTML string</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Sun, 02 May 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/how-to-get-a-react-element-as-an-html-string-oj9</link>
      <guid>https://dev.to/emmanuelgautier/how-to-get-a-react-element-as-an-html-string-oj9</guid>
      <description>&lt;p&gt;For use cases, you may want to have the generated HTML string from your React component instead of a mounted component rendered on the page.&lt;/p&gt;

&lt;p&gt;The simplest way is to use the &lt;code&gt;renderToString&lt;/code&gt; function provided by the &lt;code&gt;react-dom&lt;/code&gt; package :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderToString&lt;/span&gt; &lt;span class="p"&gt;}&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;react-dom/server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;YourAwesomeComponent&lt;/span&gt; &lt;span class="na"&gt;props1&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"value1"&lt;/span&gt; &lt;span class="na"&gt;props2&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function &lt;code&gt;renderToString&lt;/code&gt; can be used on both the server-side and client-side.&lt;/p&gt;

&lt;p&gt;If you want to render all page server-side for SEO or UX purposes for example, you can use the function &lt;code&gt;renderToNodeStream&lt;/code&gt; to improve your load time. &lt;/p&gt;

&lt;p&gt;More informations on the React &lt;a href="https://reactjs.org/docs/react-dom-server.html"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>How to manage Internationalization with NextJS SSG</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Sun, 14 Mar 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/how-to-manage-internationalization-with-nextjs-ssg-353l</link>
      <guid>https://dev.to/emmanuelgautier/how-to-manage-internationalization-with-nextjs-ssg-353l</guid>
      <description>&lt;p&gt;Statically generating a website with the NextJS framework in different languages is not so obvious. The framework does not bring clear support for this use case and the &lt;a href="https://nextjs.org/docs/advanced-features/i18n-routing#how-does-this-work-with-static-generation"&gt;NextJS documentation&lt;/a&gt; explains that i18n routing is not supported for SSG.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bootstrap the project
&lt;/h2&gt;

&lt;p&gt;First of all, let's create a new next project from the &lt;code&gt;with-react-intl&lt;/code&gt; template&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app &lt;span class="nt"&gt;-e&lt;/span&gt; with-react-intl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If don't need anymore to manage any localization client side, you can remove the &lt;code&gt;getInitialProps&lt;/code&gt; function and the part for localization in the &lt;code&gt;render&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The SSR server is useless if you only need SSG as well. So you can remove server tsconfig, &lt;code&gt;server.ts&lt;/code&gt; file and change your &lt;code&gt;package.json&lt;/code&gt; file script part as follow :&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="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;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run extract:i18n &amp;amp;&amp;amp; npm run compile:i18n &amp;amp;&amp;amp; next build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"export"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next export"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"extract:i18n"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"formatjs extract '{pages,components}/*.{js,ts,tsx}' --format simple --id-interpolation-pattern '[sha512:contenthash:base64:6]' --out-file lang/en.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"compile:i18n"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"formatjs compile-folder --ast --format simple lang compiled-lang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next start"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Static Site Generation (aka SSG) with NextJS
&lt;/h2&gt;

&lt;p&gt;When you generate your website statically, it is not possible to use browser request header or any other information from the browser to know which language to use.&lt;/p&gt;

&lt;p&gt;We need to introduce a new environment variable &lt;code&gt;NEXT_LOCALE&lt;/code&gt; which will contain the locale of the website generated during the export process.&lt;/p&gt;

&lt;p&gt;Example of content in &lt;code&gt;.env.*&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXT_LOCALE=en
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now use the &lt;code&gt;NEXT_LOCALE&lt;/code&gt; variable in your &lt;code&gt;_app.tsx&lt;/code&gt; file in the &lt;code&gt;getInitialProps&lt;/code&gt; function to define the locale.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInitialProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;appContext&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;appContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_LOCALE&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;supportedLocale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;messagePromise&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[,&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;appProps&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nx"&gt;polyfill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;supportedLocale&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;messagePromise&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getInitialProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appContext&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;appProps&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;supportedLocale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&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;Thanks to this variable and the change done, &lt;code&gt;react-intl&lt;/code&gt; will now use as locale the content from the env variable. The translated messages taken are now from the right locale.&lt;/p&gt;

&lt;p&gt;Now you have a website available for multiple languages. You can build your website for multiple domains as well dealing with multiple build processes, one for each locale. Feel free to implement it with the service you want like Netlify, Vercel, ... etc&lt;/p&gt;

&lt;p&gt;The showcase generated for two languages deployed with Vercel :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://next-showcase-ssg-en.vercel.app/"&gt;English&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://next-showcase-ssg-fr.vercel.app/"&gt;French&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to know more, have a look into the &lt;a href="https://github.com/emmanuelgautier/nextjs-showcase/tree/main/packages/ssg-i18n-routing"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>nextjs</category>
      <category>i18n</category>
    </item>
    <item>
      <title>How to render emojis with JavaScript</title>
      <dc:creator>Emmanuel Gautier</dc:creator>
      <pubDate>Sun, 28 Feb 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/emmanuelgautier/how-to-render-emojis-with-javascript-3g9b</link>
      <guid>https://dev.to/emmanuelgautier/how-to-render-emojis-with-javascript-3g9b</guid>
      <description>&lt;p&gt;For the content of your posts, emojis add some fun to your pages. This short post explains how to make that possible in JavaScript.&lt;/p&gt;

&lt;p&gt;The most conveniant is to use directly the right emoji Unicode. Here a JSX example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;u{1F680}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use the &lt;a href="https://www.npmjs.com/package/node-emoji"&gt;node-emoji package&lt;/a&gt; to help you manipulate them.&lt;/p&gt;

&lt;p&gt;If you want to know what unicode emoji to add, you can find this page useful : &lt;a href="https://unicode.org/emoji/charts/full-emoji-list.html"&gt;Full Emoji List&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
  </channel>
</rss>
