<?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: Duc Le</title>
    <description>The latest articles on Forem by Duc Le (@leduc1901).</description>
    <link>https://forem.com/leduc1901</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%2F979243%2F03f2d156-7ca7-4ade-a2a6-a2ab227717d1.jpeg</url>
      <title>Forem: Duc Le</title>
      <link>https://forem.com/leduc1901</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/leduc1901"/>
    <language>en</language>
    <item>
      <title>Reduce Docker Image size for your Next.js App</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Fri, 28 Apr 2023 09:28:20 +0000</pubDate>
      <link>https://forem.com/leduc1901/reduce-docker-image-size-for-your-nextjs-app-5911</link>
      <guid>https://forem.com/leduc1901/reduce-docker-image-size-for-your-nextjs-app-5911</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;First thing first, I expect you to know what is Docker, but if you don’t:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Docker is an open platform for developing, shipping, and running applications&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can spend time &lt;a href="https://docs.docker.com/get-started/overview/" rel="noopener noreferrer"&gt;learning about it&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NextJS, in other hand, is a flexible React framework that gives you building blocks to create fast web applications.&lt;/p&gt;

&lt;p&gt;NextJS, in other hand, is a flexible React framework that gives you building blocks to create fast web applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dockerize your App
&lt;/h3&gt;

&lt;p&gt;Before we optimize anything, we have to dockerize the application first. Let’s say our application name is &lt;code&gt;my-space&lt;/code&gt; . Starting with:&lt;/p&gt;

&lt;p&gt;Create the &lt;code&gt;Dockerfile&lt;/code&gt; :&lt;/p&gt;

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

touch Dockerfile


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

&lt;/div&gt;

&lt;p&gt;Ignore unnecessary files in &lt;code&gt;dockerignore&lt;/code&gt;:&lt;/p&gt;

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

node_modules
.next
.vscode
.gitignore
README.md
.dockerignore
.git


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

&lt;/div&gt;

&lt;p&gt;Dockerize it:&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%2F42facdtpdwj9e4f1z16t.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%2F42facdtpdwj9e4f1z16t.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the most basic example on how to dockerize your app, now let’s build it with:&lt;/p&gt;

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

docker build -t my-space .


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

&lt;/div&gt;

&lt;p&gt;Now look at the size:&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%2Fjsxvex81x5ax2vcs6qcp.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%2Fjsxvex81x5ax2vcs6qcp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;That’s just crazy, 2.42gb!!&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Unbelievable right, we can’t publish this image, it’s just too heavy !&lt;/p&gt;

&lt;h3&gt;
  
  
  Reduce the image size
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Use alpine
&lt;/h4&gt;

&lt;p&gt;The Node.js Docker team maintains a &lt;code&gt;node:alpine&lt;/code&gt; image tag and variants of it to match specific versions of the Alpine Linux distributions with those of the Node.js runtime. The original version size is about 1gb.&lt;/p&gt;

&lt;p&gt;Now we will move to the alpine version:&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%2Fko6530ky4fuwmum9kmcl.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%2Fko6530ky4fuwmum9kmcl.png" alt="Image description"&gt;&lt;/a&gt;&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%2Fjyh34s32unrjnz0ogxq7.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%2Fjyh34s32unrjnz0ogxq7.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the size shrank to &lt;strong&gt;1.65gb, 800mb smaller&lt;/strong&gt;. That’s a good start !&lt;/p&gt;

&lt;h4&gt;
  
  
  Multi-stages builds
&lt;/h4&gt;

&lt;p&gt;Multi-stage builds are useful to anyone who has struggled to optimize Dockerfiles while keeping them easy to read and maintain.&lt;/p&gt;

&lt;p&gt;We will create 2 stages in the &lt;code&gt;Dockerfile&lt;/code&gt; . I will call it &lt;code&gt;builder&lt;/code&gt; and &lt;code&gt;runner&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this way we can get rid of unnecessary files in our image:&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%2Fkes5excrwehvtthdanky.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%2Fkes5excrwehvtthdanky.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will pick files from the &lt;code&gt;builder&lt;/code&gt; and move it to the &lt;code&gt;runner&lt;/code&gt; that we will eventually use:&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%2Fq916s07kcdbu2mqkm98b.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%2Fq916s07kcdbu2mqkm98b.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;The size comes down to 1.36gb, about 300mb smaller, we are doing good !&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Remove duplicate layers
&lt;/h3&gt;

&lt;p&gt;You can see something is duplicating. Yes, we install the dependencies twice for each stage. Although this works and the project size is still the same. The image size is still big because of caching and layers.&lt;/p&gt;

&lt;p&gt;So we can pick the &lt;code&gt;node_modules&lt;/code&gt; from the build stage:&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%2F0kq7mgumj8zs9udorwy8.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%2F0kq7mgumj8zs9udorwy8.png" alt="Image description"&gt;&lt;/a&gt;&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%2Fk3q2qv01t7m9vvwj616s.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%2Fk3q2qv01t7m9vvwj616s.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The size now is quite decent for a NextJS app, &lt;strong&gt;below 500mb&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But we can still make it lighter !&lt;/p&gt;

&lt;h4&gt;
  
  
  Output File Tracing
&lt;/h4&gt;

&lt;p&gt;During a build, &lt;code&gt;Next.js&lt;/code&gt; will automatically trace each page and its dependencies to determine all of the files that are needed for deploying a production version of your application.&lt;/p&gt;

&lt;p&gt;This feature helps reduce the size of deployments drastically. Previously, when deploying with Docker you would need to have all files from your package’s dependencies installed to run &lt;code&gt;next start&lt;/code&gt;. Starting with Next.js 12, you can leverage Output File Tracing in the &lt;code&gt;.next/&lt;/code&gt; directory to only include the necessary files.&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;next.config.js&lt;/code&gt; file, enable the standalone output&lt;/p&gt;

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

experimental: {
    outputStandalone: true,
  },


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

&lt;/div&gt;

&lt;p&gt;This will create a folder at &lt;code&gt;.next/standalone&lt;/code&gt; which can then be deployed on its own without installing &lt;code&gt;node_modules&lt;/code&gt;.&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%2Fh4ophb9g862tcpn5v3wl.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%2Fh4ophb9g862tcpn5v3wl.png" alt="Image description"&gt;&lt;/a&gt;&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%2Fmv2ofqbeqizd3bwydmpu.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%2Fmv2ofqbeqizd3bwydmpu.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;The size is now 176mb! Small enough for most cases&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This is just a simple example on how to optimize your docker image sizes, you can look deeper in Docker docs to find the most suitable treatment for your app!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>docker</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Costly CSS Properties and How to Optimize Them</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Thu, 13 Apr 2023 04:10:29 +0000</pubDate>
      <link>https://forem.com/leduc1901/costly-css-properties-and-how-to-optimize-them-3bmd</link>
      <guid>https://forem.com/leduc1901/costly-css-properties-and-how-to-optimize-them-3bmd</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Some CSS properties are more costly than others in terms of performance. When used improperly, they can slow down your webpage and make it less responsive for your users. In this article, we’ll explore some of the most costly CSS properties and how to optimize them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Box-Shadow
&lt;/h3&gt;

&lt;p&gt;The box-shadow property is a popular way to add a shadow effect to an element, but it can be very costly in terms of performance. When used on a large number of elements or with a large blur radius, it can significantly slow down your webpage.&lt;/p&gt;

