<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nícolas Gabriel</title>
    <description>The latest articles on DEV Community by Nícolas Gabriel (@nickgabe).</description>
    <link>https://dev.to/nickgabe</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%2F835605%2F6a47398d-15ae-4202-af81-1a8adbf5182f.png</url>
      <title>DEV Community: Nícolas Gabriel</title>
      <link>https://dev.to/nickgabe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nickgabe"/>
    <language>en</language>
    <item>
      <title>EventSource: Real-Time Made Easy</title>
      <dc:creator>Nícolas Gabriel</dc:creator>
      <pubDate>Thu, 26 Jun 2025 11:09:33 +0000</pubDate>
      <link>https://dev.to/nickgabe/eventsource-real-time-made-easy-49co</link>
      <guid>https://dev.to/nickgabe/eventsource-real-time-made-easy-49co</guid>
      <description>&lt;p&gt;Often when you have a problem where you need real-time communication the first thing that comes to mind is... of course, WebSocket, right?&lt;/p&gt;

&lt;p&gt;And from a certain perspective, you're not wrong! But at the same time, maybe other options could better fit your use case. Today I want to talk about one of them that is not frequently mentioned: EventSource.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/API/EventSource" rel="noopener noreferrer"&gt;EventSource&lt;/a&gt; is widely available for all browsers, and it is dead simple.&lt;/p&gt;

&lt;p&gt;It’s essentially an HTTP request that stays open, allowing the server to continuously push “messages” to the client as long as the connection remains active.&lt;/p&gt;

&lt;p&gt;Those messages, just like WebSocket messages, are strings. So you could either send a &lt;code&gt;"Hello world"&lt;/code&gt;, or a &lt;code&gt;{ "hello": "World" }&lt;/code&gt;. Making it a viable option thanks to its simplicity and ease of implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not WebSocket?
&lt;/h2&gt;

&lt;p&gt;When considering that, the most important criteria is actually your &lt;strong&gt;use case&lt;/strong&gt;! Because EventSource has one really important limitation: It only sends data from server to client, not client to server. That is, it is a &lt;strong&gt;unidirectional&lt;/strong&gt; communication, not bidirectional like WebSocket.&lt;/p&gt;

&lt;p&gt;Given that it is a great fit for use cases where the client only needs to receive updates but not send them. Think of things like live notifications, real-time dashboards, stock prices, sports scores, log streams, or live comment feeds. Anywhere the server pushes data and the client listens, SSE can shine.&lt;/p&gt;

&lt;p&gt;But considering that your use case matches that limitation, then EventSource is a good option for you! It avoids all the WebSocket configuration that you need to do in order to support it both for server and client.&lt;/p&gt;

&lt;p&gt;But okay, theory is great and nice, but "talk is cheap, show me the code" right? So...&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I implement it?
&lt;/h2&gt;

&lt;p&gt;Since we have two sides, Backend and Frontend, let's start by the one who initiates the connection, which is the client.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client (Browser)
&lt;/h3&gt;

&lt;p&gt;The underlying logic differs a bit from WebSocket since it runs over plain HTTP, but the high level logic is the same, it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Client sends a request to connect to the server.&lt;/li&gt;
&lt;li&gt;The server sends back a response with "text/event-stream" content type&lt;/li&gt;
&lt;li&gt;client knows it accepted and passively listens for new messages.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In code, this listen is done like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://yourapi.com/notifications&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onopen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EventSource started!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// If it is plain text:&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;// If it is a JSON:&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EventSource failed!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. As you can see, you can do everything in less than 10 lines of code!&lt;/p&gt;

&lt;p&gt;But the server is a bit more varied, as it may change depending on which language and framework you choose, but let's go!&lt;/p&gt;

&lt;h3&gt;
  
  
  Server
&lt;/h3&gt;

&lt;p&gt;Presuming you're into the Node.JS ecosystem I'll use &lt;code&gt;express&lt;/code&gt; in the example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&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;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/notifications&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/event-stream&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cache-Control&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;send&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`data: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;\n\n`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// So every 2s, it will send a new message!&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with that you're going to keep sending notifications when the client connects to the route.&lt;br&gt;
Just some observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The "text/event-stream" header is mandatory, it is needed for the browser to understand that it needs to keep listening instead of simply closing upon first response.&lt;/li&gt;
&lt;li&gt;The "no-cache" header isn't mandatory, but it's a good practice since we want to send data dynamically instead of just once from cache.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final considerations
&lt;/h2&gt;

&lt;p&gt;As I mentioned earlier, the biggest benefit is avoiding WebSocket configs, but if you're already using it for some other reason, then it's up to you, since both seem good options!&lt;/p&gt;

&lt;p&gt;Regarding disconnection, the Browser automatically tries to reconnect if the connection was abruptly interrupted, but not if intentionally closed by one the sides.&lt;/p&gt;

&lt;p&gt;Given all that, now you know one more alternative to speak of when people ask you about server-to-client communication! 😉&lt;/p&gt;

&lt;p&gt;If you still have any questions, feel free to leave a comment. I hope this article helped you, see ya!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>api</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Centralizing type checking with Type Guards</title>
      <dc:creator>Nícolas Gabriel</dc:creator>
      <pubDate>Sat, 22 Feb 2025 20:30:23 +0000</pubDate>
      <link>https://dev.to/nickgabe/how-to-check-your-types-using-type-guards-4jma</link>
      <guid>https://dev.to/nickgabe/how-to-check-your-types-using-type-guards-4jma</guid>
      <description>&lt;p&gt;Hello my fellow TypeScript developer!&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever tried accessing properties on a variable in TypeScript, only to find that TypeScript isn’t sure what type it is? You know it could be one of two things, but TypeScript’s autocompletion is only showing you common properties?&lt;/p&gt;

