<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Gustavo</title>
    <description>The latest articles on Forem by Gustavo (@dantas).</description>
    <link>https://forem.com/dantas</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%2F675107%2Ff055c60a-ee9b-4e73-8b63-27db4adb2d52.jpg</url>
      <title>Forem: Gustavo</title>
      <link>https://forem.com/dantas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dantas"/>
    <language>en</language>
    <item>
      <title>Stop building for scale. Start building for users.</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Fri, 05 Sep 2025 15:20:18 +0000</pubDate>
      <link>https://forem.com/dantas/stop-building-for-scale-start-building-for-users-51cm</link>
      <guid>https://forem.com/dantas/stop-building-for-scale-start-building-for-users-51cm</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/shayy" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F2711665%2Fe528db00-6ac0-4654-b0d5-c68d84ed332e.png" alt="shayy"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/shayy/stop-building-for-scale-you-dont-have-users-yet-4aep" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Stop Building for "Scale." You Don't Have Users Yet.&lt;/h2&gt;
      &lt;h3&gt;Shayan ・ Sep 4&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>ai</category>
    </item>
    <item>
      <title>Great post if you have a spare Android phone laying around</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Fri, 13 Jun 2025 11:51:15 +0000</pubDate>
      <link>https://forem.com/dantas/great-post-if-you-have-a-spare-android-phone-laying-around-3jhc</link>
      <guid>https://forem.com/dantas/great-post-if-you-have-a-spare-android-phone-laying-around-3jhc</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/quave/hosting-web-app-on-your-old-android-phone-54bg" class="crayons-story__hidden-navigation-link"&gt;Hosting web app on your old Android phone&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/quave"&gt;
            &lt;img alt="Quave logo" 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%2Forganization%2Fprofile_image%2F9429%2F14d24107-7f23-4ea0-b4a2-7389a1119c20.png" class="crayons-logo__image"&gt;
          &lt;/a&gt;

          &lt;a href="/guilhermesaraujo" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&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%2Fuser%2Fprofile_image%2F2143656%2Fc4199492-32c9-429f-adb7-9074bc41cd9c.jpeg" alt="guilhermesaraujo profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/guilhermesaraujo" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Guilherme Araujo
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Guilherme Araujo
                
              
              &lt;div id="story-author-preview-content-2325383" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/guilhermesaraujo" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F2143656%2Fc4199492-32c9-429f-adb7-9074bc41cd9c.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Guilherme Araujo&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/quave" class="crayons-story__secondary fw-medium"&gt;Quave&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/quave/hosting-web-app-on-your-old-android-phone-54bg" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 20 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/quave/hosting-web-app-on-your-old-android-phone-54bg" id="article-link-2325383"&gt;
          Hosting web app on your old Android phone
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/quave/hosting-web-app-on-your-old-android-phone-54bg" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;15&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/quave/hosting-web-app-on-your-old-android-phone-54bg#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>android</category>
      <category>howto</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Automatizando requisições que exigem autenticação no Postman com pre-requests</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Tue, 20 May 2025 19:17:24 +0000</pubDate>
      <link>https://forem.com/dantas/automatizando-requisicoes-que-exigem-autenticacao-no-postman-com-pre-requests-3f4i</link>
      <guid>https://forem.com/dantas/automatizando-requisicoes-que-exigem-autenticacao-no-postman-com-pre-requests-3f4i</guid>
      <description>&lt;p&gt;No Postman, como você testa as rotas da sua API REST ou as queries da sua API GraphQL que precisam de autenticação JWT? Você provavelmente cria uma rota/mutation para login e depois copia o token e coloca no header de &lt;code&gt;authorization&lt;/code&gt;, certo? Nesse post eu vou te mostrar como você pode fazer todo esse processo de forma automatizada, seja em uma API REST ou GraphQL 🚀&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Caso tenha algum problema, veja esta seção.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Criando variáveis
&lt;/h2&gt;

&lt;p&gt;Primeiro, precisamos ter variáveis para usar como Bearer Token na requisição/mutation.&lt;/p&gt;

&lt;p&gt;Criar uma variável é bem simples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clique na sua collection criada (seu projeto) no Postman&lt;/li&gt;
&lt;li&gt;Vá para a seção variables e crie a variável:&lt;/li&gt;
&lt;/ol&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%2Fgxr3s6fyt89n6qk5028f.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%2Fgxr3s6fyt89n6qk5028f.png" width="708" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando scripts
&lt;/h2&gt;

&lt;p&gt;Primeiro, você precisa criar um request/mutation que seja responsável por retornar um &lt;code&gt;token&lt;/code&gt; que será utilizado. Por exemplo:&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%2F2egl0do6y6lipnp866vy.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%2F2egl0do6y6lipnp866vy.png" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora na request/mutation, vá para a seção &lt;code&gt;scripts&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Script para query GraphQL
&lt;/h3&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3000/graphql&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;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&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;header&lt;/span&gt; &lt;span class="o"&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;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;application/json&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;graphqlMutation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        mutation UserSignIn($email: String!, $password: String!) {
            userSignIn(input: { 
                email: $email, 
                password: $password 
            }) {
                token
                error {
                    field
                    message
                }
            }
        }
    `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postman_user@test.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pass123&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;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendRequest&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="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;header&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="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;raw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;raw&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;graphqlMutation&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="nx"&gt;err&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="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="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="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&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;json&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&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;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;GraphQL Errors:&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;response&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="nx"&gt;userSignIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&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;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;Authentication Error:&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userSignIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collectionVariables&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;bearerToken&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userSignIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;token&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;
  
  
  Script para API Rest
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`http://localhost:3000/auth`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="o"&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;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;application/json&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;seu_login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sua_senha&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;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendRequest&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="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;header&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="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;raw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;raw&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;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="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;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="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="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;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;environment&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;bearerToken&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;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;access_token&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;h2&gt;
  
  
  Mais algumas palavrinhas - troubleshooting e ajuda
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tenha em mente que os requests foram feitos de acordo com o meu schema, adapte-o para o seu caso de uso.

&lt;ul&gt;
&lt;li&gt;Você pode ver como eu adaptei para o meu projeto &lt;a href="https://github.com/gustav0d/wbonk?tab=readme-ov-file#postman" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Caso precise debuggar o próprio postman, você pode utilizar &lt;code&gt;Ctrl+Alt+C&lt;/code&gt; para abrir o console&lt;/li&gt;

&lt;li&gt;Caso precise de ajuda, você pode:

&lt;ul&gt;
&lt;li&gt;Dar uma olhada neste &lt;a href="https://blog.postman.com/powerful-debugging-with-the-postman-console/" rel="noopener noreferrer"&gt;post do Postman&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Comente aqui mesmo :)&lt;/li&gt;
&lt;li&gt;Entra em contato comigo em uma das &lt;a href="https://bento.me/dantas" rel="noopener noreferrer"&gt;minhas redes&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>postman</category>
      <category>api</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Migrando koa-graphql para grahpql-http</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Sun, 18 May 2025 21:10:49 +0000</pubDate>
      <link>https://forem.com/dantas/migrando-koa-graphql-para-grahpql-http-1kp8</link>
      <guid>https://forem.com/dantas/migrando-koa-graphql-para-grahpql-http-1kp8</guid>
      <description>&lt;p&gt;Recentemente eu desenvolvi o desafio da Woovi com Koa.js e GraphQL (&lt;a href="https://github.com/gustav0d/wbonk" rel="noopener noreferrer"&gt;link do projeto&lt;/a&gt;). Uma das especificações opcionais era o uso do &lt;code&gt;graphql-http&lt;/code&gt;, substituto do &lt;code&gt;koa-graphql&lt;/code&gt;, que está presente no &lt;a href="https://github.com/woovibr/woovi-playground" rel="noopener noreferrer"&gt;playground&lt;/a&gt; disponibilizado. No entanto, me deparei com alguns problemas iniciais: diversas funcionalidades não estavam presentes no &lt;code&gt;graphql-http&lt;/code&gt;, visto que ele é apenas uma &lt;a href="https://github.com/graphql/graphql-http#only-graphql-over-http" rel="noopener noreferrer"&gt;implementação do GraphQL sobre HTTP&lt;/a&gt;, isto é, é simples e minimalista. &lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução - Por quê? E alguns problemas
&lt;/h2&gt;

&lt;p&gt;Primeiro, por quê? Bom, principalmente, porque &lt;code&gt;koa-graphql&lt;/code&gt; foi &lt;a href="https://github.com/graphql-community/koa-graphql/issues/164" rel="noopener noreferrer"&gt;praticamente descontinuado&lt;/a&gt; e &lt;code&gt;graphql-http&lt;/code&gt; deve ser utilizado ao invés disso. Tomei esta decisão baseada em uma &lt;a href="https://github.com/graphql/graphql-http/discussions/95" rel="noopener noreferrer"&gt;discussão&lt;/a&gt; que inclusive recomendava o uso do &lt;code&gt;yoga&lt;/code&gt;, uma alternativa mais completa para servidores graphql, no entanto, eu vi que seria completamente capaz de resolver apenas com &lt;code&gt;graphql-http&lt;/code&gt;. Caso queira uma opção mais robusta, tente o &lt;a href="https://the-guild.dev/graphql/yoga-server/docs/integrations/integration-with-koa" rel="noopener noreferrer"&gt;Yoga&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Vamos aos problemas. Eu utilizava algumas funcionalidades interessantes já presentes no &lt;code&gt;koa-graphql&lt;/code&gt;, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;o uso de uma &lt;code&gt;customErrorFn&lt;/code&gt; para retornar erros do servidor de uma maneira específica, além de logar no console em ambientes de teste e desenvolvimento&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;graphiql&lt;/code&gt;: um playground GraphQL para fazer queries e mutations de maneira intuitiva pelo navegador&lt;/li&gt;
&lt;li&gt;alterar o &lt;code&gt;context&lt;/code&gt; da requisição, já que o projeto armazenava o usuário caso estivesse logado (por meio de token JWT)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Migrando para o graphql-http
&lt;/h2&gt;

