<?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: Shubham Patil</title>
    <description>The latest articles on DEV Community by Shubham Patil (@shubhampatilsd).</description>
    <link>https://dev.to/shubhampatilsd</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%2F686853%2F04b21e97-23c9-44ab-8d54-d094a0f87a94.jpg</url>
      <title>DEV Community: Shubham Patil</title>
      <link>https://dev.to/shubhampatilsd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shubhampatilsd"/>
    <language>en</language>
    <item>
      <title>Removing Timezones from Dates in Javascript</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Sun, 23 Apr 2023 00:43:58 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/removing-timezones-from-dates-in-javascript-46ah</link>
      <guid>https://dev.to/shubhampatilsd/removing-timezones-from-dates-in-javascript-46ah</guid>
      <description>&lt;h2&gt;
  
  
  Foreword
&lt;/h2&gt;

&lt;p&gt;It's been a while since I've wrote on here. I'm planning to write smaller pieces on here that relate to problems that I solve on a day-to-day basis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;I was working on the React Native app the other day for my travel-planning startup, &lt;a href="https://tripley.app" rel="noopener noreferrer"&gt;Tripley&lt;/a&gt;, and came across a somewhat unique problem. When creating events for the trip calendar, it would store dates with the current timezone in mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Bit (Too Much) About Timezones
&lt;/h2&gt;

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

&lt;p&gt;To prevent one side of the world eating their lunches in darkness, timezones were created. PST (Pacific Standard Time) is 3 hours behind EST (Eastern Standard Time). This means that &lt;code&gt;1:00&lt;/code&gt; in San Francisco is equivalent to &lt;code&gt;4:00&lt;/code&gt; in New York. &lt;/p&gt;

&lt;p&gt;Each timezone gets a code relative to the timezone in London, UK. The timezone in London is GMT (Greenwich Mean Time). Why London? Imperialism.&lt;/p&gt;

&lt;p&gt;"Universal Coordinated Time" (UTC) is derived from GMT (it's essentially the same time). The main difference between UTC and London's time is that UTC doesn't care about daylight savings. When The UK undergoes daylight savings and switches to the BST (British Summer Time) timezone, UTC stays the same time as it was before.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each timezone gets a code relative to the timezone in London, UK.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Back to this. Each timezone gets a time in hours relative to the UTC time. PST's "code" is &lt;code&gt;UTC-8&lt;/code&gt;, which specifies that PST is 8 hours behind UTC time. This isn't limited to just hours. Nepal, for example, has a code of &lt;code&gt;UTC+05:45&lt;/code&gt;, which specifies that it is 5 hours and 45 minutes ahead of UTC time. BST even has a UTC code, which is &lt;code&gt;UTC+1&lt;/code&gt;. In daylight savings time for Britain, the BST timezone is one hour of UTC time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;This was a big problem for us. Say that you selected &lt;code&gt;August 8th, 2023 at 4:30 PM&lt;/code&gt; while sitting in San Francisco. By the nature of JavaScript, the date would be registered under UTC time (in this case, it would be &lt;code&gt;August 8th, 2023 at 11:30 PM UTC&lt;/code&gt;). For your trip, if you travel to the island of Oahu, Hawaii, you would be under the HST timezone (Hawaiian Standard Time), which is 3 hours behind PST (Pacific Standard Time). &lt;/p&gt;

&lt;p&gt;The event that you scheduled for 4:30 PM would now show up at 1:30 PM for you. This would occur because JavaScript automatically adjusts UTC dates for you based on your current timezone. It would convert the UTC date we had to the HST timezone.&lt;/p&gt;

&lt;p&gt;Suppose we had a JS date variable called &lt;code&gt;date&lt;/code&gt;, and we ran this in San Francisco:&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;//Wed Feb 22 2023 14:00:43 GMT-0800 (Pacific Standard Time)&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;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, if we ran this in Honolulu, it would look a bit different:&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;//Wed Feb 22 2023 11:00:43 GMT-1000 (Hawaiian Aleutian Time)&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;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In either timezone, if you print the date using the &lt;code&gt;.toISOString()&lt;/code&gt; method, you will get a date in the ISO 8061 format: &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;//2023-02-22T22:00:43.000Z&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;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This ISO string is in UTC time. If we dissect this string, we can see that the &lt;code&gt;T&lt;/code&gt; is a separator in the string. So, we have two portions: &lt;code&gt;2023-02-22&lt;/code&gt; and &lt;code&gt;22:00:43.000Z&lt;/code&gt;. The first part is easily identifiable; it's the date! The second part is the time string. &lt;/p&gt;

&lt;p&gt;Our original date in PST was &lt;code&gt;14:00:43&lt;/code&gt;, but this date reads &lt;code&gt;22:00:43&lt;/code&gt;? This is because the date is stored in UTC. The PST timezone is 8 hours behind UTC right? If you add &lt;code&gt;8 hours&lt;/code&gt; to &lt;code&gt;14:00:43&lt;/code&gt;, you get &lt;code&gt;22:00:43&lt;/code&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;I tried a couple things when I learned about this. First of all, I tried to see if I could omit the timezone. My first thought was to use the &lt;code&gt;.toLocaleString()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Here is how it would look like:&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// "2/23/2023, 1:48:30 PM"&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;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;I decided that I would put this string (&lt;code&gt;2/23/2023, 1:48:30 PM&lt;/code&gt;) in my database. I thought that I could then input this as a parameter to the &lt;code&gt;Date&lt;/code&gt; constructor on the client, like so:&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;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2/23/2023, 1:48:30 PM&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;I tried the code above in the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date" rel="noopener noreferrer"&gt;MDN Web Docs JS Date Playground&lt;/a&gt; with my computer set in PST and HST:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu2nvr55jhh1ca72h2kmi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu2nvr55jhh1ca72h2kmi.png" width="800" height="464"&gt;&lt;/a&gt;&lt;br&gt;Code run in PST timezone
  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvi20tuzbyaueb5442zz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvi20tuzbyaueb5442zz.png" width="800" height="464"&gt;&lt;/a&gt;&lt;br&gt;Code run in HST timezone
  &lt;/p&gt;

&lt;p&gt;I looked at both results and they were the same! I finally thought that this would be a great solution: store the output of &lt;code&gt;.toLocaleString()&lt;/code&gt; and convert it to a &lt;code&gt;Date&lt;/code&gt; again on the client, all without the timezone.&lt;/p&gt;

&lt;p&gt;However, when I implemented the solution in my React Native app, it didn't work. It kept telling me that I had passed an invalid date into the &lt;code&gt;Date&lt;/code&gt; constructor. I searched on the internet. Then, I found this on the MDN Web Docs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6t31n2xktga3l5qa74n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6t31n2xktga3l5qa74n.png" alt="dialog box on docs saying Note: Parsing of strings with Date.parse is strongly discouraged due to browser differences and inconsistencies." width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gave me a hint as to why the code worked in my browser but not my React Native app. The JS in Firefox was running on a different runtime than React Native.&lt;/p&gt;

&lt;h2&gt;
  
  
  Short Note About JS Engines
&lt;/h2&gt;

&lt;p&gt;Since JavaScript is so uncoordinated, JS code typically runs in a specific environment called an engine. Each browser has their own engine: Chrome uses the V8 engine, Firefox uses their SpiderMonkey engine, and Safari uses JavaScriptCore.&lt;/p&gt;

&lt;p&gt;In React Native's case, it uses an engine called &lt;a href="https://hermesengine.dev" rel="noopener noreferrer"&gt;Hermes&lt;/a&gt;:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc471vxdtmboph7ctshbf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc471vxdtmboph7ctshbf.png" alt="hermes logo" width="493" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was testing my code on Firefox, which uses the SpiderMonkey engine, and running my code in my React Native app, which uses Hermes. Within these two engines, there must be a discrepancy between how the &lt;code&gt;Date&lt;/code&gt; constructor parses a given string.&lt;/p&gt;

&lt;h2&gt;
  
  
  Second Round of Solutions
&lt;/h2&gt;

&lt;p&gt;Now (after 2 hours) that I realized that my first idea wouldn't work, I came up with another &lt;/p&gt;

&lt;p&gt;If we create a &lt;code&gt;Date&lt;/code&gt; object with the given ISO string, the UTC time automatically gets converted to the current timezone.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2023-02-22T22:00:43.000Z&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Wed Feb 22 2023 14:00:43 GMT-0800 (Pacific Standard Time)&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;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, if we remove the &lt;code&gt;Z&lt;/code&gt; from the end of the ISO8601 string, the timezone does not get automatically converted.&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;// notice the change&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2023-02-22T22:00:43.000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Wed Feb 22 2023 22:00:43 GMT-0800 (Pacific Standard Time)&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;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;console.log&lt;/code&gt; output changes from &lt;code&gt;2:00 PM&lt;/code&gt; to &lt;code&gt;10:00 PM&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pseudocode?
&lt;/h3&gt;

&lt;p&gt;So here was the idea that I had. For simplicity purposes, let's select a date &amp;amp; time from the datepicker in our app: &lt;code&gt;Feb 22 2023 at 4:30 PM&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If we &lt;code&gt;console.log&lt;/code&gt; this &lt;code&gt;Date&lt;/code&gt; object's ISO8061 string, we'll get:&lt;/p&gt;

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

2023-02-23T00:30:00.000Z


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

&lt;/div&gt;

&lt;p&gt;Notice how the date is one day ahead and the time is 8 hours ahead of our given time. We can offset this difference simply by subtracting 8 hours (since I created this in the PST timezone) from the UTC time.&lt;/p&gt;

&lt;p&gt;If we do that (subtract 8 hours), we get&lt;/p&gt;

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

2023-02-22T16:30:00.000Z


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

&lt;/div&gt;

&lt;p&gt;However, if we create a new &lt;code&gt;Date&lt;/code&gt; object and &lt;code&gt;console.log&lt;/code&gt; that, we get this string:&lt;/p&gt;

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

Wed Feb 22 2023 22:00:43 GMT-0800 (Pacific Standard Time)


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

&lt;/div&gt;

&lt;p&gt;We can still see that the UTC time is being converted to the local time. We can fix that by chopping off that trailing &lt;code&gt;Z&lt;/code&gt; character in the ISO8601 string.&lt;/p&gt;

&lt;p&gt;This is what the resulting ISO8601 string would look like:&lt;/p&gt;

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

2023-02-22T16:30:00.000


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

&lt;/div&gt;

&lt;p&gt;Now, if we &lt;code&gt;console.log&lt;/code&gt; the given &lt;code&gt;Date&lt;/code&gt; object in San Francisco, we get this string:&lt;/p&gt;

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

Wed Feb 22 2023 16:30:00 GMT-0800 (Pacific Standard Time)


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

&lt;/div&gt;

&lt;p&gt;Now, despite the timezone information still being there in the &lt;code&gt;console.log&lt;/code&gt;, if we run the same code in Honolulu, we'll get&lt;/p&gt;

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

Wed Feb 22 2023 16:30:00 GMT-1000 (Hawaiian Aleutian Time)


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

&lt;/div&gt;

&lt;p&gt;The two dates line up! Now here is the actual implementation for the pseudocode:&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dateWithoutTimezone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&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;tzoffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTimezoneOffset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//offset in milliseconds&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withoutTimezone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;tzoffset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;withoutTimezone&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;First &lt;code&gt;tzoffset&lt;/code&gt; initializes a new Date and get the timezone offset in milliseconds (in my case, it would be 28800000 milliseconds). &lt;/p&gt;

&lt;p&gt;Then, we subtract that from the value of &lt;code&gt;date&lt;/code&gt;, which was &lt;code&gt;10:30 PM&lt;/code&gt;, so it would now be &lt;code&gt;4:30 PM&lt;/code&gt;. Then, we cut off the trailing &lt;code&gt;Z&lt;/code&gt; from the ISO String so that JS doesn't consider it in UTC and convert it.&lt;/p&gt;

&lt;p&gt;And there we go! The function returns an ISO String that we can now store in our databases.&lt;/p&gt;

&lt;p&gt;To parse this date again, you can simply run:&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;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2023-02-22T16:30:00.000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;and if we &lt;code&gt;console.log&lt;/code&gt; that, we'll get &lt;/p&gt;

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

Wed Feb 22 2023 16:30:00 GMT-1000 (Hawaiian Aleutian Time)


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

&lt;/div&gt;




&lt;h2&gt;
  
  
  End
&lt;/h2&gt;

&lt;p&gt;Hey thanks for reading my blog! I'm planning on writing small blogs (if schoolwork doesn't get in the way). &lt;/p&gt;

&lt;p&gt;It's been a while since I last blogged, but in that time I've founded &lt;a href="https://tripley.app" rel="noopener noreferrer"&gt;Tripley&lt;/a&gt;, an app that helps you plan and go on trips much more easily. It would help us out a ton if you could sign up for our &lt;a href="https://tally.so/r/wQo9aG" rel="noopener noreferrer"&gt;waitlist&lt;/a&gt; and give us a follow on &lt;a href="https://twitter.com/tripleyapp" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.instagram.com/tripleyapp/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;. Thanks!&lt;/p&gt;

&lt;p&gt;If you want to see more of my daily thoughts, follow my &lt;a href="https://twitter.com/ShubhamPatilsd" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, much appreciated!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Sanity.io: a really good CMS</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Thu, 30 Jun 2022 03:28:53 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/sanityio-a-really-good-cms-42h9</link>
      <guid>https://dev.to/shubhampatilsd/sanityio-a-really-good-cms-42h9</guid>
      <description>&lt;p&gt;A couple weeks ago, I had to figure how to serve dynamic content for my personal website. While researching, I was led to the concept of a CMS (Content Management System). Most CMSs have the concept of the frontend and backend both being included, but that wouldn't work for my use case, since I already had a frontend up and running. &lt;/p&gt;

&lt;h3&gt;
  
  
  Headless CMS
&lt;/h3&gt;

&lt;p&gt;This is where I learned about the concept of a Headless CMS. The concept of a Headless CMS is that you only get the backend, and instead you ping an API for your data.&lt;/p&gt;

&lt;p&gt;I started searching for a good list of Headless CMSs, but none of them were quite as quick to setup as I expected. Most of them required you to host them somewhere, and I &lt;em&gt;definitely&lt;/em&gt; did not want to spend money in order to host my stuff on a server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction to Sanity
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fca8gsp359m9rxa1h9gns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fca8gsp359m9rxa1h9gns.png" alt="benjamin ashbaugh (who has a profile picture of a cow) saying "&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;While I was searching for a good CMS for my website, a certain &lt;a href="https://benjaminashbaugh.me/" rel="noopener noreferrer"&gt;Benjamin Ashbaugh&lt;/a&gt; (yes, I can confirm he is a cow) in &lt;a href="https://hackclub.com/" rel="noopener noreferrer"&gt;Hack Club's&lt;/a&gt; Slack workspace told me about a certain CMS called Sanity. It didn't require me to host my own instance anywhere and was really easy to edit through a tool called Sanity Studio.&lt;/p&gt;

&lt;p&gt;So I decided to give it a try, since the worse that could happen is that I don't have a good experience and lose hours of my life ¯_(ツ)_/¯&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's-a-go!
&lt;/h3&gt;

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

&lt;p&gt;Sanity has a really good &lt;a href="https://www.sanity.io/get-started/1" rel="noopener noreferrer"&gt;starter guide&lt;/a&gt; to introduce you to the technology, so I would recommend following that to get the basic repository set up&lt;/p&gt;