&lt;p&gt;Let’s say you have an Animal type, which can either be a Bird or a Dog. You need to figure out whether the animal you’re working with is a bird before performing bird-specific logic.&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%2Frk6a8manpnturjfvzhdp.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%2Frk6a8manpnturjfvzhdp.png" alt="Type animal has two types, and we need to check first which one it is" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this situation, it would be easy to fix this problem, to know if the animal provided is a bird or not, we would only need to check its name (or some sort of identifier).&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%2F2chx093s7pc18euoc913.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%2F2chx093s7pc18euoc913.png" alt="Showing animal can be a Bird after checking name" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This works because TypeScript can infer that the animal is a Bird by the return of our function, and therefore provides the correct type information. But it is not ideal, doesn't follow well DRY principles... For example if we need to do the same check in another place we would need to do the same &lt;code&gt;animal.name === "bird"&lt;/code&gt; again...&lt;/p&gt;

&lt;p&gt;And if someday we end up changing "bird" to "eagle", every file with this check would need to be updated. So how could we center the logic in order to be easier to maintain and re-use?&lt;/p&gt;

&lt;p&gt;Simple! We can create a Type Guard, which is a function that is able to assert that a variable is from a specific type, making the process of checking types easier and centered in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Type Guard
&lt;/h2&gt;

&lt;p&gt;In practice, a Type Guard is a function that returns a boolean, and this boolean is the assertion if a variable is or not from a specific type.&lt;/p&gt;

&lt;p&gt;If we want to create a Type Guard for the above scenario, it would be written this way:&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%2F85nm24ohy6mb3cx9fzm3.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%2F85nm24ohy6mb3cx9fzm3.png" alt="Type guard to check bird" width="800" height="179"&gt;&lt;/a&gt;&lt;br&gt;
If it returns &lt;code&gt;true&lt;/code&gt; then animal is a Bird, if it is &lt;code&gt;false&lt;/code&gt; it is a Dog.&lt;/p&gt;

&lt;p&gt;The important part here is the &lt;code&gt;value is Type&lt;/code&gt; syntax, which is the core of a Type Guard. With it, we can use this function anywhere and our typings will be more powerful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Type Guard
&lt;/h2&gt;

&lt;p&gt;Let's try applying it to our previous example:&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%2Fcqz1fvlkox8br5a060wv.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%2Fcqz1fvlkox8br5a060wv.png" alt="Using type guard" width="800" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And as you can see, if it is &lt;code&gt;true&lt;/code&gt; it enters the if statement, which has the correct type for Animal: Bird. TypeScript is able to assume that because of our type-guard :).&lt;/p&gt;

&lt;p&gt;And TypeScript is smart, so if we add an else, then it would be considered a &lt;code&gt;Dog&lt;/code&gt; on it!&lt;/p&gt;

&lt;p&gt;A good detail is that the &lt;code&gt;value is Type&lt;/code&gt; syntax can be used in any function, even in callbacks! So for example you can also use it on a &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;every&lt;/code&gt;, a &lt;code&gt;filter&lt;/code&gt; or anywhere you think it would be helpful.&lt;/p&gt;

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

&lt;p&gt;I hope I helped you learn something new today! If you still have any questions, feel free to comment them below or connect to me in my social medias.&lt;/p&gt;

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

</description>
      <category>webdev</category>
      <category>typescript</category>
      <category>typeguards</category>
    </item>
    <item>
      <title>How to use Cookies with Ky</title>
      <dc:creator>Nícolas Gabriel</dc:creator>
      <pubDate>Sat, 08 Feb 2025 00:53:30 +0000</pubDate>
      <link>https://dev.to/nickgabe/how-to-use-cookies-with-ky-10ap</link>
      <guid>https://dev.to/nickgabe/how-to-use-cookies-with-ky-10ap</guid>
      <description>&lt;p&gt;Hello dear dev!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/ky/v/0.9.0" rel="noopener noreferrer"&gt;Ky&lt;/a&gt; has been around for several years now, presenting itself as a lightweight, modern alternative to browser fetching. Built on top of the Fetch API, it offers handy features such as hooks and the much-anticipated retries.&lt;/p&gt;

&lt;p&gt;But it's not all smooth sailing, for example I'm in a project requiring cookie-based authentication, and I decided to use Ky from the start. However, I quickly ran into an issue... Ky's documentation didn't mention cookies anywhere! After digging into the docs and some trial and error, I found a solution. To save others time, I'm here sharing my approach :).&lt;/p&gt;

&lt;p&gt;First, to manage cookies, we'll use &lt;a href="https://www.npmjs.com/package/tough-cookie" rel="noopener noreferrer"&gt;tough-cookie&lt;/a&gt;, a library that allows you to store, retrieve, and manipulate cookies programmatically. First, install the library and initialize it like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CookieJar&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tough-cookie&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookieJar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CookieJar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now as I mentioned before, one of the cool features about Ky is their "hooks" right? But what exactly are hooks?&lt;/p&gt;

&lt;p&gt;Ky provides hooks, which are functions that run before or after a request. Currently there are four types: &lt;code&gt;beforeRequest&lt;/code&gt;, &lt;code&gt;afterResponse&lt;/code&gt;, &lt;code&gt;beforeError&lt;/code&gt;, and &lt;code&gt;beforeRetry&lt;/code&gt;. For handling cookies specifically, the most useful hooks are &lt;code&gt;beforeRequest&lt;/code&gt; and &lt;code&gt;afterResponse&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And to use them we need to extend Ky's functionality using &lt;code&gt;ky.extend&lt;/code&gt;. These hooks will automatically handle cookies: &lt;code&gt;beforeRequest&lt;/code&gt; will inject stored cookies into the request headers, and &lt;code&gt;afterResponse&lt;/code&gt; will capture and store new cookies for future requests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ky&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;beforeRequest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&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;cookies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cookieJar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCookies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&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;cookieString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cookie&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cookieString&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="na"&gt;afterResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&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;cookies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSetCookie&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;for &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;cookie&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cookieJar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&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="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;

    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only thing is that everywhere which needs or sets cookies, you will need to use that &lt;code&gt;apiClient&lt;/code&gt; which you just created instead of the plain &lt;code&gt;ky&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And there you have it! With these simple hooks in place, your Ky requests will automatically handle cookies, saving you time and effort.&lt;/p&gt;

