<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Facundo Botta</title>
    <description>The latest articles on DEV Community by Facundo Botta (@facubotta).</description>
    <link>https://dev.to/facubotta</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%2F1400076%2Fdd58fd53-6cee-4b99-bbb2-10dfb70317e4.jpeg</url>
      <title>DEV Community: Facundo Botta</title>
      <link>https://dev.to/facubotta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/facubotta"/>
    <language>en</language>
    <item>
      <title>JavaScript - Things</title>
      <dc:creator>Facundo Botta</dc:creator>
      <pubDate>Wed, 29 Oct 2025 17:07:09 +0000</pubDate>
      <link>https://dev.to/facubotta/javascript-things-2obf</link>
      <guid>https://dev.to/facubotta/javascript-things-2obf</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this post, I want to share some JavaScript behaviors that often seem nonsensical at first, but actually reveal something about the language’s nature. Understanding them can help us avoid mistakes — and even take advantage of them.&lt;/p&gt;

&lt;p&gt;The following examples are inspired by the book &lt;a href="https://eloquentjavascript.net/3rd_edition/" rel="noopener noreferrer"&gt;Eloquent JavaScript&lt;/a&gt; and by the quiz on &lt;a href="https://jsisweird.com/" rel="noopener noreferrer"&gt;JS is Weird&lt;/a&gt;  web's site.&lt;br&gt;
Another interesting resource, not taken into account for these examples, is &lt;a href="https://jsdate.wtf/?ref=dailydev" rel="noopener noreferrer"&gt;jsdata.wtf&lt;/a&gt; that shows unexpected, or not so much, behaviors of the Date object. &lt;/p&gt;

&lt;p&gt;So:&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;true + false === 1&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Boolean values are converted into their numeric counterparts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&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="c1"&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;span class="mi"&gt;1&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="c1"&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;code&gt;!!"" === false&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The double exclamation mark (double NOT) converts any value to its corresponding boolean, based on its &lt;em&gt;truthiness&lt;/em&gt; or &lt;em&gt;falsiness,&lt;/em&gt; just like the &lt;code&gt;Boolean()&lt;/code&gt; function :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; false ("" is falsy)&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; false&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="c1"&gt;// -&amp;gt; false&lt;/span&gt;
&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="mi"&gt;666&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;code&gt;+true === 1&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is an example of type coercion, its minds JS tries to convert a value to a number. Internally JS use the &lt;code&gt;Number()&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&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="c1"&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;code&gt;true == "true" // false&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Here the loose equality operator (&lt;code&gt;==&lt;/code&gt;) tries to convert the values to number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&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="c1"&gt;// -&amp;gt; 1&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; NaN&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;code&gt;null + 0 === 0&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When performing arithmetic, &lt;code&gt;null&lt;/code&gt; is coerced to &lt;code&gt;0&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;span class="mi"&gt;0&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="c1"&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;code&gt;if ([] == false) → true&lt;/code&gt; but &lt;code&gt;if ([]) → true&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This one shows how &lt;em&gt;truthiness&lt;/em&gt; and &lt;em&gt;type coercion&lt;/em&gt; are two different mechanisms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;if([])&lt;/code&gt; 
When you use a value inside an &lt;code&gt;if&lt;/code&gt; statement, JavaScript simply checks its &lt;em&gt;truthiness&lt;/em&gt; — no type conversion, no comparison.
&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;if &lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;truthy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// → truthy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Arrays (and any non-null objects) are &lt;em&gt;truthy&lt;/em&gt;, even if they’re empty:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt; &lt;span class="c1"&gt;// → true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;code&gt;if ([] == false)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we’re using the &lt;em&gt;loose equality&lt;/em&gt; operator &lt;code&gt;==&lt;/code&gt;, which triggers &lt;em&gt;type coercion&lt;/em&gt; and the rules changes.&lt;br&gt;
When comparing an object &lt;code&gt;[]&lt;/code&gt; and a boolean &lt;code&gt;false&lt;/code&gt;, JavaScript first converts the boolean to a number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; 0&lt;/span&gt;
&lt;span class="c1"&gt;// So we get&lt;/span&gt;
&lt;span class="p"&gt;[]&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it tries to convert the array to a primitive value (a number or string).&lt;br&gt;
For an empty array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[].&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// → ""&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;// → 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;0&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="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JS uses &lt;em&gt;truthiness&lt;/em&gt; for &lt;code&gt;if(x)&lt;/code&gt; and &lt;em&gt;type coercion&lt;/em&gt; for &lt;code&gt;x == y&lt;/code&gt;, that’s why something can be &lt;em&gt;truthy&lt;/em&gt; and &lt;em&gt;loosely equal&lt;/em&gt; to &lt;code&gt;false&lt;/code&gt; at the same time.&lt;br&gt;
We have the &lt;code&gt;===&lt;/code&gt; operator to avoid these surprises...&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;code&gt;0.1 + 0.2 !== 0.3&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This behavior comes from how &lt;em&gt;floating point numbers&lt;/em&gt; are represented based on the IEEE-754 standard used by JS and every major language.&lt;br&gt;
The result is actually &lt;code&gt;0.30000000000000004&lt;/code&gt;, if you want to know more check the &lt;a href="https://0.30000000000000004.com/" rel="noopener noreferrer"&gt;https://0.30000000000000004.com/&lt;/a&gt; web site.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;code&gt;NaN !== NaN&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A &lt;em&gt;Not a Number&lt;/em&gt; value is, by definition, not equal to anything... not even to itself&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;code&gt;'5' - 3 === 2&lt;/code&gt; but &lt;code&gt;'5' + 2 === '53'&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;-&lt;/code&gt; operator always expects numbers, so &lt;code&gt;'5'&lt;/code&gt; becomes &lt;code&gt;5&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
But the &lt;code&gt;+&lt;/code&gt; operator can mean addition or string concatenation, so if one operand is a string, the string concatenation wins.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;code&gt;'' == 0 -&amp;gt; true&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The empty string is &lt;em&gt;falsy&lt;/em&gt; and JS convert it to 0:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// → 0&lt;/span&gt;
&lt;span class="mi"&gt;0&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="c1"&gt;// → true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;code&gt;0/0 -&amp;gt; NaN&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In divisions by 0, JavaScript does not always behave the same way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;// Infinity&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;// -Infinity&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;// NaN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This behavior is caused too by the IEEE-754 standard that JS uses for its &lt;em&gt;numbers&lt;/em&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;[1,2,3] + [4,5,6] // -&amp;gt; "1,2,34,5,6"&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Ones again the &lt;code&gt;+&lt;/code&gt; operator treats values like strings if they are not numbers, so it performs a string concatenation with the two arrays.&lt;/p&gt;

&lt;p&gt;If you want to save the &lt;code&gt;,&lt;/code&gt; you have to put it before the &lt;code&gt;4&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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;3&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;4&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="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; "1,2,3,4,5,6"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But not after the 3 because of the trailing coma will be ignored.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclution
&lt;/h2&gt;