&lt;h3&gt;
  
  
  Difference between Sanity Studio and Content Lake
&lt;/h3&gt;

&lt;p&gt;Sanity Studio is a really intuitive tool used to manipulate data from Sanity itself (sort of like how Prisma Studio). Content Lake is the data itself that comes from handling data in Sanity Studio. Clients can access the Content Lake from the API that Sanity provides.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schema
&lt;/h3&gt;

&lt;p&gt;After you get Sanity Studio working, you're probably going to have to generate a schema.&lt;/p&gt;

&lt;p&gt;One file will be labeled &lt;code&gt;schema.js&lt;/code&gt;, which will be the gateway to our schema. Here is an example of 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="c1"&gt;// First, we must import the schema creator&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;createSchema&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;part:@sanity/base/schema-creator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Then import schema types from any plugins that might expose them&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;schemaTypes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;all:part:@sanity/base/schema-type&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;project&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./project&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Then we give our schema to the builder and provide the result to Sanity&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;createSchema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// We name our schema&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// Then proceed to concatenate our document type&lt;/span&gt;
  &lt;span class="c1"&gt;// to the ones provided by any plugins that are installed&lt;/span&gt;
  &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;schemaTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="cm"&gt;/* Your types here! */&lt;/span&gt;
    &lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might be wondering what exactly is the &lt;code&gt;project&lt;/code&gt; import doing there. Well, that's our second file, the actual schema of the entity in question, &lt;code&gt;project.js&lt;/code&gt;. Here is an example of that file:&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;project&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;document&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Project&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;demo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Demo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;github&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Github&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Technologies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;technologies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;array&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, first of all, we import an object as the default export. Then, we define the &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt;, and &lt;code&gt;title&lt;/code&gt;. In our &lt;code&gt;project.js&lt;/code&gt; file, we specify that it is a &lt;code&gt;"document"&lt;/code&gt;. Now, you might be wondering the difference between the &lt;code&gt;name&lt;/code&gt; and the &lt;code&gt;title&lt;/code&gt;. The name is most likely how Sanity refers to the data internally, while &lt;code&gt;title&lt;/code&gt; is just how it's presented to the user.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;fields&lt;/code&gt; array contains a bunch of objects specifying the different fields in the schema. You can find more about schema types &lt;a href="https://www.sanity.io/docs/schema-types" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanity Client
&lt;/h2&gt;

&lt;p&gt;To access data from the Content Lake, I'm going to use a client for Sanity. Alternatively, you can use the &lt;a href="https://www.sanity.io/docs/http-api" rel="noopener noreferrer"&gt;HTTP API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm going to use the Node.js API, so I can simply install it with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @sanity/client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn &lt;span class="nb"&gt;install&lt;/span&gt; @sanity/client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we are going to create a new file (anywhere you want) with any name you want (I'm going to use &lt;code&gt;client.js&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Then, use the 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;sanityClient&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@sanity/client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sanityClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PROJECT_ID_PROVIDED_IN_SANITY.JSON&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DATASET_PROVIDED_IN_SANITY.JSON&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="na"&gt;useCdn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we're using the &lt;code&gt;useCdn:true&lt;/code&gt;, because the CDN is much faster to respond and gives us more API calls in our free tier. Although, it doesn't update the content as quickly as without the CDN, so do keep that in mind.&lt;/p&gt;

&lt;p&gt;Then, to get the content, we can use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`
    *[_type == "project"]
  `&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This basically selects everything document that has the type of "project" (e.g. every piece of content that follows the schema in &lt;code&gt;project.js&lt;/code&gt; from the earlier example. Remember to run this in an &lt;code&gt;async&lt;/code&gt; function by the way.&lt;/p&gt;

&lt;p&gt;If you're curious about the query language that is used by Sanity, check out the guide &lt;a href="https://www.sanity.io/docs/how-queries-work" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the &lt;a href="https://www.sanity.io/docs/query-cheat-sheet" rel="noopener noreferrer"&gt;cheatsheet&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  End
&lt;/h2&gt;

&lt;p&gt;So that's pretty much. Leave a reaction on the beautiful panel to your left (or a comment below)!&lt;/p&gt;

&lt;p&gt;Follow me on Twitter: &lt;a href="https://twitter.com/ShubhamPatilsd" rel="noopener noreferrer"&gt;https://twitter.com/ShubhamPatilsd&lt;/a&gt;&lt;br&gt;
Follow me on GitHub: &lt;a href="https://github.com/ShubhamPatilsd" rel="noopener noreferrer"&gt;https://github.com/ShubhamPatilsd&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>IP Location Grabbing</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Sun, 29 May 2022 23:28:21 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/ip-location-grabbing-595e</link>
      <guid>https://dev.to/shubhampatilsd/ip-location-grabbing-595e</guid>
      <description>&lt;p&gt;A couple of months ago, for a 12 hour hackathon, I built &lt;a href="https://geochattr.netlify.app/"&gt;https://geochattr.netlify.app/&lt;/a&gt; with &lt;a href="https://github.com/maggie-j-liu"&gt;Maggie Liu&lt;/a&gt; and &lt;a href="https://github.com/eternalmoon1234/"&gt;Gautam Paranjape&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The project is essentially a way of communicating through drawings, and you can chat with people in your city.&lt;/p&gt;

&lt;p&gt;The way we got the location to put in that city's chat room is by using your IP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guide
&lt;/h2&gt;

&lt;p&gt;To do this, we're going to have to use an API to get the location information.&lt;/p&gt;

&lt;p&gt;I generally found that most have some sort of premium plan, but &lt;a href="https://ipapi.co/"&gt;IpAPI&lt;/a&gt; is good enough and has a good amount of accuracy for it to function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Method
&lt;/h3&gt;

&lt;p&gt;To get your location, simply make a GET request to &lt;a href="https://ipapi.co/json/"&gt;https://ipapi.co/json/&lt;/a&gt; from the client. This will give directly give us all of our necessary information to get the user's location.&lt;/p&gt;

&lt;p&gt;You can use any library you want from the client. I tend to stick to &lt;code&gt;axios&lt;/code&gt;, so here is an example in &lt;code&gt;axios&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="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://ipapi.co/json/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&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="nx"&gt;log&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;data&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;However, if you're doing this with plain HTML, CSS, JS, you're going to want to use the browser's &lt;code&gt;fetch&lt;/code&gt; API.&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://ipapi.co/json/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&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="nx"&gt;log&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="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, you'll have something that looks like this (obviously I'm using a VPN):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ip"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"89.238.130.72"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"IPv4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Manchester"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"England"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"region_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ENG"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"United Kingdom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country_code_iso3"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GBR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country_capital"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"London"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country_tld"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".uk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"continent_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"EU"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"in_eu"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"postal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"M32"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"latitude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;53.4507&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"longitude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;-2.3186&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"timezone"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Europe/London"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"utc_offset"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+0100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country_calling_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"+44"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GBP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currency_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Pound"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"languages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"en-GB,cy-GB,gd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country_area"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;244820.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"country_population"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;66488991&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"asn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AS9009"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"org"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"M247 Ltd"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  More Secure Method
&lt;/h3&gt;

&lt;p&gt;Of course, the client can always disable JavaScript when they want to, meaning that they can disable the GET request to the API. However, we can still get the IP on the server.&lt;/p&gt;

&lt;p&gt;For example if a user wants to upload a post, and you want to categorize it based on what city they took it in, you can get the IP as such. We can get the IP from the user like 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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/upload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-forwarded-for&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remoteAddress&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ip address of the user&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Then, we can make a GET request to the ipapi.co again, but this time, we're going to send a bit of a different request.&lt;/p&gt;

&lt;p&gt;Instead of sending a request to &lt;code&gt;https://ipapi.co/json&lt;/code&gt;, we'll send a request to &lt;code&gt;https://ipapi.co/{ip}/json&lt;/code&gt;, where {ip} is the IP that you extracted from the incoming user's request. This would look like, for example, &lt;code&gt;https://ipapi.co/89.238.130.72/json/&lt;/code&gt;. You should probably use &lt;code&gt;axios&lt;/code&gt; for server side requests, so follow the example above on how to make the GET request. &lt;/p&gt;

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

&lt;p&gt;I hope you learned something new on how to actually do this. I remember getting stuck for an hour or two on how exactly to do this &lt;em&gt;during&lt;/em&gt; the hackathon, and I wanted to help prevent that confusion for others in the future. &lt;/p&gt;

&lt;p&gt;If you want to see a cool demo, check out &lt;a href="https://ip-grabber-demo.shubhampatilsd.repl.co/"&gt;https://ip-grabber-demo.shubhampatilsd.repl.co/&lt;/a&gt; for an interactive map.&lt;/p&gt;

&lt;p&gt;The source code is at &lt;a href="https://replit.com/@ShubhamPatilsd/ip-grabber-demograbber-demo#index.html"&gt;https://replit.com/@ShubhamPatilsd/ip-grabber-demograbber-demo#index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyways, leave a reaction on the left if you enjoyed this blog and follow me on &lt;a href="https://twitter.com/ShubhamPatilsd"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Tab and Stack Layout in React Native</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Sat, 02 Apr 2022 03:24:19 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/tab-and-stack-layout-in-react-native-3nlf</link>
      <guid>https://dev.to/shubhampatilsd/tab-and-stack-layout-in-react-native-3nlf</guid>
      <description>&lt;p&gt;I was creating a React Native app with &lt;a href="https://expo.io" rel="noopener noreferrer"&gt;Expo&lt;/a&gt; a week ago and I had to do a layout with a bottom tab navigator and implement a stack layout at the same time. Stack navigation essentially puts screens on top of other screens when you navigate to other pages, while tab navigation allows you to have a bottom page to choose between pages.&lt;/p&gt;

&lt;p&gt;Here is the demo:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/fpnekyzG8LI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ShubhamPatilsd" rel="noopener noreferrer"&gt;
        ShubhamPatilsd
      &lt;/a&gt; / &lt;a href="https://github.com/ShubhamPatilsd/tab-stack-example" rel="noopener noreferrer"&gt;
        tab-stack-example
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      React Native Tab Stack Example
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;I'm going to be using &lt;a href="https://reactnavigation.org/" rel="noopener noreferrer"&gt;React Navigation&lt;/a&gt; for this example, as it is the recommended library by Expo to use.&lt;/p&gt;

&lt;p&gt;To get started, run (if you use &lt;code&gt;npm&lt;/code&gt;)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 install @react-navigation/native

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

&lt;/div&gt;

&lt;p&gt;or run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 add @react-navigation/native

``` if you use Yarn to get started.

I prefer `yarn` so I chose that one.

Next, if you're using Expo, run
```expo

 install react-native-screens react-native-safe-area-context

``` to install the required dependencies for the project.

There is additional setup for base React Native projects, like pod linking and those additional dependencies, so check out the full setup guide [here](https://reactnavigation.org/docs/getting-started/).

Next, open up your `App.js` or `App.tsx` and import `NavigationContainer` from the React Navigation Library.

Import it by using
```js


import { NavigationContainer } from "@react-navigation/native";


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

&lt;/div&gt;

&lt;p&gt;Then, put that component in the your &lt;code&gt;App()&lt;/code&gt; component:&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NavigationContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/*It's a surprise tool that'll help us later!*/&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;NavigationContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, we need to implement the Stack screen navigator.&lt;/p&gt;

&lt;p&gt;We are going to import a function that gives us a navigator we can use to wrap all our screens in.&lt;/p&gt;

&lt;p&gt;To install the stack navigator, we need an &lt;code&gt;npm&lt;/code&gt; package called &lt;code&gt;@react-navigation/native-stack&lt;/code&gt;. (Yes, another package 🙄).&lt;/p&gt;

&lt;p&gt;Installation with &lt;code&gt;npm&lt;/code&gt;:&lt;/p&gt;

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

npm install @react-navigation/native-stack


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

&lt;/div&gt;

&lt;p&gt;Installation with &lt;code&gt;yarn&lt;/code&gt;:&lt;/p&gt;

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

yarn add @react-navigation/native-stack


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

&lt;/div&gt;

&lt;p&gt;Import it with:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createNativeStackNavigator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/native-stack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then, create the navigator with (keep it out of any components):&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createNativeStackNavigator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then, under our &lt;code&gt;&amp;lt;NavigationContainer&amp;gt;&lt;/code&gt; component, we add &lt;code&gt;&amp;lt;Stack.Navigator&amp;gt;&lt;/code&gt; as so:&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NavigationContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* TODO: Add screens later */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;NavigationContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;And next, as you guessed, we're going to add screens.&lt;/p&gt;

&lt;p&gt;Let's create two screens, &lt;code&gt;Main&lt;/code&gt; and &lt;code&gt;Settings&lt;/code&gt;. Put:&lt;/p&gt;

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

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Main"&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Settings"&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Settings&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;under &lt;code&gt;&amp;lt;Stack.Navigator&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Oh no! You don't have a &lt;code&gt;Main&lt;/code&gt;/&lt;code&gt;Settings&lt;/code&gt; component? Don't worry, we can make one really quickly.&lt;/p&gt;

&lt;p&gt;Outside of any of our other components (you can put it inside but I like it outside), create the &lt;code&gt;Main&lt;/code&gt; component with&lt;/p&gt;

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

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;I ❤ React Native&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;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;Settings&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;You got to the settings page&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The styles are the default template styles we're given when creating an Expo app, but if you need them here they are:&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;flex&lt;/span&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="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, your &lt;code&gt;App.js&lt;/code&gt;/&lt;code&gt;App.tsx&lt;/code&gt; should look like this:&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&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="s2"&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;NavigationContainer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/native&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;createNativeStackNavigator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/native-stack&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;Stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createNativeStackNavigator&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;Main&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;I ❤ React Native&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;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;Settings&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;You got to the settings page&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NavigationContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Main"&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Settings"&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Settings&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;NavigationContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="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="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;flex&lt;/span&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="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Okay, now let's add a tab navigator into the mix. Time for more packages 🥳 📦!&lt;/p&gt;

&lt;p&gt;Installation with &lt;code&gt;npm&lt;/code&gt;:&lt;/p&gt;

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

npm install @react-navigation/bottom-tabs


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

&lt;/div&gt;

&lt;p&gt;Installation with &lt;code&gt;yarn&lt;/code&gt;:&lt;/p&gt;

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

yarn add @react-navigation/bottom-tabs


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

&lt;/div&gt;

&lt;p&gt;Import it with&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createBottomTabNavigator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/bottom-tabs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;and add &lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Tab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createBottomTabNavigator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;below the &lt;code&gt;Stack&lt;/code&gt; definition:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NavigationContainer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/native&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;createNativeStackNavigator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/native-stack&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;createBottomTabNavigator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/bottom-tabs&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;Stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createNativeStackNavigator&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;Tab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createBottomTabNavigator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;//this one&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, let's go to the Main component. You want to change it so that it has a &lt;code&gt;Tab&lt;/code&gt; navigator, so that we can have tab-based navigation.&lt;/p&gt;

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

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;
      &lt;span class="na"&gt;screenOptions&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;tabBarActiveTintColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#0d9f61&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="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Home"&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Home Screen&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;headerShown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"OtherPage"&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Other Screen&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;headerShown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;Tab.Navigator&lt;/code&gt; contains screens that we can navigate to with the bottom tab bar that shows up. &lt;/p&gt;