&lt;p&gt;I hope this solution helps you as much as it helped me. :)&lt;br&gt;
Have a great day!&lt;/p&gt;

</description>
      <category>ky</category>
      <category>cookies</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Hate on Tailwind... I have seen that before!</title>
      <dc:creator>Nícolas Gabriel</dc:creator>
      <pubDate>Sat, 04 Nov 2023 17:50:20 +0000</pubDate>
      <link>https://dev.to/nickgabe/hate-on-tailwind-i-have-seen-that-before-549i</link>
      <guid>https://dev.to/nickgabe/hate-on-tailwind-i-have-seen-that-before-549i</guid>
      <description>&lt;p&gt;In 2013, a company called Facebook introduced a framework called "React," which allowed developers to blend their JavaScript logic with their HTML code without having to modify the document directly.&lt;/p&gt;

&lt;p&gt;This, my friends, was JSX, or JavaScript Extended, where you could write HTML within your JavaScript! I was just 9 years old, and I didn't know anything about programming, but the rest of the community had strong opinions about it when it was released.&lt;/p&gt;

&lt;p&gt;"The audience was skeptical. Most people thought React was a significant step backward." - at JS ConfUS 29/05/2013&lt;/p&gt;

&lt;p&gt;React was innovative because it challenged many established best practices of its time.&lt;/p&gt;

&lt;p&gt;Separating JavaScript from HTML? Discarded.&lt;br&gt;
Direct DOM manipulation? Discarded.&lt;br&gt;
Two-way data flow? Discarded.&lt;/p&gt;

&lt;p&gt;However, its boldness was a double-edged sword. Just as there were people excited about this innovation, others thought it didn't make sense. "Mixing JS with HTML? It will create more complexity and reduced maintainability.".&lt;/p&gt;

&lt;p&gt;Some had been mixing JS and HTML before, such as in the MVC design pattern, which had a Model to manage logic, a View to render the UI, and a Controller to mediate between them.&lt;/p&gt;

&lt;p&gt;Creating code that resembles React:&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%2Ftwap1t5nl45y1zz534tz.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%2Ftwap1t5nl45y1zz534tz.png" alt="MVC" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In computer science, there is a concept called "Separation of Concerns," which involves separating sections into their own contexts. In other words, you write your HTML in an HTML file, your CSS in a CSS file, and so on. This was a significant reason many opposed React.&lt;/p&gt;

&lt;p&gt;Fast forward to today, React is the dominant framework. It's quite remarkable. But how does all of this relate to Tailwind? What about today?&lt;/p&gt;

&lt;p&gt;Similar to React's history, Tailwind challenges many of the best practices we used to preach. Some people appreciate the advantages it offers, while others believe that the benefits don't outweigh the drawbacks.&lt;/p&gt;

&lt;p&gt;Some dislike it due to its verbosity, but that doesn't make much sense (example in the image):&lt;/p&gt;

&lt;p&gt;Verbosity - the quality of being wordy, speaking excessively, or using too many words to express oneself.&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%2F09aa44xmqodw2w3wpxce.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%2F09aa44xmqodw2w3wpxce.png" alt="Comparison Tailwind and CSS" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The real problem is with the "separation of concerns" mentioned earlier, and in this respect, Tailwind falls short. It's okay for CSS to have 1,000 lines if it has its own file, but a class with 1,000 words pollutes our HTML/JSX.&lt;/p&gt;

&lt;p&gt;There are third-party libraries like Tailwind Fold, but there's no native solution that resolves this 100% and is considered a good practice &lt;em&gt;(im looking to you &lt;a class="mentioned-user" href="https://dev.to/apply"&gt;@apply&lt;/a&gt;)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;With this article, I didn't intend to persuade you or provide a solution, but rather to tell a story and help you understand that this kind of debate has occurred in the past.&lt;/p&gt;

&lt;p&gt;As George Santayana said, "Those who cannot remember the past are condemned to repeat it."&lt;/p&gt;

&lt;p&gt;Who knows, maybe in 10 years, Tailwind will also become one of the most famous ways to write CSS? Only time and its evolution will tell.&lt;/p&gt;

&lt;p&gt;Anyway, thank you for reading!&lt;br&gt;
Have a good day 😄&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>css</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>O problema com vh no mobile</title>
      <dc:creator>Nícolas Gabriel</dc:creator>
      <pubDate>Fri, 13 Oct 2023 20:58:25 +0000</pubDate>
      <link>https://dev.to/nickgabe/o-problema-com-vh-no-mobile-12jn</link>
      <guid>https://dev.to/nickgabe/o-problema-com-vh-no-mobile-12jn</guid>
      <description>&lt;p&gt;Olá, tudo bem? Sabe aquela coisa chata de quando você coloca um &lt;code&gt;min-height: 100vh&lt;/code&gt; no seu body e no mobile ele fica com um scroll sem nenhum motivo aparente? Realmente é uma coisa bem irritante e que antigamente era complicada de ser resolvida sem uma certa &lt;em&gt;"gambiarra"&lt;/em&gt;. Mas vamos começar do começo!&lt;/p&gt;

&lt;p&gt;Para caso não saiba, o "vh" do css é uma unidade relativa a 1% do viewport do usuário, porém essa viewport inclui todo o navegador, desconsiderando por exemplo elementos que possam estar cobrindo a tela (como é o caso de celulares)&lt;/p&gt;

&lt;p&gt;Por isso funciona no desktop, mas em mobile deixa um scroll!&lt;/p&gt;

&lt;p&gt;Já a medida "svh" é o equivalente a "small viewport height", ou seja 1% do menor viewport considerando justamente os elementos que possam cobrir a tela como a barra de endereços do mobile.&lt;/p&gt;

&lt;p&gt;Ou seja, perfeito pra celulares pois é muito mais preciso para o que o usuário vê!&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%2F86dvs5kwkxyg94tmbrim.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%2F86dvs5kwkxyg94tmbrim.png" alt="SVH" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Já o "lvh" (large viewport height) é o exato oposto, ele pega o maior viewport possível, desconsiderando a barra de endereços ou uma UI que possa estar cobrindo a tela.&lt;/p&gt;