&lt;p&gt;This list could go on with more and more examples, but as you start to understand the why, the examples start to sound repetitive.&lt;/p&gt;

&lt;p&gt;Most of these behaviors, which seem “weird” at first, are actually the result of how the language uses different strategies to handle the values it receives.&lt;br&gt;
We can recognize in these examples some of JavasCript's main strategies, like type coercion and truthiness.&lt;/p&gt;

&lt;p&gt;It’s thanks to those decisions JavaScript makes for us that we get certain freedoms — to be care, and to be creative too, like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// -&amp;gt; "banana"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;😁 Thanks for reading!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>Git 3-3 - Workflows</title>
      <dc:creator>Facundo Botta</dc:creator>
      <pubDate>Sat, 12 Jul 2025 16:11:00 +0000</pubDate>
      <link>https://dev.to/facubotta/git-3-3-workflows-14md</link>
      <guid>https://dev.to/facubotta/git-3-3-workflows-14md</guid>
      <description>&lt;p&gt;Hi there! It's taken me a while, but I'm finally back to wrap up this 3-part series on Git and GitHub. I hope you’ve found it helpful so far!&lt;/p&gt;

&lt;p&gt;In this final part, instead of continuing with commands and terminal examples, I want to talk about Git workflows. Knowing a handful of useful commands is enough to get started, and we can always refer to the docs or ask the ever-present friend we all share: ChatGPT. 😄&lt;/p&gt;

&lt;p&gt;But when working on a team, understanding some basic collaboration strategies and branching models is very helpful.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Git workflow?
&lt;/h3&gt;

&lt;p&gt;A Git workflow is a branching strategy or structure that development teams agree to follow when working on a project. It ensures smoother collaboration, clearer versioning, more efficient debugging, and a generally more organized development process.&lt;/p&gt;

&lt;p&gt;There are several popular Git workflows out there. Personally, I’ve worked with Git Flow and GitHub Flow, but I also want to touch on Trunk-Based Development and Ship/Show/Ask, which are more modern and increasingly common.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git Flow
&lt;/h2&gt;

&lt;p&gt;Git Flow is one of the earliest formal Git workflows, proposed by Vincent Driessen in &lt;a href="https://nvie.com/posts/a-successful-git-branching-model/" rel="noopener noreferrer"&gt;this influential blog post from 2010&lt;/a&gt;. At the time, teams were transitioning from centralized version control systems to Git, and needed a more structured way to handle parallel feature development, releases, and hotfixes.&lt;/p&gt;

&lt;p&gt;Git Flow became widely adopted, especially in enterprise environments and teams building software with scheduled release cycles (e.g., desktop apps, backend APIs, mobile apps). While it can be overkill for continuous deployment setups, it remains valuable for structured, long-lived projects where stability and versioning are priorities.&lt;/p&gt;