&lt;p&gt;Here is the code so far:&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&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="s2"&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;NavigationContainer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/native&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;createNativeStackNavigator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/native-stack&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;createBottomTabNavigator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/bottom-tabs&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;Stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createNativeStackNavigator&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;Tab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createBottomTabNavigator&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;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;
      &lt;span class="na"&gt;screenOptions&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;tabBarActiveTintColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#0d9f61&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="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Home"&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Home Screen&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;headerShown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"OtherPage"&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Other Screen&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;headerShown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Settings&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;You got to the settings page&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NavigationContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Main"&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Settings"&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Settings&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;NavigationContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="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="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;flex&lt;/span&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="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, go to the &lt;code&gt;Main&lt;/code&gt; function and add a &lt;code&gt;navigator&lt;/code&gt; parameter to the function's parameters like so:&lt;/p&gt;

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

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;navigation&lt;/span&gt;&lt;span class="p"&gt;}){&lt;/span&gt;
    &lt;span class="cm"&gt;/*...*/&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Then, go to the &lt;code&gt;Tab.Screen&lt;/code&gt; called "Home", and change it to&lt;/p&gt;

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

 &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Home"&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Home Screen&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;
                &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Settings&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="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Go to settings"&lt;/span&gt;
              &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;headerShown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here, we added a button, so that we can go back to the Settings page. The &lt;code&gt;onPress&lt;/code&gt; with &lt;code&gt;navigation.navigate&lt;/code&gt; does the action of going to the "Settings" page when pressed.&lt;/p&gt;

&lt;p&gt;And there you have it!&lt;/p&gt;

&lt;p&gt;Here is the demo:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/fpnekyzG8LI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This is the entire code:&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&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="s2"&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;NavigationContainer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/native&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;createNativeStackNavigator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/native-stack&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;createBottomTabNavigator&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@react-navigation/bottom-tabs&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;Stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createNativeStackNavigator&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;Tab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createBottomTabNavigator&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;Main&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;navigation&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;
      &lt;span class="na"&gt;screenOptions&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;tabBarActiveTintColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#0d9f61&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="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Home"&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Home Screen&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;
                &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;navigation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Settings&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="si"&gt;}&lt;/span&gt;
                &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Go to settings"&lt;/span&gt;
              &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;headerShown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"OtherPage"&lt;/span&gt;
        &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Other Screen&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;headerShown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Settings&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;You got to the settings page&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NavigationContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Main"&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Main&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Screen&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Settings"&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Settings&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Navigator&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;NavigationContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="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="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;flex&lt;/span&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="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Hope this helps and I'll come back in a couple of weeks with more stuff!&lt;/p&gt;

&lt;p&gt;In the mean time, follow me on &lt;a href="https://twitter.com/ShubhamPatilsd" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; to get more frequent updates on my coding journey!&lt;br&gt;
👋&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>reactnative</category>
      <category>tutorial</category>
      <category>react</category>
    </item>
    <item>
      <title>Use Prisma Instead of SQL</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Mon, 28 Feb 2022 05:47:59 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/use-prisma-instead-of-sql-2g47</link>
      <guid>https://dev.to/shubhampatilsd/use-prisma-instead-of-sql-2g47</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is an ORM?&lt;/li&gt;
&lt;li&gt;Prisma Schemas&lt;/li&gt;
&lt;li&gt;Benefits of this schema approach&lt;/li&gt;
&lt;li&gt;Relations&lt;/li&gt;
&lt;li&gt;Prisma Client&lt;/li&gt;
&lt;li&gt;Benefits Compared To SQL&lt;/li&gt;
&lt;li&gt;Learning Resources&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Whenever I have to do anything regarding databases, my top pick with dealing with that stuff is usually &lt;a href="https://prisma.io" rel="noopener noreferrer"&gt;Prisma&lt;/a&gt;. If you didn't know, Prisma is an ORM for SQL databases (and recently, MongoDB).&lt;/p&gt;

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

&lt;h2&gt;
  
  
  What is an ORM?
&lt;/h2&gt;

&lt;p&gt;You might be wondering what an ORM is? Well, let me explain. Usually, with SQL databases, you have to write out queries in the SQL language. That includes statements like &lt;code&gt;DROP TABLE STUDENTS;&lt;/code&gt; or &lt;code&gt;SELECT * FROM STUDENTS WHERE emotion="stressed"&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;That mess is SQL, and in the 2000s, that was mainly how data was pulled from the server. Developers had to learn an entirely new "language" (not Turing-Complete of course) just to get some data from their database. This added layer of difficulty resulted in the need of specialization in these languages, and just slowed down the developer when they were making their applications. &lt;/p&gt;

&lt;p&gt;Since this was obviously really painful, solutions were made, these being ORMs. If you were building an application in Go, for example, you could directly interact with your database using Go, not the SQL query language. This was really convenient as developers could now do complex things without the hassle of learning a new language.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdma6gfcqhfospng9scqe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdma6gfcqhfospng9scqe.png" alt="ORM diagram that shows code being translated to SQL tables"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prisma is awesome!
&lt;/h2&gt;

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

&lt;p&gt;This brings me to my next point: Prisma. Prisma is one of these ORMs, but it has a ton of intuitive and awesome features.&lt;/p&gt;

&lt;p&gt;For example, if you wanted to select all the users that have signed up with Google, all you have to do in Prisma is&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;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;OAuthMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Google&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Prisma Schemas
&lt;/h2&gt;

&lt;p&gt;Where do we define the data? That leads me to the Prisma Schema.&lt;/p&gt;

&lt;p&gt;This is an example schema in the context of the users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;model Users {
    id String @default(uuid())
    OAuthMethod: String
    name String
    email String?
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me break down the model. In the first field, we are creating an &lt;code&gt;id&lt;/code&gt; for each user. This &lt;code&gt;id&lt;/code&gt; defaults to a random &lt;code&gt;uuid&lt;/code&gt; that is generated. The &lt;code&gt;id&lt;/code&gt; field has a type of String, since &lt;code&gt;uuid()&lt;/code&gt; contains non-integer values. Next, the &lt;code&gt;OAuthMethod&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; are two other strings, but they are not default and we have to manually provide the values. The last value &lt;code&gt;email&lt;/code&gt; is another string, but it is optional in the user model. It is not mandatory to give it a value, and the Prisma Client SDK won't scream at you with errors if you don't provide it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of this schema approach
&lt;/h2&gt;

&lt;p&gt;Prisma (or for that matter any ORM), is declarative compared to SQL's imperative model creation. In your &lt;code&gt;schema.prisma&lt;/code&gt; file, all you do is declare model and Prisma handles the rest for you. However, in SQL, you have to manually say &lt;code&gt;CREATE TABLE&lt;/code&gt;. This declarative approach makes it much easier to work with and understand, and allows the developer to ship their product faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Relations
&lt;/h2&gt;

&lt;p&gt;Relations are also pretty straight forward in Prisma. This is how we would do a one-to-many relation, where the User has a bunch of Posts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;model User {
    id String @default(uuid())
    OAuthMethod: String
    name String
    email String?
    user_posts Posts[]
}

model Posts {
    id String @default(uuid())
    title String
    body String
    ownerId String
    owner User @relation(fields:[ownerId], references:[id]) 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we do here is that we define a primary key (&lt;code&gt;id&lt;/code&gt;), and a foreign key &lt;code&gt;ownerId&lt;/code&gt;. The &lt;code&gt;ownerId&lt;/code&gt; links the two tables together, hence why we create a relation for it. The &lt;code&gt;fields&lt;/code&gt; parameter for the relation is the foreign key, while the &lt;code&gt;references&lt;/code&gt; parameter is the primary key. The owner in the &lt;code&gt;Posts&lt;/code&gt; model is the type of &lt;code&gt;User&lt;/code&gt;, and the relation makes it link back to the actual owner. This link between the two tables makes it so that the user has many posts, but each post has only one owner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prisma Client
&lt;/h2&gt;

&lt;p&gt;The Prisma client is also very intuitive to use. For example, to select a user that has an OAuthMethod of "Google", and list their email and their posts, (using the schema above), we can simply do 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="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
   &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
       &lt;span class="na"&gt;OAuthMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Google&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
   &lt;span class="p"&gt;},&lt;/span&gt;
   &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
       &lt;span class="na"&gt;user_posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;   
   &lt;span class="p"&gt;},&lt;/span&gt;
   &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, with &lt;code&gt;prisma.users&lt;/code&gt;, we access the &lt;code&gt;Users&lt;/code&gt; data model. Then, we use &lt;code&gt;findMany&lt;/code&gt; to, you guessed it, find multiple records that match out criteria.&lt;/p&gt;

&lt;p&gt;Everything in this function is a JSON object, and the &lt;code&gt;where&lt;/code&gt; field is another object. Inside the &lt;code&gt;where&lt;/code&gt; field, we can specify that we want &lt;code&gt;OAuthMethod&lt;/code&gt; to be equal to &lt;code&gt;"Google"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, with &lt;code&gt;include&lt;/code&gt; we can include the posts (as defined in the schema) that the user has by settings the &lt;code&gt;user_posts&lt;/code&gt; parameter to true (&lt;code&gt;user_posts&lt;/code&gt; is a field in the &lt;code&gt;User&lt;/code&gt; model). If you don't have the &lt;code&gt;include&lt;/code&gt; with the &lt;code&gt;user_posts&lt;/code&gt;, or &lt;code&gt;user_posts&lt;/code&gt; is set to &lt;code&gt;false&lt;/code&gt;, it won't include the user's posts in the output.&lt;/p&gt;

&lt;p&gt;Next, &lt;code&gt;select&lt;/code&gt; allows us to only select the user's email out of the user's data. We can also set &lt;code&gt;email&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits Compared To SQL
&lt;/h2&gt;

&lt;p&gt;One of the clear advantages of Prisma is that you're not spending precious developing time to learn a completely new query language, Prisma allows the developer to get their work done quickly and efficiently without going through the extra steps to do the same thing. You could go through enormous efforts to learn SQL, but Prisma and other ORMs will be there to lessen the load, and at that point, you're basically choosing to be inefficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning Resources
&lt;/h2&gt;

&lt;p&gt;Here are some learning resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tutorial by Laith Harb:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/mU8-nKwfw4Y"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quick rundown of Prisma by Fireship.io:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/rLRIB6AF2Dg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyways, I hope you enjoyed my blog! This one might be a bit controversial though 🙃. If you enjoyed/didn't enjoy this little blog,  I would appreciate it if you could like and share (it's really simple for you but means a lot to me). Also do let me know your opinion of Prisma/SQL in the comments below!&lt;/p&gt;

&lt;p&gt;I'll see you all in March!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>database</category>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>I wrote a script to get NFTs for me</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Sat, 08 Jan 2022 03:42:35 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/i-wrote-a-scriopt-to-get-nfts-for-me-4jg5</link>
      <guid>https://dev.to/shubhampatilsd/i-wrote-a-scriopt-to-get-nfts-for-me-4jg5</guid>
      <description>&lt;p&gt;Check it out at &lt;a href="https://www.youtube.com/watch?v=l4NJ_PvAAec"&gt;https://www.youtube.com/watch?v=l4NJ_PvAAec&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope you enjoy!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>python</category>
      <category>sideprojects</category>
      <category>nft</category>
    </item>
    <item>
      <title>Why are some frameworks so popular?</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Sat, 01 Jan 2022 06:56:02 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/why-are-some-frameworks-so-popular-3g58</link>
      <guid>https://dev.to/shubhampatilsd/why-are-some-frameworks-so-popular-3g58</guid>
      <description>&lt;h2&gt;
  
  
  Humble Beginnings
&lt;/h2&gt;

&lt;p&gt;I recently checked &lt;a href="https://insights.stackoverflow.com/survey/2021" rel="noopener noreferrer"&gt;Stack Overflow's Developer Survey 2021&lt;/a&gt; and instantly saw that&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8axqvmenzx7lesenlaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8axqvmenzx7lesenlaj.png" alt="text on survey page saying React.js surpassed jQuery as the most commonly used web framework"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is this the case though? How did React become so wide-spread?&lt;/p&gt;

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

&lt;p&gt;In this case,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Most Popular != Most Loved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we take a look back at the popular web framework in the Stack Overflow Developer Survey, we see this bar graph (I think that's what it's called):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74n1ugv5tg9mi4hksmdu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74n1ugv5tg9mi4hksmdu.png" alt="Popular framework graph, Svelte at 2nd to last place and React.js at first place"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, if we look at the most &lt;strong&gt;loved&lt;/strong&gt; frameworks,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqn5rqws9hejk41pg7v9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqn5rqws9hejk41pg7v9x.png" alt="Svelte at first place and React trailing behind at fourth place"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the first graph, it is evident that Svelte is evidently not that widespread/common compared to other frameworks. However, it seems that Svelte is immensely loved by developers compared to React.&lt;/p&gt;

&lt;p&gt;Hence, this is why I'm saying that the Most Popular framework is not the Most Loved. There are hidden gems that don't have the publicity to become widespread, and I believe Svelte is one of these.&lt;/p&gt;

&lt;h2&gt;
  
  
  React Study
&lt;/h2&gt;

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

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

&lt;p&gt;One thing that I see React has, and &lt;strong&gt;one of the most important factors&lt;/strong&gt; for increasing popularity is the size of the community for a technology. With React, if you search up for a fullstack tutorial on YouTube, I can bet that most of the results will definitely include React in them. This is because React has a bunch of developers using it, and so does JQuery.&lt;/p&gt;

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

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

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

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

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

&lt;p&gt;Now, when someone comes to learn how to create a fullstack application, they will be guided in the direction of React, not the other libraries. I'm going to call this "Filter-Pass-Down" I'm not aware if this is an actual term or not but I made it so it doesn't matter anymore unless one of you comment about it. Then I'll change it. But for now, "Filter-Pass-Down" it is. It only takes a group of developers to be enchanted by the spells of a library before spreading it to others.&lt;/p&gt;

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

&lt;p&gt;There is also another inconspicuous reason to why React is so widespread: its ecosystem. There are countless packages designed for React that just make developers' lives that much easier. Things like &lt;a href="https://www.framer.com/motion/" rel="noopener noreferrer"&gt;Framer Motion&lt;/a&gt; and &lt;a href="https://www.react-reveal.com/" rel="noopener noreferrer"&gt;React Reveal&lt;/a&gt; are mere examples of the vast and massive amounts of packages that help you get work done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Svelte
&lt;/h2&gt;

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

&lt;p&gt;One thing that Svelte lacks compared to React is the enormous community surrounding it. Don't get me wrong, it's somewhat there; the problem is that it's small. However, not many professional-grade applications are using it. There are also not that many supporting packages for it like React does. The lack of tutorials to get someone started with development don't use Svelte, so it makes it difficult for large scale adoption to occur. However, I've seen a lot of developers use Svelte and use it afterward, giving me a sense that it will grow in popularity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cherry On The Cake
&lt;/h2&gt;

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

&lt;p&gt;While the community is one of the most important things to make a framework/library succeed, the &lt;strong&gt;innovative features&lt;/strong&gt; it brings are equally important and tie the entire project together in a neat little package.&lt;/p&gt;