&lt;p&gt;A primeira coisa a ser feita é remover &lt;code&gt;koa-graphql&lt;/code&gt; completamente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm un koa-graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E adicionar &lt;code&gt;graphql-http&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm i graphql-http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, é começar a adaptar as funcionalidades.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando o handler
&lt;/h3&gt;

&lt;p&gt;Seguindo o snippet que está presente no próprio README do &lt;code&gt;graphql-http&lt;/code&gt;, para criar o handler é bem simples, é só importar o &lt;code&gt;createHandler&lt;/code&gt; para o koa e passar o schema e o context:&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;createHandler&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;graphql-http/lib/use/koa&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;graphqlHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createHandler&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;context&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;ctx&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;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&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;Ok, o schema é a parte mais fácil, apenas passei o schema definido anteriormente. No entanto, tive alguns problemas com os tipos do &lt;code&gt;context&lt;/code&gt;, especialmente porque a forma de conseguir as informações do header são diferentes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adaptando os tipos do context
&lt;/h3&gt;

&lt;p&gt;No &lt;code&gt;get-context.ts&lt;/code&gt;, criei o tipo que deveria receber para o contexto:&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="kd"&gt;type&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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;graphql-http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IncomingMessage&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;node:http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RequestContext&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;graphql-http/lib/use/koa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RequestGraphQLContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IncomingMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RequestContext&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora para o &lt;code&gt;get-user.ts&lt;/code&gt;, antes eu simplesmente pegava o valor de &lt;code&gt;context.headers.authorization&lt;/code&gt;, mas agora a tipagem para o &lt;code&gt;headers&lt;/code&gt; é completamente diferente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;é preciso utilizar &lt;code&gt;context.headers.get&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get&lt;/code&gt; pode ser uma função, uma string, ou conter array no seu valor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Portanto, criei uma função para validar corretamente, o &lt;code&gt;get-graphql-http-headers.ts&lt;/code&gt;:&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;Request&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;graphql-http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;RequestContext&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;graphql-http/lib/use/koa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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;IncomingMessage&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;node:http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;HeaderKeyType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getGraphQLHttpHeaders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IncomingMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RequestContext&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;headerKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HeaderKeyType&lt;/span&gt;
&lt;span class="p"&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="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;ctx&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="kd"&gt;get&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ctx&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;headerKey&lt;/span&gt;&lt;span class="p"&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="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;headerKey&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="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;header&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="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&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;Agora, para conseguir o &lt;code&gt;authToken&lt;/code&gt;, basta utilizar a função criada:&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;authHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getGraphQLHttpHeaders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authorization&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;Schema e Context prontos! Agora faltam as funcionalidades: &lt;code&gt;graphiql&lt;/code&gt; e tratamento de erros.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tratamento de erros
&lt;/h3&gt;

&lt;p&gt;Agora ficou ainda mais simples! Não precisamos passar uma função para o handler novo, basta apenas adicionar um middleware!&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;// graphql error handling middleware&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;use&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;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&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;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&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;error&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;GraphQLError&lt;/span&gt;&lt;span class="p"&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;logEnvironments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&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="nx"&gt;error&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="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;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;locations&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="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;errors&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;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&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="na"&gt;locations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;locations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&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="k"&gt;else&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;error&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;h3&gt;
  
  
  GraphiQL - playground
&lt;/h3&gt;

&lt;p&gt;Aqui eu mudei um pouco a forma que o playground é acessado. Como ele é utilizado apenas em ambiente de desenvolvimento, resolvi utilizar o &lt;a href="https://github.com/graphile/crystal" rel="noopener noreferrer"&gt;&lt;code&gt;ruru&lt;/code&gt;&lt;/a&gt; e adicionar um script no package.json do server para acessá-lo. Para isto, ele pede que o pacote &lt;code&gt;ruru&lt;/code&gt; seja instalado, este inclusive pode ser utilizado em qualquer endpoint graphql disponível!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx ruru &lt;span class="nt"&gt;-SP&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 3001 &lt;span class="nt"&gt;-e&lt;/span&gt; http://localhost:3000/graphql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-p&lt;/code&gt; especifica a porta do playground&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-e&lt;/code&gt; especifica a rota para o servidr graphql&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Concluindo
&lt;/h2&gt;

&lt;p&gt;Acabou! Com isso, poupei alguns KBs:&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%2Far19qgv3hjv4ozoxu210.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%2Far19qgv3hjv4ozoxu210.png" alt="Comparação de tamanho entre os pacotes graphql-http e koa-graphql. O graphql-http possui 2,2 KB minificados e 1,0 KB quando compactado com Gzip. Já o koa-graphql tem 2987,3 KB minificados e 840,9 KB com Gzip. As informações são da fonte BundlePhobia, com links para GitHub e BundlePhobia disponíveis abaixo de cada pacote" width="450" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E, principalmente, atualizei para uma lib mais atualizada.&lt;/p&gt;

&lt;p&gt;No meu projeto no &lt;a href="https://github.com/gustav0d/wbonk" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; você pode visualizar exatamente como foi minha linha de pensamento visualizando a &lt;a href="https://github.com/gustav0d/wbonk/issues/13" rel="noopener noreferrer"&gt;issue&lt;/a&gt; e o &lt;a href="https://github.com/gustav0d/wbonk/pull/43" rel="noopener noreferrer"&gt;pull request&lt;/a&gt;. E outra: tem um bônus onde eu configurei o &lt;code&gt;graphiql&lt;/code&gt; em um app &lt;code&gt;react-router v7&lt;/code&gt; (antigo Remix), vale a pena dar uma olhada!&lt;/p&gt;

&lt;p&gt;Caso tenha alguma dúvida, não hesite em comentar ou me chamar em qualquer um dos meus &lt;a href="https://bento.me/dantas" rel="noopener noreferrer"&gt;links&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Meu projeto no GitHub: &lt;a href="https://github.com/gustav0d/wbonk" rel="noopener noreferrer"&gt;https://github.com/gustav0d/wbonk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/graphql/graphql-http/discussions/95" rel="noopener noreferrer"&gt;https://github.com/graphql/graphql-http/discussions/95&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Foto de &lt;a href="https://unsplash.com/pt-br/@afgprogrammer?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Mohammad Rahmani&lt;/a&gt; na &lt;a href="https://unsplash.com/pt-br/fotografias/uma-tela-de-computador-com-um-programa-em-execucao-3Sx3hSQcQIA?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>graphql</category>
    </item>
    <item>
      <title>My First Arch Linux Installation</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Wed, 12 Jun 2024 18:07:49 +0000</pubDate>
      <link>https://forem.com/dantas/my-first-arch-linux-installation-26le</link>
      <guid>https://forem.com/dantas/my-first-arch-linux-installation-26le</guid>
      <description>&lt;p&gt;During a specific vacation from college, I figured I should try installing Arch Linux just because I was curious (and I wanted to say I use Arch btw).&lt;/p&gt;

&lt;h2&gt;
  
  
  My expectations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Learn! Since it's the first time I'm installing Arch Linux in a physical machine, I want to learn as much as I can, and write them down as much as possible&lt;/li&gt;
&lt;li&gt;Minimal installation&lt;/li&gt;
&lt;li&gt;Disk encryption&lt;/li&gt;
&lt;li&gt;Snapshots&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What you should expect (disclaimer)
&lt;/h3&gt;

&lt;p&gt;This is not a tutorial (although I wrote it as a tutorial for me). This is just a report from my first time installing Arch in a physical computer.&lt;/p&gt;

&lt;p&gt;You can use it as a kickstart for your own Arch install, or just see how I take notes.&lt;/p&gt;