&lt;p&gt;Para desktop ele funciona muito bem como pode imaginar, mas pra mobile depende do seu caso de uso. 🤔&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%2Fwrxiocwynfsqddpt6kq5.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%2Fwrxiocwynfsqddpt6kq5.png" alt="LVH" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Afinal, um é bom pra desktop e outro bom pra celular, eu teria que usar uma media query pra adaptar então??&lt;/p&gt;

&lt;p&gt;Não :D&lt;/p&gt;

&lt;p&gt;Felizmente também existe o "dvh" (dynamic viewport height) que se ajusta de acordo com o dispositivo, agindo tanto como svh ou dvh de acordo com o necessário.&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%2Fhxxjhdoup0plf61bdut1.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%2Fhxxjhdoup0plf61bdut1.png" alt="DVH" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entretanto alegria de pobre dura pouco, e eles ainda não estão disponíveis em todos os navegadores :(&lt;/p&gt;

&lt;p&gt;O firefox e IE por exemplo ainda não possuem suporte...&lt;/p&gt;

&lt;p&gt;Por isso, eu recomendo usar porém junto de um fallback! Se liga na dica:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/*
   primeiro você usa o fallback: vh
  */&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/*
    e em seguida, você usa a versão nova!
    pois caso ela não funcione, será ignorada e
    o vh informado anteriormente será usado no lugar
  */&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="n"&gt;dvh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;São propriedades super úteis e hoje em dia uma mão na roda pra evitar bugs de UI desnecessários :)&lt;/p&gt;

&lt;p&gt;E é isso, espero que tu tenha aprendido algo novo hoje!&lt;br&gt;
Obrigado por ler, boa sorte no css e até mais! :)&lt;/p&gt;

</description>
      <category>css</category>
      <category>braziliandevs</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>A base de Redux Toolkit e React Redux</title>
      <dc:creator>Nícolas Gabriel</dc:creator>
      <pubDate>Thu, 28 Sep 2023 22:08:28 +0000</pubDate>
      <link>https://dev.to/nickgabe/redux-toolkit-e-react-redux-2o9k</link>
      <guid>https://dev.to/nickgabe/redux-toolkit-e-react-redux-2o9k</guid>
      <description>&lt;p&gt;Está querendo aprender Redux num ambiente js ou react e ainda não sabe por onde começar? &lt;br&gt;
Neste artigo eu vou explicar os conceitos junto do código de forma direta para fazer você entender melhor na prática como ele funciona!&lt;/p&gt;
&lt;h2&gt;
  
  
  Tabela de conteúdos:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;O que é Redux?&lt;/li&gt;
&lt;li&gt;Store, a raiz da nossa árvore de estados&lt;/li&gt;
&lt;li&gt;Criar coleções usando Slices&lt;/li&gt;
&lt;li&gt;Ler valores com Selector&lt;/li&gt;
&lt;li&gt;Criando a lógica para alterar valores com Reducers&lt;/li&gt;
&lt;li&gt;Alterando valores usando Actions&lt;/li&gt;
&lt;li&gt;O fluxo final&lt;/li&gt;
&lt;li&gt;Finalização&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  O que é Redux?
&lt;/h3&gt;

&lt;p&gt;Primeiro vamos entender que Redux é uma biblioteca de gerenciamento de estados de forma mais "global" do que os estados que temos convencionalmente no React por exemplo. Ele facilita com que diversas áreas da aplicação possam interagir entre si e centralizar sua informação.&lt;/p&gt;
&lt;h3&gt;
  
  
  Store, a raiz da nossa árvore de estados
&lt;/h3&gt;

&lt;p&gt;No Redux, o que engloba todos esses estados globais nós chamamos de "store". Pra caso tu já tenha usado, é como um provider da &lt;a href="https://www.devmedia.com.br/react-js-passando-dados-com-context-api/42904" rel="noopener noreferrer"&gt;Context API&lt;/a&gt; do React.&lt;/p&gt;

&lt;p&gt;Aqui vou criar um objeto chamado store, para você tentar pegar uma ideia de como isso é representado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// apenas uma representação visual pra assimilar melhor:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// por enquanto&lt;/span&gt;
  &lt;span class="c1"&gt;// ela está vazia&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// exemplo real&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;configureStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@reduxjs/toolkit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// em breve vamos adicionar as propriedades aqui&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criar coleções usando Slices
&lt;/h3&gt;

&lt;p&gt;Indo de fora pra dentro, na nossa store nós podemos criar "slices", que são coleções nas quais contém dados. Cada slice é nomeado, e esse nome é utilizado para acessar os seus dados mais pra frente. A mesma lógica serve para um objeto:&lt;/p&gt;

&lt;p&gt;Vamos adicionar por exemplo um slice de configurações pra armazenar as coisas do nosso usuário:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// apenas uma representação visual pra assimilar melhor:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;configuracoes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;tema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;escuro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;notificacoes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// exemplo real&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createSlice&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@reduxjs/toolkit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;configuracoesSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;configuracoes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// este é o estado inicial, aqui você insere propriedades&lt;/span&gt;
  &lt;span class="c1"&gt;// que devem ser inicializadas com este slice logo de cara&lt;/span&gt;
  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;tema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;claro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;notificacoes&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ler valores com Selector
&lt;/h3&gt;

&lt;p&gt;Ok Ok, até aí tudo bem, mas como nós podemos ler o valor guardado no slice? É igual um objeto &lt;code&gt;store.configuracoes.tema&lt;/code&gt;?&lt;br&gt;
Não é tão simples assim, mas no contexto de React nós chamamos isso de Selector, que é quando você vai extrair um dado de dentro da store. No contexto JS isso é apenas uma leitura normal &lt;em&gt;(selector pode acabar confundindo com querySelector)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Existe a forma "nativa" de se pegar o valor, e existe a forma usada na biblioteca "react-redux", vou deixar ambos os exemplos aqui:&lt;/p&gt;