&lt;p&gt;The strategy is based on two main branches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt; (or &lt;code&gt;master&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;development&lt;/code&gt; (or &lt;code&gt;dev&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alongside them, there are support branches like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hotfix/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;release/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;feature/*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: The branch names are just conventions, you and your team can use whatever naming style suits you.&lt;/p&gt;

&lt;h3&gt;
  
  
  main branch
&lt;/h3&gt;

&lt;p&gt;This branch contains the code that is currently in production. Ideally, it should always be stable, clean, and free of debug logs or experimental features. All merges into &lt;code&gt;main&lt;/code&gt; should be reviewed, tested, and approved, ideally backed by automated tests.&lt;/p&gt;

&lt;p&gt;We do not work directly on &lt;code&gt;main&lt;/code&gt;; instead, it only receives thoroughly tested changes from &lt;code&gt;release&lt;/code&gt; or &lt;code&gt;hotfix&lt;/code&gt; branches.&lt;/p&gt;

&lt;h2&gt;
  
  
  development branch
&lt;/h2&gt;

&lt;p&gt;This branch contains the code in pre-production, features that are being actively developed but not yet ready for deployment. Developers merge their completed features here for testing, code review, and integration. Once stable, changes from &lt;code&gt;development&lt;/code&gt; are moved into &lt;code&gt;release&lt;/code&gt;, and eventually into &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  hot-fix branches
&lt;/h3&gt;

&lt;p&gt;Sometimes bugs appear in production, and the &lt;code&gt;development&lt;/code&gt; branch isn't in a deployable state, maybe it contains half-finished features. In those cases, we create a &lt;code&gt;hotfix&lt;/code&gt; branch from &lt;code&gt;main&lt;/code&gt;, apply the fix, test it, and then merge it back into both &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;development&lt;/code&gt;. This avoids introducing the bug again during the next release cycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  release branches
&lt;/h3&gt;

&lt;p&gt;These branches are used to prepare a new version of the application before pushing it to production. Think of them as a staging area to finalize bug fixes, polish features, or update documentation.&lt;/p&gt;

&lt;p&gt;When everything is ready, the &lt;code&gt;release&lt;/code&gt; branch is merged into &lt;code&gt;main&lt;/code&gt; and tagged with the version number. It is also merged back into &lt;code&gt;development&lt;/code&gt; to ensure it stays up-to-date.&lt;/p&gt;

&lt;h3&gt;
  
  
  So where do we actually do the work?
&lt;/h3&gt;

&lt;p&gt;Developers don’t work directly on &lt;code&gt;main&lt;/code&gt; or &lt;code&gt;development&lt;/code&gt;. Instead, they create temporary branches for each task, feature, or bug:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;feature/&lt;/code&gt; for new features&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fix/&lt;/code&gt; for bug fixes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;refactor/&lt;/code&gt; for code improvements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These branches are created from &lt;code&gt;development&lt;/code&gt;, and when finished, they’re merged back into it.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Make sure your main and development branches are up to date&lt;/span&gt;
git fetch origin
git switch development
git pull origin development

&lt;span class="c"&gt;# Create a new branch for your feature&lt;/span&gt;
git switch &lt;span class="nt"&gt;-c&lt;/span&gt; feature/contact-form

&lt;span class="c"&gt;# Work locally, commit changes&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add contact form to homepage"&lt;/span&gt;

&lt;span class="c"&gt;# Push your feature branch&lt;/span&gt;
git push origin feature/contact-form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, from GitHub (or GitLab), you’ll open a Pull Request (or Merge Request) targeting the &lt;code&gt;development&lt;/code&gt; branch. The team lead or reviewer will evaluate your changes and decide whether to approve them.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use Git Flow
&lt;/h3&gt;

&lt;p&gt;Git Flow works best when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your team releases software in fixed versions or sprints.&lt;/li&gt;
&lt;li&gt;You need to manage parallel development, hotfixes, and releases.&lt;/li&gt;
&lt;li&gt;You want to enforce a clean separation between stable and experimental code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It may be too rigid for teams practicing continuous deployment or working on fast-moving web applications, but for many software projects, Git Flow provides clarity and discipline.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Flow
&lt;/h2&gt;

&lt;p&gt;GitHub Flow is designed to be lightweight and fast-paced. It focuses on just one main branch (&lt;code&gt;main&lt;/code&gt;), and uses temporal branches to introduce new work. There’s no &lt;code&gt;development&lt;/code&gt;, &lt;code&gt;release&lt;/code&gt;, or &lt;code&gt;hotfix&lt;/code&gt;branches, just your feature branches and &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It was popularized by GitHub around 2011 as an alternative to more heavyweight workflows like Git Flow. It aligns well with continuous deployment practices, where the codebase is always in a deployable state and new features are delivered to users as soon as they’re ready.&lt;/p&gt;

&lt;p&gt;It’s especially popular in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SaaS applications&lt;/li&gt;
&lt;li&gt;Web apps with daily deployments&lt;/li&gt;
&lt;li&gt;Startups or small teams prioritizing speed and flexibility&lt;/li&gt;
&lt;/ul&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Make sure you're up to date with the main branch&lt;/span&gt;
git fetch origin
git switch main
git pull origin main

&lt;span class="c"&gt;# Create your feature branch&lt;/span&gt;
git switch &lt;span class="nt"&gt;-c&lt;/span&gt; feature/new-navbar

&lt;span class="c"&gt;# Work on your changes&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add new responsive navbar"&lt;/span&gt;

&lt;span class="c"&gt;# Push to GitHub&lt;/span&gt;
git push origin feature/new-navbar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When to Use GitHub Flow
&lt;/h3&gt;

&lt;p&gt;GitHub Flow is ideal if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You deploy frequently, even multiple times a day&lt;/li&gt;
&lt;li&gt;You have automated testing and CI/CD pipelines&lt;/li&gt;
&lt;li&gt;You value simplicity and speed over structured release cycles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It might not be suitable if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your project requires strict versioning&lt;/li&gt;
&lt;li&gt;You need parallel hotfix and release management&lt;/li&gt;
&lt;li&gt;You're working with large teams and long-running features&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Trunk-Based Development
&lt;/h2&gt;

&lt;p&gt;Trunk-Based Development (TBD) is a modern Git workflow used by high-performing engineering teams, especially those practicing continuous integration and continuous delivery (CI/CD).&lt;/p&gt;

&lt;p&gt;In this model, all developers commit to a single shared branch, usually called &lt;code&gt;main&lt;/code&gt; or &lt;code&gt;trunk&lt;/code&gt;. Feature branches either don’t exist or live very briefly (e.g., for hours, not days). The goal is to reduce integration overhead and release changes quickly and safely.&lt;/p&gt;

&lt;p&gt;TBD has been around for over a decade but gained traction thanks to Google, Facebook, and other companies that needed to ship code rapidly without drowning in long-lived branches.&lt;/p&gt;

&lt;p&gt;It’s often paired with practices like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feature flags&lt;/li&gt;
&lt;li&gt;Canary releases&lt;/li&gt;
&lt;li&gt;Automated testing&lt;/li&gt;
&lt;li&gt;Code reviews on small commits&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Core Concepts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Only one long-lived branch: &lt;code&gt;main&lt;/code&gt; (or &lt;code&gt;trunk&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Developers push directly to &lt;code&gt;main&lt;/code&gt; or short-lived branches merged quickly&lt;/li&gt;
&lt;li&gt;CI runs on every commit to ensure stability&lt;/li&gt;
&lt;li&gt;Use feature toggles to hide incomplete work from users&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  But... It seems the same as GitHub Flow 😄
&lt;/h3&gt;

&lt;p&gt;Yes, they are very similar, but there are some key differences:&lt;/p&gt;

&lt;h4&gt;
  
  
  Development Worflow
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In GitHub Flow, you create pull requests from your feature branches into &lt;code&gt;main&lt;/code&gt;. Once the pull request is approved, the deployment process starts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Trunk-Based Development, changes are pushed directly to &lt;code&gt;main&lt;/code&gt;, often multiple times per day. Every new commit can trigger a deployment pipeline, which is strongly backed by automated testing and CI/CD tools.&lt;/p&gt;
&lt;h4&gt;
  
  
  Handling New features
&lt;/h4&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In GitHub Flow, new features can live in their own branches until they're complete and ready for production.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In TBD, new features live inside &lt;code&gt;main&lt;/code&gt; from the start. They're controlled using feature flags or feature toggles, which allow developers to merge incomplete work without exposing it to users.&lt;br&gt;
&lt;/p&gt;&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isFeatureEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;newCheckout&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="nf"&gt;renderNewCheckout&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="nf"&gt;renderOldCheckout&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;Feature flags allow us to gradually test new features, experiment with multiple versions at the same time, or roll out functionality to a specific group of users, such as in canary releases.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use
&lt;/h3&gt;

&lt;p&gt;Use TBD when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You practice continuous integration/deployment&lt;/li&gt;
&lt;li&gt;You want to reduce merge conflicts and simplify code integration&lt;/li&gt;
&lt;li&gt;Your team ships often and values small, incremental changes\&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It may not be ideal if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You lack automated tests or CI pipelines&lt;/li&gt;
&lt;li&gt;Your team isn’t disciplined about pushing only tested code&lt;/li&gt;
&lt;li&gt;You release on a strict versioning schedule&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ship / Show / Ask
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ship/Show/Ask (SSA)&lt;/strong&gt; is less of a branching strategy and more of a philosophy for how developers collaborate and share their work. Unlike Git Flow or Trunk-Based Development, SSA doesn’t prescribe a specific structure—it’s about how and when you involve others in your development process.&lt;/p&gt;

&lt;p&gt;This model has been promoted by companies like GitHub and others that favor developer autonomy, asynchronous workflows, and decentralized decision-making.&lt;/p&gt;

&lt;p&gt;SSA defines three modes of contributing code, each reflecting a different level of collaboration:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Ship
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Ship&lt;/strong&gt; means you make the change, push it, and deploy it without asking for permission. This is best for small, low-risk, or well-understood changes—like fixing typos, updating comments, or making trivial bug fixes.&lt;/p&gt;

&lt;p&gt;It relies on strong developer judgment and confidence in the CI/test suite to catch issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Show
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Show&lt;/strong&gt; means you share your work before merging or deploying it, but you’re not necessarily asking for approval. It’s useful for mid-sized tasks, experimental ideas, or when you want early feedback. You might open a Pull Request with a title like &lt;code&gt;[WIP] Refactor login logic&lt;/code&gt; and invite comments.&lt;/p&gt;

&lt;p&gt;It’s collaborative, but informal.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Ask
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Ask&lt;/strong&gt; is the most formal mode. You request a review and wait for approval before merging. This is appropriate for high-risk, complex, or sensitive changes; basically, anything that should be reviewed before going to production.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about branches?
&lt;/h3&gt;

&lt;p&gt;SSA doesn’t enforce a particular branching model. In practice, it often looks like GitHub Flow: one long-lived branch (&lt;code&gt;main&lt;/code&gt; or &lt;code&gt;trunk&lt;/code&gt;) with short-lived feature branches. The key difference is how you handle the social process of merging, not the structure itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use Ship/Show/Ask
&lt;/h3&gt;

&lt;p&gt;SSA works well when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your team is experienced and trusts each other&lt;/li&gt;
&lt;li&gt;You value asynchronous, low-friction collaboration&lt;/li&gt;
&lt;li&gt;You have strong CI/CD and automated tests in place&lt;/li&gt;
&lt;li&gt;You want to balance autonomy with communication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It might not be ideal if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your team needs more structure or clarity&lt;/li&gt;
&lt;li&gt;Newer team members could benefit from stricter review processes&lt;/li&gt;
&lt;li&gt;Your organization requires tighter control over what reaches production&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;As we’ve seen, there are several Git workflow options, and the “right” one really depends on your team and project context. Choosing the right strategy can make a big difference in how smoothly your team works and how cleanly your project evolves.&lt;/p&gt;

&lt;p&gt;Even if you stick to just one workflow most of the time, I believe it’s important to be familiar with the others—you never know when a different model might come in handy. In the world of open source and cross-team collaboration, it's common to encounter these patterns, and recognizing them can make it much easier to jump in and contribute.&lt;/p&gt;

&lt;p&gt;I hope you’ve enjoyed this mini three-part series on Git and GitHub as much as I enjoyed writing it. If you have any questions or suggestions, feel free to drop a comment!&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Git tricks 2/3</title>
      <dc:creator>Facundo Botta</dc:creator>
      <pubDate>Sat, 29 Mar 2025 10:19:09 +0000</pubDate>
      <link>https://dev.to/facubotta/git-tricks-23-55h9</link>
      <guid>https://dev.to/facubotta/git-tricks-23-55h9</guid>
      <description>&lt;p&gt;Hi! I'm back with the second part of this series. Sorry for the delay. I don't have a lot of experience writing posts, and it takes me a moment. 😆 In this post, I want to share more cool Git commands and use cases inspired by my experience. I hope you enjoy it!&lt;/p&gt;

&lt;p&gt;By the way, I generated an image for the post with Mistral to have a cool banner picture. 😅 Let me know what you think!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Git stash&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;git stash&lt;/code&gt;&lt;/strong&gt; command is incredibly useful when you need to switch contexts but don't want to commit your current changes. It allows you to save your changes temporarily and come back to them later.&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="c"&gt;# Stash your current changes&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git stash

&lt;span class="c"&gt;# List all stashes&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git stash list

&lt;span class="c"&gt;# Apply the most recent stash&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git stash apply

&lt;span class="c"&gt;# Apply a specific stash&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git stash apply stash@&lt;span class="o"&gt;{&lt;/span&gt;1&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Drop the most recent stash&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git stash drop

&lt;span class="c"&gt;# Drop a specific stash&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git stash drop stash@&lt;span class="o"&gt;{&lt;/span&gt;1&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Clear all stashes&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git stash clear

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Git cherry-pick&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Sometimes, you might want to apply a specific commit from one branch to another. The &lt;strong&gt;&lt;code&gt;git cherry-pick&lt;/code&gt;&lt;/strong&gt; command allows you to do just that.&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="c"&gt;# Cherry-pick a specific commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git cherry-pick &amp;lt;commit_id&amp;gt;

&lt;span class="c"&gt;# Cherry-pick a range of commits&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git cherry-pick &amp;lt;start_commit_id&amp;gt;^..&amp;lt;end_commit_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Git bisect&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;git bisect&lt;/code&gt;&lt;/strong&gt; is a powerful tool for finding the commit that introduced a bug. It uses a binary search algorithm to help you identify the problematic commit efficiently.&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="c"&gt;# Start bisecting&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git bisect start

&lt;span class="c"&gt;# Mark the current commit as bad&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git bisect bad

&lt;span class="c"&gt;# Mark a known good commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git bisect good &amp;lt;commit_id&amp;gt;

&lt;span class="c"&gt;# Git will check out a commit in the middle. Test it and mark it as good or bad.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git bisect good  &lt;span class="c"&gt;# or&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git bisect bad

&lt;span class="c"&gt;# Continue this process until Git finds the first bad commit.&lt;/span&gt;

&lt;span class="c"&gt;# Reset bisecting&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git bisect reset
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Git tag&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Tagging is useful for marking specific points in your repository’s history as important. Typically, this is used to mark release points (e.g., v1.0.0).&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="c"&gt;# Create a lightweight tag&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git tag &amp;lt;tagname&amp;gt;

&lt;span class="c"&gt;# Create an annotated tag&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git tag &lt;span class="nt"&gt;-a&lt;/span&gt; &amp;lt;tagname&amp;gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Tag message"&lt;/span&gt;

&lt;span class="c"&gt;# Push a tag to the remote repository&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git push origin &amp;lt;tagname&amp;gt;

&lt;span class="c"&gt;# Push all tags to the remote repository&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git push &lt;span class="nt"&gt;--tags&lt;/span&gt;

&lt;span class="c"&gt;# List all tags&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git tag

&lt;span class="c"&gt;# Delete a local tag&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git tag &lt;span class="nt"&gt;-d&lt;/span&gt; &amp;lt;tagname&amp;gt;

&lt;span class="c"&gt;# Delete a remote tag&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git push origin :refs/tags/&amp;lt;tagname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Git diff&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/strong&gt; command shows the differences between commits, branches, files, and more. It’s a crucial tool for understanding what changes have been made.&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="c"&gt;# Show changes in the working directory that are not yet staged&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git diff

&lt;span class="c"&gt;# Show changes between the index and the last commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git diff &lt;span class="nt"&gt;--cached&lt;/span&gt;

&lt;span class="c"&gt;# Show changes between two commits&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git diff &amp;lt;commit_id_1&amp;gt; &amp;lt;commit_id_2&amp;gt;

&lt;span class="c"&gt;# Show changes between two branches&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git diff &amp;lt;branch_1&amp;gt; &amp;lt;branch_2&amp;gt;

&lt;span class="c"&gt;# Show changes in a specific file&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git diff &amp;lt;file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Git blame&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;git blame&lt;/code&gt;&lt;/strong&gt; command annotates each line in the given file with information about the last modification. This can be helpful for understanding who made specific changes and when.&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="c"&gt;# Show the last modification for each line of a file&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git blame &amp;lt;file&amp;gt;

&lt;span class="c"&gt;# Show the last modification for each line of a file at a specific commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git blame &amp;lt;commit_id&amp;gt; &lt;span class="nt"&gt;--&lt;/span&gt; &amp;lt;file&amp;gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Git commit --amend&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;git commit --amend&lt;/code&gt;&lt;/strong&gt; command is a lifesaver when you need to make changes to your most recent commit. Whether you forgot to add a file, made a typo in the commit message, or need to adjust the changes, &lt;strong&gt;&lt;code&gt;--amend&lt;/code&gt;&lt;/strong&gt; allows you to modify the last commit without creating a new one.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Use Cases&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fixing Commit Messages&lt;/strong&gt;: If you realize you made a typo or want to provide more context in your commit message, you can amend it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adding Forgotten Files&lt;/strong&gt;: If you forgot to add a file to the last commit, you can stage it and amend the commit to include it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modifying Changes&lt;/strong&gt;: If you need to make minor adjustments to the changes in the last commit, you can do so and amend the commit.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How to Use&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Make your changes (e.g., edit files, add new files)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git add &amp;lt;file&amp;gt;

&lt;span class="c"&gt;# Amend the last commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;--amend&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;When you run &lt;strong&gt;&lt;code&gt;git commit --amend&lt;/code&gt;&lt;/strong&gt;, your default text editor will open with the previous commit message. You can edit the message if needed, save, and close the editor. The commit will be updated with your changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Important Notes&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Avoid Amending Published Commits&lt;/strong&gt;: If the commit you want to amend has already been pushed to a shared repository, avoid using &lt;strong&gt;&lt;code&gt;-amend&lt;/code&gt;&lt;/strong&gt;. Amending a published commit can rewrite history and cause issues for others who have based their work on the original commit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Force Push&lt;/strong&gt;: If you must amend a published commit, you will need to force push the changes to the remote repository. Be cautious with this, as it can overwrite history.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Force push the amended commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git push &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Saving Disk Space with &lt;code&gt;git clone --depth=1&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When working with large repsitories, cloning the entire history can consume a significant amount of disk space. Fortunately, Git provides a way to clone only the latest commit, which can save you a lot of space and time. This is particularly useful when you only need the most recent version of the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Use Case&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large Repositories&lt;/strong&gt;: If you're working with a repository that has a long history and many large files, cloning the entire history can be time-consuming and disk-intensive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD Pipelines&lt;/strong&gt;: In continuous integration and deployment pipelines, you often only need the latest code to build and test. Cloning the entire history is unnecessary and can slow down the process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How to Use&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;--depth&lt;/code&gt;&lt;/strong&gt; option in &lt;strong&gt;&lt;code&gt;git clone&lt;/code&gt;&lt;/strong&gt; allows you to specify how many commits you want to clone. Setting &lt;strong&gt;&lt;code&gt;--depth=1&lt;/code&gt;&lt;/strong&gt; clones only the latest commit.&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="c"&gt;# Clone only the latest commit of a repository&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git clone &amp;lt;repo&amp;gt; &lt;span class="nt"&gt;--depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Important Notes&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shallow Clones&lt;/strong&gt;: Cloning with &lt;strong&gt;&lt;code&gt;-depth=1&lt;/code&gt;&lt;/strong&gt; creates a shallow clone. This means you won't have the full history of the repository, which can limit some Git operations that rely on the complete history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fetching More History&lt;/strong&gt;: If you later decide you need more history, you can fetch additional commits using the &lt;strong&gt;&lt;code&gt;git fetch&lt;/code&gt;&lt;/strong&gt; command with the &lt;strong&gt;&lt;code&gt;-depth&lt;/code&gt;&lt;/strong&gt; option.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fetch more history (e.g., the last 10 commits)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git fetch &lt;span class="nt"&gt;--depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unshallowing&lt;/strong&gt;: If you need to convert a shallow clone to a full clone, you can use the &lt;strong&gt;&lt;code&gt;git fetch --unshallow&lt;/code&gt;&lt;/strong&gt; command.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Convert a shallow clone to a full clone&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git fetch &lt;span class="nt"&gt;--unshallow&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;I tried to cover real-world scenario examples from my experience to show you some of Git's tools that can be useful. In the next and final post of this series, I will talk about workflows and more real-world use cases. I'm looking forward to your comments and I hope you've learned something! If you have any recommendations or corrections, please let me know!&lt;/p&gt;

&lt;p&gt;Thanks for reading, and see you next time!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>git</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>Git tricks 🚀 1/3</title>
      <dc:creator>Facundo Botta</dc:creator>
      <pubDate>Sun, 15 Dec 2024 16:50:12 +0000</pubDate>
      <link>https://dev.to/facubotta/git-tricks-13-5fk6</link>
      <guid>https://dev.to/facubotta/git-tricks-13-5fk6</guid>
      <description>&lt;p&gt;Hi there! Today I want to share with you some cool git tricks that I recently learned from a book, &lt;em&gt;“Aprendiendo Git &amp;amp; GitHub”&lt;/em&gt; (Learning Git &amp;amp; GitHub), and maybe it can be interesting to someone, and it's also a self-recap for me. I will split the post into three parts for a better reading and writing experience.&lt;/p&gt;

&lt;p&gt;In this book, we can find many pieces of advice and mentions of the importance of key concepts in the Git world, like good commit messages, descriptive PRs, and more. But here, I only want to share some useful commands I’ve learned. I’m at a trainee/junior level, so don’t judge me too harshly if the topics here are basic to you! Maybe you’ll learn something anyway 🤣. So, let's go on...&lt;/p&gt;

&lt;h3&gt;
  
  
  Git config
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;git config&lt;/code&gt; allows to us to personalize somes core aspects of our git installation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can list your current config like this :
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# To see all your config&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git config &lt;span class="nt"&gt;--list&lt;/span&gt;
&lt;span class="c"&gt;# To see only your global scope config&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git congit &lt;span class="nt"&gt;--global&lt;/span&gt; &lt;span class="nt"&gt;--list&lt;/span&gt;
&lt;span class="c"&gt;# To see your local scope config&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git config &lt;span class="nt"&gt;--local&lt;/span&gt; &lt;span class="nt"&gt;--list&lt;/span&gt;
&lt;span class="c"&gt;# To see your system config&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git config &lt;span class="nt"&gt;--system&lt;/span&gt; &lt;span class="nt"&gt;--list&lt;/span&gt;

&lt;span class="c"&gt;# You can add the --show-scope parameter to see the scope of any config&lt;/span&gt;
&lt;span class="c"&gt;# only available from 2.26.0 version of git&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git config &lt;span class="nt"&gt;--list&lt;/span&gt; &lt;span class="nt"&gt;--show-scope&lt;/span&gt;

&lt;span class="c"&gt;# You will see something like this&lt;/span&gt;
&lt;span class="c"&gt;# system  diff.astextplain.textconv=astextplain&lt;/span&gt;
&lt;span class="c"&gt;# system  filter.lfs.clean=git-lfs clean -- %f&lt;/span&gt;
&lt;span class="c"&gt;# system  filter.lfs.smudge=git-lfs smudge -- %f&lt;/span&gt;
&lt;span class="c"&gt;# system  filter.lfs.process=git-lfs filter-process&lt;/span&gt;
&lt;span class="c"&gt;# system  filter.lfs.required=true&lt;/span&gt;
&lt;span class="c"&gt;# system  http.sslbackend=openssl&lt;/span&gt;
&lt;span class="c"&gt;# system  http.sslcainfo=C:/Program Files/Git/mingw64/etc/ssl/certs/ca-bundle.crt&lt;/span&gt;
&lt;span class="c"&gt;# system  core.autocrlf=true&lt;/span&gt;
&lt;span class="c"&gt;# system  core.fscache=true&lt;/span&gt;
&lt;span class="c"&gt;# system  core.symlinks=false&lt;/span&gt;
&lt;span class="c"&gt;# system  core.editor=nano.exe&lt;/span&gt;
&lt;span class="c"&gt;# system  pull.rebase=false&lt;/span&gt;
&lt;span class="c"&gt;# system  credential.helper=manager&lt;/span&gt;
&lt;span class="c"&gt;# system  credential.https://dev.azure.com.usehttppath=true&lt;/span&gt;
&lt;span class="c"&gt;# system  init.defaultbranch=main&lt;/span&gt;
&lt;span class="c"&gt;# global  user.email=myMail@gmail.com&lt;/span&gt;
&lt;span class="c"&gt;# global  user.name=MyName&lt;/span&gt;
&lt;span class="c"&gt;# global  safe.directory=C:/xampp/htdocs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You can change some configuration like, for example, the default text editor…
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; core.editor &lt;span class="s2"&gt;"code"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we tell Git that we want VS Code as our global default text editor instead of the nano editor. You can specify another scope or text editor if you want to.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An other interesting thing you can do is set a global gitignore
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; core.excludefile path_to_the_file/.gitignore_global
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Git checkout &amp;amp; git switch
&lt;/h2&gt;

&lt;p&gt;We often use the &lt;em&gt;checkout&lt;/em&gt; command to create and/or switch between branches in Git repositories.&lt;/p&gt;

&lt;p&gt;It’s fine, but in fact, the &lt;em&gt;checkout&lt;/em&gt; command is an old and powerful command that can do more things than just switching branches:&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="c"&gt;# Switch to a specific branch&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git checkout &amp;lt;existing_branch_name&amp;gt;

&lt;span class="c"&gt;# Create and switch to a new branch&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; &amp;lt;new_branch_name&amp;gt;

&lt;span class="c"&gt;# Restore a file or many&lt;/span&gt;
&lt;span class="c"&gt;# (Note: if you don't use the -- directive you are creating a new branch...)&lt;/span&gt;
&lt;span class="c"&gt;# It will to restore the file to its state in the last commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git checkout &lt;span class="nt"&gt;--&lt;/span&gt; &amp;lt;file_1&amp;gt; &amp;lt;file_2&amp;gt; ...

&lt;span class="c"&gt;# Restore a file to a specific commit state&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git checkout &amp;lt;commit_id&amp;gt; &lt;span class="nt"&gt;--&lt;/span&gt; &amp;lt;file&amp;gt;

&lt;span class="c"&gt;# Switch to a specific commit&lt;/span&gt;
&lt;span class="c"&gt;# Note: If you do this, you won't be on any branch. This state is called "detached HEAD."&lt;/span&gt;
&lt;span class="c"&gt;# Any changes you make here can be lost because HEAD is not attached to a branch.&lt;/span&gt;
&lt;span class="c"&gt;# To save your changes, you need to create a new branch from this point.&lt;/span&gt;
&lt;span class="c"&gt;# In other words, you are not working on any branch at this moment.&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git checkout &amp;lt;commit_id&amp;gt;

&lt;span class="c"&gt;# Restore all the working tree&lt;/span&gt;
&lt;span class="c"&gt;# It will to restore all to its state in the last commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git checkout &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the &lt;em&gt;checkout&lt;/em&gt; command can do many things, and we may be doing something that we actually don’t want to do…&lt;/p&gt;

&lt;p&gt;To solve these potential confusions, Git introduced the &lt;em&gt;switch&lt;/em&gt; command in version ≥2.23:&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="c"&gt;# Switch to a specific branch&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git switch &amp;lt;branch_name&amp;gt;

&lt;span class="c"&gt;# Create and switch to a new branch&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git switch &lt;span class="nt"&gt;-c&lt;/span&gt; &amp;lt;new_branch_name&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;So to restore one o more files to the last commit state we have de &lt;em&gt;restore&lt;/em&gt; command:&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="c"&gt;# Restore une o more files&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git restore &amp;lt;file1&amp;gt;, &amp;lt;file2&amp;gt;
&lt;span class="c"&gt;# Restore all working tree&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git restore &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="c"&gt;# Restore all files with js expension&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git restore &lt;span class="s1"&gt;'*.js'&lt;/span&gt;
&lt;span class="c"&gt;# Restore a file to a specific commit state&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git restore &lt;span class="nt"&gt;--source&lt;/span&gt; &amp;lt;commit&amp;gt; &amp;lt;file&amp;gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Git reset
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If you accidentally add one or more files into the stashing area, you can run the &lt;em&gt;reset&lt;/em&gt; command to solve this problem:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Exit a file from the staging area&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &amp;lt;file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Git reset allows you to restore your branch to a specific commit
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Go back to the previous commit and SAVE THE CHANGES 😉&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--soft&lt;/span&gt; HEAD~1

&lt;span class="c"&gt;# Go back to the previous commit and DISCARD ALL the changes&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; HEAD~1

&lt;span class="c"&gt;# Go back to the second commit in this relative position&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; HEAD~2

&lt;span class="c"&gt;# Reset the branch to the remote repo state&lt;/span&gt;
&lt;span class="c"&gt;# WARNING: This will eliminate your local commits!&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; origin/&amp;lt;branch_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I use this &lt;code&gt;git reset&lt;/code&gt; when working on a feature or issue in my local branch, I might make several progressive commits, but I prefer not to "clutter" the commit history of the main branch with these intermediate commits. Instead, I aim to deliver a clean and concise PR with a single, well-organized commit.&lt;/p&gt;

&lt;p&gt;This approach ensures that only one commit is added to the main branch's history, making it easier for the team or the person responsible for reviewing and merging the PR.&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="c"&gt;# Here we see only the commits in my local branch&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt; &lt;span class="nt"&gt;--no-merges&lt;/span&gt; &lt;span class="nt"&gt;--branches&lt;/span&gt; &lt;span class="nt"&gt;--not&lt;/span&gt; &lt;span class="nt"&gt;--remotes&lt;/span&gt;

0f56980 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; preprod&lt;span class="o"&gt;)&lt;/span&gt; add_FTP_to_GA
1342e47 update_GA

&lt;span class="c"&gt;# So, I want only one commit&lt;/span&gt;
&lt;span class="c"&gt;# First, we reset to the last commit&lt;/span&gt;
&lt;span class="c"&gt;# ⚠️ use --soft !! 😂&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--soft&lt;/span&gt; HEAD~2

&lt;span class="c"&gt;# Then we can do a new sigle commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'Add FTP integration and update GA configuration'&lt;/span&gt;

&lt;span class="c"&gt;# And now we have only one commit&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt; &lt;span class="nt"&gt;--no-merges&lt;/span&gt; &lt;span class="nt"&gt;--branches&lt;/span&gt; &lt;span class="nt"&gt;--not&lt;/span&gt; &lt;span class="nt"&gt;--remotes&lt;/span&gt;

e6bc2e1 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; preprod&lt;span class="o"&gt;)&lt;/span&gt; Add FTP integration and update GA configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Git rm
&lt;/h2&gt;

&lt;p&gt;Imagine you added a &lt;code&gt;.env&lt;/code&gt; file, committed it, and then realized you forgot to add it to &lt;code&gt;.gitignore&lt;/code&gt;... maybe it's not too hard to imagine 🤣.&lt;/p&gt;

&lt;p&gt;To fix this, you can use the &lt;code&gt;git rm&lt;/code&gt; command. While &lt;code&gt;rm&lt;/code&gt; itself is a shell command, &lt;code&gt;git rm&lt;/code&gt; is part of Git and provides additional functionality to help us manage files in our repository&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="c"&gt;# Remove the file from the repository but KEEP it locally&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;--cached&lt;/span&gt; .env

&lt;span class="c"&gt;# Add it to .gitignore to ensure it's ignored in the future&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;".env"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore

&lt;span class="c"&gt;# Commit the changes&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git add .gitignore
&lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Remove .env and add it to .gitignore"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Note if you already push le .env file to your remote repo, is always recommended to update yours sensitives keys because one’s the .env file is in the remote repo this information can maybe already by exposed…&lt;/p&gt;

&lt;h2&gt;
  
  
  Git rebase
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;git rebase&lt;/code&gt; command is particularly useful when you want to keep your branch up-to-date with the main branch without introducing unnecessary merge commits. For example, if you're working on a feature branch (&lt;code&gt;feature-branch&lt;/code&gt;) and the main branch (&lt;code&gt;main&lt;/code&gt;) has received updates, you can use &lt;code&gt;git rebase&lt;/code&gt; to synchronize your branch with the latest changes. This repositions your commits so they appear as if they were made directly after the latest commits in &lt;code&gt;main&lt;/code&gt;, creating a cleaner and more linear history.&lt;/p&gt;

&lt;p&gt;This approach makes the commit history easier to read and avoids introducing extra merge commits. It’s especially helpful when collaborating in teams, as it minimizes potential conflicts and simplifies the process of merging your changes back into the main branch.&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="c"&gt;# In your feature-branch&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git pull &lt;span class="nt"&gt;--rebase&lt;/span&gt; origin main
&lt;span class="c"&gt;# or&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git fetch origin
&lt;span class="nv"&gt;$ &lt;/span&gt;git rebase origin/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To ilustrate the situation :&lt;/p&gt;

&lt;p&gt;with &lt;em&gt;rebase&lt;/em&gt; : A---B---C---D'---E'---F’&lt;/p&gt;

&lt;p&gt;without &lt;em&gt;rebase :   A---B---C---Merge---D---E---F&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Another use case for &lt;code&gt;git rebase&lt;/code&gt; is when you want to modify your local branch's commit history before publishing it. It’s important to note that you should avoid making this type of modification if your branch has already been published, as it can generate conflicts by overwriting the existing commit history. You can &lt;em&gt;squash&lt;/em&gt; multiple commits into one or change the commit’s messages and more.&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="c"&gt;# Here, -i is for interactive rebase&lt;/span&gt;
&lt;span class="c"&gt;# HEAD~4 tells Git that we want to rebase the last 4 commits&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~4

&lt;span class="c"&gt;# In your text editor, you will see something like this:&lt;/span&gt;
pick &amp;lt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Commit message A
pick &amp;lt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Commit message B
pick &amp;lt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Commit message C
pick &amp;lt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Commit message D

&lt;span class="c"&gt;# Now, you can modify the commit history:&lt;/span&gt;
&lt;span class="c"&gt;# - 'reword' allows you to change the commit message of one or more commits.&lt;/span&gt;
&lt;span class="c"&gt;# - 'squash' tells Git to combine commits into one.&lt;/span&gt;

&lt;span class="c"&gt;# Example: Changing the message of the second commit and squashing the last two commits into one.&lt;/span&gt;
pick &amp;lt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Commit message A
reword &amp;lt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Commit message B  &lt;span class="c"&gt;# Change the message of this commit&lt;/span&gt;
squash &amp;lt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Commit message C  &lt;span class="c"&gt;# Combine this commit with the previous one&lt;/span&gt;
squash &amp;lt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Commit message D  &lt;span class="c"&gt;# Combine this commit with the previous one&lt;/span&gt;

&lt;span class="c"&gt;# After saving and closing the editor:&lt;/span&gt;
&lt;span class="c"&gt;# - If you used 'reword', Git will open an editor to change the commit message.&lt;/span&gt;
&lt;span class="c"&gt;# - If you used 'squash', Git will prompt you to combine the commit messages.&lt;/span&gt;

&lt;span class="c"&gt;# This way, you can clean up your commit history, making it more concise and readable before pushing or creating a PR.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I invite you to see more details in the documentation &lt;a href="https://git-scm.com/docs/git-rebase" rel="noopener noreferrer"&gt;https://git-scm.com/docs/git-rebase&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;I think that's enough for this post. I have more things to share, but I'll save them for the next one. I'm looking forward to your comments and I hope you've learned something! If you have any recommendations or corrections, please let me know!&lt;/p&gt;

&lt;p&gt;Thanks for reading, and see you next time!&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>Meta Data in React</title>
      <dc:creator>Facundo Botta</dc:creator>
      <pubDate>Wed, 10 Apr 2024 18:34:23 +0000</pubDate>
      <link>https://dev.to/facubotta/meta-data-in-react-1p93</link>
      <guid>https://dev.to/facubotta/meta-data-in-react-1p93</guid>
      <description>&lt;p&gt;Hello! Today I want to delve into a crucial but often overlooked aspect of web development: SEO (Search Engine Optimization) and how we can improve the visibility of our React web applications through dynamic meta-data.&lt;/p&gt;

&lt;p&gt;As many of you may know, React is a powerful tool for building interactive and dynamic web applications. However, one of its limitations is its performance in terms of SEO, especially if you are working with client-side rendering. This is due to the behavior of the virtual DOM and how it renders on the page.&lt;/p&gt;

&lt;p&gt;When search engines crawl a website, they prefer static and well-structured content. However, React generates content dynamically on the client side using JavaScript, which can result in indexing issues for search engines.&lt;/p&gt;

&lt;p&gt;One way to address this issue is through the manipulation of meta-data, such as page titles, descriptions, and more meta tags, for each page of our application. This not only helps search engines understand and rank our content but also enhances the user experience by providing accurate and relevant information in search results.&lt;/p&gt;

&lt;p&gt;A common way to implement dynamic meta-data in a React application is through the use of libraries like Helmet. Helmet allows us to manipulate meta-tags programmatically, greatly simplifying the process and freeing us from the need to manually update each page.&lt;/p&gt;

&lt;p&gt;In this post, I want to share with you how I've used it to significantly improve the SEO of my applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;br&gt;
After React Helmet encountered certain difficulties in updating tags for social media, React Helmet Async emerged as a fork of React Helmet. This new library was established as a more reliable and robust solution for handling dynamic meta-tags updates. Therefore, it is recommended to use it over the original version of React Helmet to ensure consistent and optimal behavior in managing meta-data.&lt;br&gt;
So first, we need to install it with our package manager. In my case, I'm using npm, so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;helmet&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now you must wrap your application with the HelmetProvider component. In my case, it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AnimatedRoutes&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;./AnimatedRoutes.js&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="nx"&gt;Header&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;./Header.js&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="nx"&gt;Footer&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;./Footer&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;HelmetProvider&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-helmet-async&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HelmetProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AnimatedRoutes&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Footer&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/HelmetProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;So on each of your pages, you can import a Helmet component and declare each necessary meta-tag for that page within it. But why not leave that logic to a component, let's call it 'MetaTags', and have more concise and maintainable code?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Helmet&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-helmet-async&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// You can have more props. In my case, these are enough.&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MetaTags&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&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="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Helmet&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* Standard metadata tags */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;title&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;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/title&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;canonical&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* Open Graph tags (OG) */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;website&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* OG image tags */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:image:secure_url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:image:type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/jpeg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:image:width&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;200&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:image:alt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`Image of &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; site`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* Twitter tags */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitter:creator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitter:card&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;summary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitter:title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitter:description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Helmet&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MetaTags&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open Graph is a protocol developed by Facebook that allows us to control how our shared content appears on social media platforms. It is used by Facebook, LinkedIn, TikTok, and many others. However, Twitter has its own protocol for setting up its meta-tags. You can find more information about these protocols on their official websites: &lt;br&gt;
&lt;a href="https://developers.facebook.com/docs/sharing/webmasters/" rel="noopener noreferrer"&gt;Open Graph&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started" rel="noopener noreferrer"&gt;Twitter Tags&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we only need to place a MetaTag component on each page to have all our meta-data configured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;import&lt;/span&gt; &lt;span class="nx"&gt;MetaTags&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;../components/MetaTags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Example page&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MetaExample&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;lt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MetaTags&lt;/span&gt;
                &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Meta Example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
                &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is a test description to show you how to improve SEO in your React web applications!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
                &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;url to the image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
                &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;FacuDev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
            &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;MetaExample&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MetaExample&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To verify the functionality of our meta-tags, we can use a Google Chrome extension such as "META SEO Inspector":&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%2Fxwv3yuodm9sfupjz8tju.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%2Fxwv3yuodm9sfupjz8tju.png" alt="Common Tags" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvy3yla8jw557vz6e0g24.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%2Fvy3yla8jw557vz6e0g24.png" alt="Social Tags" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are hosting your site, you can see how the social cards look using the &lt;a href="https://developers.facebook.com/tools/debug/?locale=en" rel="noopener noreferrer"&gt;Facebook Card Validator&lt;/a&gt; and by simply making a post on your Twitter account. Twitter has its own card validator, but it's no longer functional, so you have to simulate a post to see it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
We have seen a simple way to manage our meta-data to provide better performance in our SEO. I consider this a crucial aspect if we are working with single-page applications and client-side rendering where this aspect is more affected.&lt;br&gt;
I hope this post has been helpful to someone, and you can suggest changes or ideas!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>seo</category>
      <category>html</category>
    </item>
    <item>
      <title>Auto-size &lt;TextArea/&gt;</title>
      <dc:creator>Facundo Botta</dc:creator>
      <pubDate>Mon, 01 Apr 2024 09:44:22 +0000</pubDate>
      <link>https://dev.to/facubotta/auto-size-492o</link>
      <guid>https://dev.to/facubotta/auto-size-492o</guid>
      <description>&lt;p&gt;Hi! Recently, in one of my React projects, I had to use a textarea for my contact form, and this time I wasn't willing to accept its default behavior... So here I show you the solution I found to give our  component the auto-sizing property.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;. So, first we have to create the basic TextArea component and set some styles for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TextArea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;70px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;scrollbarWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Firefox&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-ms-overflow-style&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;none&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;::-webkit-scrollbar&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="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;textarea&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;TextArea&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;You can set more styles or pass them as props if you want to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt;. Now, to use it, we have to import it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TextArea&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;../components/TextArea&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="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;YourParentComponent&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;textAreaRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;TextArea&lt;/span&gt;
      &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;textAreaRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;placeHolder&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;I&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="nx"&gt;textarea&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;}
      minHeight={&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;}
    /&amp;gt;
  );
};
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can set a placeholder or more options with props. To access the value of our TextArea, we have to use the useRef hook and then pass the ref to the component, so we have to modify it a little:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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="c1"&gt;// Thanks to the react's function forwardRef()&lt;/span&gt;
&lt;span class="c1"&gt;// we can give a external ref to our component.&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TextArea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;forwardRef&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;minHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;50px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;placeHolder&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;ref&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;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;minHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;scrollbarWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Firefox&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-ms-overflow-style&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;none&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;::-webkit-scrollbar&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="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;textarea&lt;/span&gt;
      &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;placeHolder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;placeHolder&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;TextArea&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3&lt;/strong&gt;. Now we can set the behavior of auto-sizing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This simple function sets the textarea's height to its scrollHeight value.&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;minHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollHeight&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// So we just have to call this function when the textarea's value changes.&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;textarea&lt;/span&gt;
      &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;placeHolder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;placeHolder&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleHeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Now our textarea is more user-friendly, in my opinion:&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%2Fsnoj2we7pbrtywvl3km3.gif" 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%2Fsnoj2we7pbrtywvl3km3.gif" alt="textarea component in action" width="600" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my case, I'm using it with a default value taken from the database. So, you have to set the defaultValue and add a useEffect() to set the height on the first render. So, finally, the TextArea component looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;forwardRef&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TextArea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;forwardRef&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;minHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;50px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;ref&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;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;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollHeight&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&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;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&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;handleHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;minHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollHeight&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&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;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;70px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;outline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;18px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;minHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;minHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;scrollbarWidth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Firefox&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-ms-overflow-style&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;none&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;::-webkit-scrollbar&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="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0px&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;textarea&lt;/span&gt;
      &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;defaultValue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleHeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;TextArea&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Only as an example, I'll show you how to retrieve the value, but you can set this value in a FormData object in your form's submit function, for instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In your parent component.&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;takeValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="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;textAreaRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nf"&gt;takeValue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're working with JavaScript and not using React, you can apply the same logic as the handleHeight() function, and instead of using useRef(), you can take the textarea element by its id with getElementById('your_textarea_id').&lt;/p&gt;

&lt;p&gt;I hope the post has been helpful for you, and feel free to ask me any questions or leave comments!&lt;/p&gt;

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