&lt;p&gt;Here are some ways you can do to reduce the cost of box-shadow :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a smaller blur radius — A smaller blur radius will reduce the amount of processing required to render the shadow. Instead of using a large blur radius, try using a smaller value that still gives you the desired effect.
Use a solid color instead of a gradient — A gradient box-shadow can be very costly in terms of performance. Instead of using a gradient, try using a solid color for your box-shadow.&lt;/li&gt;
&lt;li&gt;Use the inset keyword for inner shadows — If you’re using box-shadow to create an inner shadow, use the inset keyword. This will improve the performance of your webpage because it doesn’t require rendering an extra layer.&lt;/li&gt;
&lt;li&gt;Use the will-change property to improve performance when animating box shadows — If you’re animating box-shadow, use the will-change property to tell the browser that the box-shadow property will be changing. This will help the browser optimize the rendering of the animation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, optimizing the box-shadow property involves reducing the processing required to render the shadow. By using these techniques, you can create a box-shadow that looks great while minimizing the impact on your webpage’s performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Background Image
&lt;/h3&gt;

&lt;p&gt;The background-image property is used to add an image to an element, but it can be very costly in terms of performance. Large images or a large number of images can significantly slow down your webpage.&lt;/p&gt;

&lt;p&gt;To optimize the background-image property, you can use the following techniques:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use smaller image file sizes&lt;/li&gt;
&lt;li&gt;Use image compression techniques like JPEG or PNG optimization&lt;/li&gt;
&lt;li&gt;Use image sprites to reduce the number of HTTP requests&lt;/li&gt;
&lt;li&gt;Use lazy loading techniques to load images only when they are needed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Border-Radius
&lt;/h3&gt;

&lt;p&gt;The border-radius property is used to create rounded corners on an element, but it can be very costly in terms of performance. When used on a large number of elements or with a large radius, it can significantly slow down your webpage.&lt;/p&gt;

&lt;p&gt;To optimize the border-radius property, you can use the following techniques:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use smaller border radius values&lt;/li&gt;
&lt;li&gt;Use the border-image property instead of border-radius for complex border designs&lt;/li&gt;
&lt;li&gt;Use SVG graphics for complex border designs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Transforms
&lt;/h3&gt;

&lt;p&gt;The transform property is used to apply transformations to an element, such as rotation, scaling, or skewing. When used improperly, it can be very costly in terms of performance.&lt;/p&gt;

&lt;p&gt;To optimize the transform property, you can use the following techniques:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use 2D transforms instead of 3D transforms when possible&lt;/li&gt;
&lt;li&gt;Use the will-change property to improve performance when animating transforms&lt;/li&gt;
&lt;li&gt;Use hardware acceleration by using the transform-style: preserve-3d property&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Filters
&lt;/h3&gt;

&lt;p&gt;The filter property is used to apply visual effects to an element, such as blurring, color adjustment, or brightness. When used improperly, it can be very costly in terms of performance.&lt;/p&gt;