&lt;p&gt;Usando apenas o &lt;code&gt;redux toolkit&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;configuracoes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tema&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usando &lt;code&gt;react-redux&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Provider&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="cm"&gt;/*
  OBS: Pra usar o React-Redux, você precisa primeiro
  adicionar o Provider dele à sua aplicação:
*/&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      // ...seus componentes  
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Agora sim você pode ler o valor&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;componente&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configuracoes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tema&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criando a lógica para alterar valores com Reducers
&lt;/h3&gt;

&lt;p&gt;Perfeito, já temos configurado a nossa store, nosso slice e conseguimos ler nossos dados... porém atualmente eles estão fixos, como podemos fazer para modificar os valores?&lt;/p&gt;

&lt;p&gt;O que usamos para isso é o que chamamos de "Reducers", eles interagem com nossos slices para mudar os seus valores usando uma lógica definida por você. Inclusive tu pode até assimilar isso com o próprio &lt;a href="https://react.dev/reference/react/useReducer" rel="noopener noreferrer"&gt;useReducer&lt;/a&gt; do React, que também  usa uma lógica customizada para definir um valor.&lt;/p&gt;

&lt;p&gt;Vamos criar alguns reducers e atualizar a store para listar eles!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;configuracoesSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// propriedades mencionadas acima...&lt;/span&gt;
  &lt;span class="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// state é o slice atual&lt;/span&gt;
    &lt;span class="c1"&gt;// action.payload é o valor recebido&lt;/span&gt;
    &lt;span class="na"&gt;setarTema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;setarNotificacoes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notificacoes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&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="c1"&gt;// Agora que temos os reducers criados, precisamos&lt;/span&gt;
&lt;span class="c1"&gt;// atualizar a store pra incluir eles!&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;configuracoesSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Alterando valores usando Actions
&lt;/h3&gt;

&lt;p&gt;Com os reducers criados, podemos usá-los pra alterar os valores do nosso slice! Isso é o que vamos chamar de "Action".&lt;/p&gt;

&lt;p&gt;A action executa um reducer e lhe fornece um resultado, daí você precisa executar um dispatch para que o resultado seja persistido &lt;em&gt;(salvo)&lt;/em&gt; na nossa store.&lt;/p&gt;

&lt;p&gt;Novamente, mostrarei a forma nativa / react-redux&lt;/p&gt;

&lt;p&gt;Usando apenas &lt;code&gt;redux toolkit&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Use o dispatch para salvar a modificação&lt;/span&gt;
&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="c1"&gt;// Use a action passando o novo valor&lt;/span&gt;
  &lt;span class="nx"&gt;configuracoesSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setarTema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;escuro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usando &lt;code&gt;react-redux&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useDispatch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Componente&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDispatch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
  &lt;span class="c1"&gt;// O ato de salvar com dispatch continua igual, mas&lt;/span&gt;
  &lt;span class="c1"&gt;// ao invés de vir da store, ele vem do react-redux&lt;/span&gt;
  &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;configuracoesSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setarTema&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;escuro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  O fluxo final
&lt;/h3&gt;

&lt;p&gt;Já cobrimos muitos tópicos da base de como se utilizar Redux Toolkit e também React Redux, mas queria te fazer uma pergunta: Acabou de notar que fizemos um CRUD?&lt;/p&gt;

&lt;p&gt;Pois nós conseguimos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Criar dados usando Slices&lt;/li&gt;
&lt;li&gt;Ler os dados usando Selectors&lt;/li&gt;
&lt;li&gt;Atualizar por meio de Reducers/Actions&lt;/li&gt;
&lt;li&gt;&lt;em&gt;E também dá pra deletar com reducers&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com essas informações agora conseguimos entender este diagrama que exemplifica o fluxo de dados do Redux:&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%2Fdpo6ok8l0hr8u41cx4rd.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%2Fdpo6ok8l0hr8u41cx4rd.png" alt="Imagem que diz o ciclo do Redux&amp;lt;br&amp;gt;
View/UI -&amp;gt; dispatch -&amp;gt; action -&amp;gt; reducers -&amp;gt; store -&amp;gt; subscribe -&amp;gt; View/UI" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com os métodos ensinados neste artigo você deve conseguir se dar bem com o Redux, mas caso queira checar melhor a implementação feita neste artigo, vou disponibilizar ambos os arquivos finais para uma consulta mais fácil:&lt;/p&gt;

&lt;p&gt;Arquivo final usando apenas &lt;code&gt;redux toolkit&lt;/code&gt;: &lt;a href="https://gist.github.com/Nick-Gabe/755b76d8e87f0731e4cd62f8b47c9aa7" rel="noopener noreferrer"&gt;Gist&lt;/a&gt;&lt;br&gt;
Arquivo final usando &lt;code&gt;react-redux&lt;/code&gt;: &lt;a href="https://gist.github.com/Nick-Gabe/b7294b9d27bb2dd01622af766aa41879" rel="noopener noreferrer"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ambos estão fazendo a mesma coisa, porém em ambientes diferentes! O primeiro sendo um javascript comum, enquanto o segundo é num ambiente React.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finalização
&lt;/h3&gt;

&lt;p&gt;E é isso pessoal! Agora vocês já sabem o kit de sobrevivência pra Redux Toolkit e também React Redux!&lt;br&gt;
Espero ter te ajudado de alguma forma, e sinta-se livre para deixar comentários de dúvidas ou feedback :)&lt;/p&gt;

&lt;p&gt;Eu sempre falo de programação no &lt;a href="https://twitter.com/ImNickGabe" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, se quiser acompanhar meu conteúdo, welcome!&lt;/p&gt;

&lt;p&gt;👋 Até uma próxima.&lt;/p&gt;

</description>
      <category>redux</category>
      <category>react</category>
      <category>braziliandevs</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to use serverless functions on Netlify (JS/TS)</title>
      <dc:creator>Nícolas Gabriel</dc:creator>
      <pubDate>Mon, 20 Jun 2022 14:20:18 +0000</pubDate>
      <link>https://dev.to/nickgabe/how-to-use-serverless-functions-on-netlify-jsts-olj</link>
      <guid>https://dev.to/nickgabe/how-to-use-serverless-functions-on-netlify-jsts-olj</guid>
      <description>&lt;p&gt;&lt;strong&gt;Repository created in this blog: &lt;a href="https://github.com/Nick-Gabe/netlify-functions-tutorial" rel="noopener noreferrer"&gt;netlify-functions-tutorial&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