&lt;p&gt;React used the concept of a Virtual DOM opposed to changing the actual DOM of a webpage, speeding up the entire process of updating the page (it also used declarative state management so you simply had to tell what you wanted to change and it would change the element for you). React also implemented JSX, opposed to the HTML templates stuff the Angular used. All of these features were well liked by the developers who used React, thus promoting the product.&lt;/p&gt;

&lt;p&gt;This rise in popularity can also occur for Svelte, I believe. It gives a great user experience and is loved by many developers around the world. Svelte only needs a larger community/ecosystem for it to become a popular tool, and that very well might happen in the future.&lt;/p&gt;

&lt;p&gt;Anyways those were my thoughts.&lt;/p&gt;

&lt;p&gt;Recap of what you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Massive community/ecosystem&lt;/li&gt;
&lt;li&gt;Innovative Features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;People simply need that first taste of your library before suggesting it to others, and it only expands from there.&lt;/p&gt;




&lt;p&gt;Sorry for the late blog this month I had final exams :(&lt;br&gt;
If you liked this blog though, please leave a comment and click the buttons on the left side of the screen 👍. &lt;/p&gt;

&lt;p&gt;Anyways, I'll try to post faster next month. Happy New Year!&lt;/p&gt;

&lt;p&gt;Also, Follow me on Twitter it helps out a ton!: &lt;a href="https://twitter.com/ShubhamPatilsd" rel="noopener noreferrer"&gt;https://twitter.com/ShubhamPatilsd&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>react</category>
    </item>
    <item>
      <title>Get Started With ThreeJS</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Tue, 23 Nov 2021 19:33:25 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/get-started-with-threejs-36mo</link>
      <guid>https://dev.to/shubhampatilsd/get-started-with-threejs-36mo</guid>
      <description>&lt;p&gt;Recently, I used ThreeJS and it was really fun. Today, I'll teach you how to get started with it, with a fun (and simple) tutorial.&lt;/p&gt;

&lt;p&gt;As &lt;a href="https://en.wikipedia.org/wiki/Three.js" rel="noopener noreferrer"&gt;stated by Wikipedia&lt;/a&gt;,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Three.js is a cross-browser JavaScript library and application programming interface (API) used to create and display animated 3D computer graphics in a web browser using WebGL.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's is the finished product:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F59oimfog3q4k2q5u26kh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F59oimfog3q4k2q5u26kh.gif" alt="rotating plane"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also made a &lt;a href="https://threejs-tutorial-demo.vercel.app/" rel="noopener noreferrer"&gt;demo&lt;/a&gt; of the finished product.&lt;/p&gt;
&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;React Setup&lt;/li&gt;
&lt;li&gt;ThreeJS Setup&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm going to do this in React, but most of this stuff should apply for plain HTML CSS and JS. The ThreeJS docs have a really nice &lt;a href="https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene" rel="noopener noreferrer"&gt;starter guide&lt;/a&gt; to get you up and running with vanilla JS, so do check it out. If you haven't done React before, I would suggest watching &lt;a href="https://www.youtube.com/watch?v=MRIMT0xPXFI" rel="noopener noreferrer"&gt;this video&lt;/a&gt; by Aaron Jack to get you started as fast as possible.&lt;/p&gt;
&lt;h2&gt;
  
  
  React Setup &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Anyways, let's initialize a React project. If you want, you could also use something like &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;NextJS&lt;/a&gt;, but I'm sticking to &lt;a href="https://create-react-app.dev/" rel="noopener noreferrer"&gt;Create React App&lt;/a&gt; for now.&lt;/p&gt;

&lt;p&gt;I'm using &lt;code&gt;yarn&lt;/code&gt; to initialize my project, so here are the two commands (one with &lt;code&gt;npm&lt;/code&gt; and the other with &lt;code&gt;yarn&lt;/code&gt;) to create a React project.&lt;/p&gt;

&lt;p&gt;npm: &lt;code&gt;npx create-react-app threejs-learning&lt;/code&gt;&lt;br&gt;
yarn &lt;code&gt;yarn create react-app threejs-learning&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And yes, as &lt;a href="https://reactjs.org/docs/create-a-new-react-app.html" rel="noopener noreferrer"&gt;explained by the React docs&lt;/a&gt;, &lt;code&gt;npx&lt;/code&gt; is not a typo (it's something to run scripts that comes with &lt;code&gt;npm&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;When you initialize the project, you'll see something like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1emx3llnvhxvcbwgngng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1emx3llnvhxvcbwgngng.png" alt="New Project Structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disregard this for now (we'll deal with the unnecessary files later). What you should do is start the server so you can see what the boilerplate looks like.&lt;/p&gt;

&lt;p&gt;To do that, run the command that corresponds to what you initalized the project with:&lt;br&gt;
yarn: &lt;code&gt;yarn start&lt;/code&gt;&lt;br&gt;
npm: &lt;code&gt;npm run start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will open up a browser tab at &lt;code&gt;http://localhost:3000&lt;/code&gt; and you'll see something like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w5cfnwhumgjikmn9wut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9w5cfnwhumgjikmn9wut.png" alt="Starter template"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great job you now have a React project set up!&lt;/p&gt;

&lt;p&gt;Back to your editor now. In the &lt;code&gt;src&lt;/code&gt; folder, you'll see these files: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmqo9omlo6fi2z21xevg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmqo9omlo6fi2z21xevg.png" alt="src folder structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, you can delete &lt;code&gt;App.css&lt;/code&gt;, &lt;code&gt;App.test.js&lt;/code&gt;, &lt;code&gt;index.css&lt;/code&gt;, &lt;code&gt;logo.svg&lt;/code&gt;, &lt;code&gt;reportWebVitals.js&lt;/code&gt;, and &lt;code&gt;setupTests.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Shoot! If you look back at the browser tab, we encounter an error:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqn5xiujkvkl02ssjhs7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqn5xiujkvkl02ssjhs7d.png" alt="Files not found error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you take a look back at the &lt;code&gt;App.js&lt;/code&gt; and &lt;code&gt;index.js&lt;/code&gt; files in your editor, you'll see that they are importing some of the files we deleted, thus resulting in an error:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App.js&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;logo&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./logo.svg&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;index.js&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="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.css&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;reportWebVitals&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./reportWebVitals&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The solution is simple and requires only a couple keys. Just delete those lines from each file 🤪.&lt;/p&gt;

&lt;p&gt;But some further works still needs to be done. Our code is still using the stuff we imported.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;index.js&lt;/code&gt;, after deleting the imports, your file should look like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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="s2"&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;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom&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;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StrictMode&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StrictMode&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&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="c1"&gt;// If you want to start measuring performance in your app, pass a function&lt;/span&gt;
&lt;span class="c1"&gt;// to log results (for example: reportWebVitals(console.log))&lt;/span&gt;
&lt;span class="c1"&gt;// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals&lt;/span&gt;
&lt;span class="nf"&gt;reportWebVitals&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We need to delete the &lt;code&gt;reportWebVitals();&lt;/code&gt; and the &lt;code&gt;&amp;lt;React.StrictMode&amp;gt;&lt;/code&gt; since we removed the imports for that.&lt;/p&gt;

&lt;p&gt;This is &lt;code&gt;index.js&lt;/code&gt; after those changes:&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="s2"&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;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom&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;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&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;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, let's fix &lt;code&gt;App.js&lt;/code&gt;. This is how it should look like right now:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App-header"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;logo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App-logo"&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"logo"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Edit &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;code&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;src/App.js&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;code&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; and save to reload.
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;
          &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"App-link"&lt;/span&gt;
          &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://reactjs.org"&lt;/span&gt;
          &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt;
          &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"noopener noreferrer"&lt;/span&gt;
        &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Learn React
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;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;Just delete everything in the &lt;code&gt;return();&lt;/code&gt; function and replace it with a simple &lt;code&gt;&amp;lt;h1&amp;gt;I love React!&amp;lt;/h1&amp;gt;&lt;/code&gt;. This is how it should look:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;I love React!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;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;Ok great, now we have all the bloat out of our way. Note that this stuff we deleted &lt;em&gt;can&lt;/em&gt; be important if you have a big project, but for now it can be discarded since this a learning project.&lt;/p&gt;

&lt;p&gt;Now, if you save it, you should see this in the browser: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rsifm8wwbpv7cfa43xa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0rsifm8wwbpv7cfa43xa.png" alt="Result after deleting files"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ThreeJS Setup &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;So now we get to interact with ThreeJS. To get started, install it:&lt;/p&gt;

&lt;p&gt;yarn: &lt;code&gt;yarn add three&lt;/code&gt;&lt;br&gt;
npm: &lt;code&gt;npm install three&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Okay, now go into your &lt;code&gt;App.js&lt;/code&gt; file and import ThreeJS 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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;three&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, change your &lt;code&gt;&amp;lt;h1&amp;gt;I love React!&amp;lt;/h1&amp;gt;&lt;/code&gt; to &lt;code&gt;&amp;lt;canvas id="bg"&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/code&gt; in the &lt;code&gt;return&lt;/code&gt; function of the component. This is so that ThreeJS has something to attach itself on and do its work.&lt;/p&gt;

&lt;p&gt;At this point, we're going to have to do a clever "hack" if you'll call it that. Since the JavaScript loads before the JSX (JSX is the code that looks like HTML), our code is unable to reference the &lt;code&gt;canvas&lt;/code&gt; element if placed before the return statement.&lt;/p&gt;

&lt;p&gt;We're going to have to use something called &lt;code&gt;useEffect&lt;/code&gt; so that ThreeJS runs after the first render and we can access the canvas element.&lt;/p&gt;

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

&lt;/div&gt;


&lt;p&gt;and insert&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="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="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;above the &lt;code&gt;return&lt;/code&gt; statement. Here, the empty array as the second argument indicates for the &lt;code&gt;useEffect&lt;/code&gt; hook to only run on the first render, not repeatedly after each one. Traditionally, you would put variable name(s) there so that &lt;code&gt;useEffect&lt;/code&gt; would run after those variable(s) changed, but we only want it to run after the first render.&lt;/p&gt;

&lt;p&gt;Now, in the &lt;code&gt;useEffect&lt;/code&gt;, create a new ThreeJS scene (this scene is where everything will show up):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scene&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we have to create a camera. Add a camera with&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scene&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;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PerspectiveCamera&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;75&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;innerWidth&lt;/span&gt; &lt;span class="o"&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;innerHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;1000&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This might be a bit overwhelming, but let me break it down. The first parameter (the &lt;code&gt;75&lt;/code&gt;) is the FOV of the camera. FOV (aka Field of View) is basically how much the camera can see.&lt;/p&gt;

&lt;p&gt;Think of it like this pizza:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foqkde1axh3m3ze7mju79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foqkde1axh3m3ze7mju79.png" alt="Pizza without slice"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The angle of the missing slice is how much the camera can see. The higher the angle, the more it can see. However, if it's too high, you can get results that don't look right.&lt;/p&gt;

&lt;p&gt;The second parameter is for the aspect ratio of the view. This is basically the ratio of the width : height, and I've done so with the space of the page using the &lt;code&gt;window&lt;/code&gt; object. The next two parameters are how near and far the camera can view objects.&lt;/p&gt;

&lt;p&gt;Next, we have to create a renderer. Below the camera, create a renderer and set the background of the scene:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scene&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;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PerspectiveCamera&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;75&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;innerWidth&lt;/span&gt; &lt;span class="o"&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;innerHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;1000&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WebGL1Renderer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#bg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x4e9fe5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;canvas&lt;/code&gt; option allows ThreeJS to latch itself on an element in the DOM. The &lt;code&gt;scene.background&lt;/code&gt; enables us to create a color with the &lt;code&gt;#4e9fe5&lt;/code&gt; hex code (which will be our sky).&lt;/p&gt;

&lt;p&gt;Next, add the following code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPixelRatio&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;devicePixelRatio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setSize&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;innerWidth&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;innerHeight&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The first line sets the pixel ratio, while the second sets the dimensions for the renderer. The third line sets the position for the camera (with the &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, and &lt;code&gt;z&lt;/code&gt; axes, respectively). The last line renders the scene with the camera we made above.&lt;/p&gt;

&lt;p&gt;Now, let's make some lights:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hemiLight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HemisphereLight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xffffff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x444444&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;hemiLight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hemiLight&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;dirLight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DirectionalLight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xffffff&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;dirLight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirLight&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;ambientLight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AmbientLight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xffffff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;ambientLight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ambientLight&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The first chunk of code creates a new light, creates a gradient (from colors white to grey) of light from the top to the bottom of the scene. To wrap your head around this concept, I would suggest &lt;a href="https://threejsfundamentals.org/threejs/threejs-lights-hemisphere.html" rel="noopener noreferrer"&gt;this interactive playground&lt;/a&gt; online) We then set the position of the light (with the &lt;code&gt;xyz&lt;/code&gt; axes) and add it to the scene.&lt;/p&gt;

&lt;p&gt;The second chunk sets up a directional light, which is like a traditional light source (it illuminates from a point). We set its color to white, set its position, and add it to the scene.&lt;/p&gt;

&lt;p&gt;The ambient light is basically a light that is illuminating from everywhere in your scene. Think of your scene being put in a ball, which is then illuminated from the inside. We then set it's position to the center of the scene and add it.&lt;/p&gt;

&lt;p&gt;Ok so now we have a basic scene set up. It should look like this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifdpckuxeiysm9nd5qdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifdpckuxeiysm9nd5qdg.png" alt="Scene without anything"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to get a model in the scene now, to make it interesting. I would suggest going to &lt;a href="https://poly.pizza/" rel="noopener noreferrer"&gt;poly.pizza&lt;/a&gt; and getting a model. I am using &lt;a href="https://poly.pizza/m/7cvx6ex-xfL" rel="noopener noreferrer"&gt;this airplane&lt;/a&gt;, (Attribution for model: Small Airplane by Vojtěch Balák &lt;a href="https://creativecommons.org/licenses/by/3.0/" rel="noopener noreferrer"&gt;CC-BY&lt;/a&gt; via &lt;a href="https://poly.pizza/m/7cvx6ex-xfL" rel="noopener noreferrer"&gt;Poly Pizza&lt;/a&gt;) but I highly recommend you to use any model you want. Download the &lt;code&gt;.glb&lt;/code&gt; format of the object with this button:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kqej6rokvn9avwt2oxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kqej6rokvn9avwt2oxq.png" alt="Download Button with .obj and .glb files"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once downloaded, at this &lt;code&gt;.glb&lt;/code&gt; file to the &lt;code&gt;public/&lt;/code&gt; folder in the root of your project.&lt;/p&gt;

&lt;p&gt;At the top of your code, add this to import the &lt;code&gt;GLTFLoader&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GLTFLoader&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;three/examples/jsm/loaders/GLTFLoader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next, add this code under the ambient light code to import the model:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GLTFLoader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/NAME_OF_FILE.glb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gltf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;gltf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gltf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The first line creates a new loader object, so we can load the file. The &lt;code&gt;loader.load&lt;/code&gt; part loads the actual model. The first argument is the &lt;code&gt;.glb&lt;/code&gt; file. The &lt;code&gt;/NAME_OF_FILE.glb&lt;/code&gt; accesses it from the &lt;code&gt;public/&lt;/code&gt; folder, which is replaced by the name of your &lt;code&gt;.glb&lt;/code&gt; file. The second argument is a function that has the resulted model as a varible. We can access the proper model with &lt;code&gt;gltf.scene&lt;/code&gt;, hence why we are adding &lt;em&gt;that&lt;/em&gt; to our scene instead of just &lt;code&gt;gltf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Inside the function, I am scaling the model down to 80% of its original size since it was way too big for the viewport. Note that this is optional based on how good your model looks. It might even be small, so you can scale it up in that case.&lt;/p&gt;

&lt;p&gt;Next, we have to add an &lt;code&gt;animate()&lt;/code&gt; function. This basically just re-renders our ThreeJS scene constantly. To do that, just create a function like so:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The first line inside of the function acts like a loop (the actual term is recursion). It calls the animate function again inside of itself, so it keeps re-rendering. The next line renders the scene and the camera again. We call the function outside of itself so it can start.&lt;/p&gt;

&lt;p&gt;But wait a minute, nothing shows up in the browser! It's just a blue background! That's because we didn't add controls for the scene. ThreeJS doesn't work without these controls, hence why they are necessary.&lt;/p&gt;

&lt;p&gt;To put them in the scene, import:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;OrbitControls&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;three/examples/jsm/controls/OrbitControls&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;and add this above the &lt;code&gt;function animate()&lt;/code&gt; stuff:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;controls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OrbitControls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This creates a new object called &lt;code&gt;controls&lt;/code&gt;, which is made from the &lt;code&gt;OrbitControls&lt;/code&gt; class. The constructor of the &lt;code&gt;OrbitControls&lt;/code&gt; has a &lt;code&gt;camera&lt;/code&gt; (which we previously defined), and the domElement to put the controls in (which we set in the creation of the renderer with &lt;code&gt;canvas: document.querySelector("#bg");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, you should see this in the browser!:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiyw4j4uq6q312iuzo6gm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiyw4j4uq6q312iuzo6gm.png" alt="Plane in the scene"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can even interact with it by dragging using your left mouse button, scrolling to zoom in, and using right click to move the camera.&lt;/p&gt;

&lt;p&gt;The only problem with this is that when you resize the window, it becomes really, &lt;em&gt;REALLY&lt;/em&gt; distorted:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6lyixu21310j27g9r7p2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6lyixu21310j27g9r7p2.png" alt="distorted plane"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is definitely not what we want, so let's change that. Above the place where you defined your &lt;code&gt;animate&lt;/code&gt; function, create a function like 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resizeWindow&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;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setSize&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;innerWidth&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;innerHeight&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPixelRatio&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;devicePixelRatio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aspect&lt;/span&gt; &lt;span class="o"&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;innerWidth&lt;/span&gt; &lt;span class="o"&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;innerHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateProjectionMatrix&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;camera&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;Here, we are updating the renderer dimension data. First, we set the new width and height. Then we set the new pixel ratio (this probably will not change but we're setting it just in case). Next, we change the aspect ratio of the camera to the new width and height. We then update the camera's view and re-render the scene.&lt;/p&gt;

&lt;p&gt;If you check the browser again and resize it, you'll see that now this happens:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhoazpku9qh7rti319o9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhoazpku9qh7rti319o9p.png" alt="width and height not changing after function creation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is happening because we haven't added called the function at all yet. To do so, add this after your &lt;code&gt;resizeWindow&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resizeWindow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This line of code adds an event listener to the window object, and calls the &lt;code&gt;resizeWindow&lt;/code&gt; function whenever the window is resized.&lt;/p&gt;

&lt;p&gt;Now the plane is not distorted anymore!&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwbu69388twsp3g0ufm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwbu69388twsp3g0ufm0.png" alt="Undistorted plane"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have the model loaded, but we should add some auto-rotation to make it look cool. To do that, add this in the 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="nx"&gt;controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;autoRotate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;autoRotateSpeed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This essentially enables auto rotation, multiplies the speed by 4, and updates the controls to make it spin. If you want a laugh, change the &lt;code&gt;autoRotateSpeed&lt;/code&gt; to something like &lt;code&gt;1000.0&lt;/code&gt; and watch it go crazy 🤣.&lt;/p&gt;

&lt;p&gt;In the end, your &lt;code&gt;App.js&lt;/code&gt; should look something like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;three&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;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&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;OrbitControls&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;three/examples/jsm/controls/OrbitControls&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;GLTFLoader&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;three/examples/jsm/loaders/GLTFLoader&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="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scene&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Scene&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;camera&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PerspectiveCamera&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="mi"&gt;75&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;innerWidth&lt;/span&gt; &lt;span class="o"&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;innerHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="mi"&gt;1000&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;WebGL1Renderer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#bg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;background&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x4e9fe5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPixelRatio&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;devicePixelRatio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setSize&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;innerWidth&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;innerHeight&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;camera&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;hemiLight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HemisphereLight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xffffff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x444444&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;hemiLight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hemiLight&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;dirLight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DirectionalLight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xffffff&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;dirLight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dirLight&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;ambientLight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;THREE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AmbientLight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xffffff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;ambientLight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ambientLight&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;controls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OrbitControls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domElement&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;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GLTFLoader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/small-airplane-v3.glb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gltf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;gltf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gltf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scene&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;resizeWindow&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;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setSize&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;innerWidth&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;innerHeight&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPixelRatio&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;devicePixelRatio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aspect&lt;/span&gt; &lt;span class="o"&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;innerWidth&lt;/span&gt; &lt;span class="o"&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;innerHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateProjectionMatrix&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&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="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resizeWindow&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;animate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="nx"&gt;controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;autoRotate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;autoRotateSpeed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="nx"&gt;controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;canvas&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;&amp;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;That's it! Now you're up and running with ThreeJS. This is a beginner tutorial and there is a bunch of stuff I didn't cover, so check out the &lt;a href="https://threejs.org/docs/" rel="noopener noreferrer"&gt;ThreeJS docs and examples&lt;/a&gt;. If you've followed along with this tutorial, choose another model and send a picture in the comments section so you can share your work!&lt;/p&gt;

&lt;p&gt;The full code is in a repository on GitHub: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ShubhamPatilsd" rel="noopener noreferrer"&gt;
        ShubhamPatilsd
      &lt;/a&gt; / &lt;a href="https://github.com/ShubhamPatilsd/threejs-learning" rel="noopener noreferrer"&gt;
        threejs-learning
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Code for the tutorial for ThreeJS!
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;If you liked this post, the three shiny buttons on the left are waiting to be clicked, and if you didn't like the post, they still are open to clicking.&lt;/p&gt;

&lt;p&gt;Oh yeah, and I also have a Twitter now (very exciting stuff). If you enjoy my blogs, do follow me as I share my thoughts about programming there as well (but more frequently). Follow me at: &lt;a href="https://twitter.com/ShubhamPatilsd" rel="noopener noreferrer"&gt;https://twitter.com/ShubhamPatilsd&lt;/a&gt;&lt;/p&gt;

</description>
      <category>threejs</category>
      <category>react</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Start Using Tailwind CSS Right Now</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Sun, 03 Oct 2021 20:20:28 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/start-using-tailwind-css-right-now-3pck</link>
      <guid>https://dev.to/shubhampatilsd/start-using-tailwind-css-right-now-3pck</guid>
      <description>&lt;p&gt;I've been using Tailwind CSS for the past 4 months now, and I can confidently say that it's much much MUCH better than plain CSS.&lt;/p&gt;

&lt;p&gt;If you didn't know, Tailwind CSS basically provides utility classes that can be used to style your HTML. Think of it as Bootstrap but with much more freedom. Instead of being stuck to a certain design, Tailwind CSS gives you the ability to make your own. Although it does have a design system, it is pretty subtle compared to Bootstrap, while saving you time from creating a design system from scratch like with plain old CSS.&lt;/p&gt;

&lt;p&gt;You might be confused so let me give you an example. To create a 4rem margin above your element in CSS, you would do&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then your HTML would look like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"element"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, with Tailwind CSS, those lines of CSS get incorporated into the class of the HTML element, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-16"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the &lt;code&gt;mt-16&lt;/code&gt; stands for &lt;code&gt;margin-top: 4rem&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This leads me to my first point: creating an entire design system (including spacing and classes) can be very time-consuming and unproductive. Tailwind CSS provides a solution to this problem by providing spacing, color, responsive and basic animation classes, that act as substitute for actual CSS.&lt;/p&gt;

&lt;p&gt;For example, for spinning animation, all you need is the class name &lt;code&gt;animate-spin&lt;/code&gt;. The implementation for that would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"animate-spin"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and you have a spinning element now!&lt;/p&gt;

&lt;p&gt;The color system Tailwind has is fantastic for small projects in which you don't want to create a color scheme.&lt;/p&gt;

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

&lt;p&gt;The colors that Tailwind offers are not just CSS colors with fancy names, they are much more appealing.&lt;/p&gt;

&lt;p&gt;This is Tailwind's most vibrant blue:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibobyql8brukpc5jxgga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibobyql8brukpc5jxgga.png" alt="Tailwind Blue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then this is CSS's most vibrant blue:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnf30mh3sbg8iemh6j7qq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnf30mh3sbg8iemh6j7qq.png" alt="CSS Blue"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is noticeable that Tailwind's colors are much more soothing and are less harsh than the base CSS colors.&lt;/p&gt;

&lt;p&gt;Tailwind also has a variety of other classes that shorten the amount of styling you need to write. For example, pseudo-selectors like &lt;code&gt;hover:&lt;/code&gt;, are basically condensed into&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hover:whatever-you-want-to-do-on-hover"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tailwind also has a bit of sorcery when it comes to responsive layout. Tailwind uses pre-set (by default) pixel values for certain breakpoints. For example, there is an &lt;code&gt;sm&lt;/code&gt; breakpoint which is a screen width of 640px. If you're confused, just think of these breakpoints as media queries in CSS.&lt;/p&gt;

&lt;p&gt;To use these breakpoints, just use &lt;code&gt;breakpointName:&lt;/code&gt;. The &lt;code&gt;breakpointName&lt;/code&gt; is one of the values below:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgiyall93cfl1qiwe4tfd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgiyall93cfl1qiwe4tfd.png" alt="Breakpoint measures"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Say that you wanted to hide a &lt;code&gt;div&lt;/code&gt; on smaller screens for a responsive layout and have it shown as flex on screens bigger than 768px.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hidden md:flex"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   ...
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the HTML above, it basically says to "Hide everything below the &lt;code&gt;md&lt;/code&gt; breakpoint, and everything above the &lt;code&gt;md&lt;/code&gt; breakpoint should be shown as &lt;code&gt;flex&lt;/code&gt;". (In this case, &lt;code&gt;flex&lt;/code&gt; = &lt;code&gt;display: flex;&lt;/code&gt; in normal CSS).&lt;/p&gt;

&lt;p&gt;Tailwind also has a lot customization options. Just hop into the &lt;code&gt;tailwind.config.js&lt;/code&gt; and you have a bunch of options to customize breakpoints and other colors and stuff.&lt;/p&gt;

&lt;p&gt;However, Tailwind is not without its weak points. First let's talk about how bloated the code looks after applying these styles. &lt;/p&gt;

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

&lt;p&gt;If you wanted four buttons, you would have to do something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-blue rounded-md shadow-md px-2 py-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-blue rounded-md shadow-md px-2 py-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-blue rounded-md shadow-md px-2 py-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-blue rounded-md shadow-md px-2 py-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty repetitive right? Well, this can be solved if you use a JavaScript framework that supports the creation of components, like React, Vue, Angular, and Svelte (which is loved by a lot of developers due to its simplicity).&lt;/p&gt;

&lt;p&gt;Another option to shorten the class name is to use &lt;code&gt;@apply&lt;/code&gt; in the accompanying CSS file that Tailwind needs to apply the styles. More information about the applying concept can be found &lt;a href="https://tailwindcss.com/docs/functions-and-directives#apply" rel="noopener noreferrer"&gt;on their website&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The same example of that button class name would be condensed to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.button&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;@apply&lt;/span&gt; &lt;span class="err"&gt;bg-blue&lt;/span&gt; &lt;span class="err"&gt;rounded-md&lt;/span&gt; &lt;span class="err"&gt;shadow-md&lt;/span&gt; &lt;span class="err"&gt;px-2&lt;/span&gt; &lt;span class="err"&gt;py-1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and your button would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; ... &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a while, Tailwind becomes second nature, and you start to know exactly what to type out. This can be challenging to you if you're new to Tailwind as you think you have to memorize all the classes. Don't do this to yourself; it's like subconsciously knowing the class for the job. After a while, you simply gain the sense of which utilities to use and when to use them. Also, if you need any help, &lt;a href="https://tailwindcss.com" rel="noopener noreferrer"&gt;Tailwind's website&lt;/a&gt; is always there to assist you.&lt;/p&gt;

&lt;p&gt;If you're interested, check out &lt;a href="https://tailwindcss.com/docs/installation" rel="noopener noreferrer"&gt;https://tailwindcss.com/docs/installation&lt;/a&gt; to view the documentation on setting it up with frameworks like NextJS and even CDN through your HTML.&lt;/p&gt;

&lt;p&gt;That's all about Tailwind! As I've stated before, do check the website for more help on specific topics like, for example, CSS grid and other utilities. If you enjoyed this post, there are 3 buttons on the left side of this article for your clicking pleasure and a comment section awaiting your input. If you didn't like this article, those buttons are still open, ready to be clicked 🙃.&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>css</category>
      <category>uiweekly</category>
    </item>
    <item>
      <title>Using Arch Linux</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Sun, 15 Aug 2021 18:34:23 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/using-arch-linux-3k12</link>
      <guid>https://dev.to/shubhampatilsd/using-arch-linux-3k12</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is an article originally from Medium. I have decided to switch from Medium to dev.to and import all my posts from there.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2A29xBcvaVTSai6MfH.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2A29xBcvaVTSai6MfH.png" alt="arch linux logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I’ve been wishing to switch to Linux for about a year and a half now. There was just something intriguing about Linux that made me want to use it.&lt;/p&gt;

&lt;p&gt;I used to use a 2019 Macbook Air (I still do but not very often), but the speed of the thing kills me. Sometimes I have a couple VS Code and browser windows open and it just starts lagging a lot. Not to mention the keyboard, which (due to my fault) ended up requiring a certified Apple Repair Store to fix an arrow key. The reason is not &lt;em&gt;entirely&lt;/em&gt; me being dumb because I noticed that the key was sticky. This article is not going to be about the performance of the Mac but it was one of the reasons I wanted to switch to Linux.&lt;/p&gt;

&lt;p&gt;My first experience with Linux was installing Ubuntu on a Lenovo Ideapad 310 about a year ago. That laptop got very slow due to it’s drive being a hard drive, not an SSD.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F600%2F0%2A7byOduTCH4j8rd5F" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F600%2F0%2A7byOduTCH4j8rd5F" alt="Lenovo Ideapad 310"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ABlx6ItiidZ8jyQoo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ABlx6ItiidZ8jyQoo.png" alt="Ubuntu logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I first installed it, I encountered an error that basically left me unable to install the operating system. I decided to re-download and re-flash the &lt;code&gt;.iso&lt;/code&gt; onto the USB drive and try installing it again. This time, it actually worked!&lt;/p&gt;

&lt;p&gt;Ubuntu was very fascinating for me and it sparked an intrigue in me for Linux. I then tried multiple distros (all of them being Debian based), and finally just settled on Ubuntu.&lt;/p&gt;

&lt;p&gt;However, I didn’t really use this laptop much and didn’t use Linux commonly. I kept using my Macbook for a year or so until the golden opportunity to use Linux arose: building a PC.&lt;/p&gt;

&lt;p&gt;If you are interested, here is the part list (&lt;a href="https://pcpartpicker.com/list/rqZgW3" rel="noopener noreferrer"&gt;here is the link&lt;/a&gt; if you want to modify it):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ATqCSY7VPd4mRTLCcEnueeg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ATqCSY7VPd4mRTLCcEnueeg.png" alt="pcpartpicker part list for pc"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All in all, the entire PC came for about $808 including tax!&lt;/p&gt;

&lt;p&gt;So when the PC came, I assembled it (which took more than seven hours because this was the first time I did it) and went to sleep at 12 AM with the PC 98% complete (I had to change the PCIE slot of the WIFI card).&lt;/p&gt;

&lt;p&gt;In the next day or two, I opened up my Macbook and started searching on how to install Arch Linux. I was really hesitant about which distro of Linux to install.&lt;/p&gt;

&lt;p&gt;If you didn’t know already, a distro is kind of like a flavor of Linux. Think of it like ice cream. There are different flavors like chocolate, strawberry and vanilla, each having their own pros and cons.&lt;/p&gt;

&lt;p&gt;I had a choice of Debian based distros or Arch based distros. The former being stuff like &lt;a href="https://ubuntu.com/" rel="noopener noreferrer"&gt;Ubuntu&lt;/a&gt;, &lt;a href="https://www.debian.org/" rel="noopener noreferrer"&gt;Debian&lt;/a&gt;, &lt;a href="https://pop.system76.com/" rel="noopener noreferrer"&gt;PopOS&lt;/a&gt;, &lt;a href="https://linuxmint.com/" rel="noopener noreferrer"&gt;Linux Mint&lt;/a&gt; etc. etc. For the latter, I had options like &lt;a href="https://archlinux.org/" rel="noopener noreferrer"&gt;Arch&lt;/a&gt;, &lt;a href="https://manjaro.org/" rel="noopener noreferrer"&gt;Manjaro&lt;/a&gt;, &lt;a href="https://arcolinux.com/" rel="noopener noreferrer"&gt;Arco&lt;/a&gt; and &lt;a href="https://garudalinux.org/" rel="noopener noreferrer"&gt;Garuda&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The main reason I went with plain Arch is because the experience of setting everything up myself was really intriguing. I also thought about package availability. When it comes to installing applications, Linux is different than macOS or Windows. Power users of either two operating systems equally hate their “App stores” and normally install programs through the application developer’s website. On Linux however, these “app stores” are actually quite good and are basically the de-facto way for users to install programs. Linux distros have something called a package manager which is an interface into these “app stores.”&lt;/p&gt;

&lt;p&gt;On top of having packages, Arch Linux has something called the AUR, which is a set of programs that were adapted to run on Arch Linux by the Arch Linux community. This was cool because instead of going to the application developer’s website for programs not in the official Arch package list (which in most cases you would have to install the application manually), I could just install it like a normal package!&lt;/p&gt;

&lt;p&gt;In the Linux community there is a bit of negative stigma surrounding the Arch Linux installation process in the form of the installation difficulty. I admit that if you are not comfortable using the command line/the Bash shell, you should definitely not install Arch Linux and instead go with a GUI option other than Arch like Ubuntu or Manjaro and learn the terminal from there. The Arch Installation process relies heavily on terminal usage and if you don’t know how to use it, you could seriously mess up your computer’s existing installation or have to restart the entire installation from Step One.&lt;/p&gt;

&lt;p&gt;Now that I chose Arch to be my distro, I actually had to install it. For this, I used the &lt;a href="https://wiki.archlinux.org/title/Installation_guide" rel="noopener noreferrer"&gt;official Arch wiki page’s installation guide&lt;/a&gt; and this &lt;a href="https://itsfoss.com/install-arch-linux/" rel="noopener noreferrer"&gt;guide from It’s FOSS&lt;/a&gt;. I also got guidance from a couple Discord servers I was a part of to see if I was really doing things the right way.&lt;/p&gt;

&lt;p&gt;I didn’t make a &lt;code&gt;swap&lt;/code&gt; partition as my computer had enough resources for that and I didn’t make a &lt;code&gt;home&lt;/code&gt; partition as well because creating a user later would account for that.&lt;/p&gt;

&lt;p&gt;Note: for the step that used &lt;code&gt;pacstrap&lt;/code&gt;, I installed &lt;code&gt;network-manager&lt;/code&gt; as well because that would help me do WIFI related stuff post-installation.&lt;/p&gt;

&lt;p&gt;After installing Arch Linux, I simply rebooted the computer, took out the USB drive I had the .iso on, and arrived at a &lt;code&gt;tty&lt;/code&gt; screen with a user and password prompt. For this, I entered the username &lt;code&gt;root&lt;/code&gt; and the password, which I setup when installing Arch Linux.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ABztBnNaCH-zYHFDE" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2ABztBnNaCH-zYHFDE" alt="arch linux login screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here, I made my own user with the &lt;a href="https://linuxize.com/post/how-to-create-users-in-linux-using-the-useradd-command/#how-to-add-a-new-user-and-create-home-directory" rel="noopener noreferrer"&gt;useradd&lt;/a&gt; command, which created it’s own &lt;code&gt;/home/USERNAME&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AnEvY1TeFfWhUHjwG.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AnEvY1TeFfWhUHjwG.png" alt="dwm demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I had to get a “GUI” up and running. I had used KDE and GNOME on my old laptop before but I wanted to try something called a tiling window manager. If you didn’t know, tiling window managers basically automatically resize windows based on available space, so instead of having a bunch of windows overlapping each other like macOS or Windows, all of them are on the screen and visible to the user. For this, I was going to use &lt;a href="https://dwm.suckless.org/" rel="noopener noreferrer"&gt;a tiling window manager called &lt;code&gt;dwm&lt;/code&gt;&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AXuk6sC4OP6zD9sWkl0_bxA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AXuk6sC4OP6zD9sWkl0_bxA.png" alt="dwm logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dwm&lt;/code&gt; is a bit different than &lt;a href="https://i3wm.org/" rel="noopener noreferrer"&gt;another tiling window manager called i3&lt;/a&gt; because you edit the source code (which is a header file utilized by the C language) directly to tweak and customize it.&lt;/p&gt;

&lt;p&gt;Along with &lt;code&gt;dwm&lt;/code&gt;, I installed &lt;code&gt;dmenu&lt;/code&gt; which basically is like Spotlight except that it only opens applications that are in the &lt;code&gt;PATH&lt;/code&gt; environment variable. The applications themselves are just scripts running, so when I launch an application through &lt;code&gt;dmenu&lt;/code&gt;, it’s really just executing a script to launch that program. I didn’t really customize &lt;code&gt;dmenu&lt;/code&gt; except loading in a custom font.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AuSEjF8-DTK_qrKPU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F0%2AuSEjF8-DTK_qrKPU.png" alt="suckless terminal demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For my terminal, I decided to use the Suckless Terminal, also known as &lt;code&gt;st&lt;/code&gt;. I mainly chose this because I heard it was nice and I wasn’t ready to try out stuff like &lt;code&gt;alacritty&lt;/code&gt; or &lt;code&gt;terminator&lt;/code&gt; just yet (those are other terminal emulators by the way).&lt;/p&gt;

&lt;p&gt;Oh yeah I forgot to mention something similar about two of the Suckless projects mentioned (&lt;code&gt;dwm&lt;/code&gt; and &lt;code&gt;st&lt;/code&gt;): they can’t be installed with a package manager. In essence, because of the concept of editing the source code directly, we have to manually install these tools. You can do that by running &lt;code&gt;sudo make clean install&lt;/code&gt; after tweaking the source code (a file called &lt;code&gt;config.h&lt;/code&gt; mostly). Notice how we couldn’t use a package manager (by default the package manager on Arch is &lt;code&gt;pacman&lt;/code&gt;) to install this.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: For&lt;/em&gt; &lt;code&gt;dmenu&lt;/code&gt;&lt;em&gt;, you can install it with a package manager&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To modify &lt;code&gt;st&lt;/code&gt; terminal, you need to install things called patches, which essentially are &lt;code&gt;.diff&lt;/code&gt; files that you need to patch to the source code to add new features. For example, a patch you chose could add scrolling to the &lt;code&gt;st&lt;/code&gt; terminal, and you would have to run a command to merge those changes to the actual source code. &lt;a href="https://www.youtube.com/watch?v=fBrc_xgwQE8" rel="noopener noreferrer"&gt;This video&lt;/a&gt; is an excellent tutorial on patching the terminal.&lt;/p&gt;

&lt;p&gt;For the prompt on my terminal, I decided to use something called Starship Prompt. It is an excellent cross-platform prompt which is really colorful and gives you a lot of data about the current directory you are in, which I find very helpful, especially for &lt;code&gt;git&lt;/code&gt;. It is really fast (it’s written in Rust, which is a speedy programming language). You can find more about the prompt on &lt;a href="https://starship.rs/" rel="noopener noreferrer"&gt;their website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AedLlBPb5kgVGTKiMOQOdZg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AedLlBPb5kgVGTKiMOQOdZg.png" alt="starship prompt demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get those special symbols in the prompt, I used the FiraCode Nerd Font, which gives the ability to use these special symbols. You can download it &lt;a href="https://www.nerdfonts.com/font-downloads" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So remember those community package repositories I mentioned earlier? That is called the Arch User Repository, more commonly known as the AUR. To install a package from the AUR manually would consist of cloning repos from the AUR and running &lt;code&gt;makepkg&lt;/code&gt; or whatever, which is highly inconvenient compared to a package manager.&lt;/p&gt;

&lt;p&gt;This is why I installed an AUR helper called &lt;code&gt;paru&lt;/code&gt;. If you don’t know what an AUR helper is, it basically eases the process of installing packages from the Arch User Repository. First, to get all the tools needed to actually install the tool, I ran &lt;code&gt;sudo pacman -S --needed base-devel&lt;/code&gt; in my terminal so we can use the required command line utilities to install it. To actually install it though, I basically did a &lt;code&gt;git clone [https://aur.archlinux.org/paru.git](https://aur.archlinux.org/paru.git)&lt;/code&gt;. This makes a directory on our machine that contains the &lt;code&gt;git&lt;/code&gt; repository for &lt;code&gt;paru&lt;/code&gt;. I went into the directory of &lt;code&gt;paru&lt;/code&gt; by running &lt;code&gt;cd paru&lt;/code&gt;. Then I ran &lt;code&gt;makepkg -si&lt;/code&gt;, to install &lt;code&gt;paru&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In summary, I ran these commands to install &lt;code&gt;paru&lt;/code&gt; (&lt;a href="https://itsfoss.com/paru-aur-helper/" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; helped me):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo pacman -S --needed base-devel
git clone https://aur.archlinux.org/paru.git
cd parumakepkg -si
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, I could install AUR packages similar to installing them with &lt;code&gt;pacman&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;If you want to find how to use &lt;code&gt;paru&lt;/code&gt; you can check the guide I linked above as it gives you the basic commands you need to use it.&lt;/p&gt;

&lt;p&gt;One of the main packages I installed was VSCode. The package in the AUR was named &lt;code&gt;visual-studio-code-bin&lt;/code&gt; and I installed it by running &lt;code&gt;paru -S visual-studio-code-bin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Installing AUR packages takes a bit more time than installing packages with &lt;code&gt;pacman&lt;/code&gt; so don’t fret if it’s running scripts for a minute or so.&lt;/p&gt;

&lt;p&gt;To set my desktop wallpaper with a tool called &lt;code&gt;nitrogen&lt;/code&gt;. This package is in the base Arch repos so you don’t have to worry about using &lt;code&gt;paru&lt;/code&gt;. I ran &lt;code&gt;sudo pacman -S nitrogen&lt;/code&gt; in my terminal to install the package.&lt;/p&gt;

&lt;p&gt;To set the wallpaper, I ran the command: &lt;code&gt;nitrogen&lt;/code&gt;. However, there is one more step to get your wallpapers running. &lt;code&gt;nitrogen&lt;/code&gt; only checks for images in the certain directories that you tell it to. By default it’s set to the &lt;code&gt;Desktop&lt;/code&gt; directory. You can edit these directories manually.&lt;/p&gt;

&lt;p&gt;To do this, press the “Preferences” button in the bottom right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ABkNG1ZLVBzkhND7V5rStnA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ABkNG1ZLVBzkhND7V5rStnA.png" alt="nitrogen preferences button"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, set the directories with the “Add” and “Delete” button in the directories section in the GUI that pops up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AhPkzeMOhoaKfgu2r4kY2sw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2AhPkzeMOhoaKfgu2r4kY2sw.png" alt="directory list/add screen in nitrogen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you press the “Add” button, a file manager will popup so you can navigate to the directory containing your wallpapers!&lt;/p&gt;

&lt;p&gt;That’s all well and all, but the wallpaper won’t stay after you restart the computer or simply end your &lt;code&gt;dwm&lt;/code&gt; session by pressing &lt;code&gt;Alt + Shift + Q&lt;/code&gt;. For this, I needed to run &lt;code&gt;nitrogen --restore&lt;/code&gt;. It’s not great to run that every time you start your &lt;code&gt;dwm&lt;/code&gt; session, so I had to figure out a way to do it on auto start.&lt;/p&gt;

&lt;p&gt;To run commands on auto start, I installed a patch for &lt;code&gt;dwm&lt;/code&gt; (like the &lt;code&gt;st&lt;/code&gt; terminal) which ran a script called &lt;code&gt;autostart.sh&lt;/code&gt; in the &lt;code&gt;~/.dwm/&lt;/code&gt; directory which ran every time I started &lt;code&gt;dwm&lt;/code&gt;. This enabled me to put &lt;code&gt;nitrogen --restore &amp;amp;&lt;/code&gt; in that &lt;code&gt;autostart.sh&lt;/code&gt; file (If you were wondering what the ampersand [the &lt;code&gt;&amp;amp;&lt;/code&gt;] is doing there, it basically tells your shell to do the task in the background).&lt;/p&gt;

&lt;p&gt;If you have been using &lt;code&gt;dwm&lt;/code&gt; for sometime, you might be wondering why I don’t use the &lt;code&gt;.xinitrc&lt;/code&gt; file. For those of you who have no clue what I’m talking about, let me explain. Since I’m using Arch Linux and I started from scratch, when I boot up my computer, it just plops me in the command line. This is extremely fast and when I want to start up &lt;code&gt;dwm&lt;/code&gt;, I just run &lt;code&gt;startx&lt;/code&gt; in the command line.&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;startx&lt;/code&gt; command already has a file to execute commands when &lt;code&gt;dwm&lt;/code&gt; starts called &lt;code&gt;.xinitrc&lt;/code&gt;. I didn’t opt to use that just so that if I ever stop using &lt;code&gt;startx&lt;/code&gt; and start using a login screen (more formally known as a display manager), I can still do all the things on autostart without having to patch &lt;code&gt;dwm&lt;/code&gt; with the &lt;code&gt;autostart.sh&lt;/code&gt; thing.&lt;/p&gt;

&lt;p&gt;This whole &lt;code&gt;autostart.sh&lt;/code&gt; thing allowed me to setup update my status bar in &lt;code&gt;dwm&lt;/code&gt; really efficiently. In that &lt;code&gt;dwm&lt;/code&gt; folder, I had another file called &lt;code&gt;changebar.sh&lt;/code&gt; which basically was the script to change the status bar in &lt;code&gt;dwm&lt;/code&gt;. If you didn’t know what the status bar in &lt;code&gt;dwm&lt;/code&gt; is, it is in the top right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ADdCd9jVC-gFgSl3T9rAz1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F800%2F1%2ADdCd9jVC-gFgSl3T9rAz1A.png" alt="my customized status bar in dwm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By default, this is set to something like &lt;code&gt;dwm VERSION_NUMBER&lt;/code&gt; , but I customized it with the &lt;code&gt;changebar.sh&lt;/code&gt; file and a command that was &lt;code&gt;xsetroot -name "whatever you want in the status bar"&lt;/code&gt;. Also, if you were wondering how I customized the color of the top bar and everything else, check out &lt;a href="https://www.youtube.com/watch?v=lC-WzV7rJpQ" rel="noopener noreferrer"&gt;this video&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is where I use &lt;code&gt;changebar.sh&lt;/code&gt;. In my &lt;code&gt;autostart.sh&lt;/code&gt; file, I have this code written out:&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="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;  
        /home/shubhampatil/.dwm/changebar.sh  
        &lt;span class="nb"&gt;sleep &lt;/span&gt;5s  
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This basically enters a while loop that goes on forever, activating that &lt;code&gt;changebar.sh&lt;/code&gt; script and sleeps 5 seconds later.&lt;/p&gt;

&lt;p&gt;You might be wondering what is in that &lt;code&gt;changebar.sh&lt;/code&gt; file. Well, here it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;VOLUME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;amixer sget Master | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'Front Left:'&lt;/span&gt; | &lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/\[^\\\[\]\*\\\[\\(\[0-9\]\\{1,3\\}%\\).\*\\(on\\|off\\).\*/\\2 \\1/'&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/off/M/'&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/on //'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;  
&lt;span class="nv"&gt;TIME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="s1"&gt;'+%a %D |   %I:%M %p'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;  
xsetroot &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"| 🔊 &lt;/span&gt;&lt;span class="nv"&gt;$VOLUME&lt;/span&gt;&lt;span class="s2"&gt; |  &lt;/span&gt;&lt;span class="nv"&gt;$TIME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
bash&lt;/p&gt;

&lt;p&gt;This basically gets the current volume and gets the current time and displays it in the status bar.&lt;/p&gt;

&lt;p&gt;Now, let me talk about volume control with &lt;code&gt;dwm&lt;/code&gt;. For this, I had to edit the source code for &lt;code&gt;dwm&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;config.h&lt;/code&gt; file in the source code, I added this at the top of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;X11/XF86keysym.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cm"&gt;/* volume keys*/&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;upvol&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;\&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="s"&gt;"sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"-c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"amixer sset Master unmute; amixer set Master 5%+; /home/shubhampatil/.dwm/changebar.sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;downvol&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;\&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="s"&gt;"sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"-c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"amixer sset Master unmute; amixer set Master 5%-; /home/shubhampatil/.dwm/changebar.sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  

&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mutevol&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;\&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="s"&gt;"sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"-c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"amixer set Master toggle; /home/shubhampatil/.dwm/changebar.sh"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, I added the lines&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;XF86XK_AudioLowerVolume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{.&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;downvol&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;XF86XK_AudioMute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{.&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mutevol&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;XF86XK_AudioRaiseVolume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{.&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;upvol&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;To the &lt;code&gt;keys[]&lt;/code&gt; array in the &lt;code&gt;config.h&lt;/code&gt; file. After that, I just ran &lt;code&gt;sudo make clean install&lt;/code&gt; again in the &lt;code&gt;dwm&lt;/code&gt; source code directory, restarted &lt;code&gt;dwm&lt;/code&gt;, and it worked! Now, whenever I pressed the volume up/down/mute keys on my keyboard, it would change the volume output of the sound.&lt;/p&gt;

&lt;p&gt;One more thing about my computer: time. I found out that the clock on my computer got a minute out of sync with the rest of my devices.&lt;/p&gt;

&lt;p&gt;To combat this, I installed a package called &lt;code&gt;ntp&lt;/code&gt;(Network Time Protocol), which allowed me to sync my clock to servers on the internet that had the correct time.&lt;/p&gt;

&lt;p&gt;This package I installed generated a &lt;code&gt;.conf&lt;/code&gt; file, which allowed me to change the default servers to &lt;code&gt;pool.ntp.org&lt;/code&gt;‘s servers.&lt;/p&gt;

&lt;p&gt;My config file looks like this (located at &lt;code&gt;/etc/ntpd.config&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# Please consider joining the pool:  
#  
# http://www.pool.ntp.org/join.html 
#  
# For additional information see:  
# - https://wiki.archlinux.org/index.php/Network_Time_Protocol_daemon  
# - [http://support.ntp.org/bin/view/Support/GettingStarted](http://support.ntp.org/bin/view/Support/GettingStarted)  
# - the ntp.conf man page
&lt;/span&gt;
&lt;span class="c"&gt;#  NTP pool server setup  
&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="n"&gt;pool&lt;/span&gt;.&lt;span class="n"&gt;ntp&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;  
&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="n"&gt;pool&lt;/span&gt;.&lt;span class="n"&gt;ntp&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;  
&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;.&lt;span class="n"&gt;pool&lt;/span&gt;.&lt;span class="n"&gt;ntp&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;  
&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;.&lt;span class="n"&gt;pool&lt;/span&gt;.&lt;span class="n"&gt;ntp&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;

&lt;span class="c"&gt;# By default, the server allows:  
# - all queries from the local host  
# - only time queries from remote hosts, protected by rate limiting and kod  
&lt;/span&gt;&lt;span class="n"&gt;restrict&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;kod&lt;/span&gt; &lt;span class="n"&gt;limited&lt;/span&gt; &lt;span class="n"&gt;nomodify&lt;/span&gt; &lt;span class="n"&gt;nopeer&lt;/span&gt; &lt;span class="n"&gt;noquery&lt;/span&gt; &lt;span class="n"&gt;notrap&lt;/span&gt;  
&lt;span class="n"&gt;restrict&lt;/span&gt; &lt;span class="m"&gt;127&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;  
&lt;span class="n"&gt;restrict&lt;/span&gt; ::&lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="c"&gt;# Location of drift file  
&lt;/span&gt;&lt;span class="n"&gt;driftfile&lt;/span&gt; /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;lib&lt;/span&gt;/&lt;span class="n"&gt;ntp&lt;/span&gt;/&lt;span class="n"&gt;ntp&lt;/span&gt;.&lt;span class="n"&gt;drift&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find more info about this &lt;code&gt;pool.ntp.org&lt;/code&gt; stuff at &lt;a href="https://www.ntppool.org/en/use.html" rel="noopener noreferrer"&gt;https://www.ntppool.org/en/use.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I then had to setup my printer. Printer support with Linux is sort of complicated. I had to install the &lt;code&gt;cups&lt;/code&gt; package. Then, I ran &lt;code&gt;sudo systemctl enable cups&lt;/code&gt; and &lt;code&gt;sudo systemctl start cups&lt;/code&gt;. The former made it so that the &lt;code&gt;cups&lt;/code&gt; service would be enabled on startup. The latter basically started it right now.&lt;/p&gt;

&lt;p&gt;Then, I went to &lt;code&gt;localhost:631&lt;/code&gt; in my browser to configure my printer. I went to add my pritner but discovered that the driver for my printer wasn’t present. To get these drivers, I had to install the &lt;code&gt;hplip&lt;/code&gt; package, since I was using an HP printer. After that, the printing functionality worked properly. To find more about printer setup on Linux, I would recommend you to &lt;a href="https://www.youtube.com/watch?v=En2DJAMpwmY" rel="noopener noreferrer"&gt;watch this video&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using raw Arch Linux or Gentoo (another Linux distribution) is very different from something like Ubuntu or Manjaro. Not everything is pre-setup like you expect. Even if you install a GUI (called desktop environments) like Gnome or KDE Plasma, you will have to install some packages to get the printer setup correctly, for example. Overall, I’m glad that I tried Arch Linux, and if you’re comfortable with the Linux command line, I would suggest it too. Although, if you’re not comfortable using the command line just yet, I would suggest something like Ubuntu or PopOS!. If you’re an “intermediate” Linux user, and really want to try out Arch, I would suggest using Garuda Linux or Manjaro Linux. I am by no means an expert at Linux and I do have a lot to learn but I decided to jump in the deep end to challenge myself. In the end, Linux is still Linux so don’t feel bad about using something like Ubuntu versus raw Arch.&lt;/p&gt;

&lt;p&gt;Another difference I am yet to call out is the nature of Arch Linux’s updates. Arch is something that has a rolling release cycle. This means all the packages that make up your install are updated on an on-going basis, instead of the operating system itself with all the packages being updated every 6 months (like Ubuntu). The latter method is called a stable release cycle. To find out if you are better suited for rolling release distro or a stable release distro, check out &lt;a href="https://www.youtube.com/watch?v=212yJEH8-iA" rel="noopener noreferrer"&gt;this video&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By &lt;a href="https://medium.com/@shubhampatilsd" rel="noopener noreferrer"&gt;Shubham Patil&lt;/a&gt; on &lt;a href="https://medium.com/p/f4b0d8237947" rel="noopener noreferrer"&gt;August 15, 2021&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@shubhampatilsd/using-arch-linux-f4b0d8237947" rel="noopener noreferrer"&gt;Canonical link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exported from &lt;a href="https://medium.com" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; on August 15, 2021.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>archlinux</category>
      <category>linuxsetup</category>
      <category>ricing</category>
    </item>
    <item>
      <title>Storing Login Information With Cookies (JavaScript)</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Sun, 15 Aug 2021 18:20:26 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/storing-login-information-with-cookies-javascript-395k</link>
      <guid>https://dev.to/shubhampatilsd/storing-login-information-with-cookies-javascript-395k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is an article originally from Medium. I have decided to switch from Medium to dev.to and import all my posts from there.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wRYEvCyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZNhSOzv5Ata4Yhw8kGolxQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wRYEvCyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AZNhSOzv5Ata4Yhw8kGolxQ.png" alt="illustrated person sitting at desk with icons of the technologies covered in the blog surrounding them" width="626" height="626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s create a hypothetical situation. Say you have important login information for a site you’re building. If we wanted to implement a system where your site would automatically log the user in when they visit, the approach of making the user click the button to login every time will not work.&lt;/p&gt;

&lt;p&gt;This is where cookies come into the picture. HTTP Cookies, in simple terms, are a way to store data, which then can be sent to a server. An example in a &lt;a href="https://www.youtube.com/watch?v=OFRjZtYs3wY"&gt;video&lt;/a&gt; by Tom Scott, a cookie can be used for a dark/light mode preference. Your browser would set a cookie containing a preference of which theme to use, and the server would communicate back the correct one. In this tutorial, however, we will be using cookies for storage, not for communicating with a server.&lt;/p&gt;

&lt;p&gt;There is an npm package we can use called &lt;code&gt;js-cookie&lt;/code&gt;(or, alternatively, you can use a script tag to import it from jsDelivr CDN. Use &lt;a href="https://www.npmjs.com/package/js-cookie"&gt;this link&lt;/a&gt; for more info on how to install it.)&lt;/p&gt;

&lt;p&gt;Now comes the actual implementation. I’m going to be using React for this (a UI library for JS), but you can use anything that involves JavaScript. From my last &lt;a href="https://shubhampatilsd.medium.com/firebase-authentication-lowering-headaches-in-developers-adb61a73fbf6"&gt;writing&lt;/a&gt;, I used Firebase Authentication to get login info. I am going to be picking up the code from there (you don’t need to read that one to understand what is going on though). To import &lt;code&gt;js-cookie&lt;/code&gt; after installing it, put this line of code at the top of your JavaScript file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import Cookies from ‘js-cookie’&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, this is the code to set a cookie after we get the login information: (Login.js)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loginAsync&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="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;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;githubLogin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;//This is where we create the Cookie. Note the syntax.&lt;/span&gt;
        &lt;span class="c1"&gt;//The JavaScript object we created here is just stuff for me to use later.&lt;/span&gt;

        &lt;span class="nx"&gt;Cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userInfo&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;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;additionalUserInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;pfp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;additionalUserInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;avatar_url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&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;.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;

        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;expires&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

        &lt;span class="c1"&gt;//The expires line basically says the cookie expires in 29 days.&lt;/span&gt;

        &lt;span class="c1"&gt;//this is not a part of js-cookie but if you're interested, I have a getter and setter with React's useState hook which basically&lt;/span&gt;
        &lt;span class="c1"&gt;//says if it has to redirect to the main content.&lt;/span&gt;
        &lt;span class="nx"&gt;setRedirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;res&lt;/code&gt; variable is the response from the Firebase Authentication regarding the user’s GitHub account details (I implemented a “Login With Github” button). We set the cookie with &lt;code&gt;Cookies.set()&lt;/code&gt;. The first argument the function takes in is the name of the cookie. In this case, I set it to &lt;code&gt;userInfo&lt;/code&gt;. The second argument is an object (which resembles JSON). This is the content of the cookie. It doesn’t have to follow this structure and can contain anything as long as it is under 4 kilobytes. You can have up to 50 cookies on your domain as per &lt;a href="https://stackoverflow.com/questions/640938/what-is-the-maximum-size-of-a-web-browsers-cookies-key#4604212"&gt;this Stack Overflow post&lt;/a&gt;. The third argument is optional and is another object that defines how long the cookie will last (here, I put it for 29 days).&lt;/p&gt;

&lt;p&gt;Now, when the user signs in, we have stored their login credentials in a cookie!&lt;/p&gt;

&lt;p&gt;Retrieving this cookie is equally as easy. Now that we have stored the login credentials, you can redirect the user to the main page. If you’re using plain HTML + CSS + JavaScript, you can normally set the &lt;code&gt;window.location.href&lt;/code&gt; to the page you want your user to go to. This is a &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-create-a-web-server-in-node-js-with-the-http-module"&gt;great tutorial&lt;/a&gt; to help you setup a server to host your pages. You can also &lt;a href="https://medium.com/p/7b273e889605#6d0a"&gt;skip ahead&lt;/a&gt; as this next section will cover redirecting with React.&lt;/p&gt;

&lt;p&gt;If you are using React however, you would use &lt;a href="https://reactrouter.com/"&gt;React Rout&lt;/a&gt;er to accomplish this task.&lt;/p&gt;

&lt;p&gt;To &lt;a href="https://www.npmjs.com/package/react-router"&gt;install&lt;/a&gt; the web version of React Router, run &lt;code&gt;npm i react-router-dom&lt;/code&gt; in the directory of your project. (Note: Don’t install the package named &lt;code&gt;react-router&lt;/code&gt; as it will install the module for React Native, a way to write mobile applications with React.) Great! You now have React Router installed!&lt;/p&gt;

&lt;p&gt;Now, you should start coding in the file that contains the &lt;code&gt;ReactDOM.render()&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="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;BrowserRouter&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Switch&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-router-dom&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;ReactDOM&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-dom&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;yourComponent&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;RELATIVE_PATH_TO_YOUR_COMPONENT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;




&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;


  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Switch&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/PAGE_NAME"&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;yourComponent&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;    

    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Switch&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Let me break this down. At the top, we have our React Router imports that basically import what we need. The &lt;code&gt;import yourComponent from ‘RELATIVE_PATH_TO_YOUR_COMPONENT’;&lt;/code&gt; is more crucial however.&lt;/p&gt;

&lt;p&gt;With React Router, instead of pointing to new HTML files, we can load components when we redirect to a certain endpoint. You can rename &lt;code&gt;yourComponent&lt;/code&gt; to whatever you want. The &lt;code&gt;RELATIVE_PATH_TO_YOUR_COMPONENT&lt;/code&gt; is the path to your component from the JavaScript file that renders our React code.&lt;/p&gt;

&lt;p&gt;Now let’s look at this block of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;  
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Switch&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;  
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/PAGE\_NAME"&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;yourComponent&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;  
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Switch&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;  
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this basically does is setup the endpoints for our web application. The &lt;code&gt;&amp;lt;Router&amp;gt;&lt;/code&gt; just tells React that “This is the code where we setup the URL endpoints.” The &lt;code&gt;&amp;lt;Switch&amp;gt;&lt;/code&gt; is a component that selects the first endpoint if all of them match. For example, if we have an endpoint for &lt;code&gt;/profile&lt;/code&gt; and &lt;code&gt;/:variable&lt;/code&gt; , (the latter being so that you can retrieve parameters from the URLs of the endpoints such as retrieving the “ShubhamPatilsd” in &lt;code&gt;github.com/ShubhamPatilsd&lt;/code&gt;), &lt;code&gt;&amp;lt;Switch&amp;gt;&lt;/code&gt; will only use the first endpoint, or in this case, &lt;code&gt;/profile&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;Route&amp;gt;&lt;/code&gt; component is most important of all here. This is what defines the endpoints for our React app. You can see in this example that I’ve set the &lt;code&gt;path&lt;/code&gt; to &lt;code&gt;/PAGE_NAME&lt;/code&gt; and it renders &lt;code&gt;yourComponent&lt;/code&gt; when a user tries to access that page. Change the &lt;code&gt;PAGE_NAME&lt;/code&gt; part to the endpoint you want. For example if you wanted &lt;code&gt;/cool&lt;/code&gt; , you would change it to &lt;code&gt;/cool&lt;/code&gt; instead of &lt;code&gt;/PAGE_NAME&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;There are a lot of things that React Router offers and I suggest reading their &lt;a href="https://reactrouter.com/web/api/"&gt;documentation&lt;/a&gt; to get more information.&lt;/p&gt;

&lt;p&gt;Now that we’ve setup the infrastructure to handle our links, we can actually talk about how to retrieve the cookies.&lt;/p&gt;

&lt;p&gt;To import &lt;code&gt;js-cookie&lt;/code&gt; , again, type &lt;code&gt;import Cookies from ‘js-cookie’&lt;/code&gt; at the top of your JavaScript file. Then, to retrieve the data, use this code below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JSON.parse(Cookies.get('userInfo'));&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You’re going to need &lt;code&gt;JSON.parse&lt;/code&gt; because &lt;code&gt;js-cookie&lt;/code&gt; doesn’t automatically return the cookie data in JSON but instead returns it as a string. That’s an issue because if the rest of your code tries to access the raw string like its JSON, it will result in errors.&lt;/p&gt;

&lt;p&gt;If you’re using plain HTML, CSS, and JavaScript, this is the end of the guide! I hope you’ve got cookies working! If not, do look at &lt;a href="https://www.youtube.com/watch?v=KzG6NtO8qdg"&gt;this video&lt;/a&gt;, and if it still doesn’t work, you could write a comment so I can help you.&lt;/p&gt;

&lt;p&gt;If you’re using React however, there are still some extra steps that could benefit you in the long-run.&lt;/p&gt;

&lt;p&gt;First, import the &lt;code&gt;&amp;lt;Redirect&amp;gt;&lt;/code&gt; component from the React Router library by typing this at the top of your JavaScript file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import {Redirect} from 'react-router-dom';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, implement a if-else statement to check if the user is logged in like 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="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;Cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userInfo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Redirect&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&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;else&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;userData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userInfo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="c1"&gt;//your ui here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the condition in the first if block, it checks if the cookie by the name of &lt;code&gt;userInfo&lt;/code&gt; is null or not. If it is, we redirect the user to a certain endpoint called &lt;code&gt;/login&lt;/code&gt; . (Note: You can redirect the user to any endpoint you want, just remember to set it up!). If the cookie is not null however, we store the parsed JSON of the cookie inside a varible called &lt;code&gt;userData&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And that’s it! Now you can access this &lt;code&gt;userData&lt;/code&gt; variable like a JSON object!&lt;/p&gt;

&lt;p&gt;Thanks for reading my second Medium article! If you have any suggestions, do let me know in a private comment!&lt;/p&gt;

&lt;p&gt;By &lt;a href="https://medium.com/@shubhampatilsd"&gt;Shubham Patil&lt;/a&gt; on &lt;a href="https://medium.com/p/7b273e889605"&gt;April 19, 2021&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@shubhampatilsd/storing-login-information-with-cookies-javascript-7b273e889605"&gt;Canonical link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exported from &lt;a href="https://medium.com"&gt;Medium&lt;/a&gt; on August 15, 2021.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>cookies</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Firebase Authentication — Lowering Headaches In Developers</title>
      <dc:creator>Shubham Patil</dc:creator>
      <pubDate>Sun, 15 Aug 2021 18:09:09 +0000</pubDate>
      <link>https://dev.to/shubhampatilsd/firebase-authentication-lowering-headaches-in-developers-5ebn</link>
      <guid>https://dev.to/shubhampatilsd/firebase-authentication-lowering-headaches-in-developers-5ebn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is an article originally from Medium. I have decided to switch from Medium to dev.to and import all my posts from there.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ujoD3lAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r6hdo83766pcf459s7np.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ujoD3lAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r6hdo83766pcf459s7np.png" alt="Firebase logo" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I had to do some &lt;a href="https://docs.github.com/en/developers/apps/authorizing-oauth-apps"&gt;authentication with GitHub&lt;/a&gt; the other day for a mini-project I was making. The main idea was that I would use GitHub’s authentication service with OAuth to use with a web app for a login system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--brzXxcxv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AF04rtugyB1rdIl57VbMX8A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--brzXxcxv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2AF04rtugyB1rdIl57VbMX8A.png" alt="overview of how login screen would look like" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything was fine, I found &lt;a href="https://www.youtube.com/watch?v=PdFdd4N6LtI"&gt;this amazing tutorial&lt;/a&gt; by “Barely Coding With Daniel Bark” which showed me how to use Node.js to authenticate the user.&lt;/p&gt;

&lt;p&gt;In essence, when the user clicked the “Login With GitHub” button, my web app would redirect the user to &lt;code&gt;[https://github.com/login/oauth/authorize](https://github.com/login/oauth/authorize)&lt;/code&gt;, which I would also send my &lt;code&gt;CLIENT_ID&lt;/code&gt;of my OAuth app with.&lt;/p&gt;

&lt;p&gt;Once the user logs in on the GitHub sign-in page we redirect them to (using&lt;code&gt;https://github.com/login/oauth/authorize&lt;/code&gt;), it would then send me back a temporary code and client secret of my GitHub OAuth app on one of my endpoints with the Node.js server, because the user would be redirected there. I then had to send a &lt;code&gt;POST&lt;/code&gt; request to &lt;code&gt;[https://github.com/login/oauth/access_token](https://github.com/login/oauth/access_token)&lt;/code&gt; with my &lt;code&gt;CLIENT_ID&lt;/code&gt;, &lt;code&gt;CLIENT_SECRET&lt;/code&gt; and the &lt;code&gt;code&lt;/code&gt; we got when it redirected back to my site. After that, I would get a response with an &lt;code&gt;access_token&lt;/code&gt;, which would allow me to get other info such as the user’s profile picture on GitHub, their username, etc. etc. etc.&lt;/p&gt;

&lt;p&gt;Code for the server side from video (Not my code view &lt;a href="https://github.com/danba340/oauth-github-example/blob/master/index.js"&gt;source&lt;/a&gt;):&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As I mentioned above, I found a very intuitive tutorial on YouTube which helped me get the gist of things, and all was good. We got the access token and then redirected the user to a static HTML page. Then I realized that I had to incorporate this with React, a UI Framework for JavaScript.&lt;/p&gt;

&lt;p&gt;You might be thinking that this was no big deal and that I could easily incorporate a backend with Node.js with this. Here, the issue lies in serving the UI and communicating the &lt;code&gt;access_token&lt;/code&gt;with React.&lt;/p&gt;

&lt;p&gt;First of all, I had to serve the UI once the user is authenticated. Now you see, React is meant to be a frontend framework, or in other words, it manages the things the user can see. The backend is the infrastructure behind the frontend, which manages and serves data for the frontend. Our backend task of communicating with the GitHub OAuth App now needs to be code on the frontend, as we cannot just serve up a JSX file with React UI.&lt;/p&gt;

&lt;p&gt;React in its nature appends to an element in &lt;strong&gt;one&lt;/strong&gt; HTML file. This could be a &lt;code&gt;div&lt;/code&gt; with an &lt;code&gt;id&lt;/code&gt; of &lt;code&gt;root&lt;/code&gt; or something else. I’m going to massively oversimplify here but, React appends its own, JavaScript and HTML “hybrid” code called JSX, to the inside of that element we specified in the original HTML file.&lt;/p&gt;

&lt;p&gt;You might say that we should just load the HTML file from the server, but the HTML file is not how the React code loads. React uses a Node.js server (different one from our backend) to run the React code.&lt;/p&gt;

&lt;p&gt;To clear things up, the React server could run on &lt;code&gt;http://localhost:3000/&lt;/code&gt; while our backend server would run on &lt;code&gt;http://localhost:5000/&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;So, to have a frontend, we need to run a Node.js server so your React code can append itself to that one HTML file.&lt;/p&gt;

&lt;p&gt;Now that we have &lt;strong&gt;two&lt;/strong&gt; different Node.js servers running, (one for the backend and one for the frontend with React) this leads me into the second issue, communicating the access token to the frontend.&lt;/p&gt;

&lt;p&gt;Since we are running two Node.js servers, communicating data between them would be very hard and unintuitive (for a beginner programmer like me) and would involve multiple API endpoints and possibly cookies.&lt;/p&gt;

&lt;p&gt;This can all get pretty complicated pretty fast. You might be thinking that we should just somehow incorporate the backend in the React frontend. This isn’t impossible but it would just be very complicated for a programmer who just wants to get things done in their project. (&lt;a href="https://levelup.gitconnected.com/how-to-implement-login-with-github-in-a-react-app-bd3d704c64fc"&gt;This approach&lt;/a&gt; or &lt;a href="https://codeburst.io/react-authentication-with-twitter-google-facebook-and-github-862d59583105"&gt;this one&lt;/a&gt; can be very complicated for beginner programmers and coders who just want to get things done in their project. They’re really good if you’re advanced or you want to understand things at a very low level.)&lt;/p&gt;

&lt;p&gt;This is when Firebase Authentication really shines.&lt;/p&gt;

&lt;p&gt;As I was banging my head on a wall trying to figure this out, Benjamin S on the CodeDay Discord Server, (&lt;a href="https://www.codeday.org/"&gt;CodeDay is a non-profit dedicated to introducing students to computer science&lt;/a&gt;) told me about Firebase Authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sOZq11ZU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ac7GkdBByYMHjBTDeuA6kkQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sOZq11ZU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/800/1%2Ac7GkdBByYMHjBTDeuA6kkQ.png" alt="the person who suggested firebase auth to me" width="717" height="94"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Firebase Authentication? I’ve only heard/used Firebase Realtime Database in my personal projects such as this &lt;a href="https://chat-win98.herokuapp.com/"&gt;chat website&lt;/a&gt; and this &lt;a href="https://keyshare.now.sh/"&gt;mechanical keyboard sound test platform&lt;/a&gt;. This could be worth a shot.&lt;/p&gt;

&lt;p&gt;Worth a shot it definitely was. With &lt;a href="https://firebase.google.com/docs/auth/web/github-auth"&gt;this lovely article&lt;/a&gt; in the Firebase documentation and &lt;a href="https://www.youtube.com/watch?v=MG3ZTfdxODA"&gt;this video&lt;/a&gt;, I installed Firebase in my project (&lt;code&gt;npm install firebase&lt;/code&gt; ), setup a Firebase Project, and started coding my authentication. (I recommend using that article if you want an &lt;code&gt;in-depth&lt;/code&gt; explanation)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Npzs-lRo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/600/1%2AwqTxsSGf8oyzOmaBh-XdmA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Npzs-lRo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/600/1%2AwqTxsSGf8oyzOmaBh-XdmA.png" alt="folder structure of project" width="155" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I had a config for my Firebase project which was basically setting up my Firebase with API credentials.&lt;/p&gt;

&lt;p&gt;Code for the &lt;code&gt;firebase-config.js&lt;/code&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now on to the authentication.&lt;/p&gt;

&lt;p&gt;Code for &lt;code&gt;auth.js&lt;/code&gt; :&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now for where it all comes together, &lt;code&gt;App.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App.js&lt;/code&gt; (don’t read all of this code I’ll explain the important parts)&lt;/p&gt;

&lt;p&gt;We have the function called &lt;code&gt;loginAsync&lt;/code&gt; which I setup to handle clicks of the login button.&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;githubLogin&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;./service/auth&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;loginAsync&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="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;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;githubLogin&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We then have the actual button. (I’m using Material-UI, which allows me to have Google’s Material Design)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;loginAsync&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"contained"&lt;/span&gt; &lt;span class="na"&gt;startIcon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LockOpenIcon&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Login With GitHub&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have an &lt;code&gt;onClick&lt;/code&gt; handler, which tells the code to go to our &lt;code&gt;loginAsync&lt;/code&gt; function above.&lt;/p&gt;

&lt;p&gt;And that was it! It worked perfectly. I would redirect the users to a URL when they click the login button with the OAuth &lt;code&gt;CLIENT_ID&lt;/code&gt; , which allowed them to login. This then sent the user to a Firebase URL such as &lt;code&gt;my-app-12345.firebaseapp.com/__/auth/handler&lt;/code&gt; for an OAuth callback handler. Firebase would then redirect the user to my site and send the data with the access token again.&lt;/p&gt;

&lt;p&gt;This was amazing how it prevented me from going crazy trying to figure out authentication. Thank you Firebase!&lt;/p&gt;

&lt;p&gt;Hope this helps! You can always respond to this and give me some feedback! (This is also my first time writing on Medium)&lt;/p&gt;

&lt;p&gt;By &lt;a href="https://medium.com/@shubhampatilsd"&gt;Shubham Patil&lt;/a&gt; on &lt;a href="https://medium.com/p/adb61a73fbf6"&gt;March 23, 2021&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@shubhampatilsd/firebase-authentication-lowering-headaches-in-developers-adb61a73fbf6"&gt;Canonical link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exported from &lt;a href="https://medium.com"&gt;Medium&lt;/a&gt; on August 15, 2021.&lt;/p&gt;

</description>
      <category>firebase</category>
      <category>authentication</category>
      <category>react</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
