<?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>Forem: Sebastián Duque G</title>
    <description>The latest articles on Forem by Sebastián Duque G (@sebastiandg7).</description>
    <link>https://forem.com/sebastiandg7</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%2F85249%2F7bc10211-36a8-4eae-ab48-2a6543945b86.jpeg</url>
      <title>Forem: Sebastián Duque G</title>
      <link>https://forem.com/sebastiandg7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sebastiandg7"/>
    <language>en</language>
    <item>
      <title>Nx + NextJS + Docker: Containerizing our application</title>
      <dc:creator>Sebastián Duque G</dc:creator>
      <pubDate>Wed, 28 Jun 2023 19:36:46 +0000</pubDate>
      <link>https://forem.com/sebastiandg7/nx-nextjs-docker-the-nx-way-containerizing-our-application-1mi7</link>
      <guid>https://forem.com/sebastiandg7/nx-nextjs-docker-the-nx-way-containerizing-our-application-1mi7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the previous blog post, we learned how to create a Next.js application using Nx and set up our development environment. Now, it's time to take our application to the next level by containerizing it with Docker. Containerization allows us to package our application along with its dependencies, ensuring consistent and portable deployments. In this follow-up blog post, we will explore the process of containerizing our Nx + Next.js application and deploying it using Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Step 1: Preparing the Next.js Application&lt;/li&gt;
&lt;li&gt;
Step 2: Adding a &lt;code&gt;container&lt;/code&gt; target to the project

&lt;ul&gt;
&lt;li&gt;Understanding our &lt;code&gt;container&lt;/code&gt; target config&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Step 2: Creating a Dockerfile&lt;/li&gt;

&lt;li&gt;Step 3: Building the Docker Image&lt;/li&gt;

&lt;li&gt;Step 4: Running the Docker Container&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before proceeding, make sure you have the following prerequisites in place:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Completed the previous post steps.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/sebastiandg7" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F85249%2F7bc10211-36a8-4eae-ab48-2a6543945b86.jpeg" alt="sebastiandg7"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/sebastiandg7/nx-nextjs-docker-the-nx-way-creating-the-nextjs-application-1efl" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Nx + NextJS + Docker: Creating the NextJS application&lt;/h2&gt;
      &lt;h3&gt;Sebastián Duque G ・ Jun 28 '23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#nextjs&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#nx&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#docker&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic understanding of Docker and containerization concepts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docker installed on your machine.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: Preparing the Next.js Application
&lt;/h2&gt;

&lt;p&gt;Let's prepare our Next.js application for containerization.&lt;/p&gt;

&lt;p&gt;Good news! There is not much to do here. The &lt;code&gt;@nx/next&lt;/code&gt; plugin already takes care of most of the work for us. When we build our application using:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx build my-app


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