When trying to use Serverless Functions on Netlify I really struggled to understand how it works and how to use it, even with videos, blogs... So taking in mind my mistakes and doubts I decided to create this article for you, developer, that may be interested but doesn't know how or even why using it.&lt;/p&gt;

&lt;p&gt;So, first of all there's always a question...&lt;/p&gt;
&lt;h2&gt;
  
  
  Why should I use Netlify Functions?
&lt;/h2&gt;

&lt;p&gt;Netlify is a website hosting service, but it only hosts our front-end, while our back-end must be hosted anywhere else. And that usually is what you do, but if I'm just planning to build a small project that would be like filling a cup of water with an ocean, there is no need for that.&lt;/p&gt;

&lt;p&gt;Netlify Functions comes to solve this problem, you can keep your back and front-end together by using Functions that can be called just like a back-end api. And it makes the code easier to edit since it's all in one folder.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- Ok ok Nick, I understood, but how do I use that thing?&lt;/em&gt;&lt;br&gt;
Good question, I'll divide the answer in two separate topics: How to implement it using Javascript and how to implement it using Typescript.&lt;/p&gt;
&lt;h2&gt;
  
  
  Serverless with Javascript
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Install netlify-cli&lt;/strong&gt;&lt;br&gt;
Im presuming you already created a folder to your project, so before continuing we must install a package into it.&lt;br&gt;
To install, execute this command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;netlify&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;cli&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create a folder for your functions&lt;/strong&gt;&lt;br&gt;
So, to begin we need to create a folder for our functions, its name can be anything you want, but for the purpose of this blog I'll name mine as "functions".&lt;br&gt;
If you already installed the &lt;code&gt;netlify-cli&lt;/code&gt; package your folder must be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; functions
&amp;gt; node-modules
package.json
package-lock.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Create netlify.toml&lt;/strong&gt;&lt;br&gt;
Now we'll specify to Netlify where our functions are, and to do that, we need to create a file called &lt;code&gt;netlify.toml&lt;/code&gt;.&lt;br&gt;
Inside it you should write this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[build]
  functions = "./functions"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "./functions" is the path to your functions folder, so remember to replace that if you put another name or in a different place than the root directory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Set the redirects&lt;/strong&gt;&lt;br&gt;