&lt;p&gt;To optimize the filter property, you can use the following techniques:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use simpler filter effects&lt;/li&gt;
&lt;li&gt;Use the will-change property to improve performance when animating filters&lt;/li&gt;
&lt;li&gt;Use hardware acceleration by using the transform-style: preserve-3d property&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Original CSS code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;div {
  filter: blur(5px);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Optimized CSS code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;div {
  filter: blur(1px);
  transform: translateZ(0);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;p&gt;Instead of using a larger blur radius, we are using a smaller value of 1px. This reduces the amount of processing required to render the blur effect.&lt;/p&gt;

&lt;p&gt;We are also adding a transform property with the translateZ(0) value. This creates a new layer for the element, which can help with GPU acceleration and improve performance.&lt;/p&gt;

&lt;p&gt;By using this optimized CSS code, we can achieve the same visual effect while reducing the impact on our webpage’s performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;By optimizing CSS properties like box-shadow, filter, and border-radius, we can improve our webpage’s performance. Techniques include using smaller values, simpler shapes, and creating new layers with the transform property. These optimizations help create webpages that look great and perform well.&lt;/p&gt;

&lt;p&gt;P/s: Thumbnail Image from &lt;a href="https://kinsta.com/"&gt;https://kinsta.com/&lt;/a&gt; , please check the page out, It has a lot of cool articles&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>html</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Understanding Critical Rendering Path (CRP)</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Tue, 11 Apr 2023 03:39:21 +0000</pubDate>
      <link>https://forem.com/leduc1901/understanding-critical-rendering-path-crp-48nf</link>
      <guid>https://forem.com/leduc1901/understanding-critical-rendering-path-crp-48nf</guid>
      <description>&lt;h3&gt;
  
  
  What is Critical Rendering Path?
&lt;/h3&gt;

&lt;p&gt;The Critical Rendering Path are the steps the browser goes through to convert the HTML, CSS, and JavaScript into pixels on the screen. The critical rendering path includes the Document Object Model (DOM), CSS Object Model (CSSOM), render tree and layout.&lt;/p&gt;

&lt;p&gt;The DOM is created as the HTML is parsed. The HTML may request JavaScript that might alter the DOM. The HTML includes or makes requests for styles, which builds the CSSOM.&lt;/p&gt;

&lt;p&gt;The browser engine combines the two to create the Render Tree. Layout determines the size and location of everything on the page. Once layout is determined, pixels are painted to the screen.&lt;/p&gt;

&lt;h3&gt;
  
  
  Critical Rendering Path Deep dive
&lt;/h3&gt;

&lt;p&gt;We can go into the details of the CRP with these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A request for a web page or app starts with an HTML request
The server returns the HTML&lt;/li&gt;
&lt;li&gt;The browser then begins parsing the HTML, converting the received bytes to the DOM tree&lt;/li&gt;
&lt;li&gt;The browser initiates requests every time it finds links to external resources, that would be stylesheets, scripts, or embedded image references, some requests are blocking, which means the parsing of the rest of the HTML is halted until the imported asset is handled, this in when requests optimization comes in&lt;/li&gt;
&lt;li&gt;The browser continues to parse the HTML making requests and building the DOM, until it gets to the end, at which point it constructs the CSS object model.&lt;/li&gt;
&lt;li&gt;With the DOM and CSSOM complete, the browser builds the render tree, computing the styles for all the visible content.&lt;/li&gt;
&lt;li&gt;After the render tree is complete, layout occurs, defining the location and size of all the render tree elements&lt;/li&gt;
&lt;li&gt;Once complete, the page is rendered, or ‘painted’ on the screen.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Document Object Model
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;DOM construction is incremental&lt;/strong&gt;. The HTML response turns into nodes which turn into the DOM Tree. Nodes contain all relevant information about the HTML element. .&lt;/p&gt;

&lt;p&gt;The more nodes we have, the longer the following events in the critical rendering path will take. Remember A few extra nodes won’t make a big difference, but keep in mind that adding many extra nodes will impact performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS Object Model
&lt;/h3&gt;

&lt;p&gt;The DOM contains all the content of the page. The CSSOM contains all the styling information. CSSOM is similar to the DOM, but different.&lt;/p&gt;

&lt;p&gt;While the DOM construction is incremental, CSSOM is not. CSS is render blocking: the browser blocks page rendering until it receives and processes all the CSS. CSS is render blocking because rules can be overwritten, so the content can’t be rendered until the CSSOM is complete.&lt;/p&gt;

&lt;h3&gt;
  
  
  Render Tree
&lt;/h3&gt;

&lt;p&gt;The render tree captures both the content and the styles: the DOM and CSSOM trees are combined into the render tree.&lt;/p&gt;

&lt;p&gt;To construct the render tree, the browser checks every node, starting from root of the DOM tree, and determines which CSS rules are attached.&lt;/p&gt;

&lt;p&gt;The render tree only captures visible content. The head section (generally) doesn’t contain any visible information, so it’s not included in the render tree.&lt;/p&gt;

&lt;p&gt;If there’s a display: none; set on an element, neither it, nor any of its descendants, are in the render tree.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layout
&lt;/h3&gt;

&lt;p&gt;Once the render tree is built, layout becomes possible. Layout is dependent on the size of screen.&lt;/p&gt;

&lt;p&gt;The layout step determines where and how the elements are positioned on the page, determining the width and height of each element, and where they are in relation to each other.&lt;/p&gt;

&lt;h3&gt;
  
  
  Paint
&lt;/h3&gt;

&lt;p&gt;The last step is painting the pixels to the screen.&lt;/p&gt;

&lt;p&gt;Once the render tree is created and layout occurs, the pixels can be painted to the screen.&lt;/p&gt;

&lt;p&gt;On load, the entire screen is painted. After that, only impacted areas of the screen will be repainted, as browsers are optimized to repaint the minimum area required. Paint time depends on what kind of updates are being applied to the render tree.&lt;/p&gt;

&lt;p&gt;While painting is a very fast process, and therefore likely not the most impactful place to focus on in improving performance, it is important to remember to allow for both layout and re-paint times when measuring how long an animation frame may take.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>css</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Why you shouldn't use slow regular expressions</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Sun, 26 Feb 2023 04:41:22 +0000</pubDate>
      <link>https://forem.com/leduc1901/why-you-shouldnt-use-slow-regular-expressions-2bnc</link>
      <guid>https://forem.com/leduc1901/why-you-shouldnt-use-slow-regular-expressions-2bnc</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Most of the regular expression engines use backtracking to try all possible execution paths of the regular expression when evaluating an input, in some cases it can cause performance issues, called catastrophic backtracking situations.&lt;br&gt;
In the worst case, the complexity of the regular expression is exponential in the size of the input, this means that a small carefully-crafted input (like 20 chars) can trigger catastrophic backtracking and cause a denial of service of the application. Super-linear regex complexity can lead to the same impact too with, in this case, a large carefully-crafted input (thousands chars).&lt;/p&gt;
&lt;h3&gt;
  
  
  Why it happens ?
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Ask Yourself Whether
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The input is user-controlled.&lt;/li&gt;
&lt;li&gt;The input size is not restricted to a small number of characters.&lt;/li&gt;
&lt;li&gt;There is no timeout in place to limit the regex evaluation time.
&lt;strong&gt;There is a risk if you answered yes to any of those questions.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Recommended Secure Coding Practices
&lt;/h3&gt;

&lt;p&gt;To avoid &lt;strong&gt;catastrophic backtracking situations&lt;/strong&gt;, make sure that none of the following conditions apply to your regular expression.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In all of the following cases, catastrophic backtracking can only happen if the problematic part of the regex is followed by a pattern that can fail, causing the backtracking to actually happen.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you have a repetition &lt;code&gt;r*&lt;/code&gt; or &lt;code&gt;r*?&lt;/code&gt;, such that the regex &lt;code&gt;r&lt;/code&gt; could produce different possible matches (of possibly different lengths) on the same input, the worst case matching time can be exponential. This can be the case if &lt;code&gt;r&lt;/code&gt; contains optional parts, alternations or additional repetitions (but not if the repetition is written in such a way that there’s only one way to match it).&lt;/li&gt;
&lt;li&gt;If you have multiple repetitions that can match the same contents and are consecutive or are only separated by an optional separator or a separator that can be matched by both of the repetitions, the worst case matching time can be polynomial (O(n^c) where c is the number of problematic repetitions). For example &lt;code&gt;a*b*&lt;/code&gt; is not a problem because &lt;code&gt;a*&lt;/code&gt; and &lt;code&gt;b*&lt;/code&gt; match different things and &lt;code&gt;a*_a*&lt;/code&gt; is not a problem because the repetitions are separated by a '&lt;em&gt;' and can’t match that '&lt;/em&gt;'. However, &lt;code&gt;a*a*&lt;/code&gt; and &lt;code&gt;.*_.*&lt;/code&gt; have quadratic runtime.&lt;/li&gt;
&lt;li&gt;If the regex is not anchored to the beginning of the string, quadratic runtime is especially hard to avoid because whenever a match fails, the regex engine will try again starting at the next index. This means that any unbounded repetition, if it’s followed by a pattern that can fail, can cause quadratic runtime on some inputs. For example &lt;code&gt;str.split(/\s*,/)&lt;/code&gt; will run in quadratic time on strings that consist entirely of spaces (or at least contain large sequences of spaces, not followed by a comma).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In order to rewrite your regular expression without these patterns, consider the following strategies:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If applicable, define a maximum number of expected repetitions using the bounded quantifiers, like &lt;code&gt;{1,5}&lt;/code&gt; instead of &lt;code&gt;+&lt;/code&gt; for instance.&lt;/li&gt;
&lt;li&gt;Refactor nested quantifiers to limit the number of way the inner group can be matched by the outer quantifier, for instance this nested quantifier situation &lt;code&gt;(ba+)+&lt;/code&gt; doesn’t cause performance issues, indeed, the inner group can be matched only if there exists exactly one &lt;code&gt;b&lt;/code&gt; char per repetition of the group.&lt;/li&gt;
&lt;li&gt;Optimize regular expressions by emulating possessive quantifiers and atomic grouping.
Use negated character classes instead of &lt;code&gt;.&lt;/code&gt; to exclude separators where applicable. For example the quadratic regex &lt;code&gt;.*_.*&lt;/code&gt; can be made linear by changing it to &lt;code&gt;[^_]*_.*&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sometimes it’s not possible to rewrite the regex to be linear while still matching what you want it to match. Especially when the regex is not anchored to the beginning of the string, for which it is quite hard to avoid quadratic runtimes. In those cases consider the following approaches:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solve the problem without regular expressions&lt;/li&gt;
&lt;li&gt;Use an alternative non-backtracking regex implementations such as Google’s RE2 or node-re2.&lt;/li&gt;
&lt;li&gt;Use multiple passes. This could mean pre- and/or post-processing the string manually before/after applying the regular expression to it or using multiple regular expressions. One example of this would be to replace &lt;code&gt;str.split(/\s*,\s*/)&lt;/code&gt; with &lt;code&gt;str.split(",")&lt;/code&gt; and then trimming the spaces from the strings as a second step.&lt;/li&gt;
&lt;li&gt;It is often possible to make the regex infallible by making all the parts that could fail optional, which will prevent backtracking. Of course this means that you’ll accept more strings than intended, but this can be handled by using capturing groups to check whether the optional parts were matched or not and then ignoring the match if they weren’t. For example the regex &lt;code&gt;x*y&lt;/code&gt; could be replaced with &lt;code&gt;x*(y)?&lt;/code&gt; and then the call to str.match(regex) could be replaced with &lt;code&gt;matched = str.match(regex)&lt;/code&gt; and &lt;code&gt;matched[1] !== undefined.&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Sensitive Code Example
&lt;/h3&gt;
&lt;h4&gt;
  
  
  The regex evaluation will never end:
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/(a+)+$/.test(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+
"aaaaaaaaaaaaaaa!"
); // Sensitive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Compliant Solution
&lt;/h3&gt;

&lt;p&gt;Possessive quantifiers do not keep backtracking positions, thus can be used, if possible, to avoid performance issues. Unfortunately, they are not supported in JavaScript, but one can still mimick them using lookahead assertions and backreferences:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/((?=(a+))\2)+$/.test(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"+
"aaaaaaaaaaaaaaa!"
); // Compliant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;References:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
OWASP Top 10 2017 Category A1 — Injection&lt;br&gt;
MITRE, CWE-400 — Uncontrolled Resource Consumption&lt;br&gt;
MITRE, CWE-1333 — Inefficient Regular Expression Complexity&lt;br&gt;
owasp.org — OWASP Regular expression Denial of Service — ReDoS&lt;br&gt;
stackstatus.net(archived) — Outage Postmortem — July 20, 2016&lt;br&gt;
regular-expressions.info — Runaway Regular Expressions: Catastrophic Backtracking&lt;br&gt;
docs.microsoft.com — Backtracking with Nested Optional Quantifiers&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Things you should look for in a Code Review</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Sun, 05 Feb 2023 03:51:39 +0000</pubDate>
      <link>https://forem.com/leduc1901/things-you-should-look-for-in-a-code-review-ll2</link>
      <guid>https://forem.com/leduc1901/things-you-should-look-for-in-a-code-review-ll2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Code review&lt;/strong&gt;, or you can call it Peer review, is an activity for Software Quality assurance, which one or several people involve to check parts of the code.&lt;/p&gt;

&lt;p&gt;This article is sort of a guide on what to look for in a code review, so the code base can have better quality, reviewers and the author can learn from it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functionality
&lt;/h3&gt;

&lt;p&gt;The first thing to look for in a code review is the &lt;strong&gt;functionality&lt;/strong&gt;. For a feature, reviewers can look for edge cases, potential problems, to make sure no obvious bugs are visible just by looking at the code.&lt;/p&gt;

&lt;p&gt;You can have a validation on the changes. Try the feature, or run a demo to see if there is any bugs for performance issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complexity
&lt;/h3&gt;

&lt;p&gt;Have you ever seen a function or a component that is too complex to even understand it in a quick look ? Even though the code can run fine, but reviewers can’t understand it quick enough might be a logic problem. There would be potential bugs if a piece of code is too complex too, and debug it will be even more painful.&lt;/p&gt;

&lt;p&gt;We can call it &lt;strong&gt;Over-engineering&lt;/strong&gt;, when a piece of code has things that isn’t presently needed by the system, engineers should be focused on things that they need to do at the moment first, not problems that might be needed to solve in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Naming
&lt;/h3&gt;

&lt;p&gt;Did the variables name are good ? Did functions name are good ? Did classes name are good ? A good name is long enough to fully communicate what the code is or does, without being so long that it becomes hard to read.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comments
&lt;/h3&gt;

&lt;p&gt;In my opinion, comments are commonly bad. So whenever I see comments while doing code review, I often have a lot of question for the existence of it. I&lt;a href="https://medium.com/gitconnected/stop-writing-bad-comments-in-your-code-tips-for-clean-code-73f1af5eaf31" rel="noopener noreferrer"&gt; wrote an article about it, right here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In short, did the developer write clear comments without errors ? Are all of the comments actually necessary? If the code isn’t clear enough to explain itself, then the code should be made simpler.&lt;/p&gt;

&lt;p&gt;There are some exceptions (regular expressions and complex algorithms often benefit greatly from comments that explain what they’re doing, for example) but mostly comments are for information that the code itself can’t possibly contain, like the reasoning behind a decision.&lt;/p&gt;

&lt;h3&gt;
  
  
  Styling
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Coding conventions&lt;/strong&gt; are a set of guidelines for a specific programming language with recommended programming style and practice.&lt;/p&gt;

&lt;p&gt;Reviewers need to make sure the changes follows the appropriate style guides.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tests
&lt;/h3&gt;

&lt;p&gt;Unless the changes are hot fixes, reviewers should ask for unit or integration or end-to-end tests.&lt;/p&gt;

&lt;p&gt;Reviewers need to make sure the tests are useful, clear, and correct.&lt;br&gt;
Don’t forget that tests are also code, we should look for all of the things above when review tests&lt;/p&gt;

&lt;h3&gt;
  
  
  Compliments
&lt;/h3&gt;

&lt;p&gt;If the code looks good, don’t be shy, we can tell the author about it. This can encourage the developers to continue doing good stuffs&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Create your first WebSockets-based application in NestJS</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Fri, 03 Feb 2023 08:17:53 +0000</pubDate>
      <link>https://forem.com/leduc1901/create-your-first-websockets-based-application-in-nestjs-2hp</link>
      <guid>https://forem.com/leduc1901/create-your-first-websockets-based-application-in-nestjs-2hp</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;h4&gt;
  
  
  What are Websockets
&lt;/h4&gt;

&lt;p&gt;Websockets is a communication protocol which provides full-duplex communication channels over a single TCP connection established between a web browser and a web server. This allows the server to sent to the browser without being called by the client. There are many usages of Websockets, like chat app, or account balance,… Where everything needs to be update in real time&lt;/p&gt;

&lt;h4&gt;
  
  
  Websockets in NestJS
&lt;/h4&gt;

&lt;p&gt;According to NestJS, a gateway is simply a class annotated with &lt;code&gt;@WebSocketGateway()&lt;/code&gt; decorator. Technically, gateways are platform-agnostic which makes them compatible with any WebSockets library once an adapter is created.&lt;/p&gt;

&lt;p&gt;Before we dive in writing the application, I assume you already know how to create a NestJS application with TypeORM implemented, if not, you can check out &lt;a href="https://medium.com/codex/set-up-a-postgresql-database-and-connect-to-nestjs-with-typeorm-4a2a2f67339b" rel="noopener noreferrer"&gt;my tutorial right here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up
&lt;/h3&gt;

&lt;p&gt;We are going to build a simple send and receive message app&lt;/p&gt;

&lt;p&gt;First, we need to install some dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add socket.io @nestjs/websockets @nestjs/platform-socket.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we will create a Gateway called &lt;code&gt;MessageGateway&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class MessageGateway
  implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect
{

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

&lt;/div&gt;



&lt;p&gt;Don’t forget to add it to our providers in &lt;code&gt;MessageModule&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Module({
  imports: [TypeOrmModule.forFeature([Message])],
  controllers: [MessagesController],
  providers: [MessagesService, MessageGateway],
})
export class MessagesModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Build the Server
&lt;/h4&gt;

&lt;p&gt;Right now the IDE will tell you that you need to have some methods called &lt;code&gt;afterInit&lt;/code&gt; &lt;code&gt;handleDisconnect&lt;/code&gt; &lt;code&gt;handleConnection&lt;/code&gt; in MessageGateway&lt;/p&gt;

&lt;p&gt;Because this is just a simple app, and we don’t actually need to do anything in these methods, we will simply log the data out&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  private logger: Logger = new Logger('MessageGateway');

  @WebSocketServer() wss: Server;

  afterInit(server: Server) {
    this.logger.log('Initialized');
  }

  handleDisconnect(client: Socket) {
    this.logger.log(`Client Disconnected: ${client.id}`);
  }

  handleConnection(client: Socket, ...args: any[]) {
    this.logger.log(`Client Connected: ${client.id}`);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, we will know when the Server started, which client is connected and disconnected&lt;/p&gt;

&lt;h3&gt;
  
  
  Handle events
&lt;/h3&gt;

&lt;p&gt;We need 2 events in this app, first is the &lt;code&gt;sendMessage&lt;/code&gt; event and the second is &lt;code&gt;receiveMessage&lt;/code&gt; event&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@SubscribeMessage('sendMessage')
  async handleSendMessage(client: Socket, payload: string): Promise&amp;lt;void&amp;gt; {
    const newMessage = await this.messagesService.createMessage(payload);
    this.wss.emit('receiveMessage', newMessage);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this piece of code, we will use &lt;code&gt;SubscribeMessage&lt;/code&gt;decorate to subscribe to the &lt;code&gt;sendMessage&lt;/code&gt; event. Whenever a &lt;code&gt;sendMessage&lt;/code&gt; event occured, we will create a new message through &lt;code&gt;messageService&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;Then we emit this created message through receiveMessage event&lt;/p&gt;

&lt;h3&gt;
  
  
  Build the Client
&lt;/h3&gt;

&lt;p&gt;To test the gateway, we need a client, I will use the most popular UI library out there to test it, &lt;code&gt;React&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We need to install &lt;code&gt;socket.io&lt;/code&gt; since the server uses &lt;code&gt;socket.io&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add socket.io-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we will create a socket with it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import io from "socket.io-client";
const socket = io("http://localhost:3000");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we will implement the socket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  useEffect(() =&amp;gt; {
    socket.on("receiveMessage", (msg) =&amp;gt; {
      receiveMessage(msg);
    });

    getInitialMessages();
  }, []);

  function getInitialMessages() {
    fetch("http://localhost:3000/messages")
      .then((res) =&amp;gt; res.json())
      .then((data) =&amp;gt; {
        setMessages(data);
      });
  }

  function receiveMessage(msg: Message) {
    const newMessages = [...messages, msg];
    setMessages(newMessages);
  }

  function sendMessage() {
    socket.emit("sendMessage", newMessage);
    setNewMessage("");
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that on first render, I will subscribe to the &lt;code&gt;receiveMessage&lt;/code&gt; event, to listen if there is any new event and take action with &lt;code&gt;receiveMessage&lt;/code&gt; method. Then I get the initial messages through the get api&lt;/p&gt;

&lt;p&gt;On &lt;code&gt;receiveMessage&lt;/code&gt; method, I append new message to the state.&lt;/p&gt;

&lt;p&gt;Every time we need to send a new message, we will emit &lt;code&gt;sendMessage&lt;/code&gt; event&lt;/p&gt;

&lt;p&gt;This will be the result:&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%2Fitvp02sov0pb5f4tt75v.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%2Fitvp02sov0pb5f4tt75v.png" alt="Image description" width="597" height="539"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This is the most basic example on how to create your first websockets app. You will know how to send and receive messages through the gateway. If the article is not that clear to you, just check out the &lt;a href="https://github.com/leduc1901/nestjs-websocket" rel="noopener noreferrer"&gt;source code&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Last Words
&lt;/h3&gt;

&lt;p&gt;Although my content is free for everyone, but if you find this article helpful, &lt;a href="https://www.buymeacoffee.com/kylele19" rel="noopener noreferrer"&gt;you can buy me a coffee here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>backend</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Set up a PostgreSQL database and connect to NestJS with TypeORM</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Mon, 30 Jan 2023 04:40:29 +0000</pubDate>
      <link>https://forem.com/leduc1901/set-up-a-postgresql-database-and-connect-to-nestjs-with-typeorm-35np</link>
      <guid>https://forem.com/leduc1901/set-up-a-postgresql-database-and-connect-to-nestjs-with-typeorm-35np</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;The most important thing when learning backend development is how to store the data. In this article, we look into how to create a database with &lt;strong&gt;PostgreSQL&lt;/strong&gt; and connect it to &lt;strong&gt;NestJS&lt;/strong&gt;. To manage a database easier, we’ll use an Object-relational mapping (ORM) tool called &lt;strong&gt;TypeORM&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the database
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;, often simply “Postgres”, is an object-relational database management system. To quickly create a PostgreSQL database, we will use &lt;strong&gt;Docker&lt;/strong&gt; ( make sure you installed Docker )&lt;/p&gt;

&lt;p&gt;First, we create the &lt;code&gt;docker-compose.yml&lt;/code&gt; file with these configurations&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fuu7p0alhe0krk8u7j2s6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fuu7p0alhe0krk8u7j2s6.png" alt="Image description" width="720" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we create the &lt;code&gt;docker.env&lt;/code&gt; file to store environment variables:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnwtlu8e4f41jbb3pnw4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnwtlu8e4f41jbb3pnw4w.png" alt="Image description" width="720" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, so now we have Docker and PostgreSQL, the next thing we want to do is to connect the database with NestJS&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting database
&lt;/h3&gt;

&lt;p&gt;Before connecting NestJS app with the database, we need to install some dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@nestjs/typeorm typeorm&lt;/code&gt; : 2 libraries about TypeORM&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pg&lt;/code&gt; : PostgreSQL client&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@hapi/joi @types/hapi__joi&lt;/code&gt; : schema validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, we need to create &lt;code&gt;.env&lt;/code&gt; file with more variables about our database and the &lt;code&gt;database.module.ts&lt;/code&gt; to get all of the env and config &lt;strong&gt;TypeORM&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F88wqvfxs22onvxstq9hh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F88wqvfxs22onvxstq9hh.png" alt="Image description" width="720" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Frz1nodxj36qo96tul4rz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Frz1nodxj36qo96tul4rz.png" alt="Image description" width="720" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F93kxjp6u2jiw7iaqgawj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F93kxjp6u2jiw7iaqgawj.png" alt="Image description" width="720" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Beside the &lt;code&gt;MessageModule&lt;/code&gt; , you can see I configured the schema validation with &lt;code&gt;Joi&lt;/code&gt; and the database’s module and import them all to our root module ( app )&lt;/p&gt;

&lt;h3&gt;
  
  
  Entity
&lt;/h3&gt;

&lt;p&gt;If you know about databases, you’ll probably know about tables, in TypeORM, the most important concept about it is &lt;strong&gt;Entity&lt;/strong&gt;, it maps to a database table:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F5aw879vs4dgfun3g8jfi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5aw879vs4dgfun3g8jfi.png" alt="Image description" width="720" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I created a simple entity called &lt;code&gt;Message&lt;/code&gt; , you can think about it like a &lt;code&gt;message&lt;/code&gt; table with ID is its primary key and another column is content&lt;/p&gt;

&lt;h3&gt;
  
  
  Let’s write some APIs
&lt;/h3&gt;

&lt;p&gt;Enough of the setup, we have connected NestJS with the database and create a table. Next thing we want to do is creating the &lt;code&gt;controller&lt;/code&gt; and the &lt;code&gt;service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3f7az02xla7wdjhbp7j4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3f7az02xla7wdjhbp7j4.png" alt="Image description" width="720" height="772"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9gum08rpsvz39wsgb9vx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9gum08rpsvz39wsgb9vx.png" alt="Image description" width="720" height="614"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbhhrmfvxlo5yrmb7vfh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbhhrmfvxlo5yrmb7vfh6.png" alt="Image description" width="720" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With TypeORM’s repository, I created some RESTful APIs with simple methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;getAllMessages&lt;/code&gt; : I used the find method, you can pass a lot of options to it, if not, It will get all of the records in the table&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getMessageById&lt;/code&gt;: we can use the find method above, but I suggest the findOne method that only return the first record that match our criteria&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;createMessage&lt;/code&gt;: a simple create method to create new message&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;First, we need to start Docker with &lt;code&gt;docker-compose up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, we start our NestJS server with &lt;code&gt;yarn start:dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F73o96r5g2vibbcpbbzgw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F73o96r5g2vibbcpbbzgw.png" alt="Image description" width="720" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I used Postman to create new message, it works fine&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this article, we’ve gone through the basics of connecting our NestJS application with a PostgreSQL database and used TypeORM for easily managing queries.&lt;/p&gt;

&lt;p&gt;You can find the &lt;a href="https://github.com/leduc1901/nestjs-websocket" rel="noopener noreferrer"&gt;source code here&lt;/a&gt; if the article isn’t clear&lt;/p&gt;

&lt;h3&gt;
  
  
  Last Words
&lt;/h3&gt;

&lt;p&gt;Although my content is free for everyone, but if you find this article helpful, &lt;a href="https://www.buymeacoffee.com/kylele19" rel="noopener noreferrer"&gt;you can buy me a coffee here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rag</category>
      <category>ai</category>
      <category>nlp</category>
      <category>gpt3</category>
    </item>
    <item>
      <title>How to Add JWT Authentication to NestJS Apps</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Sat, 28 Jan 2023 05:25:06 +0000</pubDate>
      <link>https://forem.com/leduc1901/how-to-add-jwt-authentication-to-nestjs-apps-6bb</link>
      <guid>https://forem.com/leduc1901/how-to-add-jwt-authentication-to-nestjs-apps-6bb</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Authentication is an important part of our applications. From time to time, there are many ways to handle authentication. With each requirement, we find the suitable approach to handle authentication.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This article is a simple tutorial on how to implement authentication with NestJS, before go into the guide, I’m going to demonstrate the technologies that are going to be used in the guide&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JWT or JSON Web Token is an industry standard &lt;strong&gt;RFC 7519&lt;/strong&gt; method for representing claims securely between two parties.&lt;br&gt;
Passport is the most popular Node authentication library, well-known by the community and successfully used in many production application, &lt;strong&gt;NestJS&lt;/strong&gt; has supported it outside the box with &lt;code&gt;@nestjs/passport&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;First, we create the project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nest new your-project-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we add the dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @nestjs/passport passport passport-local passport-jwt @nestjs/jwt 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are going to use &lt;code&gt;mongoose&lt;/code&gt; to store the data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add mongoose @nestjs/mongoose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generate modules, services and controllers
&lt;/h3&gt;

&lt;p&gt;For the authentication, we need 2 modules &lt;code&gt;AuthModule&lt;/code&gt; and &lt;code&gt;UserModule&lt;/code&gt; , each of them need controller and service files&lt;/p&gt;

&lt;h4&gt;
  
  
  Auth module:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nest g module auth
nest g service auth
nest g controller auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  User module
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nest g module users
nest g service users
nest g controller users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Define schema and interface
&lt;/h3&gt;

&lt;p&gt;We need an &lt;code&gt;UserSchema&lt;/code&gt; and an &lt;code&gt;User&lt;/code&gt; interface, let’s create the &lt;code&gt;user.model.ts&lt;/code&gt; file&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fdpfv672byl78k5340tvm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fdpfv672byl78k5340tvm.png" alt="Image description" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create User Service
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fq6rns3effrmxu40kdbkf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fq6rns3effrmxu40kdbkf.png" alt="Image description" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We created the &lt;code&gt;users.service.ts&lt;/code&gt; before, next we create 3 methods for the sign up ( createUser ), get all users ( getUsers ) and get an user ( getUser )&lt;/p&gt;

&lt;h3&gt;
  
  
  Create User Module an Controller
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fvt4cfcwyi04ok21qx0rw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fvt4cfcwyi04ok21qx0rw.png" alt="Image description" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fndiyhrghzxixueubqa92.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fndiyhrghzxixueubqa92.png" alt="Image description" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nothing much to say about these files, I created 2 routes in the &lt;code&gt;UsersController&lt;/code&gt; to sign up and get all users and import all we have with users to the &lt;code&gt;users.module.ts&lt;/code&gt; file&lt;/p&gt;

&lt;p&gt;Only thing to keep in mind is the &lt;code&gt;@UseGuards(AuthGuard('jwt))&lt;/code&gt; part, which means we can’t access this route without logged in and have the jwt&lt;/p&gt;

&lt;h3&gt;
  
  
  Auth Service
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F0b4qbv53xfu9xsiear3z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F0b4qbv53xfu9xsiear3z.png" alt="Image description" width="800" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are 2 methods in the &lt;code&gt;AuthService&lt;/code&gt; , one is to validate if the user exist in our database with correct credentials, the other one is to return an &lt;code&gt;access_token&lt;/code&gt; which is a JWT assigned with an &lt;code&gt;username&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Strategies
&lt;/h3&gt;

&lt;p&gt;We have to create the &lt;code&gt;strategies&lt;/code&gt;, in this guide I will create 2 strategies, one is &lt;code&gt;LocalStrategy&lt;/code&gt; and the other is &lt;code&gt;JwtStrategy&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fxa3kva9sdcxkw40jmwpl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxa3kva9sdcxkw40jmwpl.png" alt="Image description" width="800" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;LocalStrategy&lt;/code&gt; serves a purpose when we need to validate the &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; before going deeper into the controller. In this case, I create the built-in &lt;code&gt;validation&lt;/code&gt; method with the &lt;code&gt;validateUserCredentials&lt;/code&gt; from the &lt;code&gt;AuthService&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fob9yu1hoz75cqklpyoki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fob9yu1hoz75cqklpyoki.png" alt="Image description" width="800" height="756"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the &lt;code&gt;JwtStrategy&lt;/code&gt; we extend the &lt;code&gt;PassportStrategy&lt;/code&gt; from the &lt;code&gt;@nestjs/passport&lt;/code&gt; library just like above, then we return an object consists the &lt;code&gt;username&lt;/code&gt; . The constructor need to extract the JWT from Header Bearer token (the &lt;code&gt;access_token&lt;/code&gt;). We also need a secret key for JWT Strategy, mine is &lt;code&gt;SECRET_KEY&lt;/code&gt; but I suggest you to use a more secure way to store keys.&lt;/p&gt;

&lt;h3&gt;
  
  
  Auth module and controller
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fj6e2thxu4k2q5081iagv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fj6e2thxu4k2q5081iagv.png" alt="Image description" width="800" height="756"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Like the &lt;code&gt;UserController&lt;/code&gt; above, we define the route for authentication, in this controller is the &lt;code&gt;login&lt;/code&gt; route. You can see I used &lt;code&gt;AuthGuard('local')&lt;/code&gt; from the &lt;code&gt;LocalStrategy&lt;/code&gt; above. So we only proceed to login after the validation succeeded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fw6ns1mqofrehm6z9z1u9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fw6ns1mqofrehm6z9z1u9.png" alt="Image description" width="800" height="775"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nothing much to say about the &lt;code&gt;auth.module.ts&lt;/code&gt; file, we import all the modules we need assign the &lt;code&gt;providers&lt;/code&gt; , &lt;code&gt;controllers&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  App module
&lt;/h3&gt;

&lt;p&gt;Every NestJS project comes with the &lt;code&gt;app.module.ts&lt;/code&gt; file that centralizes all the modules&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Frbdda22j0zczs5u6wff0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Frbdda22j0zczs5u6wff0.png" alt="Image description" width="800" height="775"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: I used MongoDB Atlas to create a cloud database, but you can decide what database to use&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Let’s try our APIs in Postman to see if it works&lt;/p&gt;

&lt;p&gt;First, start the server with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn start:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open Postman, we’re gonna start with the &lt;code&gt;login&lt;/code&gt; route&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fftekk37a4ew6hqcbh7lo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fftekk37a4ew6hqcbh7lo.png" alt="Image description" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see the server returns &lt;code&gt;access_token&lt;/code&gt; for us, we will copy this into every guarded API, like the &lt;code&gt;getUsers&lt;/code&gt; from &lt;code&gt;UserController&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F4ad40gog1rmxcuvf9ytf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4ad40gog1rmxcuvf9ytf.png" alt="Image description" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s all, isn’t that hard right, you can check out &lt;a href="https://github.com/leduc1901/nestjs-jwt-auth" rel="noopener noreferrer"&gt;my source code here.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Last Words
&lt;/h3&gt;

&lt;p&gt;Although my content is free for everyone, but if you find this article helpful, &lt;a href="https://www.buymeacoffee.com/kylele19" rel="noopener noreferrer"&gt;you can buy me a coffee here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>certification</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Why Cookie is preferable compared to localStorage when it comes to authentication</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Tue, 27 Dec 2022 07:49:49 +0000</pubDate>
      <link>https://forem.com/leduc1901/why-cookie-is-preferable-compared-to-localstorage-when-it-comes-to-authentication-48mb</link>
      <guid>https://forem.com/leduc1901/why-cookie-is-preferable-compared-to-localstorage-when-it-comes-to-authentication-48mb</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;We know about JWT, or JSON Web Token, as an industry standard RFC 7519 method for representing claims securely between two parties. JWT is very common nowadays. But where should we store them in the front end?&lt;/p&gt;

&lt;p&gt;In this article, I will break down 2 common places to store tokens. &lt;strong&gt;Cookies&lt;/strong&gt; and &lt;strong&gt;LocalStorage&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparison
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Local Storage
&lt;/h3&gt;

&lt;p&gt;To use &lt;code&gt;localStorage&lt;/code&gt;, just simply call use the &lt;code&gt;localStorage&lt;/code&gt; object&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;localStorage.setItem("yourTokenName", yourToken)
localStorage.getItem("yourTokenName", yourToken)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very convenient, don’t need any backend, just pure JavaScript.&lt;/li&gt;
&lt;li&gt;Big Data size, about 5mb.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vulnerable to XSS attacks. An XSS attack happens when an attacker can can take the access token that you stored in your localStorage because they can run JavaScript on your website.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cookies
&lt;/h3&gt;

&lt;p&gt;To set &lt;code&gt;cookie&lt;/code&gt; , we can do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;document.cookie = "cookieName=value"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or do this with http request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set-Cookie: &amp;lt;cookie-name&amp;gt;=&amp;lt;cookie-value&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you’re using httpOnly and secure cookies this means that your cookies cannot be accessed using JavaScript so even if an attacker can run JS on your site, they can't read your access token from the cookie.&lt;/li&gt;
&lt;li&gt;Can set expiration date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only 4kb of storage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security concerns
&lt;/h3&gt;

&lt;h3&gt;
  
  
  XSS Attacks
&lt;/h3&gt;

&lt;p&gt;Like I said above, local storage is vulnerable because it’s easily accessible using JavaScript and an attacker can retrieve your access token. However, while &lt;code&gt;httpOnly&lt;/code&gt; cookies are not accessible using JavaScript, this doesn't mean that by using cookies you are safe from XSS attacks involving your access token.&lt;/p&gt;

&lt;p&gt;If an attacker can run JavaScript in your application, they can just send an HTTP request to your server which will automatically include your cookies; It’s just less convenient for the attacker because they can’t read the content of the token although they might don’t have to.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSRF Attacks
&lt;/h3&gt;

&lt;p&gt;Cross-site request forgery (also known as CSRF) is a web security vulnerability that allows an attacker to induce users to perform actions that they do not intend to perform.&lt;/p&gt;

&lt;p&gt;However, this can be mitigated easily using &lt;code&gt;sameSite&lt;/code&gt; flag in your cookie by including an anti-CSRF token.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Cookies still have some vulnerabilities but it’s preferable compared to localStorage whenever possible. Because:&lt;/p&gt;

&lt;p&gt;Both &lt;code&gt;localStorage&lt;/code&gt; and &lt;code&gt;cookies&lt;/code&gt; are vulnerable to XSS attacks, but it's harder for the attacker to do the attack when you're using httpOnly cookies.&lt;br&gt;
Cookies are vulnerable to CSRF attacks, but it can be mitigated using sameSite flag and anti-CSRF tokens.&lt;br&gt;
You can still make it work, even if you need to use the Authorization: Bearer header or your JWT is larger than 4KB.&lt;/p&gt;

</description>
      <category>refactoring</category>
    </item>
    <item>
      <title>Improve Your Next.js App’s Performance in 10 Minutes</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Mon, 19 Dec 2022 08:00:33 +0000</pubDate>
      <link>https://forem.com/leduc1901/improve-your-nextjs-apps-performance-in-10-minutes-1gn2</link>
      <guid>https://forem.com/leduc1901/improve-your-nextjs-apps-performance-in-10-minutes-1gn2</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;We all know Next.js is quite heavyweight, especially compared to Svelte Kit or Nuxt.js and optimization is not everyone’s favorite thing. Your product owner might not want to waste time on optimization and prefer shipping features. Your QA and tester might not want to regression-test all the features that might be affected.&lt;/p&gt;

&lt;p&gt;This article is a simple tutorial on Next.js optimization, so you can achieve better performance, lighthouse score… in the shortest amount of time&lt;/p&gt;

&lt;h3&gt;
  
  
  Relocate your third party scripts
&lt;/h3&gt;

&lt;p&gt;If your app has Google Analytics, Hotjar, Facebook Pixel…or any third-party scripts. You might want to relocate those scripts onto service workers and off the main thread.&lt;/p&gt;

&lt;p&gt;I have an article about this &lt;a href="https://duckylele.medium.com/use-your-third-party-scripts-without-the-performance-hit-with-partytown-b2860cd27007" rel="noopener noreferrer"&gt;right here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Trust me, it won’t take long and the results might surprise you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use dynamic imports
&lt;/h3&gt;

&lt;p&gt;Next.js supports lazy loading external libraries with &lt;code&gt;import()&lt;/code&gt; and React components with &lt;code&gt;next/dynamic&lt;/code&gt;. Deferred loading helps improve the initial loading performance by decreasing the amount of JavaScript necessary to render the page. Components or libraries are only imported and included in the JavaScript bundle when they're used.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;next/dynamic&lt;/code&gt; is an extension of &lt;code&gt;React.lazy&lt;/code&gt;. When used in combination with &lt;code&gt;Suspense&lt;/code&gt;, components can delay hydration until the Suspense boundary is resolved.&lt;/p&gt;

&lt;p&gt;For instance, my home page has 4 big blocks, but only one of them shows at the first load, user has to scroll to see other blocks. So I don’t want all 4 to load at first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Overview = dynamic(() =&amp;gt; import('./Overview'));
const Project = dynamic(() =&amp;gt; import('./Projects'));
const Contact = dynamic(() =&amp;gt; import('./Contact'));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s look at the results&lt;/p&gt;

&lt;p&gt;Before:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fuj15l9lwdgo8hx1x4zwv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fuj15l9lwdgo8hx1x4zwv.png" alt="Image description" width="720" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fhjl1bf2ewvl2tb02uzut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fhjl1bf2ewvl2tb02uzut.png" alt="Image description" width="720" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see the first load JS is reduced from 115kb to 100kb, not much, but it is honest work&lt;/p&gt;

&lt;h3&gt;
  
  
  Preact instead of React
&lt;/h3&gt;

&lt;p&gt;Next.js is built on top of React, but Preact is a JavaScript library, considered the lightweight 3kb alternative of React with the same modern API and ECMA Script support.&lt;/p&gt;

&lt;p&gt;So if your app is just a common Next.js app, I don’t see any reason to not use Preact. Its downside is just a lack of community support.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to implement:
&lt;/h4&gt;

&lt;p&gt;First, you have to install Preact&lt;br&gt;
Open your &lt;code&gt;next.config.js&lt;/code&gt; file and reassign react:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; webpack: (config, { dev, isServer }) =&amp;gt; {
    if (!dev &amp;amp;&amp;amp; !isServer) {
      Object.assign(config.resolve.alias, {
        react: 'preact/compat',
        'react-dom/test-utils': 'preact/test-utils',
        'react-dom': 'preact/compat',
      });
    }
    return config;
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now look at the performance:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F8lblva8pqf55clqc3bb7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F8lblva8pqf55clqc3bb7.png" alt="Image description" width="720" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The bundle size is significantly smaller.&lt;/p&gt;

&lt;p&gt;But not just that, let’s see it in production:&lt;/p&gt;

&lt;p&gt;Before&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fl655jyhq0knjzmo1o28d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fl655jyhq0knjzmo1o28d.png" alt="Image description" width="720" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fmtco0wolykvp5i90uwbi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmtco0wolykvp5i90uwbi.png" alt="Image description" width="720" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see all JS files are smaller.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;There are many other ways to improve your app performance out there, but they require more work and research.&lt;/p&gt;

&lt;p&gt;I hope the methods above work for you, if not, please comment down below and we can find the best way!&lt;/p&gt;

&lt;h4&gt;
  
  
  Last Words
&lt;/h4&gt;

&lt;p&gt;Although my content is free for everyone, but if you find this article helpful, &lt;strong&gt;&lt;a href="https://www.buymeacoffee.com/kylele19" rel="noopener noreferrer"&gt;you can buy me a coffee here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>hiring</category>
    </item>
    <item>
      <title>Use your third-party scripts without the performance hit with Partytown</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Fri, 16 Dec 2022 03:27:46 +0000</pubDate>
      <link>https://forem.com/leduc1901/use-your-third-party-scripts-without-the-performance-hit-with-partytown-2bdf</link>
      <guid>https://forem.com/leduc1901/use-your-third-party-scripts-without-the-performance-hit-with-partytown-2bdf</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Partytown is a lazy-loaded library to help relocate resource intensive scripts into a web worker, and off of the main thread. Its goal is to help speed up sites by dedicating the main thread to your code, and offloading third-party scripts to a web worker and optimize your page speed and lighthouse score.&lt;/p&gt;

&lt;p&gt;Even when your website following all of today’s best practices and has the perfect lighthouse score. It’s very likely that your performance wins will be wiped out when third-party scripts are added.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up
&lt;/h3&gt;

&lt;p&gt;According to Partytown:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Partytown is fairly different from most web development libraries in mainly what’s required for its setup and configuration. At the lowest level, Partytown can work with just vanilla HTML, meaning it doesn’t need to be a part of a build process, doesn’t need a bundler, doesn’t require a specific framework, etc. Because it can integrate with any HTML page, it also makes it much easier to then create wrapper components or plugins for almost any ecosystem, such as Shopify, WordPress, Nextjs, Gatsby and much more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can install the package with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @builder.io/partytown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Although Partytown can work with just vanilla HTML, but in this example, I will show you how to use Partytown with a very common frontend library that is React, or NextJS specifically and a very common third party script is Google Tag Manager for analytics.&lt;/p&gt;

&lt;p&gt;Let’s look at my website performance at the moment ( mobile ):&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%2F47py4364y0my89ow85n4.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%2F47py4364y0my89ow85n4.png" alt="Image description"&gt;&lt;/a&gt;&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%2F3upff68zkwre0v02et68.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%2F3upff68zkwre0v02et68.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see although other scores are high, the performance only react 69 and Lighthouse points the third party script is the main factor. So we will optimize it with Partytown right now&lt;/p&gt;

&lt;p&gt;First, from the root index page, we only have to include &lt;code&gt;type="text/partytown"&lt;/code&gt; for our script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script
 async
 type="text/partytown"
 src="https://www.googletagmanager.com/gtag/js?id=G-BDYELQMSCB"
&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type="text/partytown" id="gtm"&amp;gt;
 {`
   window.dataLayer = window.dataLayer || [];
   window.gtag = function gtag(){window.dataLayer.push(arguments);}
   gtag('js', new Date());
   gtag('config', 'G-BDYELQMSCB',{ 'debug_mode':true });
 `}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because &lt;code&gt;gtag&lt;/code&gt; add a global variable to &lt;code&gt;window&lt;/code&gt; which user code calls in order to send data to the service.&lt;/p&gt;

&lt;p&gt;Since GTM was actually loaded in the web worker, then we need to forward these calls. The &lt;code&gt;forward&lt;/code&gt; config is used to set which &lt;code&gt;window&lt;/code&gt; variables should be patched and forwarded on. The forward string value is of the function to call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Partytown debug={true} forward={['gtag']} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can safely call &lt;code&gt;window.gtag&lt;/code&gt; in your app.&lt;/p&gt;

&lt;p&gt;Let’s look at the score after we implement Partytown:&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%2Fpyh5ups7etkhn9qzsxwc.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%2Fpyh5ups7etkhn9qzsxwc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The performance score is now 93, highly improved and the suggestion Lighthouse gave us is no longer there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Third-party scripts are very common nowadays, especially when websites need trackers and ads like Hotjar, Google Analytics or Facebook Pixel.&lt;/p&gt;

&lt;p&gt;I hope this article can help you improve your website performance in a very short time&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Add Google Analytics to React/Next in 5 minutes</title>
      <dc:creator>Duc Le</dc:creator>
      <pubDate>Tue, 13 Dec 2022 03:24:01 +0000</pubDate>
      <link>https://forem.com/leduc1901/add-google-analytics-to-reactnext-in-5-minutes-fbb</link>
      <guid>https://forem.com/leduc1901/add-google-analytics-to-reactnext-in-5-minutes-fbb</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;Websites and applications have tons of trackers, but they serve many purposes, and some are good purposes.&lt;/p&gt;

&lt;p&gt;Let's say you want to track how many users went to your websites, how many users actually use a feature, or how many users drop when doing certain actions.&lt;/p&gt;

&lt;p&gt;One of the most outstanding tracking tool out there is Google Analytics. So I'm writing this article to show you how to integrate Google Analytics to your React apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up
&lt;/h3&gt;

&lt;p&gt;First, you need to create a google account, which you probably have.&lt;/p&gt;

&lt;p&gt;Then you need to inject some scripts for Google Tag Manager to your apps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &amp;lt;Script
        async
        strategy="afterInteractive"
        src="https://www.googletagmanager.com/gtag/js?id=YOUR ID"
      &amp;gt;&amp;lt;/Script&amp;gt;
      &amp;lt;Script strategy="afterInteractive" id="gtm"&amp;gt;
        {`
           window.dataLayer = window.dataLayer || [];
           function gtag(){dataLayer.push(arguments);}
           gtag('js', new Date());
           gtag('config', YOUR ID,{ 'debug_mode':true });
        `}
      &amp;lt;/Script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first Script tag is to install GTM, the second tag is to config Google Tag, you need to provide your GTM id, you can enable the debug mode to inspect the actions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sending Events
&lt;/h3&gt;

&lt;p&gt;Although by default, Google provided some events built in, like page view event or scroll to bottom event. And we can create custom events on the dashboard&lt;/p&gt;

&lt;p&gt;But in my opinion, we should fire custom events from our code, for better behavior customization. So I created a utility for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type WindowWithDataLayer = Window &amp;amp; {
  gtag: Function;
};

declare const window: WindowWithDataLayer;

type TrackerProps = {
  eventName: string;
};

export const tracker = ({ eventName }: TrackerProps) =&amp;gt; {
  window.gtag('event', eventName);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the tracker function, we will be able to fire any event we like with a custom event name ( you can even provide parameters, just customize my function above ). This is how it can be called:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          onClick={() =&amp;gt; {
            tracker({ eventName: 'open_projects' });
            set(open =&amp;gt; !open);
          }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I fired an event name &lt;code&gt;open_projects&lt;/code&gt; on click.&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%2Fcads8gfwrjc4pnt43w2r.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%2Fcads8gfwrjc4pnt43w2r.png" alt="Image description" width="720" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I tried to fire the event multiple times to see if it works, as you can see, it works perfectly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This is just a very basic tutorial on how you can implement Google Analytics to your app, you can modify the example above to send parameters, or go to google’s dashboard to create advanced events.&lt;/p&gt;

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