&lt;/div&gt;
&lt;p&gt;You will notice in the &lt;code&gt;dist/apps/my-app&lt;/code&gt; directory that a &lt;code&gt;package.json&lt;/code&gt; file was created. This file will represent a subset of the workspace &lt;code&gt;package.json&lt;/code&gt; containing only and just only the packages needed by our app (and it's workspace dependencies).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dist/apps/my-app/package.json&lt;/code&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my-app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&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;"next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"13.4.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"18.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-dom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"18.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"typescript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5.1.5"&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;"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;"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="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;This generated &lt;code&gt;package.json&lt;/code&gt; will help us to only install the minimum required dependencies needed by the application in our container.&lt;/p&gt;

&lt;p&gt;If you are not using static dependency versions in your root &lt;code&gt;package.json&lt;/code&gt; you may want to also generate a lock file to ensure dependency versions in production match with your development environment. To achieve this add the following option to your application &lt;code&gt;build&lt;/code&gt; target:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;{
    ...
    "build": {
      "executor": "@nx/next:build",
      "outputs": ["{options.outputPath}"],
      "defaultConfiguration": "production",
      "options": {
        "outputPath": "dist/apps/my-app"
      },
      "configurations": {
        "development": {
          "outputPath": "apps/my-app"
        },
        "production": {
&lt;span class="gi"&gt;+         "generateLockfile": true
&lt;/span&gt;        }
      },
      "dependsOn": ["build-custom-server"]
    },
    ...
}
&lt;span class="err"&gt;

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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 2: Adding a &lt;code&gt;container&lt;/code&gt; target to the project
&lt;/h2&gt;

&lt;p&gt;We want to run the container build process the same way as we lint, build and test our app: with a project target. To achieve this, we will make use the awesome &lt;code&gt;@nx-tools/nx-container&lt;/code&gt; Nx plugin.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@nx-tools/nx-container&lt;/code&gt; Nx plugin provides first class support for Container builds in your Nx workspace. It supports Docker, Podman and Kaniko engines. Leave a star in its &lt;a href="https://github.com/gperdomor/nx-tools" rel="noopener noreferrer"&gt;repo&lt;/a&gt; and take a look there for advanced configuration.&lt;/p&gt;

&lt;p&gt;Start by installing the plugin, run:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm add &lt;span class="nt"&gt;-D&lt;/span&gt; @nx-tools/nx-container


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

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; You can optionally follow &lt;a href="https://github.com/gperdomor/nx-tools/blob/main/packages/nx-container/README.md#setting-up-the-container-plugin" rel="noopener noreferrer"&gt;the docs&lt;/a&gt; about using the &lt;code&gt;@nx-tools/container-metadata&lt;/code&gt; package to enable automatic image tagging with &lt;a href="https://github.com/opencontainers/image-spec/blob/main/annotations.md" rel="noopener noreferrer"&gt;OCI Image Format Specification&lt;/a&gt; labels.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, let's setup our project to be containerized:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx g @nx-tools/nx-container:init my-app &lt;span class="nt"&gt;--template&lt;/span&gt; next &lt;span class="nt"&gt;--engine&lt;/span&gt; docker


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

&lt;/div&gt;
&lt;p&gt;You will see a new &lt;code&gt;container&lt;/code&gt; target added to the application's &lt;code&gt;project.json&lt;/code&gt;. Let's configure the target as shown below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apps/my-app/project.json&lt;/code&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"targets"&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"container"&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;"executor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@nx-tools/nx-container: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;"dependsOn"&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="s2"&gt;"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;"defaultConfiguration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"options"&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;"engine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docker"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/apps/my-app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apps/my-app/Dockerfile"&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;"configurations"&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;"local"&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;"tags"&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="s2"&gt;"my-app:latest"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"push"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;"production"&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;"tags"&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="s2"&gt;"my.image-registry.com/my-app:latest"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"push"&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;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="err"&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 replace the &lt;code&gt;production&lt;/code&gt; configuration with what better suits your needs. You are also free to add all the necessary configurations.&lt;/p&gt;
&lt;h3&gt;
  
  
  Understanding our &lt;code&gt;container&lt;/code&gt; target config
&lt;/h3&gt;

&lt;p&gt;We have configured the &lt;code&gt;container&lt;/code&gt; target to make use of Docker as the container engine with some additional options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;context&lt;/code&gt;: we are telling docker to use our app's output directory as the context passed to the image build process. This way we don't waste memory passing the whole monorepo when we only need some specific files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;push&lt;/code&gt;: For the &lt;code&gt;local&lt;/code&gt; configuration this option is turned off as we don't want to push the built image to the registry by default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;file&lt;/code&gt;: Here we specify where to find the &lt;code&gt;Dockerfile&lt;/code&gt; used for the container image build, this path is relative to the workspace root.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 2: Creating a Dockerfile
&lt;/h2&gt;

&lt;p&gt;A Dockerfile is a text file that contains instructions for building a Docker image. In this step, we will create a Dockerfile for our Next.js application. We'll define the base image, copy the application code, and specify the required dependencies.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Install dependencies only when needed&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;docker.io/node:lts-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;dependencies&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; libc6-compat
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; .npmrc package.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production

&lt;span class="c"&gt;# Production image, copy all the files and run next&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;docker.io/node:lts-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;runner&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; dumb-init

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_ENV production&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PORT 3000&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; HOST 0.0.0.0&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NEXT_TELEMETRY_DISABLED 1&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="c"&gt;# Copy installed dependencies from dependencies stage&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=dependencies /usr/src/app/node_modules ./node_modules&lt;/span&gt;

&lt;span class="c"&gt;# Copy built application files&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./ ./&lt;/span&gt;

&lt;span class="c"&gt;# Run the application under "node" user by default&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; node:node .
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; node&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="c"&gt;# If you are using the custom server implementation:&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["dumb-init", "node", "server/main.js"]&lt;/span&gt;

&lt;span class="c"&gt;# If you are using the NextJS built-int server:&lt;/span&gt;
&lt;span class="c"&gt;# CMD ["dumb-init", "npm", "start"]&lt;/span&gt;


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

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; If you are also using &lt;code&gt;pnpm&lt;/code&gt; and enabled the &lt;code&gt;generateLockfile&lt;/code&gt; option for &lt;code&gt;build&lt;/code&gt; target, you may want to first install pnpm in the dependencies stage to make use of the generated &lt;code&gt;pnpm-lock.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;You will also need to copy the &lt;code&gt;pnpm-lock.yaml&lt;/code&gt; before running the installation command:&lt;/p&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gi"&gt;+ RUN npm install -g pnpm
&lt;/span&gt;&lt;span class="gd"&gt;- COPY .npmrc package.json ./
&lt;/span&gt;&lt;span class="gi"&gt;+ COPY .npmrc package.json pnpm-lock.yaml ./
&lt;/span&gt;&lt;span class="gd"&gt;- RUN npm install --only=production
&lt;/span&gt;&lt;span class="gi"&gt;+ RUN pnpm install --frozen-lockfile --prod
&lt;/span&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;To improve the efficiency of our Docker builds and reduce the image size, we are leveraging the concept of multi-stage builds. Using a multi-stage build allow us to separate the dependencies installation environment from the runtime environment. This way, as an example, we can remove sensitive data like private registries authentication tokens from our app runtime container.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Building the Docker Image
&lt;/h2&gt;

&lt;p&gt;With the Dockerfile in place and our &lt;code&gt;container&lt;/code&gt; target configured, we'll proceed to build the Docker image. We'll use the &lt;code&gt;container&lt;/code&gt; target to execute the build process, which involves pulling the base image, installing dependencies, and creating the final image.&lt;/p&gt;

&lt;p&gt;To build our image, run:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx container my-app


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

&lt;/div&gt;
&lt;p&gt;This will first build our application and it's dependencies prior to run the docker container build. To visualize this tasks dependencies you can run:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx container my-app &lt;span class="nt"&gt;--graph&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;You will find the following task dependency structure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2beompojkigizs3b1yt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2beompojkigizs3b1yt.png" alt="Task dependency graph of the container target for the my-app project"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Running the Docker Container
&lt;/h2&gt;

&lt;p&gt;Once the Docker image is built, we'll run it as a container to verify that our application is working correctly within the containerized environment.&lt;/p&gt;

&lt;p&gt;To start our container, run:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 &lt;span class="nt"&gt;-t&lt;/span&gt; my-app:latest


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

&lt;/div&gt;
&lt;p&gt;You will get and output like:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

➜ docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 &lt;span class="nt"&gt;-t&lt;/span&gt; my-app:latest
shared-util-nextjs-server
&lt;span class="o"&gt;[&lt;/span&gt; ready &lt;span class="o"&gt;]&lt;/span&gt; on http://0.0.0.0:3000


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

&lt;/div&gt;
&lt;p&gt;You can now visit &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; to access your NextJS application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1n50nfn0bx0qy1abks0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1n50nfn0bx0qy1abks0.png" alt="nextjs application running inside a docker container"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can even send an HTTP request to your exposed API endpoints:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

➜ curl http://localhost:3000/api/hello
Hello, from API!


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

&lt;/div&gt;
&lt;p&gt;Great! 🎉&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Containerization provides numerous benefits, including improved portability, scalability, and reproducibility of our applications. In this follow-up blog post, we've learned how to containerize our Nx + Next.js application using Docker. By leveraging Docker, we can simplify the deployment process and ensure consistent behavior across different environments. &lt;/p&gt;

&lt;p&gt;Stay tuned for more exciting topics as we continue our journey with Nx, Next.js, and Docker!&lt;/p&gt;

&lt;p&gt;You can find all related code in the following Github repo:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sebastiandg7" rel="noopener noreferrer"&gt;
        sebastiandg7
      &lt;/a&gt; / &lt;a href="https://github.com/sebastiandg7/nx-nextjs-docker" rel="noopener noreferrer"&gt;
        nx-nextjs-docker
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      An Nx workspace containing a NextJS app ready to be deployed as a Docker container.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Nx + Next.js + Docker&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;This repository contains the code implementation of the steps described in the blog posts titled:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/sebastiandg7/nx-nextjs-docker-the-nx-way-creating-the-nextjs-application-1efl" rel="nofollow"&gt;Nx + NextJS + Docker - The Nx way: Creating the NextJS application&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/sebastiandg7/nx-nextjs-docker-the-nx-way-containerizing-our-application-1mi7" rel="nofollow"&gt;Nx + NextJS + Docker - The Nx way: Containerizing our application&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;The blog post provides a detailed guide on setting up a Next.js application using Nx and Docker, following best practices and leveraging the capabilities of the Nx workspace.&lt;/p&gt;

&lt;p&gt;The repository contains all the necessary code and configuration files to follow along with the steps outlined in the blog post.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Prerequisites&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;To successfully run the Next.js application and Dockerize it, ensure that you have the following dependencies installed on your system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker (version 23)&lt;/li&gt;
&lt;li&gt;Node.js (version 18)&lt;/li&gt;
&lt;li&gt;pnpm (version 8)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can alternatively use &lt;a href="https://volta.sh/" rel="nofollow noopener noreferrer"&gt;Volta&lt;/a&gt; to setup the right tooling for this project.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;To get started, follow the steps below:&lt;/p&gt;


&lt;ol&gt;

&lt;li&gt;

&lt;p&gt;Clone the…&lt;/p&gt;


&lt;/li&gt;

&lt;/ol&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sebastiandg7/nx-nextjs-docker" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
    </item>
    <item>
      <title>Nx + NextJS + Docker: Creating the NextJS application</title>
      <dc:creator>Sebastián Duque G</dc:creator>
      <pubDate>Wed, 28 Jun 2023 04:58:28 +0000</pubDate>
      <link>https://forem.com/sebastiandg7/nx-nextjs-docker-the-nx-way-creating-the-nextjs-application-1efl</link>
      <guid>https://forem.com/sebastiandg7/nx-nextjs-docker-the-nx-way-creating-the-nextjs-application-1efl</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome to this blog post, where we will guide you through the process of creating a NextJS application using Nx and Docker. In this tutorial, we will cover the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating a monorepo workspace using modern tooling.&lt;/li&gt;
&lt;li&gt;Adding a NextJS application with a custom server implementation to the workspace.&lt;/li&gt;
&lt;li&gt;Building and shipping the app in an optimized Docker container with minimal dependencies.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Warning:&lt;/strong&gt; If you prefer not to use a custom server implementation for your NextJS project, you can skip the steps related to the server. We will provide alternate configurations for the built-in NextJS server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prerequisites&lt;/li&gt;
&lt;li&gt;Step 1: Set up your environment&lt;/li&gt;
&lt;li&gt;
Step 2: Create your Nx workspace

&lt;ul&gt;
&lt;li&gt;Install the required Nx plugins&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Step 3: Generating our Next.js application&lt;/li&gt;

&lt;li&gt;Step 4: Adding some workspace libraries&lt;/li&gt;

&lt;li&gt;Step 5: Fixing our &lt;code&gt;build-custom-server&lt;/code&gt; target&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To complete this tutorial, we will be using the following tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JS Tool Manager: &lt;a href="https://volta.sh/" rel="noopener noreferrer"&gt;Volta&lt;/a&gt; v1.1.1&lt;/li&gt;
&lt;li&gt;JS Runtime: &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node&lt;/a&gt; v18&lt;/li&gt;
&lt;li&gt;Package manager: &lt;a href="https://pnpm.io/" rel="noopener noreferrer"&gt;pnpm&lt;/a&gt; v8&lt;/li&gt;
&lt;li&gt;Monorepo build system: &lt;a href="https://nx.dev" rel="noopener noreferrer"&gt;Nx&lt;/a&gt; v16.4.0&lt;/li&gt;
&lt;li&gt;App framework: &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;NextJS&lt;/a&gt; v13&lt;/li&gt;
&lt;li&gt;Container engine: &lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; v23.0.4 | &lt;a href="https://github.com/docker/buildx" rel="noopener noreferrer"&gt;Buildx&lt;/a&gt; v0.10.4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You will need to have Docker installed. We will guide you installing the remaining tools.&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Set up your environment
&lt;/h2&gt;

&lt;p&gt;First, let's install Volta by following the instructions &lt;a href="https://docs.volta.sh/guide/getting-started" rel="noopener noreferrer"&gt;here&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

curl https://get.volta.sh | bash


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

&lt;/div&gt;
&lt;p&gt;Once Volta is installed, enable Volta's PNPM feature:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"export VOLTA_FEATURE_PNPM=1 &amp;gt;&amp;gt; ~/.zshrc"&lt;/span&gt;


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

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; If you're not using zsh as your shell, update the respective shell configuration file for your system.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, let's install Node v18:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

volta &lt;span class="nb"&gt;install &lt;/span&gt;node@18
node &lt;span class="nt"&gt;-v&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;Now, install pnpm:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

volta &lt;span class="nb"&gt;install &lt;/span&gt;pnpm@8
pnpm &lt;span class="nt"&gt;-v&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 2: Create your Nx workspace
&lt;/h2&gt;

&lt;p&gt;With our tooling set up, it's time to create our Nx workspace. Run the following command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm dlx create-nx-workspace@16.4.0 myorg &lt;span class="nt"&gt;--pm&lt;/span&gt; pnpm &lt;span class="nt"&gt;--nxCloud&lt;/span&gt; &lt;span class="nt"&gt;--preset&lt;/span&gt; empty


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

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;You can opt out of using &lt;a href="https://nx.dev/nx-cloud/intro/what-is-nx-cloud" rel="noopener noreferrer"&gt;Nx Cloud&lt;/a&gt; by passing --nxCloud false, but we recommend giving it a shot!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Navigate into the workspace directory and pin the Node and pnpm versions we're using for this project:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;cd &lt;/span&gt;myorg
volta pin node@18
volta pin pnpm@8


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

&lt;/div&gt;
&lt;p&gt;Make sure your package.json file reflects the pinned versions:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"volta"&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;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"18.16.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pnpm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8.6.5"&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;h3&gt;
  
  
  Install the required Nx plugins
&lt;/h3&gt;

&lt;p&gt;We'll be using Nx in an &lt;a href="https://nx.dev/tutorials/integrated-repo-tutorial" rel="noopener noreferrer"&gt;Integrated Monorepo&lt;/a&gt; setup, which relies on Nx plugins to handle most of the heavy lifting. Let's install the NextJs and ESBuild plugins:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm add &lt;span class="nt"&gt;-D&lt;/span&gt; @nx/next@16.4.0 @nx/esbuild@16.4.0


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 3: Generating our Next.js application
&lt;/h2&gt;

&lt;p&gt;Now that we have the &lt;code&gt;@nx/next&lt;/code&gt; plugin installed we can run generators to scaffold NextJS code in our workspace.&lt;/p&gt;

&lt;p&gt;In your terminal, run the following command to generate the NextJS application:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx g @nx/next:app my-app &lt;span class="nt"&gt;--customServer&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; css &lt;span class="nt"&gt;--appDir&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;Replace my-app with the desired name for your application.&lt;/p&gt;

&lt;p&gt;This command will generate a new directory named my-app inside the apps folder of your Nx workspace, containing the initial NextJS application structure.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; to know more about the included generators, run &lt;code&gt;pnpm nx list @nx/next&lt;/code&gt; in your terminal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You will notice in the &lt;code&gt;apps/my-app/next.config.js&lt;/code&gt; the usage of the &lt;code&gt;withNx&lt;/code&gt; next plugin from &lt;code&gt;@nx/next&lt;/code&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;//@ts-check&lt;/span&gt;

&lt;span class="c1"&gt;// eslint-disable-next-line @typescript-eslint/no-var-requires&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;composePlugins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;withNx&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&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;@nx/next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @type {import('@nx/next/plugins/with-nx').WithNxOptions}
 **/&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;nx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Set this to true if you would like to use SVGR&lt;/span&gt;
    &lt;span class="c1"&gt;// See: https://github.com/gregberge/svgr&lt;/span&gt;
    &lt;span class="na"&gt;svgr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="c1"&gt;// Add more Next.js plugins to this list if needed.&lt;/span&gt;
  &lt;span class="nx"&gt;withNx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;composePlugins&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;nextConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;This plugin, among other things, is in charge of automatically passing the workspace libs your app is using to the NextJS &lt;a href="https://nextjs.org/docs/app/api-reference/next-config-js/transpilePackages" rel="noopener noreferrer"&gt;transpilePackages&lt;/a&gt; config so you don't have to manually do it. Read more about it &lt;a href="https://nx.dev/packages/next/documents/next-config-setup" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As of the moment of writing this post, @nx/next v16.4.0 generates a custom server build target that fails if you try to serve your application:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

➜ pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx serve my-app

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; nx run my-app:serve:development

/.../nx-nextjs-docker/node_modules/.pnpm/@nx+js@16.4.0_nx@16.4.0_typescript@5.1.5/node_modules/@nx/js/src/executors/node/node.impl.js:235
                throw new Error&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;Could not find &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;fileToRun&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; Make sure your build succeeded.&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                      ^
Error: Could not find /.../nx-nextjs-docker/dist/apps/my-app/main.js. Make sure your build succeeded.


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

&lt;/div&gt;
&lt;p&gt;we will fix this later 🙂.&lt;/p&gt;

&lt;p&gt;In the meanwhile you can build and run your NextJS app this way:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx build my-app
&lt;span class="nb"&gt;cd&lt;/span&gt; ./dist/apps/my-app
&lt;span class="c"&gt;# If using a custom server&lt;/span&gt;
node server/main.js
&lt;span class="c"&gt;# If not using a custom server&lt;/span&gt;
npm start


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 4: Adding some workspace libraries
&lt;/h2&gt;

&lt;p&gt;Let's create a feature library for our application&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx g @nx/next:lib feature-main &lt;span class="nt"&gt;--directory&lt;/span&gt; my-app &lt;span class="nt"&gt;--buildable&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;Next, let's use this library in our root page:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apps/my-app/app/page.tsx&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gi"&gt;+import { MyAppFeatureMain } from '@myorg/my-app/feature-main';
&lt;/span&gt;&lt;span class="p"&gt;import styles from './page.module.css';
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;export default async function Index() {
&lt;/span&gt;  /*
   * Replace the elements below with your own.
   *
   * Note: The corresponding styles are in the ./index.css file.
   */
  return (
    &amp;lt;div className={styles.page}&amp;gt;
      &amp;lt;div className="wrapper"&amp;gt;
        &amp;lt;div className="container"&amp;gt;
&lt;span class="gi"&gt;+         &amp;lt;MyAppFeatureMain /&amp;gt;
&lt;/span&gt;          &amp;lt;div id="welcome"&amp;gt;
            &amp;lt;h1&amp;gt;
              &amp;lt;span&amp;gt; Hello there, &amp;lt;/span&amp;gt;
              Welcome my-app 👋
            &amp;lt;/h1&amp;gt;
          &amp;lt;/div&amp;gt;
&lt;span class="err"&gt;

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

&lt;/div&gt;
&lt;p&gt;Now, let's add a utility library with an example function that will be used by our custom server implementation:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx g @nx/js:lib util-nextjs-server &lt;span class="nt"&gt;--directory&lt;/span&gt; shared


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

&lt;/div&gt;
&lt;p&gt;Next, let's use this utility library in the &lt;code&gt;server/main.ts&lt;/code&gt; file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apps/my-app/server/main.ts&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="p"&gt;import { createServer } from 'http';
import { parse } from 'url';
import * as path from 'path';
import next from 'next';
&lt;/span&gt;&lt;span class="gi"&gt;+import { sharedUtilNextjsServer } from '@myorg/shared/util-nextjs-server';
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;// .... 
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;async function main() {
&lt;/span&gt;&lt;span class="gi"&gt;+ console.log(sharedUtilNextjsServer());
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  const nextApp = next({ dev, dir });
  const handle = nextApp.getRequestHandler();
  // ....
&lt;span class="err"&gt;

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

&lt;/div&gt;
&lt;p&gt;At this point, if you run the Nx graph:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx graph


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

&lt;/div&gt;
&lt;p&gt;your workspace should look something similar to this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3k6fxp4739hblpevxp50.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3k6fxp4739hblpevxp50.png" alt="Nx dependency graph displaying the workspace projects and how they depend on each other"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! 🎉&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 5: Fixing our &lt;code&gt;build-custom-server&lt;/code&gt; target
&lt;/h2&gt;

&lt;p&gt;Now it's time to fix all the build errors we are having with our custom server build. If you are not using a custom server, everything should be working at this point.&lt;/p&gt;

&lt;p&gt;To fix our &lt;code&gt;build-custom-server&lt;/code&gt; target we will configure this target using the &lt;code&gt;@nx/esbuild&lt;/code&gt; nx plugin, similar to what &lt;code&gt;@nx/node&lt;/code&gt; generated apps do for their &lt;code&gt;build&lt;/code&gt; target. Read more about it &lt;a href="https://nx.dev/packages/node" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the previous steps, we installed the &lt;code&gt;@nx/esbuild&lt;/code&gt; plugin in our workspace. Let's now call its &lt;code&gt;init&lt;/code&gt; generator to install all the required dependencies this plugin needs:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx g @nx/esbuild:init


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

&lt;/div&gt;
&lt;p&gt;Next, let's update our NextJS app's project.json and configure the build-custom-server target as shown below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apps/my-app/project.json&lt;/code&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"targets"&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build-custom-server"&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;"executor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@nx/esbuild:esbuild"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"defaultConfiguration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"production"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"options"&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;"outputPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dist/apps/my-app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apps/my-app/server/main.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"tsConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apps/my-app/tsconfig.server.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;"clean"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"assets"&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;"platform"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"outputFileName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"server/main.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"format"&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="s2"&gt;"cjs"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"bundle"&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="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"thirdParty"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"esbuildOptions"&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;"sourcemap"&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="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"outExtension"&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;".js"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".js"&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;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"configurations"&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;"development"&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;"sourcemap"&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="nl"&gt;"production"&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;"sourcemap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"assets"&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="s2"&gt;".npmrc"&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="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="err"&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="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;This new build configuration for our custom server will bundle all the imported libraries into a single file, which is perfect for deploying our application without needing the rest of our monorepo dependencies (and results in smaller containers 👀).&lt;/p&gt;

&lt;p&gt;If you encounter the following error while building the &lt;code&gt;my-app&lt;/code&gt; project:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

error TS5069: Option &lt;span class="s1"&gt;'tsBuildInfoFile'&lt;/span&gt; cannot be specified without specifying option &lt;span class="s1"&gt;'incremental'&lt;/span&gt; or option &lt;span class="s1"&gt;'composite'&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;remove the &lt;code&gt;"tsBuildInfoFile"&lt;/code&gt; line from the &lt;code&gt;tsconfig.server.json&lt;/code&gt; file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apps/my-app/tsconfig.server.json&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "commonjs",
    "noEmit": false,
    "incremental": true,
&lt;span class="gd"&gt;-   "tsBuildInfoFile": "../../tmp/buildcache/apps/my-app/server",
&lt;/span&gt;    "types": ["node"]
  },
  "include": ["server/**/*.ts"]
}
&lt;span class="err"&gt;

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

&lt;/div&gt;
&lt;p&gt;Now that our &lt;code&gt;build-custom-server&lt;/code&gt; target is working, let's tell Nx to first build the project dependencies before building the custom server. Add the following to your &lt;code&gt;nx.json&lt;/code&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"targetDefaults"&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build-custom-server"&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;"dependsOn"&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="s2"&gt;"^build"&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="err"&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="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;To locally serve your application, run:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pnpm &lt;span class="nb"&gt;exec &lt;/span&gt;nx serve my-app


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

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

&lt;p&gt;Your NextJS app is now ready to work with a custom server and use workspace libraries in the &lt;code&gt;server.ts&lt;/code&gt; or in any other place of your application 🥳&lt;/p&gt;

&lt;p&gt;In the next post of this series, we will address building our application for production and packing it into a container in the most efficient way possible. You can find it here:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/sebastiandg7" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F85249%2F7bc10211-36a8-4eae-ab48-2a6543945b86.jpeg" alt="sebastiandg7"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/sebastiandg7/nx-nextjs-docker-the-nx-way-containerizing-our-application-1mi7" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Nx + NextJS + Docker: Containerizing our application&lt;/h2&gt;
      &lt;h3&gt;Sebastián Duque G ・ Jun 28 '23&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;You can find all related code in the following Github repo:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sebastiandg7" rel="noopener noreferrer"&gt;
        sebastiandg7
      &lt;/a&gt; / &lt;a href="https://github.com/sebastiandg7/nx-nextjs-docker" rel="noopener noreferrer"&gt;
        nx-nextjs-docker
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      An Nx workspace containing a NextJS app ready to be deployed as a Docker container.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Nx + Next.js + Docker&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;This repository contains the code implementation of the steps described in the blog posts titled:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/sebastiandg7/nx-nextjs-docker-the-nx-way-creating-the-nextjs-application-1efl" rel="nofollow"&gt;Nx + NextJS + Docker - The Nx way: Creating the NextJS application&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/sebastiandg7/nx-nextjs-docker-the-nx-way-containerizing-our-application-1mi7" rel="nofollow"&gt;Nx + NextJS + Docker - The Nx way: Containerizing our application&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The blog post provides a detailed guide on setting up a Next.js application using Nx and Docker, following best practices and leveraging the capabilities of the Nx workspace.&lt;/p&gt;
&lt;p&gt;The repository contains all the necessary code and configuration files to follow along with the steps outlined in the blog post.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Prerequisites&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;To successfully run the Next.js application and Dockerize it, ensure that you have the following dependencies installed on your system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker (version 23)&lt;/li&gt;
&lt;li&gt;Node.js (version 18)&lt;/li&gt;
&lt;li&gt;pnpm (version 8)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can alternatively use &lt;a href="https://volta.sh/" rel="nofollow noopener noreferrer"&gt;Volta&lt;/a&gt; to setup the right tooling for this project.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;To get started, follow the steps below:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Clone the…&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sebastiandg7/nx-nextjs-docker" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>nextjs</category>
      <category>nx</category>
      <category>docker</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Modern Shopify Themes Development with Nx-Shopify</title>
      <dc:creator>Sebastián Duque G</dc:creator>
      <pubDate>Fri, 14 May 2021 14:03:18 +0000</pubDate>
      <link>https://forem.com/trafilea/modern-shopify-themes-development-with-nx-shopify-31ho</link>
      <guid>https://forem.com/trafilea/modern-shopify-themes-development-with-nx-shopify-31ho</guid>
      <description>&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;Nx-Shopify is an &lt;a href="https://nx.dev" rel="noopener noreferrer"&gt;Nx&lt;/a&gt; plugin for developing Shopify themes with performance, modern tooling, and ergonomics in mind.&lt;/p&gt;

&lt;p&gt;Check the Getting Started guide and the full docs at the &lt;a href="https://trafilea.github.io/nx-shopify/" rel="noopener noreferrer"&gt;Nx-Shopify&lt;/a&gt; official website.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/trafilea" rel="noopener noreferrer"&gt;
        trafilea
      &lt;/a&gt; / &lt;a href="https://github.com/trafilea/nx-shopify" rel="noopener noreferrer"&gt;
        nx-shopify
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Nx plugin for developing performance-first Shopify themes 🚀
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-logo.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnrwl%2Fnx%2Fmaster%2Fimages%2Fnx-logo.png" width="80" height="50"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;
  Nx-Shopify
&lt;/h1&gt;
&lt;/div&gt;

&lt;div&gt;
&lt;p&gt;&lt;a href="https://github.com/trafilea/nx-shopify/actions/workflows/e2e.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/trafilea/nx-shopify/actions/workflows/e2e.yml/badge.svg" alt="e2e"&gt;&lt;/a&gt;
&lt;a href="http://commitizen.github.io/cz-cli/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1d01d79de532fa2a8b9d3e1c29e2b5d6f700b6d36f108c8416faca472cb35b6f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f6d6d6974697a656e2d667269656e646c792d627269676874677265656e2e737667" alt="Commitizen friendly"&gt;&lt;/a&gt;
&lt;a href="https://github.com/trafilea/nx-shopify/blob/master/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/34e973688eaffdcf48165a50d4b46612cc9bd464837f81d9e0e9989fd76f3966/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f74726166696c65612f6e782d73686f70696679" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/@trafilea/nx-shopify" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d2aff0ee53b9ebee998ca8d225799f6d58d1e7a7f22cd8f03514316d13d7be24/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f4074726166696c65612f6e782d73686f70696679" alt="npm (scoped)"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/@trafilea/nx-shopify" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/92065019b6a335ae28ee762c0882121285c5dd8987d2df6d04d776b5cb9ef61a/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f64742f4074726166696c65612f6e782d73686f70696679" alt="npm"&gt;&lt;/a&gt;
&lt;a href="https://github.com/semantic-release/semantic-release" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/251b82ec02847188c7f2f024d0a6752bb8e0422772baaace42e7a7dc3fd8c88a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2532302532302546302539462539332541362546302539462539412538302d73656d616e7469632d2d72656c656173652d6531303037392e737667" alt="semantic-release"&gt;&lt;/a&gt;
&lt;a href="https://github.com/prettier/prettier" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/97be20604d833ecbf2b0a9d3d17e3f0e29ae6de33b102c744849d0bf17f399e4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64655f7374796c652d70726574746965722d6666363962342e7376673f7374796c653d666c61742d737175617265" alt="code style: prettier"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/trafilea/nx-shopify#contributors-" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ebc019cd16befd901bfe054d09a21add163b3a820cdce210165560483fcc03f4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f616c6c5f636f6e7472696275746f72732d372d6f72616e67652e7376673f7374796c653d666c61742d737175617265" alt="All Contributors"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;🔎 &lt;strong&gt;An &lt;a href="https://nx.dev" rel="nofollow noopener noreferrer"&gt;Nx&lt;/a&gt; plugin for developing performance-first Shopify themes 🚀&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Be it you need to build a custom Shopify store theme, develop a generic theme or even maintain multiple stores/themes with shared code across them, this Nx plugin helps you power-up your development experience&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Install the Nx CLI globally&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;# npm
$ npm install --global nx

# yarn
$ yarn add --global nx

# pnpm
$ pnpm install --global nx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create an empty Nx workspace (or use an existing one)&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ npx create-nx-workspace my-org --preset=empty
$ cd ./my-org
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Install the Nx-Shopify plugin as a devDependency&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;# npm
$ npm install --save-dev @trafilea/nx-shopify

# yarn
$ yarn add --save-dev @trafilea/nx-shopify

# pnpm
$ pnpm install --save-dev @trafilea/nx-shopify
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Generate a Shopify theme using the Nx CLI&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ nx generate @trafilea/nx-shopify:theme my-theme
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Check the generators and executors provided by the plugin&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ nx list @trafilea/nx-shopify
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Documentation&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;🤓 Read the full…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/trafilea/nx-shopify" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h1&gt;
  
  
  A little history: Shopify Slate &amp;amp; Themekit
&lt;/h1&gt;

&lt;p&gt;Before being &lt;a href="https://github.com/Shopify/slate/pull/1091" rel="noopener noreferrer"&gt;deprecated in January 2020&lt;/a&gt;, Shopify's official toolkit for developing Shopify themes was &lt;a href="https://github.com/Shopify/slate" rel="noopener noreferrer"&gt;Slate&lt;/a&gt;. Slate provided a theme development environment that enabled the developer to have a better project structure than the regular directories found in a Shopify theme. With the deprecation of Slate, the only official tool for theme development left is &lt;a href="https://shopify.dev/tools/theme-kit" rel="noopener noreferrer"&gt;Themekit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Themekit acts like a bridge between the developer's local files and the files found in a Shopify store's theme. The folder structure of a Themekit theme is meant more for the theme rendering process than for code maintainability or multiple developers constantly working on the same code base. Additionally, a Themekit project provides little to zero build tooling for the application code. &lt;/p&gt;

&lt;p&gt;This is how a basic Themekit project looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zd9i6v38g40jnm5x1ep.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zd9i6v38g40jnm5x1ep.png" alt="Themekit Structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Given the context above, the need to have a well-defined project structure, dev ergonomics, high-quality code, and use of modern web technologies, were limited due to lack of tooling.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://trafilea.com" rel="noopener noreferrer"&gt;Trafilea&lt;/a&gt;, we heavily use Shopify themes and are constantly making changes to them according to our business needs and growth. Providing our developers a functional, stable, and feature-rich development experience is crucial, this why we built and open-sourced &lt;a href="https://github.com/trafilea/nx-shopify" rel="noopener noreferrer"&gt;Nx-Shopify&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Nx-Shopify 🚀
&lt;/h1&gt;

&lt;p&gt;Nx-Shopify is an Nx plugin that adds support for modern Shopify Themes development to an Nx workspace. It comes with various features including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript based.&lt;/li&gt;
&lt;li&gt;Styling with SASS and PostCSS.&lt;/li&gt;
&lt;li&gt;Out of the box unit testing with Jest.&lt;/li&gt;
&lt;li&gt;Out of the box code formatting using Prettier and ESLint.&lt;/li&gt;
&lt;li&gt;Multiple application and Themekit environments.&lt;/li&gt;
&lt;li&gt;Code lazy loading.&lt;/li&gt;
&lt;li&gt;Code generator for creating new themes with separate configs.&lt;/li&gt;
&lt;li&gt;Code generators for creating theme blocks such as layouts, templates, sections, and snippets.&lt;/li&gt;
&lt;li&gt;React integration via &lt;code&gt;@nrwl/react&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Webpack extended configuration.&lt;/li&gt;
&lt;li&gt;➕ all features included in an Nx workspace.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nx-Shopify makes use of Shopify Themekit under the hood, so every project built with Nx-Shopify will be compliant with the themekit project format, in case you need to run specific themekit commands in your project. &lt;strong&gt;TIP:&lt;/strong&gt; you can add custom targets for your projects using the &lt;a href="http://nx.dev/workspace/run-commands-executor" rel="noopener noreferrer"&gt;Nx run commands executor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ok, but...&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Nx?
&lt;/h2&gt;

&lt;p&gt;Nx is a set of dev tools for monorepos designed to provide a great development experience in a plug-and-play way. According to their website: "&lt;strong&gt;Nx&lt;/strong&gt; is a suite of powerful, extensible dev tools to help you architect, test, and build at any scale — integrating seamlessly with modern technologies and libraries while providing a robust CLI, caching, dependency management, and more."&lt;/p&gt;

&lt;p&gt;Watch this 35 seconds video to have a general overview of some of the things Nx does:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/BIeQTWLyAqc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;(We ❤️ Nx)&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Generators
&lt;/h2&gt;

&lt;p&gt;Most Nx plugins include code generators to facilitate developers' life so they can focus on what really matters. Nx-Shopify includes generators for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://trafilea.github.io/nx-shopify/docs/fundamentals/creating-a-theme" rel="noopener noreferrer"&gt;New themes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://trafilea.github.io/nx-shopify/docs/cli-usage/generators/layout" rel="noopener noreferrer"&gt;Layouts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://trafilea.github.io/nx-shopify/docs/cli-usage/generators/template" rel="noopener noreferrer"&gt;Templates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://trafilea.github.io/nx-shopify/docs/cli-usage/generators/section" rel="noopener noreferrer"&gt;Sections&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://trafilea.github.io/nx-shopify/docs/cli-usage/generators/snippet" rel="noopener noreferrer"&gt;Snippets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A fresh generated Shopify theme would look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnm046v355dupw99pdh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnm046v355dupw99pdh5.png" alt="Nx-Shopify Structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every theme block is organized in a component-based/cohesive design with its respective Liquid, styles, Typescript, and test files. You can also nest blocks under another block's directory if that makes sense to you. You have control of your theme project architecture. &lt;/p&gt;

&lt;h2&gt;
  
  
  CLI commands
&lt;/h2&gt;

&lt;p&gt;The CLI commands that can be executed against a theme are known in Nx as executors. The list of executors included with Nx-Shopify are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://trafilea.github.io/nx-shopify/docs/cli-usage/executors/build" rel="noopener noreferrer"&gt;build&lt;/a&gt; - Builds the theme to a Themekit compliant structure ready to be deployed to Shopify&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://trafilea.github.io/nx-shopify/docs/cli-usage/executors/serve" rel="noopener noreferrer"&gt;serve&lt;/a&gt; - Runs a local web &amp;amp; assets server for local theme development&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://trafilea.github.io/nx-shopify/docs/cli-usage/executors/test" rel="noopener noreferrer"&gt;test&lt;/a&gt; - Runs Jest tests against the theme code.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://trafilea.github.io/nx-shopify/docs/cli-usage/executors/deploy" rel="noopener noreferrer"&gt;deploy&lt;/a&gt; - Deploys a built theme to Shopify according to the Themekit environment configured in the &lt;code&gt;config.yml&lt;/code&gt; file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You get a list of all plugin's generators and executors by running the following command in your workspace:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nx list @trafilea/nx-shopify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  React integration via &lt;code&gt;@nrwl/react&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Do not miss the &lt;a href="https://trafilea.github.io/nx-shopify/docs/guides/using-react" rel="noopener noreferrer"&gt;React integration step-by-step guide&lt;/a&gt; on our docs site.&lt;/p&gt;



&lt;p&gt;Star ⭐ the repo, check the &lt;a href="https://trafilea.github.io/nx-shopify/" rel="noopener noreferrer"&gt;docs&lt;/a&gt;, and power up your Shopify themes development experience!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/trafilea" rel="noopener noreferrer"&gt;
        trafilea
      &lt;/a&gt; / &lt;a href="https://github.com/trafilea/nx-shopify" rel="noopener noreferrer"&gt;
        nx-shopify
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Nx plugin for developing performance-first Shopify themes 🚀
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-logo.png"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fnrwl%2Fnx%2Fmaster%2Fimages%2Fnx-logo.png" width="80" height="50"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;
  Nx-Shopify
&lt;/h1&gt;
&lt;/div&gt;

&lt;div&gt;
&lt;p&gt;&lt;a href="https://github.com/trafilea/nx-shopify/actions/workflows/e2e.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/trafilea/nx-shopify/actions/workflows/e2e.yml/badge.svg" alt="e2e"&gt;&lt;/a&gt;
&lt;a href="http://commitizen.github.io/cz-cli/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1d01d79de532fa2a8b9d3e1c29e2b5d6f700b6d36f108c8416faca472cb35b6f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f6d6d6974697a656e2d667269656e646c792d627269676874677265656e2e737667" alt="Commitizen friendly"&gt;&lt;/a&gt;
&lt;a href="https://github.com/trafilea/nx-shopify/blob/master/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/34e973688eaffdcf48165a50d4b46612cc9bd464837f81d9e0e9989fd76f3966/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f74726166696c65612f6e782d73686f70696679" alt="License"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/@trafilea/nx-shopify" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d2aff0ee53b9ebee998ca8d225799f6d58d1e7a7f22cd8f03514316d13d7be24/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f4074726166696c65612f6e782d73686f70696679" alt="npm (scoped)"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/@trafilea/nx-shopify" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/92065019b6a335ae28ee762c0882121285c5dd8987d2df6d04d776b5cb9ef61a/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f64742f4074726166696c65612f6e782d73686f70696679" alt="npm"&gt;&lt;/a&gt;
&lt;a href="https://github.com/semantic-release/semantic-release" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/251b82ec02847188c7f2f024d0a6752bb8e0422772baaace42e7a7dc3fd8c88a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f2532302532302546302539462539332541362546302539462539412538302d73656d616e7469632d2d72656c656173652d6531303037392e737667" alt="semantic-release"&gt;&lt;/a&gt;
&lt;a href="https://github.com/prettier/prettier" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/97be20604d833ecbf2b0a9d3d17e3f0e29ae6de33b102c744849d0bf17f399e4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64655f7374796c652d70726574746965722d6666363962342e7376673f7374796c653d666c61742d737175617265" alt="code style: prettier"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/trafilea/nx-shopify#contributors-" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ebc019cd16befd901bfe054d09a21add163b3a820cdce210165560483fcc03f4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f616c6c5f636f6e7472696275746f72732d372d6f72616e67652e7376673f7374796c653d666c61742d737175617265" alt="All Contributors"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;🔎 &lt;strong&gt;An &lt;a href="https://nx.dev" rel="nofollow noopener noreferrer"&gt;Nx&lt;/a&gt; plugin for developing performance-first Shopify themes 🚀&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Be it you need to build a custom Shopify store theme, develop a generic theme or even maintain multiple stores/themes with shared code across them, this Nx plugin helps you power-up your development experience&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Install the Nx CLI globally&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;# npm
$ npm install --global nx

# yarn
$ yarn add --global nx

# pnpm
$ pnpm install --global nx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Create an empty Nx workspace (or use an existing one)&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ npx create-nx-workspace my-org --preset=empty
$ cd ./my-org
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Install the Nx-Shopify plugin as a devDependency&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;# npm
$ npm install --save-dev @trafilea/nx-shopify

# yarn
$ yarn add --save-dev @trafilea/nx-shopify

# pnpm
$ pnpm install --save-dev @trafilea/nx-shopify
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Generate a Shopify theme using the Nx CLI&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ nx generate @trafilea/nx-shopify:theme my-theme
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Check the generators and executors provided by the plugin&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ nx list @trafilea/nx-shopify
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Documentation&lt;/h2&gt;

&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;🤓 Read the full…&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/trafilea/nx-shopify" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>shopify</category>
    </item>
    <item>
      <title>Could you review my first react app since 3 years ago?</title>
      <dc:creator>Sebastián Duque G</dc:creator>
      <pubDate>Mon, 23 Mar 2020 05:15:42 +0000</pubDate>
      <link>https://forem.com/sebastiandg7/could-you-review-my-first-react-app-since-3-years-ago-3nbh</link>
      <guid>https://forem.com/sebastiandg7/could-you-review-my-first-react-app-since-3-years-ago-3nbh</guid>
      <description>&lt;p&gt;I just built a very little react app for a technical interview. I come from a solid Angular background, the last time I wrote a react component was back in 2017. So, I've made my best effort to write this app in a clean, solid and consistent architecture.&lt;/p&gt;

&lt;p&gt;I would like to receive some feedback from you. Best practices, anti-patterns, code styling, architecture, S.O.L.I.D., component composition... everything is welcome! Could give it a check? :)&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sebastiandg7"&gt;
        sebastiandg7
      &lt;/a&gt; / &lt;a href="https://github.com/sebastiandg7/tf-react-coding-test"&gt;
        tf-react-coding-test
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      React coding test - Use of Nx workspaces, hooks, ref forwarding, lazy loading, dynamic redux modules, formik, yup, react-input-mask
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Welcome to tf-react-coding-test 👋
&lt;/h1&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/8d54ad865e12c41b931adc8fab3ba97a720286ae849b70b5fcf0a9cd0e12ce33/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d302e312e312d626c75652e7376673f63616368655365636f6e64733d32353932303030"&gt;&lt;img src="https://camo.githubusercontent.com/8d54ad865e12c41b931adc8fab3ba97a720286ae849b70b5fcf0a9cd0e12ce33/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d302e312e312d626c75652e7376673f63616368655365636f6e64733d32353932303030" alt="Version"&gt;&lt;/a&gt;
&lt;a href="https://github.com/sebastiandg7/tf-react-coding-test/blob/master/README.md"&gt;&lt;img src="https://camo.githubusercontent.com/335378d3b5837f055d0c9bcab2850a8845250dbd39b91e91a7fee77b50a96cfb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63756d656e746174696f6e2d7965732d627269676874677265656e2e737667" alt="Documentation"&gt;&lt;/a&gt;
&lt;a href="https://github.com/sebastiandg7/tf-react-coding-test#"&gt;&lt;img src="https://camo.githubusercontent.com/78f47a09877ba9d28da1887a93e5c3bc2efb309c1e910eb21135becd2998238a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://twitter.com/sebastiandg7" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/982690f632a725f0e8800a953cc39216fc7e117273d69d2c58ab9e9626a4b94a/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f73656261737469616e6467372e7376673f7374796c653d736f6369616c" alt="Twitter: sebastiandg7"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;react coding challenge&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
🏠 &lt;a href="https://github.com/sebastiandg7/tf-react-coding-test"&gt;Homepage&lt;/a&gt;
&lt;/h3&gt;
&lt;h3&gt;
✨ &lt;a href="https://sebastiandg7.github.io/tf-react-coding-test/" rel="nofollow"&gt;Demo&lt;/a&gt; - Also hosted in &lt;a href="http://sdg-tf-react-coding-test.surge.sh" rel="nofollow"&gt;surge.sh&lt;/a&gt; (over HTTP, API calls will work)&lt;/h3&gt;
&lt;h2&gt;
Usage&lt;/h2&gt;
&lt;h3&gt;
Install&lt;/h3&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
Serve&lt;/h3&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm start react-coding-test&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
Dependency graph&lt;/h3&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm run dep-graph&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
Used libs &amp;amp; techniques&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://nx.dev/" rel="nofollow"&gt;Nx&lt;/a&gt;:&lt;/strong&gt; workspace &amp;amp; dev tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/conventional-changelog/standard-version"&gt;standard-version&lt;/a&gt;:&lt;/strong&gt; automatic versioning &amp;amp; changelog generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://reactjs.org/docs/code-splitting.html#reactlazy" rel="nofollow"&gt;Lazy loading&lt;/a&gt;:&lt;/strong&gt; lazy load application features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://redux-dynamic-modules.js.org/" rel="nofollow"&gt;Redux Dynamic Modules&lt;/a&gt;:&lt;/strong&gt; modular Redux state management loaded on demand&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/marak/Faker.js"&gt;Faker.js&lt;/a&gt;:&lt;/strong&gt; fake data generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://jaredpalmer.com/formik" rel="nofollow"&gt;Formik&lt;/a&gt;:&lt;/strong&gt; forms handling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/jquense/yup"&gt;Yup&lt;/a&gt;:&lt;/strong&gt; data validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://nicolas-cusan.github.io/destyle.css" rel="nofollow"&gt;destyle.css&lt;/a&gt;:&lt;/strong&gt; CSS reset&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Workspace setup&lt;/h2&gt;
&lt;p&gt;You can find all the generated code script under &lt;a href="https://github.com/sebastiandg7/tf-react-coding-test/tools/workspace-setup.sh"&gt;&lt;code&gt;./tools/workspace-setup.sh&lt;/code&gt;&lt;/a&gt; (suitable for worksapce architecture replication)&lt;/p&gt;
&lt;h2&gt;
Author&lt;/h2&gt;
&lt;p&gt;👤 &lt;strong&gt;Sebastián Duque Gutiérrez&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Twitter: &lt;a href="https://twitter.com/sebastiandg7" rel="nofollow"&gt;@sebastiandg7&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Github: &lt;a href="https://github.com/sebastiandg7"&gt;@sebastiandg7&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://linkedin.com/in/sebastianduqueg" rel="nofollow"&gt;@sebastianduqueg&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
🤝 Contributing&lt;/h2&gt;
&lt;p&gt;Contributions, issues and feature requests are welcome!&lt;/p&gt;
&lt;p&gt;Feel free to check &lt;a href="https://github.com/sebastiandg7/tf-react-coding-test/issues"&gt;issues page&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
Show your support&lt;/h2&gt;
&lt;p&gt;Give a ⭐️ if this project helped you!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This README was generated with ❤️ by &lt;a href="https://github.com/kefranabg/readme-md-generator"&gt;readme-md-generator&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sebastiandg7/tf-react-coding-test"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Thank you!&lt;/p&gt;

&lt;p&gt;PD: CSS is not my best strength (currently working on getting better at it!)&lt;/p&gt;

&lt;p&gt;Stay home, stay safe and wash your hands regularly.&lt;/p&gt;

</description>
      <category>react</category>
      <category>interview</category>
    </item>
    <item>
      <title>How do you handle role/permissions updates with JWT?</title>
      <dc:creator>Sebastián Duque G</dc:creator>
      <pubDate>Thu, 29 Aug 2019 15:59:23 +0000</pubDate>
      <link>https://forem.com/sebastiandg7/how-do-you-handle-role-permissions-updates-with-jwt-3778</link>
      <guid>https://forem.com/sebastiandg7/how-do-you-handle-role-permissions-updates-with-jwt-3778</guid>
      <description>&lt;p&gt;Usually, JWT implementations in a REST Api backend save the user roles and/or permissions inside the JWT token claims. In this cases, clients make use of this claims to restrict user's interaction with some of the app features.&lt;/p&gt;

&lt;p&gt;There are some user, or server, actions that update the user's authorization roles/permissions. However, &lt;strong&gt;the last emitted JWT token has not expired yet&lt;/strong&gt; so it still has the old roles/permissions in it's claims.&lt;/p&gt;

&lt;p&gt;How do you or your team handle this scenarios in order to update user's authorization in client side apps?&lt;/p&gt;

&lt;p&gt;I've seen many options out there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a token version and update it in server side to compare with new request&lt;/li&gt;
&lt;li&gt;Keep token lifetime short&lt;/li&gt;
&lt;li&gt;Use refresh token mechanism and invalidate the user's current token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I want to hear you...&lt;/p&gt;

</description>
      <category>security</category>
      <category>jwt</category>
      <category>rest</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