The base url for acessing your functions is &lt;code&gt;localhost:8888/.netlify/functions/functionname&lt;/code&gt; but that's a really long and unnecessary url, so I like to set up a redirect in my projects.&lt;br&gt;
To do that you must create a file called &lt;code&gt;_redirects&lt;/code&gt;&lt;em&gt;(without extension)&lt;/em&gt; and put this code inside it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/* /.netlify/functions/:splat 200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;/api/*&lt;/code&gt; will be our new url to acess the functions, meaning that now we can acess &lt;code&gt;localhost:8888/api/functionname&lt;/code&gt;. The &lt;code&gt;/.netlify/functions/:splat&lt;/code&gt; is the url it will be redirected to, replacing the &lt;code&gt;:splat&lt;/code&gt; with the function you inserted. And &lt;code&gt;200&lt;/code&gt; is just the status code that will be returned to the redirect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Creating functions&lt;/strong&gt;&lt;br&gt;
This is the last step we need. The function I will create is just an example, but feel free to expand it however you want.&lt;/p&gt;

&lt;p&gt;Let's create a file called "helloworld.js" &lt;strong&gt;inside&lt;/strong&gt; our functions folder.&lt;br&gt;
The first code we will insert is basically an export, this way Netlify can retrieve the function and execute it when you or someone acesses the api url.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want and know how to it, you can change how you export it, but keep in mind you can't change the "handler" name, else the function will not be readable.&lt;/p&gt;

&lt;p&gt;In our function my plan is to return a string with a message. If the user sends a "name" to our api, it will send "Hello name!", if not, then it sends "Hello world!". Pretty simple concept, let's do it!&lt;/p&gt;

&lt;p&gt;We will pick the name from the query string parameters. They are specified after a "?" in the url, with a key=value.&lt;br&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%2Fia2bze45rwdg78nc44pq.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%2Fia2bze45rwdg78nc44pq.png" alt="Query String Parameters Example" width="653" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I created a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment" rel="noopener noreferrer"&gt;destructuring&lt;/a&gt; that picks elements from the event parameters, and then a variable "message" with a string that can be either "Hello name!" or "Hello world!"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryStringParameters&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, now we need to send back the answer to our requisition, and to do that we only need to return an object, containing a body &lt;em&gt;(The data we want to send back)&lt;/em&gt; and a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status" rel="noopener noreferrer"&gt;status code&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryStringParameters&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Amazing! It's done!&lt;/strong&gt; To test your API just run the command &lt;code&gt;netlify dev&lt;/code&gt; in your terminal. It will say the functions that were loaded and also the server being used &lt;em&gt;(in my case "localhost:8888")&lt;/em&gt;&lt;br&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%2F70m747r0f7kvygh8r6fc.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%2F70m747r0f7kvygh8r6fc.png" alt="Netlify Dev Command Example" width="738" height="309"&gt;&lt;/a&gt;&lt;br&gt;
If you go in your browser and enter the url &lt;code&gt;localhost:8888/api/helloworld&lt;/code&gt; you should receive a string containing "hello world" just like this:&lt;br&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%2F28n162skydoy4xpfdwem.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%2F28n162skydoy4xpfdwem.png" alt="Hello world" width="455" height="105"&gt;&lt;/a&gt;&lt;br&gt;
If you insert your name as a parameter in the url like this: &lt;code&gt;localhost:8888/api/helloworld?name=Nick&lt;/code&gt;, it will return a different response:&lt;br&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%2Fboev7pw7x2ffhxujf84z.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%2Fboev7pw7x2ffhxujf84z.png" alt="Hello Nick" width="439" height="85"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To gather that data from the front-end you simply need to do a local request, an example would be &lt;code&gt;fetch("/api/helloworld")&lt;/code&gt;, since both front and back run on the same host.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Bonus: Sending JSON's&lt;/strong&gt;&lt;br&gt;
For most cases you don't want to return just a string, instead you want to return a &lt;a href="https://www.w3schools.com/js/js_json_intro.asp" rel="noopener noreferrer"&gt;JSON&lt;/a&gt;, basically an object that can be readed by the browser. And the implementation is really straighforward, you just need to send your response body as a JSON.stringify().&lt;br&gt;
Look at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryStringParameters&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of returning a string, this time we will return a JSON of an object containing a property called "data" that contains our message.&lt;br&gt;
If we enter the url again...&lt;br&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%2F2t5siv6w2za9txhdr13b.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%2F2t5siv6w2za9txhdr13b.png" alt="JSON" width="437" height="204"&gt;&lt;/a&gt; &lt;br&gt;
Awesome, it worked! With Netlify Functions you can create anything you want, from token authorizations, database modifications...&lt;/p&gt;
&lt;h2&gt;
  
  
  Serverless with Typescript
&lt;/h2&gt;

&lt;p&gt;The process is almost the same as Javascript, with the only exceptions being the function creation and some packages you need to install.&lt;br&gt;
Along with the &lt;code&gt;netlify-cli&lt;/code&gt; you installed before, you need to install &lt;code&gt;@netlify-functions&lt;/code&gt; to get the function types. To do it, just run this in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;netlify&lt;/span&gt;&lt;span class="sr"&gt;/functions --de&lt;/span&gt;&lt;span class="err"&gt;v
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we'll adapt the previous Javascript function we created into a Typescript function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// I imported the "Handler" type to use in the function&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Handler&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@netlify/functions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Created a variable called handler, with the type Handler&lt;/span&gt;
&lt;span class="c1"&gt;// and being an asynchronous function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This code is almost the same, I only added a&lt;/span&gt;
  &lt;span class="c1"&gt;// nullish verification in the query parameters&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;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queryStringParameters&lt;/span&gt; &lt;span class="o"&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;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Hello &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&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="c1"&gt;// Instead of using module exports, we will&lt;/span&gt;
&lt;span class="c1"&gt;// use export { handler }, and just as javascript,&lt;/span&gt;
&lt;span class="c1"&gt;// handler is a reserved word, other names will not be readed&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it, every file you create will be a new endpoint.&lt;br&gt;
I don't explained Typescript detailed as Javascript simply because the process is almost the same, and it would be kind of redundant to do so.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ending
&lt;/h2&gt;

&lt;p&gt;This took me some hours to write, I hope I helped you, but if there's still any questions, feel free to DM me on &lt;a href="https://twitter.com/MyNickIsNick_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and I will try to help in your specific case :).&lt;br&gt;
Also I don't write too many articles, but anyways, see ya!&lt;/p&gt;

</description>
      <category>netlify</category>
      <category>serverless</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Como criar um README dinâmico usando Javascript</title>
      <dc:creator>Nícolas Gabriel</dc:creator>
      <pubDate>Wed, 23 Mar 2022 19:50:07 +0000</pubDate>
      <link>https://dev.to/nickgabe/como-criar-um-readme-dinamico-usando-javascript-4mhg</link>
      <guid>https://dev.to/nickgabe/como-criar-um-readme-dinamico-usando-javascript-4mhg</guid>
      <description>&lt;p&gt;&lt;strong&gt;Olá! Você já pensou como seria poder gerar um README dinamicamente para aquele seu projeto do GitHub?&lt;/strong&gt;&lt;br&gt;
Eu já, mas nunca pensei em como funcionaria... até eu pesquisar se era possível e acabar me surpreendendo.&lt;/p&gt;

&lt;p&gt;Depois de algumas pesquisas descobri uma feature do GitHub chamada "GitHub Actions", e ela consegue executar um código que você especificar, em diversas situações como: após um push, pull-request, e até mesmo em um intervalo especificado. Isso era justamente o que eu precisava, e com essa feature em mãos comecei a escrever meu Javascri- calma...&lt;/p&gt;

&lt;p&gt;...Como isso é um guia, melhor eu documentar como fiz e como você também pode fazer e utilizar de diversas maneiras como quiser. Então vamos começar pelo começo:&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Criando uma base
&lt;/h2&gt;

&lt;p&gt;Gerar um markdown direto do Javascript &lt;em&gt;não é tão prático assim&lt;/em&gt;, pois para visualizar você precisaria executar o Javascript, e repetir isso para cada mudança definitivamente não é viável a longo prazo &lt;em&gt;(vamos ignorar o nodemon)&lt;/em&gt;. Por isso eu recomendo criar um &lt;strong&gt;arquivo base em markdown&lt;/strong&gt;, e modificá-lo usando Javascript, ao invés de gerá-lo por completo.&lt;/p&gt;

&lt;p&gt;Como exemplo, &lt;strong&gt;vou criar um novo repositório&lt;/strong&gt; no GitHub e disponibilizarei ao final do blog. Então vamos começar por essa base em markdown (que nomeei como "readme_base"), definindo nela as informações que serão fixas, e quais serão geradas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# %{titulo}&lt;/span&gt;
Eu coloquei o titulo dentro de &lt;span class="sb"&gt;`%{}`&lt;/span&gt; apenas para evitar que
haja alguma ambiguidade com textos comuns.

Todas as partes desta base podem ser manipuladas e modificadas,
por exemplo aqui eu irei inserir uma lista de nomes:
%{listaDeNomes}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Modificando a base
&lt;/h2&gt;

&lt;p&gt;Para testamos se está tudo funcionando, vamos criar um arquivo em Javascript, no qual nomearei como "index.js", para modificar a base:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* o fs é quem irá ler o arquivo e gerar um novo,
ele vem por padrão no node, então não se preocupe */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&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;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// esta parte lê o arquivo "README_BASE"&lt;/span&gt;
&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;README_BASE.md&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* aqui é onde acontecem as substituições, por exemplo
substituindo %{titulo} por "Dynamic Readme" */&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;substituicoes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;titulo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Dynamic Readme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;listaDeNomes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`- Carlos\n- Ana\n- Sérgio`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* aqui é o que verifica e executa as substituições, um
regex bem simples com object literals, não precisa mexer aqui */&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modificado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sr"&gt;/%{.*}/gm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;substituicoes&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="cm"&gt;/* após ter feito as mudanças ele cria um arquivo
chamado "README.md" com a nova versão */&lt;/span&gt;
    &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;README.md&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;modificado&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;✔ Processo finalizado!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este código será executado via node, então &lt;strong&gt;sinta-se livre para adicionar o que quiser&lt;/strong&gt;, sejam pacotes, requisições em apis, gerar imagens, está em suas mãos.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Automatizando o processo
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;"Mas isso apenas gerou o arquivo pois fui eu quem iniciou o javascript, então para executar esse processo automaticamente eu precisaria de um host?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Felizmente não&lt;/strong&gt;, pois no caso do GitHub ele disponibiliza o github actions no qual eu havia falado. Ela permite que o processo rode em diversas circunstâncias, e no caso deste exemplo usarei o &lt;code&gt;schedule&lt;/code&gt; que permite que o código seja executado a cada intervalo especificado.&lt;/p&gt;