&lt;p&gt;Make sure to double check the information since they might not be completely up-to-date or outlined in a more simplistic way compared to the reality (always check the &lt;a href="https://wiki.archlinux.org/" rel="noopener noreferrer"&gt;Arch Wiki&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Anyways, if you have any doubt or suggestions, make sure you &lt;a href="https://www.dantas15.com/contact" rel="noopener noreferrer"&gt;reach me&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  First things first
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://archlinux.org/download/" rel="noopener noreferrer"&gt;Download&lt;/a&gt; the ISO&lt;/li&gt;
&lt;li&gt;Prepare an installation medium (I use &lt;a href="https://www.ventoy.net/en/index.html" rel="noopener noreferrer"&gt;Ventoy&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;You can change the keyboard layout as well. Layouts can be listed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;localectl list-keymaps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since my laptop is ABNT-2 (Brazil's default), I can change it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;loadkeys br-abnt2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, this is completely optional, but I like to change the font:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;setfont Lat2-Terminus16
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Network and Internet connection
&lt;/h3&gt;

&lt;p&gt;&lt;br&gt;
  In the installation image, &lt;a href="https://wiki.archlinux.org/title/Systemd-networkd" rel="noopener noreferrer"&gt;systemd-networkd&lt;/a&gt;,&lt;br&gt;
  &lt;a href="https://wiki.archlinux.org/title/Systemd-resolved" rel="noopener noreferrer"&gt;systemd-resolved&lt;/a&gt;, &lt;a href="https://wiki.archlinux.org/title/Iwd" rel="noopener noreferrer"&gt;iwd&lt;/a&gt; and&lt;br&gt;
  &lt;a href="https://wiki.archlinux.org/title/ModemManager" rel="noopener noreferrer"&gt;ModemManager&lt;/a&gt; are preconfigured and enabled by default.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Since I was using wired connection, I didn't need to setup anything, but, if it's not your case (something's not right or you're using wireless connection, check &lt;a href="https://wiki.archlinux.org/title/Iwd#iwctl" rel="noopener noreferrer"&gt;this&lt;/a&gt;).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To test if you're connected to the internet, ping any website:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ping archlinux.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  System clock
&lt;/h3&gt;

&lt;p&gt;Now it's time to check if everything is right running &lt;code&gt;timedatectl&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can list the timezones with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;timedatectl list-timezones
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then you can select your timezone, for example &lt;code&gt;America/Sao_Paulo&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;timedatectl set-timezone America/Sao_Paulo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Disk partitioning
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I strongly recommend you to disconnect other disks except for the one you'll be Installing Arch so you don't erase anything you didn't want to&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If there's any error, first check the &lt;a href="https://wiki.archlinux.org/title/Installation_guide#Partition_the_disks" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to see if any of the notes can help&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify the disk you'll be partitioning
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fdisk &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I'll be using &lt;code&gt;/dev/sda/&lt;/code&gt; but you should change it according to your case&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the &lt;code&gt;fdisk&lt;/code&gt; specifying the disk&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fdisk /dev/sda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If the device does not contain a recognized partition table, &lt;code&gt;fdisk&lt;/code&gt; &lt;a href="https://unix.stackexchange.com/questions/685924/fdisk-output-new-dos-disklabel" rel="noopener noreferrer"&gt;will automatically create a DOS (MBR) disklabel&lt;/a&gt;. Although it changes automatically to &lt;code&gt;gpt&lt;/code&gt; once you create a GPT partition, you can already start the disk with GPT using the &lt;code&gt;-t&lt;/code&gt; flag:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  fdisk &lt;span class="nt"&gt;-t&lt;/span&gt; gpt /dev/sda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming you're in fdisk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To create a &lt;a href="https://wiki.archlinux.org/title/Partitioning#Partition_table" rel="noopener noreferrer"&gt;partition table&lt;/a&gt;, type &lt;code&gt;g&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Now in order to create the boot partition, now type &lt;code&gt;n&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Select the first sector (kind of the starting point of the partition), the default (for the first partition) is 2048&lt;/li&gt;
&lt;li&gt;Select the last sector. There are a few tips on how to select them:&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;+&lt;/code&gt; symbol by the partition size&lt;/li&gt;
&lt;li&gt;The size can be specified in kibibytes (K), mebibytes (M), gibibytes (G), tebibytes (T), or pebibytes (P)&lt;/li&gt;
&lt;li&gt;Since it's the boot partition I'll set 1GiB with &lt;code&gt;+1G&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The default type for newly created partitions is &lt;code&gt;Linux Filesystem&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Since it's the boot partition, the type has to be changed. For that, type &lt;code&gt;t&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Then specify the type (type &lt;code&gt;L&lt;/code&gt; to list all available types)&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;EFI System&lt;/code&gt; type is &lt;code&gt;1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Repeat this process as needed in order to create the desired partitions

&lt;ul&gt;
&lt;li&gt;Personally, I just create another partition with the rest of the available space (all defaults)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;When you finish creating the partitions, type &lt;code&gt;w&lt;/code&gt; to write changes to the disk&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Create a FAT 32 system on the EFI partition (in my casse it's &lt;code&gt;/dev/sda1&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mkfs.fat &lt;span class="nt"&gt;-F&lt;/span&gt; 32 /dev/sda1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  System encryption
&lt;/h2&gt;

&lt;p&gt;Initialize encryption on the Linux Filesystem partition. It'll prompt a password to encrypt your system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cryptsetup &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; luksFormat /dev/sda2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Map &lt;code&gt;/dev/sda2&lt;/code&gt; to &lt;code&gt;/dev/mapper/cryptroot&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cryptsetup open /dev/sda2 root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  BTRFS parititioning and Swapfile
&lt;/h2&gt;

&lt;p&gt;Create BTRFS on the encrypted Linux Filesystem partition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mkfs.btrfs /dev/mapper/cryptroot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now mount it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mount /dev/mapper/cryptroot /mnt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;cd&lt;/code&gt; to &lt;code&gt;/mnt&lt;/code&gt; and create the subvolumes &lt;a href="https://wiki.archlinux.org/title/snapper#Suggested_filesystem_layout" rel="noopener noreferrer"&gt;as recommended&lt;/a&gt; for use with &lt;code&gt;snapper&lt;/code&gt; (a program I found on Cody Hou's Arch installation, reference below):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /mnt
btrfs subvolume create @
btrfs subvolume create @home
btrfs subvolume create @snapshots
btrfs subvolume create @var_log
btrfs subvolume create @swap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unmount &lt;code&gt;root&lt;/code&gt; and remount the subvolumes and the boot partition. &lt;a href="https://opensource.com/article/20/6/linux-noatime" rel="noopener noreferrer"&gt;noatime&lt;/a&gt; is used for better performance &lt;a href="https://github.com/facebook/zstd" rel="noopener noreferrer"&gt;zstd&lt;/a&gt; as file compression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd
&lt;/span&gt;umount /mnt
mount &lt;span class="nt"&gt;-o&lt;/span&gt; noatime,compress&lt;span class="o"&gt;=&lt;/span&gt;zstd,space_cache&lt;span class="o"&gt;=&lt;/span&gt;v2,subvol&lt;span class="o"&gt;=&lt;/span&gt;@ /dev/mapper/cryptroot /mnt
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /mnt/&lt;span class="o"&gt;{&lt;/span&gt;boot,home,.snapshots,var/log,swap&lt;span class="o"&gt;}&lt;/span&gt;
mount &lt;span class="nt"&gt;-o&lt;/span&gt; noatime,compress&lt;span class="o"&gt;=&lt;/span&gt;zstd,space_cache&lt;span class="o"&gt;=&lt;/span&gt;v2,subvol&lt;span class="o"&gt;=&lt;/span&gt;@home /dev/mapper/cryptroot /mnt/home
mount &lt;span class="nt"&gt;-o&lt;/span&gt; noatime,compress&lt;span class="o"&gt;=&lt;/span&gt;zstd,space_cache&lt;span class="o"&gt;=&lt;/span&gt;v2,subvol&lt;span class="o"&gt;=&lt;/span&gt;@snapshots /dev/mapper/cryptroot /mnt/.snapshots
mount &lt;span class="nt"&gt;-o&lt;/span&gt; noatime,compress&lt;span class="o"&gt;=&lt;/span&gt;zstd,space_cache&lt;span class="o"&gt;=&lt;/span&gt;v2,subvol&lt;span class="o"&gt;=&lt;/span&gt;@var_log /dev/mapper/cryptroot /mnt/var/log
mount &lt;span class="nt"&gt;-o&lt;/span&gt; noatime,subvol&lt;span class="o"&gt;=&lt;/span&gt;@swap /dev/mapper/cryptroot /mnt/swap
mount /dev/sda1 /mnt/boot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Make sure the swap subvolume is not being snapshoted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a &lt;a href="https://wiki.archlinux.org/title/Btrfs#Swap_file" rel="noopener noreferrer"&gt;swap file&lt;/a&gt;. Change the &lt;code&gt;count&lt;/code&gt; parameter in order to specify the size of the swap file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /mnt/swap
chattr +C /mnt/swap
&lt;span class="nb"&gt;dd &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/zero &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./swapfile &lt;span class="nv"&gt;bs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1M &lt;span class="nv"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8192 &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;progress
&lt;span class="nb"&gt;chmod &lt;/span&gt;0600 ./swapfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can install the &lt;a href="https://wiki.archlinux.org/title/Installation_guide#Install_essential_packages" rel="noopener noreferrer"&gt;essential packages&lt;/a&gt; in your system. (replace &lt;code&gt;intel-ucode&lt;/code&gt; with &lt;code&gt;intel-ucode&lt;/code&gt;if you're using an Intel processor):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pacstap &lt;span class="nt"&gt;-K&lt;/span&gt; /mnt base base-devel linux linux-firmware amd-ucode vim git networkmanager btrfs-progs dosfstools e2fsprogs exfat-utils ntfs-3g smartmontools dialog man-db man-pages texinfo pacman-contrib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring the system
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fstab
&lt;/h3&gt;

&lt;p&gt;Generate &lt;a href="https://wiki.archlinux.org/title/Fstab" rel="noopener noreferrer"&gt;fstab&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;genfstab &lt;span class="nt"&gt;-U&lt;/span&gt; /mnt &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /mnt/etc/fstab
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Chroot
&lt;/h3&gt;

&lt;p&gt;Change root into the system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;arch-chroot /mnt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Time
&lt;/h3&gt;

&lt;p&gt;Set the time zone accordingly (you can look in /usr/share/zoneinfo for your region and city):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-sf&lt;/span&gt; /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;hwclock&lt;/code&gt; to generate &lt;code&gt;/etc/adjtime&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hwclock &lt;span class="nt"&gt;--systohc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Localization
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/locale.gen&lt;/code&gt; and uncomment the needed UTF-8 locales (In my case, I'll uncomment &lt;code&gt;en_US.UTF-8 UTF-8&lt;/code&gt; and &lt;code&gt;pt_BR.UTF-8 UTF-8&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim /etc/locale.gen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you uncomment the locales, you have to generate the locales:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now you can create &lt;code&gt;/etc/locale.conf&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim /etc/locale.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And set the LANG variable accordingly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;pt_BR.UTF-8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, if you're using a keyboard layout other than US, you might want to persist the current keyboard layout. In &lt;code&gt;/etc/vconsole.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;KEYMAP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;br-abnt2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Network configuration
&lt;/h3&gt;

&lt;p&gt;Set the hostname (name of your machine) by creating the &lt;code&gt;/etc/hostname&lt;/code&gt; and adding the name of your hostname inside it.&lt;/p&gt;

&lt;p&gt;Now, in order to prevent software unsafely resolving localhost over the network because they migh still read &lt;code&gt;/etc/hosts&lt;/code&gt;, add the following entries to &lt;code&gt;/etc/hosts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;127.0.0.1        localhost
::1              localhost
127.0.1.1        yourhostname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  User configuration
&lt;/h3&gt;

&lt;p&gt;Create a root password:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Create your user with administrative privileges (the &lt;code&gt;-s&lt;/code&gt; can be omitted as bash is the default shell). In my case, my username will be &lt;code&gt;gus&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;useradd &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="nt"&gt;-G&lt;/span&gt; wheel,rfkill &lt;span class="nt"&gt;-s&lt;/span&gt; /bin/bash gus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specify the password for the created user:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;In order to enable the recently created user to have administrative privileges (e.g. be able to use &lt;code&gt;sudo&lt;/code&gt;), you'll need to uncomment the &lt;code&gt;wheel&lt;/code&gt; line on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;EDITOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;vim visudo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want, you can specify the full user name with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;chfn &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"Gustavo Dantas"&lt;/span&gt; gus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Initramfs
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;/etc/mkinitcpio.conf&lt;/code&gt;, add &lt;code&gt;btrfs&lt;/code&gt; to &lt;code&gt;MODULES&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Still in &lt;code&gt;/etc/mkinitcpio.conf&lt;/code&gt;, make sure the &lt;code&gt;HOOKS&lt;/code&gt; looks like the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The order of the hooks matter, so make sure &lt;code&gt;block&lt;/code&gt; and &lt;code&gt;encrypt&lt;/code&gt; are before &lt;code&gt;filesystems&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Regenerate &lt;code&gt;initramfs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mkinitcpio &lt;span class="nt"&gt;-P&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Boot loader
&lt;/h3&gt;

&lt;p&gt;You can use &lt;a href="https://wiki.archlinux.org/title/GRUB" rel="noopener noreferrer"&gt;grub&lt;/a&gt; or &lt;a href="https://wiki.archlinux.org/title/systemd" rel="noopener noreferrer"&gt;systemd&lt;/a&gt;. I'll use grub because it enables more customization and there are some packages that allows restoring snapshots from the grub interface as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; grub efibootmgr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate the bootloader:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;grub-install &lt;span class="nt"&gt;--target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;x86_64-efi &lt;span class="nt"&gt;--efi-directory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/boot &lt;span class="nt"&gt;--bootloader-id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;GRUB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you need to obtain the UUID of the partition the system was installed:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; Use the UUID of the partition itself (in my case it's &lt;code&gt;/dev/sda2&lt;/code&gt;, or if you're using NVME it should be something like &lt;code&gt;/dev/nvme0n1p2)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/default/grub&lt;/code&gt; and at the line beginning with &lt;code&gt;GRUB_CMDLINE_LINUX_DEFAULT&lt;/code&gt;, insert at the end with a space after quiet. Replace the content of &lt;code&gt;[UUID]&lt;/code&gt; with the correspondent UUID of your system partition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/mapper/cryptroot &lt;span class="nv"&gt;cryptdevice&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;UUID]:root 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Regenerate &lt;code&gt;grub.cfg&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;grub-mkconfig &lt;span class="nt"&gt;-o&lt;/span&gt; /boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it's time to add or configure additional software, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enabling networking on reboot:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;NetworkManager.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Pacman cache clearner:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;paccache.timer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;And if you're using SSD, enable TRIM:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;fstrim.timer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's time to exit chroot, reboot the system and remove the installation medium.&lt;/p&gt;

&lt;p&gt;You should be prompted to enter the password of the encrypted partition right before loggin in.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If what described above didn't happened, something not right happened along the process, like the UUID isn't correct.

&lt;ul&gt;
&lt;li&gt;In this case, you should use your installation medium again, remount all the partitions and use arch-chroot to fix this &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Snapshots
&lt;/h2&gt;

&lt;p&gt;Install &lt;code&gt;snapper&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; snapper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the snapshot configuration is created with &lt;code&gt;snapper&lt;/code&gt;, it will also create a subvolume and a folder called &lt;code&gt;/.snapshots&lt;/code&gt;, even thouth the &lt;code&gt;snapshots&lt;/code&gt; subvolume was alreay created and mounted on &lt;code&gt;/.snapshots&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To fix this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Unmount &lt;code&gt;snapshots&lt;/code&gt; subvolume
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;umount /.snapshots
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Delete the &lt;code&gt;/.snapshots&lt;/code&gt; folder
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo rm&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /.snapshots
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create &lt;code&gt;snapper&lt;/code&gt; config&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;snapper &lt;span class="nt"&gt;-c&lt;/span&gt; root create-config /
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Check that snapper created the subvolume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```bash
sudo btrfs subvolume list /
```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Delete the newly created subvolume and folder
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;btrfs subvolume delete /.snapshots
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create the &lt;code&gt;/.snapshots&lt;/code&gt; folder again
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; /.snapshots
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Remount it to snapshots subvolume
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now give the right read, write and execute permissions to the snapshots:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;750 /.snapshots
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your user to &lt;code&gt;ALLOW_USERS="yourusername"&lt;/code&gt; in the snapper config at &lt;code&gt;/etc/snapper/configs/root&lt;/code&gt;. You can also change the frequency and the history listed on the snapper &lt;a href="https://wiki.archlinux.org/title/snapper#Set_snapshot_limits" rel="noopener noreferrer"&gt;wiki page&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/snapper/configs/root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable the snapper services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; snapper-timeline.timer
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &lt;span class="nt"&gt;--now&lt;/span&gt; snapper-cleanup.timer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AUR helper
&lt;/h3&gt;

&lt;p&gt;An &lt;a href="https://wiki.archlinux.org/title/AUR_helpers" rel="noopener noreferrer"&gt;AUR helper&lt;/a&gt; automates the usage of the Arch User Repository (which is one of the great pros about using Arch really).&lt;/p&gt;

&lt;p&gt;Even when I used Arch on WSL, I really liked &lt;a href="https://github.com/Jguer/yay" rel="noopener noreferrer"&gt;yay&lt;/a&gt;, because it's really fun to type :)&lt;/p&gt;

&lt;p&gt;But you can also choose another one (like &lt;a href="https://aur.archlinux.org/packages/paru" rel="noopener noreferrer"&gt;paru&lt;/a&gt; which is written in Rust), or if you're really going in Arch Linux way, get familiar with the &lt;a href="https://wiki.archlinux.org/title/Arch_User_Repository#Installing_and_upgrading_packages" rel="noopener noreferrer"&gt;manual build process&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyway, I'm installing &lt;code&gt;yay&lt;/code&gt;. From the &lt;a href="https://github.com/Jguer/yay?tab=readme-ov-file#installation" rel="noopener noreferrer"&gt;docs&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; &lt;span class="nt"&gt;--needed&lt;/span&gt; git base-devel &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git clone https://aur.archlinux.org/yay-bin.git &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;yay-bin &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; makepkg &lt;span class="nt"&gt;-si&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to take a snapshot after every single install with pacman so you can revert if an upgrade breaks something, we can use &lt;code&gt;snap-pac-grub&lt;/code&gt;.&lt;br&gt;
But, because of the way the partitions were configured, the &lt;code&gt;/boot&lt;/code&gt; is not being snapshotted, so in order to copy the files of &lt;code&gt;/boot&lt;/code&gt; on every Linux kernel upgrade, &lt;code&gt;rsync&lt;/code&gt; will be installed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay &lt;span class="nt"&gt;-S&lt;/span&gt; snap-pac-grub rsync
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's also the possibility to enable booting the snapshots from &lt;code&gt;grub&lt;/code&gt;. For that, in &lt;code&gt;/etc/mkinitcpio.conf&lt;/code&gt; add &lt;code&gt;grub-btrfs-overlayfs&lt;/code&gt; to the end of &lt;code&gt;HOOKS&lt;/code&gt;. And don't forget to regenerate your &lt;code&gt;initramfs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mkinitcpio &lt;span class="nt"&gt;-P&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Kernel snapshots
&lt;/h3&gt;

&lt;p&gt;As said above, the &lt;code&gt;/boot&lt;/code&gt; is not being snapshotted, so if an update causes instability, you'll need to restore the older kernel image. For that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the folder &lt;code&gt;/etc/pacman.d/hooks&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; /etc/pacman.d/hooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;In the recently created folder, create a hook that will sync &lt;code&gt;/boot&lt;/code&gt; before a kernel upgrade
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vim /etc/pacman.d/hooks/0-bootbackup-preupdate.hook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Trigger]
Operation = Upgrade
Operation = Install
Operation = Remove
Type = Path
Target = usr/lib/modules/*/vmlinuz

[Action]
Depends = rsync
Description = Backing up /boot before updating...
When = PreTransaction
Exec = /usr/bin/rsync -a --delete /boot /.bootbackup/preupdate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Duplicate the hook to copy the new kernel after updating
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp&lt;/span&gt; /etc/pacman.d/hooks/0-bootbackup-preupdate.hook /etc/pacman.d/hooks/95-bootbackup-postupdate.hook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Trigger]
Operation = Upgrade
Operation = Install
Operation = Remove
Type = Path
Target = usr/lib/modules/*/vmlinuz

[Action]
Depends = rsync
Description = Backing up /boot after updating...
When = PostTransaction
Exec = /usr/bin/rsync -a --delete /boot /.bootbackup/postupdate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reboot the system.&lt;/p&gt;

&lt;p&gt;Now make an image for rollback to the system as it is in case something goes wrong in the near future:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;snapper &lt;span class="nt"&gt;-c&lt;/span&gt; root create &lt;span class="nt"&gt;--description&lt;/span&gt; “Clean BTRFS &lt;span class="nb"&gt;install &lt;/span&gt;with Snapper”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Of course, from here there are endless possibilities for the system to be configured and since I don't have a preference yet, I'll leave it up to your creativity.&lt;/p&gt;

&lt;p&gt;But, if you're really curious about what I do from here, you can check my &lt;a href="https://github.com/dantas15/dotfiles" rel="noopener noreferrer"&gt;dotfiles&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's it! Hope you enjoyed it. Please &lt;a href="https://www.dantas15.com/contact" rel="noopener noreferrer"&gt;contact&lt;/a&gt; me if you have any suggestions, recommendations, tips, questions or if you just want to have philosophical conversations!&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshoot
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;During the installation with &lt;code&gt;pacstrap&lt;/code&gt;, I received some errors about someone's signature key &lt;code&gt;is unknown trust&lt;/code&gt; or &lt;code&gt;invalid or corrupted package (PGP signature)&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;I had to refresh the keys for it to work properly (this might take some time)
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pacman-key &lt;span class="nt"&gt;--refresh-keys&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://wiki.archlinux.org/" rel="noopener noreferrer"&gt;Arch Wiki&lt;/a&gt; (In almost every section there are references to specific things that were being configured, make sure to check them as well)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codyhou.com/arch-encrypt-swap/" rel="noopener noreferrer"&gt;Cody Hou's Arch installation with encrypt and swap&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>archlinux</category>
      <category>linux</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Descrevendo e criando issues como um profissional</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Thu, 17 Aug 2023 03:15:01 +0000</pubDate>
      <link>https://forem.com/compjunior/descrevendo-e-criando-issues-como-um-profissional-1a28</link>
      <guid>https://forem.com/compjunior/descrevendo-e-criando-issues-como-um-profissional-1a28</guid>
      <description>&lt;p&gt;Domine a arte de criar descrições profissionais de problemas no GitHub! Este post revela como usar templates de issues para agilizar a documentação de bugs, incluindo elementos-chave como ambiente, comportamento esperado, passos para reproduzir e soluções. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Introdução&lt;/li&gt;
&lt;li&gt;Descrevendo issues como um profissional&lt;/li&gt;
&lt;li&gt;Utilizando templates para criar issues&lt;/li&gt;
&lt;li&gt;Exemplo de template&lt;/li&gt;
&lt;li&gt;Exemplos no mundo real&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Esse é o segundo post da série falando sobre issues e GitHub Projects. Já expliquei sobre as issues no &lt;a href="https://dev.to/compjunior/documentando-o-desenvolvimento-com-issues-32ki"&gt;primeiro post&lt;/a&gt;, recomendo que comece por ele.&lt;/p&gt;

&lt;p&gt;Agora vou focar na descrição das issues e mostrar uma forma mais automatizada de criar issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Descrevendo issues como um profissional
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dados do Ambiente:&lt;/strong&gt; Este é o contexto em que o problema ocorre. Pode incluir a versão do software, versão do sistema operacional, dependências relevantes e qualquer outra informação relevante.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comportamento Esperado:&lt;/strong&gt; O que você achava que o software faria ou deveria fazer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comportamento Real:&lt;/strong&gt; O que o software está realmente fazendo. Aqui é onde você detalha o problema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Passos para Reproduzir:&lt;/strong&gt; Um guia passo a passo para recriar o problema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Imagens/Capturas de Tela:&lt;/strong&gt; Ajudas visuais para ilustrar o problema ou a sua ideia.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registros de Erro:&lt;/strong&gt; Os famosos logs, se disponíveis, podem fornecer informações valiosas sobre o problema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Possível Solução/Sugestões:&lt;/strong&gt; Ideias ou sugestões que possam ajudar a resolver o problema.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Utilizando templates para criar issues como um profissional
&lt;/h2&gt;

&lt;p&gt;Agora que você já sabe como descrever as issues de forma profissional, é hora de dar um passo adiante e otimizar ainda mais o processo, tornando-o mais consistente e eficiente. Uma ótima maneira de fazer isso é utilizando templates para criar issues no GitHub.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vantagens de usar templates de issues
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Padronização: Os templates garantem que todas as issues sigam um formato consistente, o que facilita a compreensão por parte de todos os envolvidos no projeto.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Informações Relevantes: Com campos específicos para o ambiente, comportamento esperado, comportamento real e outros detalhes importantes, os templates ajudam a capturar as informações necessárias para uma análise eficiente do problema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Economia de Tempo: Ao criar issues a partir de templates, você economiza tempo ao não precisar pensar repetidamente em quais informações incluir. Isso acelera o processo de documentação e resolução de problemas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Como criar e usar templates de issues
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Acesse as Configurações do Repositório: No GitHub, vá até o seu repositório e clique na aba "Settings".&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%2Fawsjka330hwqnxh8fj8q.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%2Fawsjka330hwqnxh8fj8q.png" alt="Aba do repositório do GitHub" width="800" height="46"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Desça até a seção "Features" e clique em "Set up Templates"&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%2Fxz8tphkyortvxp81b8cx.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%2Fxz8tphkyortvxp81b8cx.png" alt="Seção features no GitHub" width="779" height="383"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Depois disso, você pode escolher o tipo de issue mais usuais: Bug, Feature. Ou você pode criar um template customizado para outro propósito em "Custom template"&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%2Fm4mtw6v85rncv7gsgmlx.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%2Fm4mtw6v85rncv7gsgmlx.png" alt="Tela de seleção de tipo de template de issue" width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Preencha o Template: Quando você cria uma nova issue, você terá a opção de escolher um template e preencher os campos correspondentes. Isso garante que todas as informações relevantes sejam inseridas de maneira organizada.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quando terminar, não se esqueça de salvar as alterações ao clicar no botão "Propose Changes". Aparecerá uma tela para aplicar as alterações no repositório por meio de um commit, é só especificar a mensagem e fazer o commit clicando em "commit changes"!&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%2F9r2pmce46udzj92lintw.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%2F9r2pmce46udzj92lintw.png" alt="Formulário de commit antes de salvar as issues" width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Exemplo de template
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Descrição do Problema&lt;/span&gt;

[Descreva aqui o problema de maneira sucinta]

&lt;span class="gu"&gt;### Dados do Ambiente&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Versão do Software:**&lt;/span&gt; [inserir versão]
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Versão do Sistema Operacional:**&lt;/span&gt; [inserir versão]
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Dependências Relevantes:**&lt;/span&gt; [listar dependências, se aplicável]

&lt;span class="gu"&gt;### Comportamento Esperado&lt;/span&gt;

[Descreva aqui o comportamento que era esperado]

&lt;span class="gu"&gt;### Comportamento Real&lt;/span&gt;

[Descreva aqui o comportamento observado]

&lt;span class="gu"&gt;### Passos para Reproduzir&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; [Descreva o primeiro passo]
&lt;span class="p"&gt;2.&lt;/span&gt; [Descreva o segundo passo]
&lt;span class="p"&gt;3.&lt;/span&gt; [E assim por diante...]

&lt;span class="gu"&gt;### Imagens/Capturas de Tela&lt;/span&gt;

[Insira imagens ou capturas de tela para ilustrar o problema]

&lt;span class="gu"&gt;### Registros de Erro&lt;/span&gt;

[Inclua logs ou mensagens de erro relevantes]

&lt;span class="gu"&gt;### Possível Solução/Sugestões&lt;/span&gt;

[Tenha espaço para ideias ou sugestões para resolver o problema]

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exemplos no mundo real
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/facebook/react/" rel="noopener noreferrer"&gt;React&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Issue de bugs:
&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%2Fcs7maq7a85dmey233c75.png" alt="Preview do template de issue do tipo bug no repositório do React" width="800" height="369"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/freeCodeCamp/freeCodeCamp" rel="noopener noreferrer"&gt;FreeCodeCamp&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Issue do freeCodeCamp para entregar desafios de código da plataforma
&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%2Fj1gtd6jmdavw7q00uyc1.png" alt="Issue do freeCodeCamp para entregar desafios de código da plataforma" width="800" height="1025"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Dominar a arte de descrever issues de maneira profissional e aproveitar os templates do GitHub é fundamental para um gerenciamento eficiente de projetos. Essas práticas não apenas aprimoram a comunicação, mas também impulsionam a resolução de problemas de forma estruturada e colaborativa. À medida que você avança em sua jornada de desenvolvimento, lembre-se sempre de aplicar esses conhecimentos para alcançar resultados mais sólidos e produtivos!&lt;/p&gt;

&lt;h2&gt;
  
  
  A Comp Júnior!
&lt;/h2&gt;

&lt;p&gt;A Comp Júnior é uma EJ (não sabe o que é? Então &lt;a href="https://dev.to/compjunior/o-que-e-uma-empresa-junior-jdi"&gt;clique aqui&lt;/a&gt;) que atua no mercado de tecnologia há mais de 20 anos em Lavras e região, prestando serviço de desenvolvimento web, mobile e multiplataforma.&lt;/p&gt;

&lt;p&gt;Nossa missão é oferecer a transformação digital aos nossos clientes, expandindo os seus negócios para o mercado digital e alcançando um potencial desconhecido.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se você quer saber mais, acesse nosso &lt;a href="https://compjunior.com.br" rel="noopener noreferrer"&gt;site&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;Ou, se preferir, acesse nosso &lt;a href="https://compjunior.com.br" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>braziliandevs</category>
      <category>github</category>
      <category>management</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Documentando o desenvolvimento com issues</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Tue, 15 Aug 2023 18:58:01 +0000</pubDate>
      <link>https://forem.com/compjunior/documentando-o-desenvolvimento-com-issues-32ki</link>
      <guid>https://forem.com/compjunior/documentando-o-desenvolvimento-com-issues-32ki</guid>
      <description>&lt;h2&gt;
  
  
  Conteúdos
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introdução&lt;/li&gt;
&lt;li&gt;O que é uma Issue&lt;/li&gt;
&lt;li&gt;A anatomia de uma issue&lt;/li&gt;
&lt;li&gt;Acompanhando uma issue&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;li&gt;Links e referências&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Quero bater um papo sobre algo que está sempre presente no nosso dia a dia, mas nem sempre damos a devida atenção: o mundo do GitHub. Se você já passou pela situação de olhar para um código que fez há meses e se perguntar "O que diabos eu estava pensando aqui?", então, meu amigo, este post é para você!&lt;/p&gt;

&lt;p&gt;Muitas vezes nos pegamos focados no ato de codar, implementar, criar, e esquecemos que a documentação é como a bússola que nos guia em meio ao caos do código. É aquele mapa detalhado que não apenas nos ajuda a lembrar o que fizemos quando voltamos para o projeto depois de um tempo, mas também permite que outros colegas de equipe se juntem e consigam contribuir sem ficarem completamente perdidos.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclaimer: Se você nunca ouviu falar de Git ou GitHub, recomendo fortemente que leia o &lt;a href="https://github.com/DanielHe4rt/git4noobs" rel="noopener noreferrer"&gt;Git4Noobs&lt;/a&gt; e pratique antes de continuar!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  O que é uma Issue?
&lt;/h2&gt;

&lt;p&gt;Em inglês, &lt;em&gt;issue&lt;/em&gt; quer dizer problema, porém, utilizamos para diversas coisas além disso, como rastrear ideias, comentários, tarefas ou erros nos repositórios no GitHub.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando uma issue
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Acesso ao Repositório: Primeiro, acesse o repositório no GitHub. Certifique-se de estar logado em sua conta.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Navegando para Issues: No menu superior do repositório, clique na guia "Issues". Aqui podemos visualizar todas as issues do repositório (por padrão, são mostradas as issues que ainda não foram resolvidas, fechadas):&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%2Fyltn68a9cdvt349yl6jg.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%2Fyltn68a9cdvt349yl6jg.png" alt="Seção de issues do repositório facebook/react no GitHub como exemplo" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Criando uma Nova Issue: Para criar uma nova issue, clique no botão verde "New Issue". Agora, você estará pronto para preencher os detalhes.&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%2F9fxsjuwg1wnc35c8pjtf.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%2F9fxsjuwg1wnc35c8pjtf.png" alt="Tela de cadastro de issue" width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A anatomia de uma issue
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Título:&lt;/strong&gt; Um título conciso, porém descritivo, que resume o problema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Etiquetas/Tags:&lt;/strong&gt; Etiquetas ou tags aplicáveis para categorizar o problema, facilitando a ordenação e o gerenciamento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Labels&lt;/strong&gt;: As labels ajudam a categorizar e identificar o tipo de issue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assignees&lt;/strong&gt;: A issue pode ser atribuída a um ou mais colaboradores do projeto utilizando essa seção&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Descrição&lt;/strong&gt;: Qualquer informação que possa auxiliar na compreensão ou resolução da issue (lembrando que uma issue pode ser desde um bug até uma ideia de feature nova).

&lt;ul&gt;
&lt;li&gt;Você pode marcar outras issues, com &lt;code&gt;#&lt;/code&gt;, ou marcar pessoas com &lt;code&gt;@&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Até aqui podemos ver o poder e a quantidade de informação que podemos armazenar com as issues, mas é só isso? Não!! Há um ponto importante que temos que destacar quando estamos lidando com várias pessoas contribuindo em um projeto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acompanhando uma issue
&lt;/h2&gt;

&lt;p&gt;Criar a issue é apenas o primeiro passo! Acompanhar uma issue é uma parte fundamental do gerenciamento de projetos e colaboração eficaz no GitHub. Mas como se manter atualizado das discussões? Bem, temos algumas formas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ative as notificações&lt;/strong&gt; para acompanhar qualquer atividade relacionada a ela. Clique na opção "Subscribe" na parte superior direita da issue para receber alertas por e-mail sempre que houver novos comentários, mudanças de status ou atualizações.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Participe ativamente das discussões na issue&lt;/strong&gt;. Comente, forneça feedback e colabore com a equipe. Essas discussões podem levar a ideias melhores e a uma compreensão mais clara dos requisitos da tarefa.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atribua a issue&lt;/strong&gt; ou &lt;strong&gt;marque-o&lt;/strong&gt; (com &lt;code&gt;@&lt;/code&gt;) a um membro da equipe responsável pelo desenvolvimento. Isso ajuda a evitar confusões sobre quem está trabalhando na tarefa e permite um acompanhamento direcionado.&lt;/li&gt;
&lt;li&gt;Utilize &lt;strong&gt;milestones&lt;/strong&gt; para definir marcos ou metas específicas para a issue. À medida que o trabalho avança, atualize o status da issue e mova-a para o milestone correspondente. Isso proporciona uma visão clara do progresso geral do projeto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mantenha a descrição da issue atualizada&lt;/strong&gt; à medida que o desenvolvimento progride. Isso inclui adicionar informações relevantes, capturas de tela, links ou quaisquer detalhes importantes que surgirem durante o processo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E por último mas não menos importante... Quando a tarefa estiver concluída, certifique-se de que o trabalho seja revisado e testado. Comente na issue indicando que a tarefa está pronta para revisão ou integração. Após a revisão bem-sucedida, &lt;strong&gt;&lt;em&gt;feche a issue&lt;/em&gt;&lt;/strong&gt;. Se houver ajustes futuros, é só mencionar, a issue continuará salva e poderá ser reaberta se necessário.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Agora você está equipado com o poder das issues no GitHub! Elas são como post-its digitais que mantêm seu projeto na linha. Lembram o que você estava pensando (ou não) e ajudam a galera toda a trabalhar junto, mesmo quando o mundo está de cabeça para baixo.&lt;/p&gt;

&lt;p&gt;Lembrou de uma ideia brilhante no meio da noite? Pode criar uma issue! Quer atribuir tarefas? É só marcar alguém com um 'arroba'. E não se preocupe, quando você tiver feito o seu trampo, é só revisar, testar e fechar a issue.&lt;/p&gt;

&lt;p&gt;Então, da próxima vez que você mergulhar no código, lembre-se das suas amigas issues, elas vão fazer seu trabalho render mais e podem te poupar de futuros momentos "que diabos eu estava fazendo aqui".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Psst, você aí! Quer agilizar ainda mais a criação de issues num projeto? Fica ligado no &lt;a href="https://docs.github.com/pt/issues/planning-and-tracking-with-projects/learning-about-projects/quickstart-for-projects" rel="noopener noreferrer"&gt;GitHub Projects&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Links e referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/pt/issues" rel="noopener noreferrer"&gt;Issues | Doc do GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/DanielHe4rt/git4noobs" rel="noopener noreferrer"&gt;Git4Noobs - Passo a passo para quem está começando agora&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cover por &lt;a href="https://unsplash.com/@mimithian?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Mimi Thian&lt;/a&gt; no &lt;a href="https://unsplash.com/photos/ZKBzlifgkgw?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Comp Júnior!
&lt;/h2&gt;

&lt;p&gt;A Comp Júnior é uma EJ (não sabe o que é? Então &lt;a href="https://dev.to/compjunior/o-que-e-uma-empresa-junior-jdi"&gt;clique aqui&lt;/a&gt;) que atua no mercado de tecnologia há mais de 20 anos em Lavras e região, prestando serviço de desenvolvimento web, mobile e multiplataforma.&lt;/p&gt;

&lt;p&gt;Nossa missão é oferecer a transformação digital aos nossos clientes, expandindo os seus negócios para o mercado digital e alcançando um potencial desconhecido.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se você quer saber mais, acesse nosso &lt;a href="https://compjunior.com.br" rel="noopener noreferrer"&gt;site&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;Ou, se preferir, acesse nosso &lt;a href="https://compjunior.com.br" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>braziliandevs</category>
      <category>git</category>
      <category>github</category>
      <category>management</category>
    </item>
    <item>
      <title>O que é uma Empresa Júnior?</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Mon, 14 Aug 2023 17:44:17 +0000</pubDate>
      <link>https://forem.com/compjunior/o-que-e-uma-empresa-junior-jdi</link>
      <guid>https://forem.com/compjunior/o-que-e-uma-empresa-junior-jdi</guid>
      <description>&lt;ol&gt;
&lt;li&gt;Introdução&lt;/li&gt;
&lt;li&gt;Por que entrar em uma empresa júnior?&lt;/li&gt;
&lt;li&gt;O Movimento Empresa Júnior&lt;/li&gt;
&lt;li&gt;TL;DR; - Resumão&lt;/li&gt;
&lt;li&gt;A Comp Júnior&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Uma empresa é uma organização que reúne recursos humanos, financeiros e materiais com o objetivo de desenvolver e oferecer produtos, serviços ou soluções para atender às necessidades do mercado.&lt;/p&gt;

&lt;p&gt;Ser júnior refere-se a uma fase inicial da carreira profissional, geralmente associada a indivíduos que estão nos primeiros anos de atuação em uma determinada área ou empresa. Profissionais juniores estão em processo de aprendizado e desenvolvimento, frequentemente sob a orientação e supervisão de colegas mais experientes. Essa etapa é marcada por oportunidades de crescimento, aquisição de habilidades práticas e conhecimento específico, além de proporcionar um ambiente propício para explorar diferentes aspectos do trabalho e construir uma base sólida para o progresso profissional futuro.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mas como uma empresa se encaixa nisso?
&lt;/h3&gt;

&lt;p&gt;Uma empresa júnior é uma organização estudantil sem fins lucrativos, associada a uma universidade ou faculdade.&lt;/p&gt;

&lt;p&gt;Ela opera como uma entidade empresarial controlada por alunos, proporcionando uma experiência prática, por meio de projetos reais, os membros da empresa júnior aplicam conhecimentos teóricos adquiridos em sala de aula para enfrentar desafios reais do mercado. Essa abordagem permite que os estudantes desenvolvam habilidades profissionais, como trabalho em equipe, liderança e resolução de problemas, enquanto oferecem serviços de qualidade a clientes reais a preços acessíveis. O termo "júnior" denota o caráter educacional da organização, indicando que os participantes estão em uma fase de aprendizado e crescimento, sob a supervisão de professores e profissionais do setor, preparando-se para suas futuras carreiras.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que entrar em uma empresa júnior?
&lt;/h2&gt;

&lt;p&gt;Muitos no ambiente universitário nunca tiveram contato com empresas do seu segmento de estudo, ou seja, não sabem como colocar em prática o conteúdo teórico aprendido durante o curso.&lt;/p&gt;

&lt;p&gt;Além disso, a universidade acaba deixando de lado as soft skills, que são habilidades interpessoais e sociais que afetam a maneira como nos relacionamos com os outros e lidamos com situações do dia a dia.&lt;/p&gt;

&lt;p&gt;Com isso em mente, uma empresa júnior é responsável por acolher e desenvolver seus membros, oferecendo a primeira oportunidade profissional e contato com o mercado de trabalho, suas metodologias e estruturas.&lt;/p&gt;

&lt;p&gt;Em uma empresa júnior, você é encorajado a tomar suas próprias decisões e a pedir ajuda, não somente para os membros da sua empresa, mas para toda a rede.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mas que rede é essa?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  O MEJ
&lt;/h2&gt;

&lt;p&gt;O Movimento Empresa Júnior (MEJ para os íntimos) atua como uma rede que reúne diversas empresas juniores, oferecendo suporte, capacitação e troca de experiências entre essas organizações. Ele busca fomentar a &lt;em&gt;cultura empreendedora&lt;/em&gt; entre os estudantes universitários, estimulando-os a aplicar os conhecimentos adquiridos em sala de aula em projetos reais, e ao mesmo tempo contribuir para o desenvolvimento de empresas e comunidades locais.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A estrutura está pelos membros, e não os membros pela estrutura&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Isso quer dizer que, se tivermos alguma dificuldade, seja estratégica, tática ou operacional, temos toda uma rede que provavalmente já passou pela mesma coisa. E temos total liberdade (na verdade, somos encorajados) a pedir por conselhos e ajuda de toda a rede!&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;Empresa Júnior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organização estudantil sem fins lucrativos associada a uma universidade.&lt;/li&gt;
&lt;li&gt;Controlada por alunos, oferece experiência prática por meio de projetos reais.&lt;/li&gt;
&lt;li&gt;Aplica conhecimentos teóricos em desafios de mercado.&lt;/li&gt;
&lt;li&gt;Desenvolve habilidades profissionais e oferece serviços a clientes reais.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Benefícios de uma empresa júnior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Colocar em prática conhecimentos teóricos do curso.&lt;/li&gt;
&lt;li&gt;Desenvolver soft skills (habilidades interpessoais).&lt;/li&gt;
&lt;li&gt;Oferecer primeira oportunidade profissional e contato com o mercado.&lt;/li&gt;
&lt;li&gt;Tomar decisões e buscar ajuda dentro de uma rede.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Movimento Empresa Júnior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rede que reúne empresas juniores.&lt;/li&gt;
&lt;li&gt;Oferece suporte, capacitação e troca de experiências.&lt;/li&gt;
&lt;li&gt;Estimula cultura empreendedora e aplicação de conhecimentos em projetos reais.&lt;/li&gt;
&lt;li&gt;Ênfase na colaboração e apoio mútuo entre membros.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Comp Júnior
&lt;/h2&gt;

&lt;p&gt;A Comp Júnior é uma EJ (Empresa Júnior) que atua no mercado de tecnologia há mais de 20 anos em Lavras e região, prestando serviço de desenvolvimento web, mobile e multiplataforma.&lt;/p&gt;

&lt;p&gt;Nossa missão é oferecer a transformação digital aos nossos clientes, expandindo os seus negócios para o mercado digital e alcançando um potencial desconhecido.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se você quer saber mais, acesse &lt;a href="http://compjunior.com.br/" rel="noopener noreferrer"&gt;nosso site&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;Ou, se preferir, acesse nosso &lt;a href="https://www.instagram.com/compjunior/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>motivation</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Solving prop drilling in React with ContextAPI</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Mon, 10 Apr 2023 13:34:28 +0000</pubDate>
      <link>https://forem.com/dantas/using-context-in-react-to-solve-some-issues-o96</link>
      <guid>https://forem.com/dantas/using-context-in-react-to-solve-some-issues-o96</guid>
      <description>&lt;h2&gt;
  
  
  Prop Drilling
&lt;/h2&gt;

&lt;p&gt;The most simple way to pass data between components is using props, but it can lead to a messy code and probably making it unmaintainable, specially with prop drilling, where a props have to be passed to multiple layers of components:&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%2Fk5qihyvqx0w56ysj09yg.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%2Fk5qihyvqx0w56ysj09yg.png" alt="Five blue blocks stacked vertically and with arrows representing props being passed to the next block below" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Solving this (and maybe others) issue(s) with Context
&lt;/h2&gt;

&lt;p&gt;| Context lets you write components that “adapt to their surroundings and display themselves differently depending on where (or, in other words, in which context) they are being rendered. - &lt;a href="https://react.dev/learn/passing-data-deeply-with-context" rel="noopener noreferrer"&gt;react.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically, Context enables us to pass data through the component tree without having to pass props down manually at every level (prop drilling for example).&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;First, we need to create a Context using &lt;code&gt;React.createContext&lt;/code&gt; and then we can use it in our components
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;createContext&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="c1"&gt;// If you'se using TypeScript, you can also pass a default value to the context with the type of the value you're going to pass&lt;/span&gt;
  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createContext&lt;/span&gt;&lt;span class="p"&gt;({}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;MyContextType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;then we need to wrap all the components we want to use the context in a &lt;code&gt;Provider&lt;/code&gt; component
&lt;/li&gt;
&lt;/ul&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;MyContext&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;./MyContext&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* value of your context */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ComponentA&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ComponentB&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ComponentC&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;MyContext&lt;/span&gt;&lt;span class="p"&gt;.&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;now you can access the data from your context in any component that is wrapped in the &lt;code&gt;Provider&lt;/code&gt; component using &lt;code&gt;useContext&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&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;MyContext&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;./MyContext&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ComponentA&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyContext&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;That's it! I honestly believe that the best way to learn anything is trying for yourself, so I encourage you to try to create a simple counter app using Context.&lt;/li&gt;
&lt;li&gt;Also, if you want to see it in action, check this &lt;a href="https://github.com/ist4/timer-react-ts" rel="noopener noreferrer"&gt;simple timer app on my Github&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;In this app I used Context to share the state of the timer between the &lt;code&gt;Home&lt;/code&gt;, &lt;code&gt;Countdown&lt;/code&gt; and &lt;code&gt;NewCycleForm&lt;/code&gt; components&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://react.dev/learn/passing-data-deeply-with-context" rel="noopener noreferrer"&gt;Passing data deeply with context | react.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/react-context-for-beginners/" rel="noopener noreferrer"&gt;React Context for begginers - freeCodeCamp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.alura.com.br/artigos/prop-drilling-no-react-js" rel="noopener noreferrer"&gt;Prop Drilling: o que é? - Alura&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react.dev/reference/react/createContext" rel="noopener noreferrer"&gt;&lt;code&gt;createContext&lt;/code&gt; | react.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react.dev/reference/react/useContext" rel="noopener noreferrer"&gt;&lt;code&gt;useContext&lt;/code&gt; | react.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cover image by &lt;a href="https://unsplash.com/@afgprogrammer?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Mohammad Rahmani&lt;/a&gt; on &lt;a href="https://unsplash.com/pt-br/fotografias/W-LQbAUhE64?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Get the distance between the given date and now in words using date-fns</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Fri, 07 Apr 2023 14:07:29 +0000</pubDate>
      <link>https://forem.com/dantas/get-the-distance-between-the-given-date-and-now-in-words-using-date-fns-35j7</link>
      <guid>https://forem.com/dantas/get-the-distance-between-the-given-date-and-now-in-words-using-date-fns-35j7</guid>
      <description>&lt;ul&gt;
&lt;li&gt;import the formatDistanceToNow function from date-fns:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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;formatDistanceToNow&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;date-fns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;format the date to now:
&lt;/li&gt;
&lt;/ul&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;date&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;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2020-01-01T12:00:00Z&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;formatDistanceToNow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;addSuffix&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;as you've seen, we can also pass the second parameter as an object to specify the options, such as adding the suffix.&lt;/li&gt;
&lt;li&gt;you can see all the available options for &lt;code&gt;formatDistanceToNow&lt;/code&gt; &lt;a href="https://date-fns.org/v2.29.3/docs/formatDistanceToNow#arguments" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using a different language
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;we need to import the language from date-fns, for example, portuguese from Brazil:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ptBR&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;date-fns/locale/pt-BR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;then use the second parameter to specify the locale
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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;formatDistanceToNow&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;date-fns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ptBR&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;date-fns/locale/pt-BR&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;date&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;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2020-01-01T12:00:00Z&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;formatDistanceToNow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;addSufix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ptBR&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;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://date-fns.org/" rel="noopener noreferrer"&gt;&lt;code&gt;date-fns&lt;/code&gt; docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cover image from &lt;a href="https://unsplash.com/@romanbozhko?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Roman Bozhko&lt;/a&gt; on &lt;a href="https://unsplash.com/pt-br/fotografias/PypjzKTUqLo?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to clean up useEffect's code</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Tue, 04 Apr 2023 12:41:54 +0000</pubDate>
      <link>https://forem.com/dantas/how-to-clean-up-useeffects-code-c5e</link>
      <guid>https://forem.com/dantas/how-to-clean-up-useeffects-code-c5e</guid>
      <description>&lt;h2&gt;
  
  
  What is useEffect?
&lt;/h2&gt;

&lt;p&gt;| "useEffect is a React Hook that lets you synchronize a component with an external system." - &lt;a href="https://react.dev/reference/react/useEffect" rel="noopener noreferrer"&gt;react.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, whenever there is something on screen we want to update when another variable changes, we can use &lt;code&gt;useEffect&lt;/code&gt;. But be careful, &lt;a href="https://react.dev/reference/react/useEffect#caveats" rel="noopener noreferrer"&gt;always think twice before using it&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to clean it up
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;you can return a function inside &lt;code&gt;useEffect's&lt;/code&gt; first parameter, so it runs after the main code is executed&lt;/li&gt;
&lt;li&gt;this was really useful for me when I was coding a pomodoro-like app to know wether to &lt;em&gt;update&lt;/em&gt; or &lt;em&gt;interrupt&lt;/em&gt; the amounts of seconds past
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&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;activeCycle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;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="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;secondsDifference&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;differenceInSeconds&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="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startedAt&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;secondsDifference&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;totalSeconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// interrupt the cycle code&lt;/span&gt;
        &lt;span class="c1"&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;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// update the amount of seconds past in the current cycle&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&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="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totalSeconds&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;in this example, I needed a way to close the intervals, since &lt;code&gt;useEffect&lt;/code&gt; created a new interval each time it executed and this interval kept executing every time

&lt;ul&gt;
&lt;li&gt;so the timer was basically not working as it should.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;for it to work, I needed to clean up every execution&lt;/li&gt;

&lt;li&gt;that's the result:
&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&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;let&lt;/span&gt; &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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;activeCycle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&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="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;secondsDifference&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;differenceInSeconds&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="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startedAt&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;secondsDifference&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;totalSeconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// interrupt the cycle code&lt;/span&gt;
        &lt;span class="c1"&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;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// update the amount of seconds past in the current cycle&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&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;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;activeCycle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;totalSeconds&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;I declared interval before, so I could clear it on the &lt;a href="https://react.dev/reference/react/useEffect#useeffect" rel="noopener noreferrer"&gt;setup function&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;react.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cover image from &lt;a href="https://unsplash.com/@juanjodev02?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Juanjo Jaramillo&lt;/a&gt; on &lt;a href="https://unsplash.com/pt-br/fotografias/mZnx9429i94?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you have any doubts or advice, feel free to leave a comment or ping me on Twitter&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Quick sort algorithm in C++</title>
      <dc:creator>Gustavo</dc:creator>
      <pubDate>Tue, 07 Mar 2023 13:52:37 +0000</pubDate>
      <link>https://forem.com/dantas/quick-sort-algorithm-in-c-10pl</link>
      <guid>https://forem.com/dantas/quick-sort-algorithm-in-c-10pl</guid>
      <description>&lt;p&gt;In this post I'll show what I learned from the quicksort algorithm. I'll be sorting in ascending order an &lt;code&gt;int&lt;/code&gt; array in C++.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pivot
&lt;/h2&gt;

&lt;p&gt;The quicksort algorithm is based on the pivot you choose. It can be the first, last, the middle or you can have other ways of choosing the pivot, like &lt;a href="https://ece.uwaterloo.ca/~dwharder/aads/Algorithms/Sorting/Quick_sort/Median_of_three/" rel="noopener noreferrer"&gt;median-of-three&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where the pivot is supposed to be
&lt;/h3&gt;

&lt;p&gt;You should be asking where are we putting this pivot. Well, the pivot should abide by some rules so we know it is in its right place:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It occupies the right sorted position on the given array.&lt;/li&gt;
&lt;li&gt;All items to the left are smaller&lt;/li&gt;
&lt;li&gt;All items to the right are bigger&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The partition function
&lt;/h2&gt;

&lt;p&gt;In this example, I'll be choosing the last element as the pivot.&lt;br&gt;
In the function we call &lt;code&gt;partition&lt;/code&gt;, we are going to find the right index where the pivot is supposed to be and return it to use in our &lt;code&gt;quicksort&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ARR_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;partition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pivot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// get the last element as pivot&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sortedIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;left&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="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&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="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;pivot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;sortedIndex&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sortedIndex&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&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="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sortedIndex&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="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sortedIndex&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sortedIndex&lt;/code&gt; will store the previous index that the pivot will occupy at the end of the function&lt;/li&gt;
&lt;li&gt;We iterate from &lt;code&gt;left&lt;/code&gt; to &lt;code&gt;right&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the element is smaller than the pivot, we add &lt;code&gt;+ 1&lt;/code&gt; to &lt;code&gt;sortedIndex&lt;/code&gt; and swap the elements &lt;code&gt;arr[sortedIndex]&lt;/code&gt; and &lt;code&gt;arr[j]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;At the end of the function, we swap the pivot (last element) with the &lt;code&gt;sortedIndex + 1&lt;/code&gt;th element, and we return the new index of the pivot.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Quick Sort recursive function
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In the quicksort function, we receive the array, the &lt;code&gt;left&lt;/code&gt; and the &lt;code&gt;right&lt;/code&gt; index.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Here we are basically getting the correct pivot position with the &lt;code&gt;partition&lt;/code&gt; function and dividing the array in two:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;from &lt;code&gt;left&lt;/code&gt; to &lt;code&gt;pivot - 1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;from &lt;code&gt;pivot + 1&lt;/code&gt; to &lt;code&gt;right&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;The stop criteria is when the function receives &lt;code&gt;left&lt;/code&gt; equal or bigger than &lt;code&gt;right&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;And like that, we have our quicksort function:&lt;br&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;quicksort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&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="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pivot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;partition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;quicksort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pivot&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="n"&gt;quicksort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pivot&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="n"&gt;right&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;h2&gt;
  
  
  Final code
&lt;/h2&gt;

&lt;p&gt;Let's use an array with 7 positions and sort it using the quicksort function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ARR_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;partition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pivot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sortedIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;left&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="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&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="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;pivot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;sortedIndex&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sortedIndex&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&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="n"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sortedIndex&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="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sortedIndex&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="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;quicksort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&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="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pivot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;partition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;quicksort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pivot&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="n"&gt;quicksort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pivot&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="n"&gt;right&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="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ARR_SIZE&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;-------------Original array-------------&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;ARR_SIZE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;quicksort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ARR_SIZE&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="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;-------------Sorted array-------------&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;ARR_SIZE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;cout&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EXIT_SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope you could find it useful! If you have any advice, tips, recommendations or doubts, just ping me on Twitter&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>algorithms</category>
      <category>quicksort</category>
    </item>
  </channel>
</rss>