&lt;p&gt;Para isso iremos criar uma pasta chamada &lt;code&gt;.github&lt;/code&gt;, e dentro dela uma outra chamada &lt;code&gt;workflows&lt;/code&gt;, com um arquivo &lt;code&gt;main.yaml&lt;/code&gt;.&lt;br&gt;
Resumindo: &lt;code&gt;.github/workflows/main.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No arquivo main.yaml é onde diremos ao github &lt;strong&gt;quando, como e o quê rodar.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Nome do processo&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Update automático&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# cron é o "intervalo" de execução, recomendo usar&lt;/span&gt;
    &lt;span class="c1"&gt;# o site crontab.guru para lhe ajudar a definir.&lt;/span&gt;
    &lt;span class="c1"&gt;# nesse caso aqui, ele irá rodar a cada 10 minutos.&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;cron&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;*/10&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;*'&lt;/span&gt;

&lt;span class="c1"&gt;# Aqui vem os passos que a ação segue&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Inicia uma máquina virtual ubuntu&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="c1"&gt;# Checa o código atual do repositório&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repo&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="c1"&gt;# Instala o node na versão 16.10&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Use Node.js&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v1&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16.10&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build --if-present&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;CI&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

    &lt;span class="c1"&gt;# Aqui em index.js você insere&lt;/span&gt;
    &lt;span class="c1"&gt;# o nome do seu arquivo javascript&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Roda o arquivo&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
        &lt;span class="s"&gt;node index.js&lt;/span&gt;
        &lt;span class="s"&gt;cat README.md&lt;/span&gt;

    &lt;span class="c1"&gt;# E no final commita e faz um push caso haja alguma diferença&lt;/span&gt;
    &lt;span class="c1"&gt;# comparada ao código atual do repositório&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Commit e push&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
        &lt;span class="s"&gt;git diff&lt;/span&gt;
        &lt;span class="s"&gt;git config --global user.email "bot-readme@example.com"&lt;/span&gt;
        &lt;span class="s"&gt;git config --global user.name "bot automático"&lt;/span&gt;
        &lt;span class="s"&gt;git add -A&lt;/span&gt;
        &lt;span class="s"&gt;git commit -m "Arquivo atualizado!" || exit 0&lt;/span&gt;
        &lt;span class="s"&gt;git push&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso feito, sua pasta/repositório deve estar mais ou menos assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; .github
  &amp;gt; workflows
    &amp;gt; main.yaml
&amp;gt; index.js
&amp;gt; readme_base.md
&amp;gt; README.md (gerado)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se estiver assim, perfeito, tá tudo certo. Casos os nomes estejam diferentes ou não tenha gerado o README ainda, tá tudo bem também.&lt;/p&gt;

&lt;p&gt;Mas só avisando que caso você mande tudo pro GitHub, e em 10 minutos seu repositório não atualize, &lt;em&gt;calma&lt;/em&gt;. &lt;strong&gt;O GitHub Actions nem sempre é imediato&lt;/strong&gt;, algumas vezes leva mais tempo do que o especificado. Por exemplo no meu teste desse repositório, apesar de eu especificar 10 minutos levou 25 😅.&lt;/p&gt;

&lt;p&gt;Você pode acompanhar as actions por aqui, sempre que uma for executada ela irá aparecer:&lt;br&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%2F8ar3u99uur84gpwc19a6.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%2F8ar3u99uur84gpwc19a6.png" alt="Actions page" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E falando no repositório, &lt;strong&gt;aqui está o link pra ele&lt;/strong&gt;: &lt;a href="https://github.com/Nick-Gabe/dynamic-readme" rel="noopener noreferrer"&gt;Dynamic Readme&lt;/a&gt;. Se quiser pode fazer um fork e modificar ou seguir este tutorial, como preferir.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. O final
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Opa! Gostou do blog?&lt;/strong&gt; É o meu primeiro, mas tentei deixar ele completo e simples de se entender, espero ter conseguido ^^.&lt;/p&gt;

&lt;p&gt;E não pensa que dá pra fazer só essas coisinhas de trocar texto por texto não! No &lt;a href="https://github.com/Nick-Gabe/Nick-Gabe" rel="noopener noreferrer"&gt;meu readme&lt;/a&gt; eu fiz uma seção que atualiza mostrando minhas atividades mais recentes, e até gera uma imagem utilizando a api do github para pegar um seguidor aleatório meu!&lt;br&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%2Fa2nxpf63ju91qmlurvnd.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%2Fa2nxpf63ju91qmlurvnd.png" alt="Sample" width="670" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tô ansioso pra ver o que vocês também conseguem criar.&lt;br&gt;
Me marca no Twitter caso faça algo bacana com isso. 'Inté!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>github</category>
      <category>tutorial</category>
      <category>markdown</category>
    </item>
  </channel>
</rss>
