<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Abhinav Rajesh's Blog]]></title><description><![CDATA[Hey, I'm Abhinav Rajesh a passionate UI/UX Designer and Full Stack Web Developer. I created this blog to help beginners to code using amazing frameworks like NextJS, React, etc.]]></description><link>https://blog.abhinavrajesh.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1627375796185/YylSL7ThM.png</url><title>Abhinav Rajesh&apos;s Blog</title><link>https://blog.abhinavrajesh.com</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 06 Jun 2026 22:10:40 GMT</lastBuildDate><atom:link href="https://blog.abhinavrajesh.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I built CLI version of Wordle game]]></title><description><![CDATA[For the past couple of months, my Twitter feed is filled with a bunch of green and yellow boxes which are the attempts of different people at Wordle




Since seeing these tweets, I decided to give wordle a try.
At first, it seemed like a basic game,...]]></description><link>https://blog.abhinavrajesh.com/wordle-cli</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/wordle-cli</guid><category><![CDATA[cli]]></category><category><![CDATA[TypeScript]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Sat, 05 Feb 2022 16:59:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1643569351361/eCylCzGbl.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For the past couple of months, my Twitter feed is filled with a bunch of green and yellow boxes which are the attempts of different people at <a target="_blank" href="https://www.powerlanguage.co.uk/wordle/">Wordle</a></p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1643569767565/7u_EWWyI3.png" alt="My wordle twitter feed" />
</center>

<p>Since seeing these tweets, I decided to give wordle a try.</p>
<p>At first, it seemed like a basic game, nothing special about it just a basic minimal UI with input boxes and pretty straightforward. Then I started playing the game and it felt kinda cool.</p>
<p>Few key takeaways from the game</p>
<ul>
<li><p>A random five-letter word is generated.</p>
</li>
<li><p>Six attempts at finding the word.</p>
</li>
<li><p>No words are repeated (at the time of writing this post).</p>
</li>
<li><p>Letter not present in the word are greyed out.</p>
</li>
<li><p>Letter present in the word but at the incorrect location is marked as yellow.</p>
</li>
<li><p>Letter present in the word and at the correct location is marked as green.</p>
</li>
<li><p>Only a single word a day</p>
</li>
<li><p>Option to share the boxes on Twitter or any social media application.</p>
</li>
</ul>
<p>After playing around with the game, and being a developer I decided to create a clone. But I didn't really wanna create a web clone as there are already a ton of them present online and really wanted to try something out, like a mobile app or something else.</p>
<p>And that's when a video of fireship was dropped about building a CLI application using NodeJS.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/_oHByo8tiEY">https://youtu.be/_oHByo8tiEY</a></div>
<p> </p>
<p>I really wanted to create a CLI app and I have only created one before, so I decided to create a CLI clone of Wordle!</p>
<h2 id="heading-building">Building</h2>
<p>So I started out by listing out the features that need to be implemented and the required items for the build.</p>
<ul>
<li><p>A collection of five letter valid words</p>
</li>
<li><p>Six attempts at guessing the word</p>
</li>
<li><p>Only show 1 word per day</p>
</li>
<li><p>Save and display the previous guesses on the same day</p>
</li>
<li><p>Option to share the result on Twitter or any other social media application</p>
</li>
</ul>
<p>I started by creating a <a target="_blank" href="https://github.com/AbhinavRajesh/wordle-cli">Github repository</a></p>
<p>Then I needed a collection of words, my friend from discord helped me get a collection of 12,930 five-letter words. I have no clue where he got the list from, but anyways really appreciate it.</p>
<p>The words list is present at my <a target="_blank" href="https://github.com/AbhinavRajesh/wordle-cli/blob/main/src/words.json">Github Repository</a>. While you are at it, might as well star the repo :P</p>
<p>After I have all the words required, I started by creating a function to set the word for the day. I wanted to make the game such that on a particular day anyone using the app would be having the same word.</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/cli/setWord.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> setWord = <span class="hljs-keyword">async</span> (today: <span class="hljs-built_in">Date</span>) =&gt; {
  <span class="hljs-keyword">const</span> referenceDate = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">"01/29/2022"</span>).getTime();
  <span class="hljs-keyword">const</span> diffTime: <span class="hljs-built_in">number</span> = <span class="hljs-built_in">Math</span>.abs(today.getTime() - referenceDate);
  <span class="hljs-keyword">const</span> offsetDays = <span class="hljs-built_in">Math</span>.ceil(diffTime / (<span class="hljs-number">1000</span> * <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">24</span>));
  <span class="hljs-keyword">const</span> newData: <span class="hljs-keyword">typeof</span> data = {
    name: data.name,
    date: {
      ...data.date,
      [today.toLocaleDateString(<span class="hljs-string">"en-GB"</span>)]: {
        word: words[offsetDays % words.length],
        guesses: [],
      },
    },
  };
  <span class="hljs-keyword">await</span> fs.writeFileSync(
    path.resolve(__dirname, <span class="hljs-string">"../data.json"</span>),
    <span class="hljs-built_in">JSON</span>.stringify(newData)
  );
};
</code></pre>
<p>This function basically calculates the offset of the current day from the initial release of the package (29th of January 2022). And based on this offset I fetch the corresponding word in the words list.</p>
<p>After selecting the word for the day, I decided to create a function to get the user input. For getting the guess from the user I used the package called <code>inquirer</code>. This package has many options to fetch input from the user in the form of input, checkbox, etc.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getGuess = <span class="hljs-keyword">async</span> (guessNumber: <span class="hljs-built_in">number</span>) =&gt; {
  inquirer.registerPrompt(<span class="hljs-string">"maxlength-input"</span>, MaxLengthInputPrompt);
  <span class="hljs-keyword">const</span> { guess } = <span class="hljs-keyword">await</span> inquirer.prompt([
    {
      <span class="hljs-keyword">type</span>: <span class="hljs-string">"maxlength-input"</span>,
      message: <span class="hljs-string">`Enter guess #<span class="hljs-subst">${guessNumber.toString()}</span>`</span>,
      name: <span class="hljs-string">"guess"</span>,
      maxLength: <span class="hljs-number">5</span>,
      validate: <span class="hljs-function">(<span class="hljs-params">input: <span class="hljs-built_in">string</span></span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (input.length === <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">"Enter some text"</span>;
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (input.length &lt; <span class="hljs-number">5</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">"Enter 5 letter word"</span>;
        <span class="hljs-keyword">else</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
      },
    },
  ]);
  <span class="hljs-keyword">const</span> today = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toLocaleDateString(<span class="hljs-string">"en-GB"</span>);
  <span class="hljs-keyword">const</span> jsonData = <span class="hljs-keyword">await</span> <span class="hljs-built_in">JSON</span>.parse(
    fs.readFileSync(path.resolve(__dirname, <span class="hljs-string">"../data.json"</span>), <span class="hljs-string">"utf-8"</span>)
  );
  fs.writeFileSync(
    path.resolve(__dirname, <span class="hljs-string">"../data.json"</span>),
    <span class="hljs-built_in">JSON</span>.stringify({
      word: jsonData.word,
      date: {
        ...jsonData.date,
        [today]: {
          word: jsonData.date?.[today].word,
          guesses: [...jsonData.date?.[today].guesses, guess],
        },
      },
    })
  );
  <span class="hljs-keyword">return</span> guess.toLowerCase();
};
</code></pre>
<p>After getting the user's guess, I needed to compare the guess with the word for the day and display the result according to the rules of the game. For displaying the colours for the background of each letter, I used the package called <code>chalk</code>. For performing all this, I implemented the following function</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> chalk <span class="hljs-keyword">from</span> <span class="hljs-string">"chalk"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> displayGuess = <span class="hljs-function">(<span class="hljs-params">word: <span class="hljs-built_in">string</span>, guess: <span class="hljs-built_in">string</span></span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> backgroundColors: <span class="hljs-built_in">string</span>[] = [];
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; word.length; i++) {
    <span class="hljs-keyword">if</span> (word[i] === guess[i]) backgroundColors.push(<span class="hljs-string">"green"</span>);
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (word.indexOf(guess[i]) !== <span class="hljs-number">-1</span>) backgroundColors.push(<span class="hljs-string">"yellow"</span>);
    <span class="hljs-keyword">else</span> backgroundColors.push(<span class="hljs-string">"white"</span>);
  }
  <span class="hljs-keyword">let</span> finalLog = <span class="hljs-string">""</span>;
  guess.split(<span class="hljs-string">""</span>).forEach(<span class="hljs-function">(<span class="hljs-params">character, i</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (backgroundColors[i] === <span class="hljs-string">"green"</span>)
      finalLog += chalk.black.bold.bgGreen(<span class="hljs-string">` <span class="hljs-subst">${character}</span> `</span>);
    <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (backgroundColors[i] === <span class="hljs-string">"yellow"</span>)
      finalLog += chalk.black.bold.bgYellow(<span class="hljs-string">` <span class="hljs-subst">${character}</span> `</span>);
    <span class="hljs-keyword">else</span> finalLog += chalk.black.bold.bgWhite(<span class="hljs-string">` <span class="hljs-subst">${character}</span> `</span>);
    finalLog += <span class="hljs-string">" "</span>;
  });
  <span class="hljs-built_in">console</span>.log(finalLog);
};
</code></pre>
<p>And finally, I check if the user made the correct guess. If the user made the correct guess display a congratulations message and display the shareable boxes also with a URL to Twitter which when clicked posts the result to Twitter. If the user doesn't make the correct guess the user is again asked to guess till the number of guesses left exhausts and finally the word is revealed.</p>
<p>And in the end, you would get something like this</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644078673653/LI0N_RprC.png" alt="image.png" />
</center>

<p>The game is available on npm. To play follow these steps</p>
<pre><code class="lang-plaintext"># Installation step
# Using npm
npm install -g @abhinavrajesh/wordle

# Using yarn
yarn global add @abhinavrajesh/wordle

# Run the game
wordle
</code></pre>
<p>And that's it for this article! Do give your feedback on the application in the comments below.</p>
<p>Links:</p>
<ul>
<li><p>npm: <a target="_blank" href="https://www.npmjs.com/package/@abhinavrajesh/wordle">@abhinavrajesh/wordle</a></p>
</li>
<li><p>Github: <a target="_blank" href="https://github.com/AbhinavRajesh/wordle-cli">AbhinavRajesh/wordle-cli</a> [If you liked the project do give the repository a 🌟]</p>
<p>  Feel free to drop a PR or an issue if you find any bugs.</p>
</li>
</ul>
<p>If you enjoyed the article do consider sharing the article and by following me on Hashnode and Twitter <a target="_blank" href="https://twitter.com/_AbhinavRajesh_">@_AbhinavRajesh_</a></p>
<h2 id="heading-support">🙌 Support</h2>
<p>If you're enjoying my articles, consider supporting me with a coffee ☕️. It really helps me a lot.</p>
<p><a target="_blank" href="https://www.buymeacoffee.com/abhinavrajesh">![Buy Me A Coffee](https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&amp;emoji=&amp;slug=abhinavrajesh&amp;button_colour=FFDD00&amp;font_colour=000000&amp;font_family=Cookie&amp;outline_colour=000000&amp;coffee_colour=ffffff align="left")</a></p>
<h2 id="heading-lets-connect">🌎 Lets connect</h2>
<p><a target="_blank" href="https://github.com/AbhinavRajesh">Github</a><br /><a target="_blank" href="https://twitter.com/_AbhinavRajesh_">Twitter</a><br /><a target="_blank" href="https://linkedin.com/in/abhinavrajesh">LinkedIn</a>  </p>
<h2 id="heading-feedback">🎸 Feedback</h2>
<p>Feedback helps to improve my articles. I'd love to hear feedback and thoughts on the article. Looking forward to your views.</p>
]]></content:encoded></item><item><title><![CDATA[How hashnode helped me land an internship at Github!]]></title><description><![CDATA[Hey everyone! It's been a while since I have written a blog post, and I'm really sorry for that. Would be getting back to writing a few posts every month.
Now to address the obvious reason why I'm writing this post, I'm really excited to share with y...]]></description><link>https://blog.abhinavrajesh.com/how-hashnode-helped-me-land-an-internship-at-github</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/how-hashnode-helped-me-land-an-internship-at-github</guid><category><![CDATA[Hashnode]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[internships]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Sat, 29 Jan 2022 07:37:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1643441492961/ajT5oG_BV.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey everyone! It's been a while since I have written a blog post, and I'm really sorry for that. Would be getting back to writing a few posts every month.</p>
<p>Now to address the obvious reason why I'm writing this post, I'm really excited to share with y'all that I have received an internship offer from <a target="_blank" href="https://github.com">Github</a> to join as DevRel Engineering Intern! 🥳</p>
<center>
<img src="https://c.tenor.com/NDT9kTczQfMAAAAC/celebration-celebrate.gif" />
</center>

<h2 id="heading-where-did-i-get-this-internship-from">Where did I get this internship from?</h2>
<p>There is this program called "Github Externship Program" which is a remote internship conducted twice every year(Winter and Summer Cohort) for students currently in their penultimate year of college. This program has 27 partner organisations which include famous organisations like Appwrite, Cred, Fampay, Hoppscotch, and many more!</p>
<p>More on it at their official website <a target="_blank" href="https://externship.github.in">Github Externship</a></p>
<h2 id="heading-the-application-process">The application process</h2>
<p>Applicants are supposed to write proposals for the organisation in which they are interested. Each organisation have multiple projects under them and an applicant can make 4 proposals in total to these 27 organisations.</p>
<p>Even though I could make 4 proposals, I only made 2 of them and both of them were to 2 different projects under Github(DevRel Engineer Engineering Project and Github India Engineering Project) because I was really interested in working at Github.</p>
<p>After a week, I got a mail saying my proposal for the DevRel Engineering role was accepted, and an interview was scheduled in the coming days. Different organisations have different approaches to this, some conduct coding tests before the interview, some have multiple rounds of interviews, etc. In the case of Github, there was only one interview for DevRel role.</p>
<p>I was mostly asked questions based on the proposal I had submitted and most of them revolved around the project, different UI/UX designs I have created previously, etc.</p>
<p>Fast forward to a few weeks, I received my offer letter yesterday!</p>
<h2 id="heading-how-exactly-did-hashnode-help-me-secure-this-internship">How exactly did hashnode help me secure this internship?</h2>
<p>There were 14,000+ students applicants and 8,000+ proposals made by students from India to these 27 organisations. And I'm really happy that I was among the few students out of these applicants who got selected! And this was mainly because of Hashnode!</p>
<p>During August and September of 2021, <strong><a class="user-mention" href="https://hashnode.com/@hashnode">hashnode</a></strong> conducted 2 amazing hackathons along with <strong><a class="user-mention" href="https://hashnode.com/@clerk">Clerk.dev</a></strong> and <strong>Auth0</strong>.</p>
<p>This resulted in me brainstorming for ideas and creating 2 amazing personal projects, <a target="_blank" href="https://blog.abhinavrajesh.com/introducing-chatbotish">Chatbotish</a> and <a target="_blank" href="https://blog.abhinavrajesh.com/introducing-aura-see-your-mood-in-a-whole-new-light">Aura</a> for my portfolio and without these hackathons, these projects would not have existed!</p>
<p>For the proposal, I gave these 2 projects as proof of my previous work/experience and during the interview for the same, I was asked questions based on these projects on how I've implemented the product, the technologies used, etc. These were kind of unique projects for a student with 100+ Producthunt upvotes and 1.5k+ page views and the interviewer really liked the personal projects I had created and the blog posts for the same and I believe because of this I landed the offer!</p>
<h2 id="heading-closing-notes">Closing notes</h2>
<p>For anyone who is looking to crack their first internship/job, I would recommend you to </p>
<ol>
<li><strong>Create personal projects:</strong> Create a handful of projects. And always give importance to quality over quantity. </li>
<li>Learn concepts by creating projects, this is also a great way to get out of <strong>tutorial hell.</strong></li>
<li>If you are trying to get into tech then I would recommend you to <strong>write more technical blogs!</strong> It helps to increase and broaden your knowledge.</li>
<li>Keep believing in yourself, and yes, dreams do come true.</li>
</ol>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/_AbhinavRajesh_/status/1487067158853009420">https://twitter.com/_AbhinavRajesh_/status/1487067158853009420</a></div>
<h2 id="heading-lets-connect">Lets connect</h2>
<p>If you have any questions, feel free to reach out to me via Mail, LinkedIn or Twitter, I would be happy to help you. The following are my socials and if possible drop a follow :)</p>
<ul>
<li>Mail: <code>me@abhinavrajesh.com</code></li>
<li>Github: <a target="_blank" href="https://github.com/AbhinavRajesh">AbhinavRajesh</a> <br /></li>
<li>Twitter: <a target="_blank" href="https://twitter.com/_AbhinavRajesh_">_AbhinavRajesh_</a> <br /></li>
<li>LinkedIn: <a target="_blank" href="https://linkedin.com/in/abhinavrajesh">abhinavrajesh</a> <br /></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Part 1: Complete guide on creating a Discord bot with TypeScript using discord.js]]></title><description><![CDATA[Hello everyone 👋 I'm Abhinav Rajesh and I'm back with another series. And in this series, we would be learning how to create a discord bot using typescript with the help of discord.js package. We would also be using Hashnode API!
We would be buildin...]]></description><link>https://blog.abhinavrajesh.com/discord-bot-part-1</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/discord-bot-part-1</guid><category><![CDATA[hashnodebootcamp]]></category><category><![CDATA[bots]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Tutorial]]></category><category><![CDATA[2Articles1Week]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Thu, 16 Sep 2021 05:53:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1631704764072/S8VnJJWyQ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone 👋 I'm Abhinav Rajesh and I'm back with another series. And in this series, we would be learning how to create a discord bot using typescript with the help of discord.js package. We would also be using Hashnode API!</p>
<p>We would be building out a simple discord bot that would return the user profile stats by fetching the data from <a target="_blank" href="https://api.hashnode.com">hashnode API</a> when we enter a certain message such as <code>?hashnode</code> or <code>?hashnode &lt;username&gt;</code></p>
<p>So let's get started!</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>Any code editor of your choice</li>
<li>No prior knowledge of TypeScript or JavaScript (Though knowing a bit before following the tutorial is a good idea to help you understand better)</li>
<li>Device with <a target="_blank" href="https://nodejs.org">Nodejs</a> installed (v16.9.1 is what I'm gonna be using for this tutorial)</li>
</ul>
<h2 id="introduction">Introduction</h2>
<h3 id="what-is-discordjs-httpsdiscordjsorg">What is <a target="_blank" href="https://discord.js.org">discord.js </a>?</h3>
<p>It is a <strong>powerful Node.js module</strong> that allows you to interact with the <a target="_blank" href="https://discord.com/developers/docs/intro">Discord API</a> very easily. It takes a much more object-oriented approach than most other JS Discord libraries, making your bot's code significantly tidier and easier to comprehend.</p>
<p>Usability, consistency, and performance are key focuses of discord.js, and it also has nearly 100% coverage of the Discord API. It receives new Discord features shortly after they arrive in the API.</p>
<h3 id="what-is-typescript-httpswwwtypescriptlangorg">What is <a target="_blank" href="https://www.typescriptlang.org">TypeScript </a>?</h3>
<p>TypeScript is a popular language created and maintained by <strong>Microsoft</strong>. It’s a <strong>superset of JavaScript</strong>, which makes all its features optional.</p>
<p>You can convert your existing JavaScript app to TypeScript and it should work as expected as long as your code is valid JavaScript. TypeScript allows you to set types on your variables and functions so you can <strong>type-check your code statically and catch errors at compile time.</strong></p>
<p>You can also use modern features that are not yet supported in JavaScript.</p>
<h2 id="setting-up-the-project">Setting up the project</h2>
<p><strong><em>NOTE: I would link the source code required for this project at the end of this article, but I would suggest you to follow along for better understanding</em></strong></p>
<ol>
<li><p><strong>Create a folder and inside the folder, open up the terminal and type out the below snippet</strong></p>
<pre><code>npm <span class="hljs-keyword">init</span> -y
</code></pre><p> <code>npm init</code> initializes a project and creates <code>package.json</code> file and <code>-y</code> flag means "yes" to all default options. The generated file should look something similar to this</p>
<pre><code class="lang-json"><span class="hljs-comment">// package.json</span>
{
   <span class="hljs-attr">"name"</span>: <span class="hljs-string">"hashnode-bot"</span>,
   <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
   <span class="hljs-attr">"description"</span>: <span class="hljs-string">"A discord bot to reply with stats of a user according to the user name"</span>,
   <span class="hljs-attr">"main"</span>: <span class="hljs-string">"index.js"</span>,
   <span class="hljs-attr">"scripts"</span>: {
        <span class="hljs-attr">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>
   },
   <span class="hljs-attr">"keywords"</span>: [
       <span class="hljs-string">"hashnode"</span>,
       <span class="hljs-string">"discord"</span>,
       <span class="hljs-string">"bot"</span>
   ],
   <span class="hljs-attr">"author"</span>: <span class="hljs-string">"Abhinav Rajesh"</span>,
   <span class="hljs-attr">"license"</span>: <span class="hljs-string">"MIT"</span>
}
</code></pre>
<p> You may edit the file with whatever values you want, but I would recommend you to not edit it and leave it as it is if you don't know much about it.</p>
</li>
<li><p><strong>Installing the required dependencies</strong></p>
<p> For this tutorial, we would be needing discord.js and also we would be needing few dev dependencies for setting up typescript with our project. We would also be needing <code>nodemon</code> for our project to make developing the bot easier. We would install the remaining dependencies as we progress further in the tutorial. Now to install the dependencies we use the following commands</p>
<ul>
<li><p>Installing TypeScript</p>
<pre><code><span class="hljs-comment"># using npm</span>
npm <span class="hljs-keyword">install</span> <span class="hljs-comment">--save-dev typescript</span>
<span class="hljs-comment"># or using yarn</span>
yarn <span class="hljs-keyword">add</span> -D typescript
</code></pre></li>
<li><p>We would also be needing types for node</p>
<pre><code># <span class="hljs-keyword">using</span> npm
npm install <span class="hljs-comment">--save-dev @types/node</span>
# <span class="hljs-keyword">or</span> <span class="hljs-keyword">using</span> yarn
yarn <span class="hljs-keyword">add</span> -D @<span class="hljs-keyword">types</span>/node
</code></pre></li>
<li><p>We would also be needing nodemon as a dev dependency. So every time you make a change, you would have to restart the server. And this is not really good for us as a developer. So what nodemon basically does is whenever we make a change in a file and save, it restarts the server on it's own!</p>
<pre><code><span class="hljs-comment"># using npm</span>
npm <span class="hljs-keyword">install</span> <span class="hljs-comment">--save-dev nodemon</span>
<span class="hljs-comment"># or using yarn</span>
yarn <span class="hljs-keyword">add</span> -D nodemon
</code></pre></li>
<li><p>And finally, we would be installing discord.js</p>
<pre><code><span class="hljs-comment"># using npm</span>
npm <span class="hljs-keyword">install</span> discord.js
<span class="hljs-comment"># or using yarn</span>
yarn <span class="hljs-keyword">add</span> discord.js
</code></pre></li>
</ul>
</li>
<li><p><strong>Setting up scripts</strong></p>
<p> Now, the thing is Nodejs cannot understand typescript and can only understand javascript. So we need to do something to compile the typescript code to javascript code. To do that we can add the following script to <code>package.json</code> file inside the <code>"scripts"</code></p>
<pre><code class="lang-json"><span class="hljs-comment">// package.json</span>
{  ...,
 <span class="hljs-attr">"scripts"</span>: {
     <span class="hljs-attr">"watch"</span>: <span class="hljs-string">"tsc -w"</span>,
  }
}
</code></pre>
<p> Now when you run <code>npm run watch</code> or <code>yarn run watch</code> what this script basically does is, it "watches" over the typescript files and convert them into javascript files inside <code>dist</code> folder in your project.</p>
<p> We need to add 2 more scripts, one is <code>start</code> and another is <code>dev</code>. So your <code>package.json</code> should have the following scripts</p>
<pre><code class="lang-json"><span class="hljs-comment">// package.json</span>
{  ...,
 <span class="hljs-attr">"scripts"</span>: {
     <span class="hljs-attr">"watch"</span>: <span class="hljs-string">"tsc -w"</span>,
     <span class="hljs-attr">"start"</span>: <span class="hljs-string">"node dist/index.js"</span>,
     <span class="hljs-attr">"dev"</span>: <span class="hljs-string">"nodemon dist/index.js"</span>
   },
}
</code></pre>
<p> We would only be using the <code>start</code> script once we are completely done with the project, i.e, during the time of <strong>hosting the bot</strong>. The <code>dev</code> script <strong>would only be used during the development of the bot and would not be used in the production environment</strong>. It uses <code>nodemon</code>, which basically improves the developer experience as mentioned before.</p>
</li>
<li><p><strong>Creating a folder for typescript code</strong></p>
<p> Inside the root of the project, create a folder <code>src</code>, this is where the code for typescript goes in. Inside <code>src</code> create a file name <code>index.ts</code>. This file would be the entry point for our application. For now, just add a simple console log in it just to test if the setup is working.</p>
<pre><code class="lang-ts"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello, World!"</span>)
</code></pre>
</li>
<li><p><strong>Testing out if everything works as intended</strong></p>
<p> Now open up 2 terminals, one to watch for file changes and the other to convert all the typescript code to javascript code.</p>
<pre><code><span class="hljs-comment"># In Terminal 1</span>
<span class="hljs-comment"># using npm</span>
<span class="hljs-built_in">npm</span> run watch
<span class="hljs-comment"># or using yarn</span>
yarn run watch
</code></pre><pre><code><span class="hljs-comment"># In Terminal 2</span>
<span class="hljs-comment"># using npm</span>
<span class="hljs-built_in">npm</span> run dev
<span class="hljs-comment"># or using yarn</span>
yarn run dev
</code></pre><p> And you should see something like this on the terminal </p>
 <center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631704675352/TjOmFEbW3.png" alt="image.png" />
</center>

</li>
</ol>
<p>And that's it! 🥳 You are all set to follow along with this tutorial on creating a discord bot! Meet you in the second part of the series.</p>
<p>And as always, linking the  <a target="_blank" href="https://github.com/AbhinavRajesh/Hashnode-Discord-Bot/tree/part-1">GitHub repository</a>  with source code required for this article.</p>
<h2 id="support">🙌 Support</h2>
<p>If you're enjoying my articles, consider supporting me with a coffee ☕️. It really helps me a lot.</p>
<p><a href="https://www.buymeacoffee.com/abhinavrajesh" target="_blank"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&amp;emoji=&amp;slug=abhinavrajesh&amp;button_colour=FFDD00&amp;font_colour=000000&amp;font_family=Cookie&amp;outline_colour=000000&amp;coffee_colour=ffffff" alt="Buy Me A Coffee" /></a></p>
<h2 id="lets-connect">🌎 Lets connect</h2>
<p><a target="_blank" href="https://github.com/AbhinavRajesh">Github</a> <br />
<a target="_blank" href="https://twitter.com/_AbhinavRajesh_">Twitter</a> <br />
<a target="_blank" href="https://linkedin.com/in/abhinavrajesh">LinkedIn</a> <br /></p>
<h2 id="feedback">🎸 Feedback</h2>
<p>Feedback helps to improve my articles. I'd love to hear feedback and thoughts on the article. Looking forward to your views.</p>
]]></content:encoded></item><item><title><![CDATA[How I got into technical writing]]></title><description><![CDATA[Hello everyone 👋 I'm Abhinav Rajesh and in this article, I would like to share with you all my path to become interested in technical writing. I'm writing this article as part of  Bootcamp by Hashnode on The art and business of technical writing



...]]></description><link>https://blog.abhinavrajesh.com/how-i-got-into-technical-writing</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/how-i-got-into-technical-writing</guid><category><![CDATA[hashnodebootcamp]]></category><category><![CDATA[Hashnode]]></category><category><![CDATA[HashnodeCommunity]]></category><category><![CDATA[Technical writing ]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Tue, 14 Sep 2021 09:05:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1631609195605/5iK_hyqIK.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello everyone 👋 I'm Abhinav Rajesh and in this article, I would like to share with you all my path to become interested in technical writing. I'm writing this article as part of  Bootcamp by Hashnode on <strong><em>The art and business of technical writing</em></strong></p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631590910889/0Yqwg_bC-.png" alt="image.png" />
</center>

<h3 id="a-little-about-myself">A little about myself 🤗</h3>
<p>I'm Abhinav Rajesh, I'm a UI/UX Designer and Full Stack Developer. I'm currently pursuing my Bachelor's degree in Computer Science and Engineering and am currently in junior year. </p>
<h3 id="the-journey">The journey</h3>
<p>It all started when I was in the freshman year of my college, got motivated by my friends who were really good at technical writing and also the pandemic started and wanted to try out something new, so I decided to create a blog article on creating a "COVID-19 Tracker" to track the number of cases every day by fetching data from an API endpoint. This was the time when there were not many tutorials on this.</p>
<p>So, I started writing the blog, for every day I wrote like 2-3 paragraphs explaining in detail about the working of code with examples for around a week until one day I lost my motivation to complete the article. It was mainly because I saw few others posting an article on the same topic of creating "COVID-19 Tracker", so I felt like it was too late to publish the article and there was a lot to cover. So I decided to stop writing the article and deleted the draft!😶(I still regret not publishing the article)</p>
<p>As the time passed the thought of writing a blog post came to me at times but didn't really have any motivation to complete the article. Also, I hated how Medium worked. Asking to authenticate to view, advertising about their mobile app and much more annoying things for a reader and I really was looking for a platform where this wasn't a thing and which had a better user experience.</p>
<h3 id="blogging-platform-which-i-was-looking-for">Blogging platform which I was looking for 🦸‍♂️</h3>
<p>Three months ago, I was reading articles and found a few interesting ones. Most had similar UI but the thing which intrigued me the most was the reader experience for these blogs. It was an amazing reading experience, no signup required, no advertisements nothing. I thought this was some blog template on WordPress or something when I noticed "Proudly part of hashnode" and that's when I found hashnode! This blogging platform was exactly what I was looking for!</p>
<p>So I created my Hashnode account 3 months ago (on 17th June 2021 to be precise :P) and released my first blog on the 27th June 2021. Although I barely got any reactions for my initial few articles also views were not bad, I still kept writing hoping someday I would make it to the "Top stories from Hashnode" weekly newsletter.</p>
<p>During these times I participated in hackathons conducted by Hashnode and writing a blog explaining my project in detail really helped me on how to write better technical blogs. And then one day, one of my articles made it into the newsletter 🥳</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631595766879/CIDwrYF-L.png" alt="image.png" />
</center>

<p>I was so happy that my article made it to the top stories and this really boosted my morale to write more! This led to me finally completing my series <a target="_blank" href="https://blog.abhinavrajesh.xyz/series/nextjs-crashcourse">How to Build a NextJS App using Typescript and TailwindCSS: The Complete Guide</a>, got a good amount of reactions and the best part, hashnode promoted my article on their Twitter handle!</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/hashnode/status/1437362948704546820">https://twitter.com/hashnode/status/1437362948704546820</a></div>
<p>Hashnode played an important role in making me interested in technical writing and I'm really thankful for the things done by hashnode which really motivate me to keep writing more articles.</p>
<h3 id="the-art-and-business-of-technical-writing-session-1">The art and business of technical writing: <em>Session 1</em></h3>
<p>Yesterday was the first day of Bootcamp and we had 2 amazing sessions by <a class="user-mention" href="https://hashnode.com/@tanoaksam">Sam Sycamore</a>, <a class="user-mention" href="https://hashnode.com/@quincy">Quincy Larson</a> and <a class="user-mention" href="https://hashnode.com/@didicodes">Edidiong Asikpo</a>.</p>
<p>Few of the points to take away from the first session by <a class="user-mention" href="https://hashnode.com/@quincy">Quincy Larson</a></p>
<ul>
<li><p><strong>Do you have advice for coming up with catchy titles or banners?</strong></p>
<ul>
<li>Being explicit is better than being clever. </li>
<li>Make sure the banner matches the title, and make sure text is readable on all types of devices such as mobile where most people are reading. </li>
<li>Keeping it simple is better.</li>
</ul>
</li>
<li><p><strong>Recommended length to maximize success?</strong></p>
<p>  <em>Generally, as long as it needs to be, and no longer. Long-form absolutely has its place though. Deep dives on a specific topic can build up quickly, but make sure you have real content to fill that space.</em></p>
</li>
<li><p><strong>What if I'm not gaining traction?</strong></p>
<ul>
<li>Use reverse SEO strategies to <strong><em>write specifically about what people are searching for.</em></strong></li>
<li>Alternatively, be personality-driven like thecodercoder or <a class="user-mention" href="https://hashnode.com/@Catalinpit">Catalin Pit</a>
. Build a reputation as being someone that is generally helpful!</li>
</ul>
</li>
<li><p><strong><em>Some articles, no matter your presence, will have low engagement. Keep writing and keep practising </em></strong></p>
</li>
</ul>
<p>Few points to take away from the second session by <a class="user-mention" href="https://hashnode.com/@didicodes">Edidiong Asikpo</a></p>
<ul>
<li><p>She gave a clear <strong>definition of technical writing</strong></p>
<p>   <em>A type of writing where the author is covering a subject that requires direction, instruction, or detailed explanation.</em></p>
</li>
<li><p>She also asked a good question, whether <strong>Writers are made or born?</strong></p>
<p>   In my opinion, writers can be both made or born. Writing is a skill that can be developed over time. Where you start is not a direct indicator of where you can go!</p>
</li>
<li><p>Audience perception is knowing what your audience wants and who is your audience. This can be determined by answering these questions</p>
<ul>
<li>As a reader what would I need?</li>
<li>Where would they be reading? Probably a mobile phone</li>
<li>When would they be reading?</li>
<li>And most importantly, why will they be reading your article?</li>
</ul>
</li>
<li><p>Some resources to improve your technical writing skills </p>
<ul>
<li>Google's writing style guide</li>
<li>Microsoft's writing style guide</li>
<li>FreeCodeCamp's style guide</li>
</ul>
</li>
<li><p>Get your audience' perception. Would they understand what you are writing or the certain terminology you are using?</p>
</li>
</ul>
<p>There are plenty more amazing points said during the session, but unfortunately, I won't be able to add all of those points here, but these are the main takeaway from the session!</p>
<p>It was fun writing about the session as a blog post, and thank you Hashnode for conducting this amazing Bootcamp. </p>
<h3 id="is-there-something-which-i-would-like-to-change-from-the-past">Is there something which I would like to change from the past?</h3>
<p>I'm really regretting my decision of deleting the draft of the "COVID-19 tracker", really wish I had completed the post and published it. Even if you feel like it's too late, or feel like it's not good enough, still do publish the post, it may help someone :) </p>
<blockquote>
<p>It's not about the destination, It's about the journey</p>
<p>-<cite> Ralph Waldo Emerson</cite></p>
</blockquote>
<p>So, that's it for this article, I would love to connect with you all people for reading the complete article and bearing with me :P, below are my social links, do follow me for more! Also, give your thoughts about the article in the comment section.</p>
<h3 id="lets-connect">Lets connect 🌎</h3>
<p><a target="_blank" href="https://github.com/AbhinavRajesh">Github</a> <br />
<a target="_blank" href="https://twitter.com/_AbhinavRajesh_">Twitter</a> <br />
<a target="_blank" href="https://linkedin.com/in/abhinavrajesh">LinkedIn</a> <br /></p>
<h3 id="feedback">Feedback 🎸</h3>
<p>Feedback helps to improve my articles. I'd love to hear feedback and thoughts on the article. Looking forward to your views. </p>
]]></content:encoded></item><item><title><![CDATA[Part 4: How to Build a NextJS App using Typescript and TailwindCSS: The Complete Guide]]></title><description><![CDATA[Hello Everyone 👋
I'm Abhinav Rajesh and I'm back with the 4th Part of the series "How to Build a NextJS App using Typescript and TailwindCSS: The Complete Guide" where we would be learning about ESLint and Head & Script Tag of NextJS, and Deploying ...]]></description><link>https://blog.abhinavrajesh.com/head-script-eslint-deploying-nextjs</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/head-script-eslint-deploying-nextjs</guid><category><![CDATA[Next.js]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[React]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Fri, 10 Sep 2021 16:33:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1626359934316/i5tZ77KSQ.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Hello Everyone</strong> 👋
I'm Abhinav Rajesh and I'm back with the 4th Part of the series "How to Build a NextJS App using Typescript and TailwindCSS: The Complete Guide" where we would be learning about ESLint and Head &amp; Script Tag of NextJS, and Deploying the NextJS Applcation to Vercel. </p>
<p>I'm really sorry for the gap between the articles, got busy with hackathons(Adding link to articles on my <a target="_blank" href="https://blog.abhinavrajesh.xyz/series/hackathon">hackathon projects</a> In case you wanna check it out) and stuff in life.</p>
<h3 id="previous-parts-of-series">Previous Parts of Series</h3>
<ol>
<li><a target="_blank" href="https://blog.abhinavrajesh.xyz/setting-up-nextjs-with-typescript-and-tailwindcss">Part 1: Setting up NextJS with Typescript and TailwindCSS</a> </li>
<li><a target="_blank" href="https://blog.abhinavrajesh.xyz/fetching-from-api-in-nextjs-using-getstaticprops-typescript">Part 2: Fetching and displaying data from API in NextJS using getStaticProps, TailwindCSS @apply directive and Typescript Interface.</a> </li>
<li><a target="_blank" href="https://blog.abhinavrajesh.xyz/dynamic-routing-and-api-endpoints-in-nextjs">Part 3: Dynamic routing and API endpoints in NextJS</a></li>
</ol>
<p>In the last article, we discussed about Dynamic routing and API endpoints in NextJS. In case you missed the <a target="_blank" href="https://blog.abhinavrajesh.xyz/dynamic-routing-and-api-endpoints-in-nextjs">article</a> I would recommend checking them out first.</p>
<p>In this article we would be going through the following</p>
<ul>
<li><a href="#head">Adding meta tags with the help of <code>Head</code> provided by NextJS to optimize SEO of the pages.</a></li>
<li><a href="#script"><code>Script</code> by NextJS</a></li>
<li><a href="#eslint-in-nextjs">ESLint</a></li>
<li><a href="#deploying-the-application">Deploying NextJS Application</a></li>
</ul>
<h3 id="head">Head</h3>
<p><code>Head</code> is a built-in component for appending elements to the <code>head</code> of the page. We can add stylesheets, JS Scripts, meta tags, custom title, etc.</p>
<p><code>Head</code> is really useful for SEO optimization and to rank the website higher in google indexing.</p>
<p>In our example we would be adding multiple meta tags to improve the SEO of our project.</p>
<p>If you got to the chrome devtools and run the lighthouse tests for SEO, you would see something similar as below</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631085686788/stdmUqMru.png" alt="image.png" />
</center>

<h4 id="now-you-may-ask-whats-the-use-of-title-and-description">Now you may ask what's the use of title and description?</h4>
<p>Title is really important for a page to be indexed at the top of the result. <a target="_blank" href="https://web.dev/document-title/">Learn More</a></p>
<blockquote>
<p>The title gives screen reader users an overview of the page, and search engine users rely on it heavily to determine if a page is relevant to their search.</p>
</blockquote>
<p>Description is as important as Title is.  <a target="_blank" href="https://web.dev/meta-description">Learn More</a> </p>
<blockquote>
<p>Meta descriptions may be included in search results to concisely summarize page content</p>
</blockquote>
<p>As this tutorial is just to make you understand what <code>Head</code> tag by NextJS does, I'm not diving deep into the SEO part. Would release an article on ranking higher in Google search index in coming future!</p>
<p>So, we would add title and description for out articles. To do that go to <code>/pages/article/[id].tsx</code> and change the <code>Article</code>function to the following snippet</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> Article = <span class="hljs-function">(<span class="hljs-params">{
  article,
}: InferGetStaticPropsType&lt;<span class="hljs-keyword">typeof</span> getStaticProps&gt;</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"max-w-5xl mx-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>{article.title}<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">{</span>`${<span class="hljs-attr">article.body.slice</span>(<span class="hljs-attr">0</span>, <span class="hljs-attr">140</span>)}<span class="hljs-attr">...</span>`} /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Head</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col items-start justify-center mt-40"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold text-4xl capitalize mb-4"</span>&gt;</span>{article.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>{article.body}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"py-2 px-4 bg-blue-600 hover:bg-blue-500 text-white rounded mt-4"</span>&gt;</span>
            Go Back
          <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};
</code></pre>
<p>Here we have added <code>Head</code> tag inside the Article function and have added <code>title</code> and <code>meta description</code> tags. If you go to your browser and check the tab, you should see something similar</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631086833842/oKw1TDSmu.png" alt="image.png" />
</center>

<p>The title of the article acts as the title of the webpage! And if you inspect the page and check the <code>head</code> tag, you can see <code>meta description</code> tag too! </p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631086915859/coMroyZ1Nl.png" alt="image.png" />
</center>

<p>So from this example, we could understand that, whatever you input inside the <code>Head</code> component of NextJS, it gets injected to <code>head</code> tag of the page!</p>
<h4 id="what-if-there-are-multiple-head-tags">What if there are multiple <code>Head</code> tags?</h4>
<p>NextJS handles multiple <code>Head</code> tags by itself. Just to be sure there are no duplicates we can add <code>key</code> prop in the <code>meta</code> tag. By default meta tags with duplicate names would automatically be handled by NextJS.</p>
<p>Similarly, we could add meta tags for our home and about page. This I would give as a practice for you to do, do try it out so you understand what it really does and let me know in the comments!</p>
<blockquote>
<p>P.S. Also, create the about page for this application as a practice</p>
</blockquote>
<h3 id="script">Script</h3>
<p>Previously to add script tags to your project, we would have to define <code>script</code> tag inside <code>Head</code> of NextJS in you page. </p>
<p>But since NextJS v11, NextJS comes with a <code>Script</code> component. The <code>Script</code> component enables developers to set the loading priority of third-party scripts to save developer time and improve loading performance.</p>
<p>There are 3 loading priorities for the scripts:</p>
<ul>
<li><code>beforeInteractive</code>: These are used critical scripts that need to be fetched and executed before the page is interactive, such as bot detection and consent management. These scripts are injected into the initial HTML from the server and run before self-bundled JavaScript is executed.</li>
</ul>
<ul>
<li><p><code>afterInteractive</code>: This mode is set as default if you do not specify strategy. These are the scripts that can fetch and execute after the page is interactive, such as tag managers and analytics. These scripts are injected on the client-side and will run after hydration.</p>
</li>
<li><p><code>lazyOnload</code>: These are for scripts that can wait to load during idle time, such as chat support and social media widgets. (Chat widgets such as <a target="_blank" href="https://chatbotish.vercel.app">Chatbotish</a>)</p>
</li>
</ul>
<p>However, we won't be using <code>Script</code> component by NextJS for this application because we do not have any external scripts to load. But, here is a small example taken from the NextJS Documentation</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> Script <span class="hljs-keyword">from</span> <span class="hljs-string">'next/script'</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Script</span> <span class="hljs-attr">strategy</span>=<span class="hljs-string">"afterInteractive"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://www.google-analytics.com/analytics.js"</span> /&gt;</span><span class="xml">
    <span class="hljs-tag">&lt;/&gt;</span></span></span>
  )
}
</code></pre>
<p>Also an important point to note</p>
<blockquote>
<p><code>next/script</code> must not be placed in either a <code>next/head</code> component or in pages/_document.js.</p>
</blockquote>
<p><strong>And this brings us to the last section of this series</strong></p>
<h3 id="eslint-in-nextjs">ESLint in NextJS</h3>
<p>It is a tool that analyzes source code to flag programming errors, bugs, stylistic errors, and suspicious constructs.</p>
<p>Since version 11.0.0, Next.js provides an integrated ESLint experience out of the box.</p>
<p>You just have to run <code>yarn lint</code>. It would throw any warning or errors present and fixing them accordingly is best practice. In this application if you run the command, there should not be any warning or errors as we are following best practices :)</p>
<h3 id="deploying-the-application">Deploying the Application!</h3>
<p>Vercel and Netlify are the best platform to deploy any react application.</p>
<p>For this tutorial I chose <a target="_blank" href="https://vercel.com">Vercel</a> because the easiest way to deploy Next.js to production is to use the Vercel platform from the <strong>creators of Next.js!</strong> Also it automatically deploys from Github repository whenever a new commit is made.</p>
<p>Before this add your code to <a target="_blank" href="https://github.com">Github</a> and create a repository and add the code to it.</p>
<p>Then <strong>Head over to <a target="_blank" href="https://vercel.com">https://vercel.com</a></strong> and create an account if you don't have an account already.</p>
<p>Once you are in the <a target="_blank" href="https://vercel.com/dashboard">dashboard</a>, click on <a target="_blank" href="https://vercel.com/new">New Project</a>. Connect your Github Account with vercel.</p>
<p>Choose the repository where your code is. In my case it's <code>nextjs-blog</code>. Click on <code>import</code></p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631286179105/8fUN3FSh1.png" alt="Nextjs-blog.png" />
</center>

<p>On the next screen, click on <strong>Skip</strong> for when it asks for <code>Creating a Team</code></p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631286286188/kcn87XoPU.png" alt="image.png" />
</center>

<p>Click on deploy and your application would be deployed! 🎉</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631286371393/_VuSU1T9w.png" alt="image.png" />
</center>

<p>Uh Oh! If you check the build, it probably would have failed. It's because, we are trying to statically generate a the page using the data from the endpoint which is currently not deployed. Hence, the error. To fix this, we have to change all the statically generated pages (Home and Article Page) to be Server side rendered (Change all the types of getStaticProps and getStaticProps to types of getServerSideProps to getServerSideProps respectively). </p>
<p>I would recommend you to do this by yourself to understand how these works.</p>
<p>Once you have tried on your own, cross-check with the code snippets below. The <code>/pages/articel/[id].tsx</code> should look something like below snippet</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// pages/articles/[id].tsx</span>

<span class="hljs-keyword">import</span> { GetServerSideProps, InferGetServerSidePropsType } <span class="hljs-keyword">from</span> <span class="hljs-string">"next"</span>;
<span class="hljs-keyword">import</span> Link <span class="hljs-keyword">from</span> <span class="hljs-string">"next/link"</span>;
<span class="hljs-keyword">import</span> Head <span class="hljs-keyword">from</span> <span class="hljs-string">"next/head"</span>;

<span class="hljs-keyword">import</span> { API_URL } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../constants"</span>;
<span class="hljs-keyword">import</span> { Articles } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../types"</span>;

<span class="hljs-keyword">import</span> Navbar <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/Navbar"</span>;

<span class="hljs-keyword">const</span> Article = <span class="hljs-function">(<span class="hljs-params">{
  article,
}: InferGetServerSidePropsType&lt;<span class="hljs-keyword">typeof</span> getServerSideProps&gt;</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"max-w-5xl mx-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>{article.title}<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">{</span>`${<span class="hljs-attr">article.body.slice</span>(<span class="hljs-attr">0</span>, <span class="hljs-attr">140</span>)}<span class="hljs-attr">...</span>`} /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Head</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col items-start justify-center mt-40"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold text-4xl capitalize mb-4"</span>&gt;</span>{article.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>{article.body}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"py-2 px-4 bg-blue-600 hover:bg-blue-500 text-white rounded mt-4"</span>&gt;</span>
            Go Back
          <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getServerSideProps: GetServerSideProps = <span class="hljs-keyword">async</span> (context) =&gt; {
  <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`<span class="hljs-subst">${API_URL}</span>/articles/<span class="hljs-subst">${context.params!.id}</span>`</span>);
  <span class="hljs-keyword">const</span> article: Articles = <span class="hljs-keyword">await</span> res.json();

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      <span class="hljs-attr">article</span>: article,
    },
  };
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Article;
</code></pre>
<p>And edit the <code>index.tsx</code> as follows</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { InferGetServerSidePropsType } <span class="hljs-keyword">from</span> <span class="hljs-string">"next"</span>;
<span class="hljs-keyword">import</span> { Articles } <span class="hljs-keyword">from</span> <span class="hljs-string">"../types"</span>;

<span class="hljs-keyword">import</span> Navbar <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Navbar"</span>;
<span class="hljs-keyword">import</span> Article <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Article"</span>;
<span class="hljs-keyword">import</span> { API_URL } <span class="hljs-keyword">from</span> <span class="hljs-string">"../constants"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params">{
  articles,
}: InferGetServerSidePropsType&lt;typeof getServerSideProps&gt;</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"max-w-5xl mx-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"grid grid-cols-1 md:grid-cols-2 space-x-5 space-y-5"</span>&gt;</span>
        {articles?.map((article) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">Article</span>
            <span class="hljs-attr">body</span>=<span class="hljs-string">{article.body}</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">{article.id}</span>
            <span class="hljs-attr">title</span>=<span class="hljs-string">{article.title}</span>
            <span class="hljs-attr">userId</span>=<span class="hljs-string">{article.userId}</span>
            <span class="hljs-attr">key</span>=<span class="hljs-string">{article.id}</span>
          /&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getServerSideProps = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> articles: Articles[] = <span class="hljs-keyword">await</span> (
    <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`<span class="hljs-subst">${API_URL}</span>/articles`</span>)
  ).json();

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      articles,
    },
  };
};
</code></pre>
<p>Now, if you visit the deployed page you would most probably see a blank page. Now why is that? Remember we setup <code>API_URL</code> in the previous article? We need to to add the domain in the <code>constants.ts</code> file.</p>
<p>To get the url for the deployed version, go to the project and copy the one present here</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631287312450/UY3ai18BU.png" alt="nextjs-blog-2.png" />
</center>

<pre><code><span class="hljs-keyword">const</span> __prod__ = process.env.NODE_ENV === <span class="hljs-string">"production"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> API_URL = __prod__ ? <span class="hljs-string">"https://REPLACE_WITH_THE_DOMAIN_IN_DASHBOARD"</span> : <span class="hljs-string">"http://localhost:3004/api"</span>;
</code></pre><p>Then, push the changes to github and you are good to go! </p>
<p>Similarly, you may also deploy to  <a target="_blank" href="https://www.netlify.com/">Netlify</a> , it's also an amazing hosting provider.</p>
<p>As always, linking the <a target="_blank" href="https://github.com/AbhinavRajesh/nextjs-blog/tree/part-4">Github Repository</a>.</p>
<h3 id="wrapping-up-the-series">Wrapping up the series</h3>
<p>This was the final article of this series and I had lot of fun creating this. And I apologize for the delay of this article but I'm pretty sure you guys would have a fair amount of idea on NextJS, TailwindCSS and TypeScript. In case you feel any difficulty, feel free to contact me through comments or from my social accounts which I'm linking at the end of this article.</p>
<blockquote>
<p><a target="_blank" href="https://github.com/AbhinavRajesh/nextjs-blog">Github Repository</a></p>
</blockquote>
<h3 id="support">Support 🙌</h3>
<p>If you're enjoying my articles, consider supporting me with a coffee ☕️ or upvoting the articles. It really motivates me to keep going.</p>
<p><a href="https://www.buymeacoffee.com/abhinavrajesh" target="_blank"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&amp;emoji=&amp;slug=abhinavrajesh&amp;button_colour=FFDD00&amp;font_colour=000000&amp;font_family=Cookie&amp;outline_colour=000000&amp;coffee_colour=ffffff" alt="Buy Me A Coffee" /></a></p>
<h3 id="lets-connect">Lets connect 🌎</h3>
<p><a target="_blank" href="https://github.com/AbhinavRajesh">Github</a> <br />
<a target="_blank" href="https://twitter.com/_AbhinavRajesh_">Twitter</a> <br />
<a target="_blank" href="https://linkedin.com/in/abhinavrajesh">LinkedIn</a> <br /></p>
<h3 id="feedback">Feedback 🎸</h3>
<p>Feedback helps to improve my articles. I'd love to hear feedback and thoughts on the article. Looking forward to your views. </p>
]]></content:encoded></item><item><title><![CDATA[Increase user engagement with Chatbotish.]]></title><description><![CDATA[Hello Everyone 👋
I'm Abhinav Rajesh and today I'm here to introduce you all to my project for #Auth0Hackathon. 
Introducing Chatbotish: Adding Feedback, FAQ, Bug report, Feature request to your website made easy.
Chatbotish is an easy to use widget ...]]></description><link>https://blog.abhinavrajesh.com/introducing-chatbotish</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/introducing-chatbotish</guid><category><![CDATA[Auth0]]></category><category><![CDATA[Auth0Hackathon]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Tailwind CSS]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Mon, 30 Aug 2021 06:18:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630235147880/JFY3SoDMZ.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="hello-everyone">Hello Everyone 👋</h3>
<p>I'm Abhinav Rajesh and today I'm here to introduce you all to my project for <a target="_blank" href="https://townhall.hashnode.com/auth0-hackathon">#Auth0Hackathon</a>. </p>
<h1 id="introducing-chatbotish-adding-feedback-faq-bug-report-feature-request-to-your-website-made-easy">Introducing Chatbotish: Adding Feedback, FAQ, Bug report, Feature request to your website made easy.</h1>
<p><a target="_blank" href="https://chatbotish.vercel.app">Chatbotish</a> is an easy to use widget to add to your amazing web apps to increase user engagement. With Chatbotish, you can place a widget to your website and make your customers engage with your website, more than just normal browsing.</p>
<h2 id="coming-up-with-the-idea">Coming up with the idea 🤔</h2>
<p>To be honest, it took me a lot of time to come up with this idea (I was even considering not to submit the project for this hackathon 😶), I only started creating the app 2 weeks ago!</p>
<p>Anyways, so about 2 weeks back, I was at my home, testing out different open-source projects, when I noticed a minor bug for an application. So, I decided to report the bug by creating an issue in Github. No big deal right? Then something struck my brain. There are many users who do not know/use Github and are not well versed in technology. So reporting bugs and requesting features for an application was not possible unless they contact the maker directly. </p>
<p>So I decided to create a widget which can be added to a website by just adding 2 lines of code which can serve as a Feedback Form, Bug Report Form, Feature Request Form, FAQ Section and Contact Section, where all the responses from the forms would be available to the maker at dashboard!</p>
<h2 id="tldr">TL;DR</h2>
<p><strong>Here is a small demo(~4 mins) of chatbotish explaining in detail on how to setup and add Chatbotish to your website!</strong></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/dzA-VtUvubE">https://youtu.be/dzA-VtUvubE</a></div>
<p> </p>
<h2 id="features">Features ✨️</h2>
<h3 id="add-anonymous-feedback-form-to-your-website-in-seconds">Add Anonymous feedback form to your website in seconds!</h3>
<p>The biggest advantage of anonymous feedback is that responses tend to be more honest; when someone has to identify themselves, they may have a tendency to hold back for fear of damaging a relationship or making themselves look bad.</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630223233228/ZuoorMYcH.png" alt="image.png" />
</center>

<h3 id="bug-reports">Bug Reports</h3>
<p>Often when a user encounters a bug in your application they may not know how to create an issue on github. With the help of Chatbotish you can add a simple form for reporting bugs!</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630223339898/jox6E7x64.png" alt="image.png" />
</center>

<h3 id="listen-to-your-customers-need">Listen to your customers need</h3>
<p>Quite often there would be times when users wished a particular feature was present in the application but have no idea where they should ask for it. With the help of Chatbotish you can add a simple form for accepting feature requests!</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630223388256/2YSoANy_X.png" alt="image.png" />
</center>

<h3 id="contact">Contact</h3>
<p>For simple one page application, for users to contact you, you would have to create a separate contact page. With the help of Chatbotish you can add a simple page in the widget for displaying contact details!</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630223435648/K1WOd1YHr.png" alt="image.png" />
</center>

<h2 id="faq-section">FAQ Section</h2>
<p>Tired of giving the same answer to users asking same question over-and-over again? Add an FAQ section in minutes for your website with the help of Chatbotish!</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630229589227/wND2wkKM6.png" alt="image.png" />
</center>

<h2 id="dashboard">Dashboard</h2>
<p>Manage different projects, view installation steps for different web apps and view responses for different forms in the dashboard</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630223464172/MC2bGtNnq.png" alt="image.png" />
</center>

<h3 id="its-a-progressive-web-app">It's a Progressive Web App 🎉</h3>
<p>It's a PWA, it means that you can install the web app into you phone/tab/desktop and use it to view reported bugs, feature requests and much more!</p>
<center>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630223578089/ljKHinD2K.png" alt="image.png" />
</center>

<h2 id="why-and-what-technology-did-i-use-to-make-this-app">Why and what technology did I use to make this app?💻</h2>
<ul>
<li><p><a target="_blank" href="https://nextjs.org/">NextJS</a> </p>
<ul>
<li>The React Framework for Production</li>
<li>Next.js gives you the best developer experience with all the features you need for production: hybrid static &amp; server rendering, TypeScript support, smart bundling, route pre-fetching, and more. No config needed.</li>
</ul>
</li>
<li><p><a target="_blank" href="https://www.typescriptlang.org/">TypeScript</a> </p>
<ul>
<li>Why did I chose typescript? It ships less bug to production and most of the minor mistakes such as getting types of variable/function parameter wrong in developments get caught easily.</li>
</ul>
</li>
<li><p><a target="_blank" href="https://tailwindcss.com/docs">TailwindCSS</a>  </p>
<ul>
<li>Easy to use utility-first css framework. </li>
<li>I'm really thankful that tailwindCSS exist, because of which I was able to create the UI Fast! </li>
<li>It feels like I have more control over the styling of a component as in case of Bootstrap or other similar framework it's different with pre-built component with less to no modification possible.</li>
</ul>
</li>
<li><p><a target="_blank" href="https://firebase.google.com/docs/firestore">Firestore</a> </p>
<ul>
<li>Flexible, scalable NoSQL cloud database to store and sync data for client- and server-side development.</li>
<li>For storing the chatbot details and the user' email(Used as unique identifier)</li>
</ul>
</li>
<li><p><a target="_blank" href="https://auth0.com/">Auth0</a> </p>
<ul>
<li>Used for authenticating user using traditional email-password authentication or Google OAuth. All user related details such as Email, First Name, Last Name, etc. are stored here</li>
<li>I was worried thinking that I wouldn't get much time to integrate Auth0 with my NextJS application, but then this <a target="_blank" href="https://youtu.be/egnVe9lXY0E">video</a> by <a class="user-mention" href="https://hashnode.com/@jamesqquick">James Q Quick</a> and Auth0 was a relief for me when I found out there was a NextJS SDK for Auth0 which would take care of almost all parts of Authentication related stuff.</li>
</ul>
</li>
<li><p><a target="_blank" href="https://react.geist-ui.dev/">Geist-UI</a></p>
<ul>
<li>An open source design system for building modern websites and applications.</li>
<li>Geist UI is an elegant and beautiful React component library with Geek style, originating from Vercel design system. And I love how Vercel' website design, simple and modern!</li>
</ul>
</li>
<li><p><a target="_blank" href="https://vercel.com/">Vercel</a></p>
<ul>
<li>Vercel and <a target="_blank" href="https://www.netlify.com/">Netlify</a> are the best platform to deploy your react application. </li>
<li>I chose Vercel because the easiest way to deploy Next.js to production is to use the Vercel platform from the creators of Next.js! Also it automatically deploys from Github repository whenever a new commit is made.</li>
</ul>
</li>
</ul>
<h2 id="quality-of-code">Quality of Code</h2>
<p>Same as last hackathon, this hackathon too I have used the same for ensuring the quality of code.</p>
<ul>
<li><a target="_blank" href="https://prettier.io/">Prettier VS Code Extension</a> <ul>
<li>An opinionated code formatter</li>
<li>Supports many language</li>
<li>Used for formatting the code so that other contributors can read the code easily</li>
</ul>
</li>
<li>TypeScript<ul>
<li>For type checking for different functions and components to ship the app with as minimum bugs as possible</li>
</ul>
</li>
<li><a target="_blank" href="https://nextjs.org/docs/basic-features/eslint">ESLint</a> <ul>
<li>It is a tool that analyzes source code to flag programming errors, bugs, stylistic errors, and suspicious constructs.</li>
<li>Since version 11.0.0, Next.js provides an integrated ESLint experience out of the box.</li>
</ul>
</li>
</ul>
<p><a target="_blank" href="https://github.com/AbhinavRajesh/Chatbotish">Github Repo</a>  / <a target="_blank" href="https://chatbotish.vercel.app">Live URL</a></p>
<p><strong><em>Leaving a ⭐ would make my day :D</em></strong></p>
<h2 id="whats-in-the-pipeline">What's in the pipeline?</h2>
<ul>
<li><strong>Hashnode Integration as a widget</strong>: As a blogger, I would love to know what people think about my blog and also what do they expect of my blog. Although there is comment section available for each blog post, people won't give their honest opinion due to reasons mentioned before. Adding a widget would do the job well!</li>
<li><strong>Dark mode</strong>: Developers love dark mode and I would be trying to implement it as soon as possible.</li>
<li><strong>Option to add custom tabs</strong> with customizable content.</li>
<li><strong>Push notification/email reminders</strong> for when a certain number of bug reports are made.</li>
<li><strong>Option to add a chat window.</strong></li>
<li><strong>Remove Firestore</strong> and use a free alternative.</li>
<li>And much more! If you have any feature in mind which might make this app better then feel free to  <a target="_blank" href="https://github.com/abhinavrajesh/chatbotish/issues/new/choose">drop an issue at my GitHub repository</a>  or through Chatbotish from <a target="_blank" href="https://chatbotish.vercel.app">Chatbotish 😉</a> and I would be more than happy to go through them!</li>
</ul>
<h2 id="what-did-i-learn-from-this-hackathon">What did I learn from this hackathon?</h2>
<p>As compared to last hackathon I didn't get much to learn, probably because of time constraints but I did manage to learn something new and also increase my knowledge.</p>
<ul>
<li>I was able to increase my knowledge on Firestore, Figma and NextJS.</li>
<li>I haven't used GeistUI before, I saw it on some projects before and I really wanted to test it out, and finally got a chance to use it for my project. (Would recommend 10/10)</li>
<li>Most importantly learnt how to create a widget, I took most of the time researching on how to create one.</li>
<li>And finally got to learn about <strong>Auth0</strong>, didn't expect it to be this easy to integrate with projects. I did have some hiccups in between but Auth0 docs / Youtube tutorials  helped me a lot.</li>
</ul>
<h2 id="contributing-to-chatbotish">Contributing to Chatbotish</h2>
<p>This is an open source project so you're always welcome to contribute ideas, report issues or send in pull requests!</p>
<p><a target="_blank" href="https://github.com/AbhinavRajesh/Chatbotish">GitHub Repository</a> </p>
<h2 id="credits">Credits 💰</h2>
<ul>
<li>Learnt to create widget from this amazing blog post by <a target="_blank" href="https://javascriptpros.com/creating-react-widgets-embedded-anywhere/">Creating React “Widgets” that can be embedded on any website, by anyone - Gio Logist</a> </li>
<li><a target="_blank" href="https://youtu.be/egnVe9lXY0E">Auth0 and Next.js SDK - Add Authentication in Minutes! by Auth0</a></li>
<li>As always I would like to thank <a target="_blank" href="https://stackoverflow.com/">Stackoverflow</a>, without which the project may not even exist!</li>
</ul>
<h2 id="support">Support</h2>
<p>If you're enjoying my app, maybe consider supporting me with a coffee ☕️ or reacting to the article or Leaving a ⭐ to the <a target="_blank" href="https://github.com/AbhinavRajesh/Chatbotish">repo</a> would make my day and motivate me to keep going :D</p>
<p><a href="https://www.buymeacoffee.com/abhinavrajesh" target="_blank"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&amp;emoji=&amp;slug=abhinavrajesh&amp;button_colour=FFDD00&amp;font_colour=000000&amp;font_family=Cookie&amp;outline_colour=000000&amp;coffee_colour=ffffff" alt="Buy Me A Coffee" /></a></p>
<h2 id="lets-connect">Lets connect</h2>
<p>Github: <a target="_blank" href="https://github.com/AbhinavRajesh">AbhinavRajesh</a> <br />
Twitter: <a target="_blank" href="https://twitter.com/_AbhinavRajesh_">_AbhinavRajesh_</a> <br />
LinkedIn: <a target="_blank" href="https://linkedin.com/in/abhinavrajesh">abhinavrajesh</a> <br /></p>
<h3 id="feedback">Feedback</h3>
<p>Thank you for reading this article. I'd love to hear feedback and thoughts on <a target="_blank" href="https://chatbotish.vercel.app">Chatbotish</a>. Looking forward to your views. </p>
]]></content:encoded></item><item><title><![CDATA[Introducing Aura: See your mood in a whole new light.]]></title><description><![CDATA[Hello Everyone 👋
I'm Abhinav Rajesh and today I'm here to introduce you all to my project for #ClerkHackathon. 
Introducing Aura: See your mood in a whole new light.
We know our mood changes throughout the days. But what if you could see it?
Introdu...]]></description><link>https://blog.abhinavrajesh.com/introducing-aura-see-your-mood-in-a-whole-new-light</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/introducing-aura-see-your-mood-in-a-whole-new-light</guid><category><![CDATA[The Clerk Hackathon on Hashnode]]></category><category><![CDATA[Clerk.dev]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[Tailwind CSS]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Tue, 27 Jul 2021 07:58:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1626506742675/N1YhW3GIy.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="hello-everyone">Hello Everyone 👋</h3>
<p>I'm Abhinav Rajesh and today I'm here to introduce you all to my project for <a target="_blank" href="https://townhall.hashnode.com/a-new-hackathon-the-clerk-and-hashnode-hackathon">#ClerkHackathon</a>. </p>
<h1 id="introducing-aura-see-your-mood-in-a-whole-new-light">Introducing Aura: See your mood in a whole new light.</h1>
<p>We know our mood changes throughout the days. <strong><em>But what if you could see it?</em></strong></p>
<p>Introducing <a target="_blank" href="https://aura-ar.vercel.app">Aura</a>, an easy to use mood tracking app that takes your daily life's mood into account. It allows you to understand yourself better and helps you maintain an even mood throughout the day. The app has various features such as <strong>graphs, statistics, insights, and ambience sounds to improve your mood.</strong></p>
<h2 id="coming-up-with-the-idea">Coming up with the idea 🤔</h2>
<p>So, I was reading through an article a while back on <a target="_blank" href="https://www.frontiersin.org/research-topics/14627/impact-of-the-coronavirus-pandemic-covid-19-on-mood-disorders-and-suicide">Impact of the Coronavirus Pandemic (COVID-19) on Mood Disorders and Suicide</a> and there was this paragraph which intrigued me</p>
<blockquote>
<p><strong>Mood disorders are rising exponentially</strong> due to fatalities, economic turndown and isolation. Little attention is also given to health workers and practitioners, who are severely affected and overwhelmed by this emergency. Considering the global number of deaths - about 380,000 - the entire world is affected by these processes in different and faceted ways. Confinement, future instability, and fear not only exacerbated pre-existing issues, such as domestic violence, social phobias and depressive symptoms, but also trigger new psychopathological problems, sometimes escalating even in <strong>suicide</strong>.</p>
</blockquote>
<p>I thought of creating an app where user can add in their mood for the day with notes on why their mood was good/bad which helps the user to monitor their mood over a period of time on a dashboard to check if their mood is improving or deteriorating as the day passes. They could show their profile to their therapist and get to work with them why their mood was bad and help improve their mental health! 
But then I got too lazy 😪 to create the app and finally thanks to <a class="user-mention" href="https://hashnode.com/@clerk">Clerk.dev</a> and <a class="user-mention" href="https://hashnode.com/@hashnode">Hashnode</a> for organizing the hackathon so that I could finally create this! 🎉</p>
<h2 id="features">Features ✨️</h2>
<h3 id="add-your-mood-to-calendar">Add your mood to calendar</h3>
<p><strong>It's super easy to add your mood to the calendar with just few clicks!</strong>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626708228691/DXmv86NKU.gif" alt="Aura add mood to calendar.gif" /></p>
<h3 id="mood-history">Mood History</h3>
<p><strong>View your mood history displayed similar to Github contributions or as in a monthly calendar view!</strong>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626800828141/_8wycTvBE.png" alt="MoodHistory.png" /></p>
<h3 id="analyse-your-mood">Analyse your mood</h3>
<p><strong>View and Analyse your mood in the form of beautiful graphs!</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626800962445/agd_qvEvCT.png" alt="MoodGraph.png" /></p>
<h3 id="enhance-your-mood-with-aura">Enhance your mood with Aura</h3>
<p><strong>Listen to 20+ ambient noise to enlighten your mood and get relief from stress and anxiety</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1626802278231/y_cf0z505.png" alt="Aura.png" /></p>
<h3 id="its-a-progressive-web-app">It's a Progressive Web App 🎉</h3>
<p>It's a PWA, it means that you can <strong>install the web app into you phone/tab/desktop</strong> and use it as a native app!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1627143503743/R2g4f2Bsr.png" alt="PWA.png" /></p>
<h2 id="why-and-what-technology-did-i-use-to-make-this-app">Why and what technology did I use to make this app?💻</h2>
<ul>
<li><a target="_blank" href="https://reactjs.org/">React </a> <ul>
<li>A JavaScript library for building user interfaces</li>
<li>I like how easy it is to setup and get started with a React project using  <a target="_blank" href="https://create-react-app.dev/">CRA</a>. </li>
</ul>
</li>
<li><a target="_blank" href="https://www.typescriptlang.org/">TypeScript</a> <ul>
<li>Why did I chose typescript? It ships less bug to production and most of the minor mistakes such as getting types of variable/function parameter wrong in developments get caught easily. </li>
<li>In love with this since I started using typescript</li>
</ul>
</li>
<li><a target="_blank" href="https://tailwindcss.com/docs">TailwindCSS</a>  <ul>
<li>Easy to use utility-first css framework. Helping me to ship the product x10 faster :D</li>
<li>It feels like I have more control over the styling of a component as in case of Bootstrap or other similar framework it's different with pre-built component with less to no modification possible.</li>
</ul>
</li>
<li><a target="_blank" href="https://firebase.google.com/docs/firestore">Firestore</a> <ul>
<li>Flexible, scalable NoSQL cloud database to store and sync data for client- and server-side development.</li>
<li>For storing the mood of the user and the email(Used as unique identifier)</li>
</ul>
</li>
<li><a target="_blank" href="https://clerk.dev/">Clerk</a> <ul>
<li>Used for authenticating user using traditional email-password authentication or Google OAuth. All user related details such as Email, First Name, Last Name, etc. are stored here</li>
<li>I'm amused as how easy it is to integrate with react app. Usually I use firebase for authentication, so for private route I would have to create separate components to check if the user is authenticated or not and redirect them accordingly, which took a lot of time in development. But with clerk these components were prebuilt! It was super easy to use clerk and I'm so glad that I found clerk.</li>
</ul>
</li>
<li><a target="_blank" href="https://www.chartjs.org/">ChartJS</a> <ul>
<li>Simple yet flexible JavaScript charting for designers &amp; developers</li>
<li>I needed something really good for displaying the beautiful graphs of users mood and ChartJS was perfect! The <a target="_blank" href="https://www.npmjs.com/package/react-chartjs-2">react-chartjs-2</a> package made the job really easy to integrate the graph with react application</li>
</ul>
</li>
<li><a target="_blank" href="https://howlerjs.com/">Howler</a> <ul>
<li>Audio library for the modern web.</li>
<li>For the aura section (Ambience Noise), I needed some package which would play sound in the browser. So I searched for a package to do this job and found Howler was the perfect fit for my use case. </li>
</ul>
</li>
<li><a target="_blank" href="https://vercel.com/">Vercel</a><ul>
<li>Vercel and <a target="_blank" href="https://www.netlify.com/">Netlify</a> are the best platform to deploy your react application. </li>
<li>I chose Vercel because it's really easy to deploy your application from your GitHub and also it automatically redeploys the app whenever there is a new commit in main branch!</li>
</ul>
</li>
</ul>
<h2 id="quality-of-code">Quality of Code</h2>
<ul>
<li><a target="_blank" href="https://prettier.io/">Prettier VS Code Extension</a> <ul>
<li>An opinionated code formatter</li>
<li>Supports many language</li>
<li>Used for formatting the code so that other contributors can read the code easily</li>
</ul>
</li>
<li>TypeScript<ul>
<li>For type checking for different functions and components to ship the app with as minimum bugs as possible</li>
</ul>
</li>
<li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint">ESLint VS Code Extension</a> <ul>
<li>It is a tool that analyzes source code to flag programming errors, bugs, stylistic errors, and suspicious constructs.</li>
</ul>
</li>
</ul>
<p><a target="_blank" href="https://github.com/AbhinavRajesh/Aura">Github Repo</a>  / <a target="_blank" href="https://aura-ar.vercel.app">Live URL</a></p>
<p><strong><em>Leaving a ⭐ would make my day :D</em></strong></p>
<h2 id="whats-in-the-pipeline">What's in the pipeline?</h2>
<ul>
<li><strong>Dark mode</strong>: Users love dark mode and I would be trying to implement it as soon as possible.</li>
<li><strong>Daily push notification/email reminders</strong> for users to remind them to enter their mood.</li>
<li>Suggest methods to improve users mood when they feel low.</li>
<li><strong>Weekly emails with reports and ways to improve their mood</strong> if their average mood score is low for the week.</li>
<li><strong>A tab to enter and store users best memories</strong> so they could relive that moment and be happy.</li>
<li>And much more! If you have any feature in mind which might make this app better then feel free to  <a target="_blank" href="https://github.com/abhinavrajesh/aura/issues/new/choose">drop an issue at my GitHub repository</a>  and I would be happy to go through them!</li>
</ul>
<h2 id="what-did-i-learn-from-this-hackathon">What did I learn from this hackathon?</h2>
<p>Believe it or not, I actually got to learn a lot of cool stuff from this hackathon</p>
<ul>
<li>I learnt to use ChartJS to display different line/bar graphs.</li>
<li>I learnt how to play audio from browser using the Howler package.</li>
<li>I have used Firestore before for my group projects but never really learnt it. I mostly use MongoDB as database for my personal projects and I really wanted to try Firestore this time so that I could learn how to use it and it was fairly easy to learn.</li>
<li>And finally this amazing tool, powering the  hackathon and authentication system of Aura,  Clerk.dev.  I'm amazed on how easy it is to use and setup authentication for react application and also the documentation for this is really good. Also it is very developer friendly would recommend you guys to give it a try. It's still in early stages and hopefully brings more amazing features in the future!</li>
</ul>
<h2 id="contributing-to-aura">Contributing to Aura</h2>
<p>This is an open source project so you're always welcome to contribute ideas, report issues or send in pull requests!</p>
<p><a target="_blank" href="https://github.com/AbhinavRajesh/Aura">GitHub Repository</a> </p>
<h2 id="credits">Credits 💰</h2>
<ul>
<li>Logo "Heavily inspired" from <a target="_blank" href="https://dribbble.com/shots/15679362-Aura-Brand-Guidelines">dribble</a> </li>
<li><a target="_blank" href="https://www.premiumbeat.com/blog/free-ambient-background-tracks/">Ambient Background Noise Tracks</a></li>
<li>And finally I would like to thank <a target="_blank" href="https://stackoverflow.com/">Stackoverflow</a>, without which the project wouldn't be as good as it is now(Or maybe non-existent!).</li>
</ul>
<h2 id="support">Support</h2>
<p>If you're enjoying my app, maybe consider supporting me with a coffee ☕️ or reacting to the article or Leaving a ⭐ to the <a target="_blank" href="https://github.com/AbhinavRajesh/Aura">repo</a> would make my day and motivate me to keep going :D</p>
<p><a href="https://www.buymeacoffee.com/abhinavrajesh" target="_blank"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&amp;emoji=&amp;slug=abhinavrajesh&amp;button_colour=FFDD00&amp;font_colour=000000&amp;font_family=Cookie&amp;outline_colour=000000&amp;coffee_colour=ffffff" alt="Buy Me A Coffee" /></a></p>
<h2 id="lets-connect">Lets connect</h2>
<p>Github: <a target="_blank" href="https://github.com/AbhinavRajesh">AbhinavRajesh</a> <br />
Twitter: <a target="_blank" href="https://twitter.com/_AbhinavRajesh_">_AbhinavRajesh_</a> <br />
LinkedIn: <a target="_blank" href="https://linkedin.com/in/abhinavrajesh">abhinavrajesh</a> <br /></p>
<h3 id="feedback">Feedback</h3>
<p>Thank you for reading this article. I'd love to hear feedback and thoughts on <a target="_blank" href="https://aura-ar.vercel.app">Aura</a>. Looking forward to your views. </p>
<div class="hn-embed-widget" id="chatbotish"></div>]]></content:encoded></item><item><title><![CDATA[Part 3: How to Build a NextJS App using Typescript and TailwindCSS: The Complete Guide]]></title><description><![CDATA[Hello Everyone 👋
I'm Abhinav Rajesh and this is 3rd Part of the series "How to Build a NextJS App using Typescript and TailwindCSS: The Complete Guide" where we would be learning about creating dynamic routes and how to setup API endpoints in NextJS...]]></description><link>https://blog.abhinavrajesh.com/dynamic-routing-and-api-endpoints-in-nextjs</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/dynamic-routing-and-api-endpoints-in-nextjs</guid><category><![CDATA[Next.js]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Sat, 10 Jul 2021 08:14:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1625898658486/DBuUs15KV.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Hello Everyone</strong> 👋
I'm Abhinav Rajesh and this is 3rd Part of the series "How to Build a NextJS App using Typescript and TailwindCSS: The Complete Guide" where we would be learning about creating dynamic routes and how to setup API endpoints in NextJS.</p>
<h3 id="previous-parts-of-series">Previous Parts of Series</h3>
<ol>
<li><a target="_blank" href="https://blog.abhinavrajesh.xyz/setting-up-nextjs-with-typescript-and-tailwindcss">Part 1: Setting up NextJS with Typescript and TailwindCSS</a> </li>
<li><a target="_blank" href="https://blog.abhinavrajesh.xyz/fetching-from-api-in-nextjs-using-getstaticprops-typescript">Part 2: Fetching and displaying data from API in NextJS using getStaticProps, TailwindCSS @apply directive and Typescript Interface.</a> </li>
</ol>
<p>In the last article, we discussed Routing in NextJS, interfaces in TypeScript and @apply directives of TailwindCSS. In case you missed the  <a target="_blank" href="https://blog.abhinavrajesh.xyz/fetching-from-api-in-nextjs-using-getstaticprops-typescript">article </a> I would recommend checking them out first.</p>
<p>In this article, we would be going through a bunch of stuff like</p>
<ul>
<li><a class="post-section-overview" href="#dynamic-routing">Dynamic Routing</a> <ul>
<li>Displaying article in a new dynamic page</li>
</ul>
</li>
<li><a class="post-section-overview" href="#api-in-nextjs">API in NextJS</a><ul>
<li>getStaticProps</li>
<li>getStaticPath</li>
</ul>
</li>
<li><a class="post-section-overview" href="#using-the-api-instead-of-the-fake-server">Using API instead of Fake Server</a></li>
</ul>
<h3 id="dynamic-routing">Dynamic Routing</h3>
<p>In the last article, we ended it when we displayed all the articles on the homepage.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625898775604/2_XtBNs9a.png" alt="image.png" /></p>
<p>Now we would be creating a page to display the article when clicked by the user. For that create a folder inside the <code>pages</code> folder and name it <code>article</code> and inside the article folder create a new file <code>[id].tsx</code>.</p>
<p>Your folder structure should look something like this</p>
<pre><code>pages/
┣ api/
┃ ┗ hello.ts
┣ article/
┃ ┗ [id].tsx
┣ <span class="hljs-keyword">index</span>.tsx
┗ _app.tsx
</code></pre><p>Now inside <code>article/[id].tsx</code> add the following code</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// pages/article/[id].tsx</span>
<span class="hljs-keyword">import</span> { GetServerSideProps, InferGetServerSidePropsType } <span class="hljs-keyword">from</span> <span class="hljs-string">"next"</span>;
<span class="hljs-keyword">import</span> Link <span class="hljs-keyword">from</span> <span class="hljs-string">"next/link"</span>;
<span class="hljs-keyword">import</span> Navbar <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/Navbar"</span>;
<span class="hljs-keyword">import</span> { Articles } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../types"</span>;

<span class="hljs-keyword">const</span> Article = <span class="hljs-function">(<span class="hljs-params">{
  article,
}: InferGetServerSidePropsType&lt;<span class="hljs-keyword">typeof</span> getServerSideProps&gt;</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"max-w-5xl mx-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col items-start justify-center mt-40"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold text-4xl capitalize mb-4"</span>&gt;</span>{article.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>{article.body}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"py-2 px-4 bg-blue-600 hover:bg-blue-500 text-white rounded mt-4"</span>&gt;</span>
            Go Back
          <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getServerSideProps: GetServerSideProps = <span class="hljs-keyword">async</span> (context) =&gt; {
  <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(
    <span class="hljs-string">`https://jsonplaceholder.typicode.com/posts/<span class="hljs-subst">${context.params!.id}</span>`</span>
  );
  <span class="hljs-keyword">const</span> article: Articles = <span class="hljs-keyword">await</span> res.json();

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      <span class="hljs-attr">article</span>: article,
    },
  };
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Article;
</code></pre>
<p>Here in the above code, we are fetching the data from a <a target="_blank" href="https://jsonplaceholder.typicode.com">fake server</a> according to the id of the post the user clicked on and displaying the result.</p>
<p>Now when we click on any article, it should show some page similar to this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625901415877/-pYVb2-C5.png" alt="image.png" /></p>
<p>But there is a small issue affecting the performance here. That is, each time we are sending a request to the article it fetches from the API and displays the result after server-side rendering. To make it more performant what we can do is to change the Server-side fetching to static fetching. So what basically happens is it creates the page in build time and returns the page when requested! [More on this on  <a target="_blank" href="https://blog.abhinavrajesh.xyz/fetching-from-api-in-nextjs-using-getstaticprops-typescript">Part 2 of this series</a>]
So change the code to following</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// pages/article/[id].tsx</span>
<span class="hljs-keyword">import</span> { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } <span class="hljs-keyword">from</span> <span class="hljs-string">"next"</span>;
<span class="hljs-keyword">import</span> Link <span class="hljs-keyword">from</span> <span class="hljs-string">"next/link"</span>;
<span class="hljs-keyword">import</span> Navbar <span class="hljs-keyword">from</span> <span class="hljs-string">"../../components/Navbar"</span>;
<span class="hljs-keyword">import</span> { Articles } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../types"</span>;

<span class="hljs-keyword">const</span> Article = <span class="hljs-function">(<span class="hljs-params">{
  article,
}: InferGetStaticPropsType&lt;<span class="hljs-keyword">typeof</span> getStaticProps&gt;</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"max-w-5xl mx-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex flex-col items-start justify-center mt-40"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-bold text-4xl capitalize mb-4"</span>&gt;</span>{article.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-xl"</span>&gt;</span>{article.body}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"py-2 px-4 bg-blue-600 hover:bg-blue-500 text-white rounded mt-4"</span>&gt;</span>
            Go Back
          <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getStaticProps: GetStaticProps = <span class="hljs-keyword">async</span> (context) =&gt; {
  <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(
    <span class="hljs-string">`https://jsonplaceholder.typicode.com/posts/<span class="hljs-subst">${context.params!.id}</span>`</span>
  );
  <span class="hljs-keyword">const</span> article: Articles = <span class="hljs-keyword">await</span> res.json();

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      <span class="hljs-attr">article</span>: article,
    },
  };
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getStaticPaths: GetStaticPaths = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`https://jsonplaceholder.typicode.com/posts`</span>);
  <span class="hljs-keyword">const</span> articles: Articles[] = <span class="hljs-keyword">await</span> res.json();

  <span class="hljs-keyword">const</span> ids = articles.map(<span class="hljs-function">(<span class="hljs-params">article</span>) =&gt;</span> article.id);

  <span class="hljs-keyword">const</span> paths = ids.map(<span class="hljs-function">(<span class="hljs-params">id</span>) =&gt;</span> ({
    <span class="hljs-attr">params</span>: {
      <span class="hljs-attr">id</span>: id.toString(),
    },
  }));
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">paths</span>: paths,
    <span class="hljs-attr">fallback</span>: <span class="hljs-literal">false</span>,
  };
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Article;
</code></pre>
<p>Here the <code>getStaticPaths</code> specifies all the dynamic routes to pre-render pages based on data. And <code>getStaticProps</code> fetches the data at build time.</p>
<h3 id="api-in-nextjs">API in NextJS</h3>
<p>Your NextJS app can be used as an API! If you visit the <code>http://localhost:3000/api/hello</code>, you would be seeing the following endpoint which returns a json object with <code>name</code> as key and <code>John Doe</code> as value</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625901579424/0W0_l8o8n.png" alt="api/hello endpoint" /></p>
<p>Let's create an endpoint to replace the fake server which we were using. In the root directory, create a file named <code>data.ts</code> and add the code from my  <a target="_blank" href="https://github.com/AbhinavRajesh/nextjs-blog/blob/part-3/data.ts">here</a> or copy the following code</p>
<pre><code class="lang-ts"><span class="hljs-comment">// data.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> data = [
  {
    userId: <span class="hljs-number">1</span>,
    id: <span class="hljs-number">1</span>,
    title:
      <span class="hljs-string">"sunt aut facere repellat provident occaecati excepturi optio reprehenderit"</span>,
    body: <span class="hljs-string">"quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"</span>,
  },
  {
    userId: <span class="hljs-number">1</span>,
    id: <span class="hljs-number">2</span>,
    title: <span class="hljs-string">"qui est esse"</span>,
    body: <span class="hljs-string">"est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"</span>,
  },
  {
    userId: <span class="hljs-number">1</span>,
    id: <span class="hljs-number">3</span>,
    title: <span class="hljs-string">"ea molestias quasi exercitationem repellat qui ipsa sit aut"</span>,
    body: <span class="hljs-string">"et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"</span>,
  },
  {
    userId: <span class="hljs-number">1</span>,
    id: <span class="hljs-number">4</span>,
    title: <span class="hljs-string">"eum et est occaecati"</span>,
    body: <span class="hljs-string">"ullam et saepe reiciendis voluptatem adipisci\nsit amet autem assumenda provident rerum culpa\nquis hic commodi nesciunt rem tenetur doloremque ipsam iure\nquis sunt voluptatem rerum illo velit"</span>,
  },
  {
    userId: <span class="hljs-number">1</span>,
    id: <span class="hljs-number">5</span>,
    title: <span class="hljs-string">"nesciunt quas odio"</span>,
    body: <span class="hljs-string">"repudiandae veniam quaerat sunt sed\nalias aut fugiat sit autem sed est\nvoluptatem omnis possimus esse voluptatibus quis\nest aut tenetur dolor neque"</span>,
  },
  {
    userId: <span class="hljs-number">1</span>,
    id: <span class="hljs-number">6</span>,
    title: <span class="hljs-string">"dolorem eum magni eos aperiam quia"</span>,
    body: <span class="hljs-string">"ut aspernatur corporis harum nihil quis provident sequi\nmollitia nobis aliquid molestiae\nperspiciatis et ea nemo ab reprehenderit accusantium quas\nvoluptate dolores velit et doloremque molestiae"</span>,
  },
  {
    userId: <span class="hljs-number">1</span>,
    id: <span class="hljs-number">7</span>,
    title: <span class="hljs-string">"magnam facilis autem"</span>,
    body: <span class="hljs-string">"dolore placeat quibusdam ea quo vitae\nmagni quis enim qui quis quo nemo aut saepe\nquidem repellat excepturi ut quia\nsunt ut sequi eos ea sed quas"</span>,
  },
  {
    userId: <span class="hljs-number">1</span>,
    id: <span class="hljs-number">8</span>,
    title: <span class="hljs-string">"dolorem dolore est ipsam"</span>,
    body: <span class="hljs-string">"dignissimos aperiam dolorem qui eum\nfacilis quibusdam animi sint suscipit qui sint possimus cum\nquaerat magni maiores excepturi\nipsam ut commodi dolor voluptatum modi aut vitae"</span>,
  },
  {
    userId: <span class="hljs-number">1</span>,
    id: <span class="hljs-number">9</span>,
    title: <span class="hljs-string">"nesciunt iure omnis dolorem tempora et accusantium"</span>,
    body: <span class="hljs-string">"consectetur animi nesciunt iure dolore\nenim quia ad\nveniam autem ut quam aut nobis\net est aut quod aut provident voluptas autem voluptas"</span>,
  },
  {
    userId: <span class="hljs-number">1</span>,
    id: <span class="hljs-number">10</span>,
    title: <span class="hljs-string">"optio molestias id quia eum"</span>,
    body: <span class="hljs-string">"quo et expedita modi cum officia vel magni\ndoloribus qui repudiandae\nvero nisi sit\nquos veniam quod sed accusamus veritatis error"</span>,
  },
];
</code></pre>
<p>Now inside the <code>api</code> folder create an <code>articles</code> folder and add 2 file, <code>index.ts</code> and <code>[id].ts</code>.</p>
<p>Inside the <code>index.ts</code> add the following code</p>
<pre><code class="lang-ts"><span class="hljs-comment">// pages/api/articles/index.ts</span>
<span class="hljs-keyword">import</span> { NextApiRequest, NextApiResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">"next"</span>;
<span class="hljs-keyword">import</span> { data } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../../data"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">_req: NextApiRequest, res: NextApiResponse</span>) </span>{
  <span class="hljs-keyword">const</span> articles = data;
  <span class="hljs-keyword">if</span> (articles.length &gt; <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json(articles);
  <span class="hljs-keyword">return</span> res
    .status(<span class="hljs-number">500</span>)
    .json({ message: <span class="hljs-string">`Error fetching the articles. Please try again later.`</span> });
}
</code></pre>
<p>We fetch all the articles from the <code>data.ts</code> file which we created just now and sends the article as a response to the request.</p>
<p>If you visit the endpoint <code>http://localhost:3000/api/articles</code> you could see all the articles present there</p>
<p>Now in <code>api/articles/[id].ts</code> file add the following code</p>
<pre><code class="lang-ts"><span class="hljs-comment">// pages/api/articles/[id].ts</span>
<span class="hljs-keyword">import</span> { NextApiRequest, NextApiResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">"next"</span>;
<span class="hljs-keyword">import</span> { data } <span class="hljs-keyword">from</span> <span class="hljs-string">"../../../data"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handler</span>(<span class="hljs-params">
  { query: { id } }: NextApiRequest,
  res: NextApiResponse
</span>) </span>{
  <span class="hljs-keyword">const</span> article = data.filter(<span class="hljs-function">(<span class="hljs-params">article</span>) =&gt;</span> article.id.toString() === id);
  <span class="hljs-keyword">if</span> (article.length &gt; <span class="hljs-number">0</span>) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json(article[<span class="hljs-number">0</span>]);
  <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">404</span>).json({ message: <span class="hljs-string">`Article with id: <span class="hljs-subst">${id}</span> not found!`</span> });
}
</code></pre>
<p>Here it fetches the data from the <code>data.ts</code> file and returns the article which has the same <code>id</code> as in the query</p>
<h3 id="using-the-api-instead-of-the-fake-server">Using the API instead of the Fake Server</h3>
<p>Instead of using the fake server, we can use the API endpoint created by us just now. So, head over to <code>pages/index.tsx</code> file and change the <code>url</code> inside the <code>getStaticProps</code> function to <code>/api/articles</code></p>
<pre><code class="lang-jsx"><span class="hljs-comment">// pages/index.tsx</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getStaticProps = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> articles: Articles[] = <span class="hljs-keyword">await</span> (<span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"/api/articles"</span>)).json();

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      articles,
    },
  };
};
</code></pre>
<p>This would give us an error saying <code>TypeError: Only absolute URLs are supported</code>, so what we have to do now is, create a <code>constants.ts</code> file in the root directory and add the following code</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> __prod__ = process.env.NODE_ENV === <span class="hljs-string">"production"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> API_URL = __prod__ ? <span class="hljs-string">""</span> : <span class="hljs-string">"http://localhost:3000/api"</span>;
</code></pre>
<p>Here, this file checks if it's production, if it is it should point to the production URL (Which we haven't added yet, we would add it when we deploy. For now leave it as an empty string) else it would point to <code>localhost:3000/api</code> </p>
<p>Now, change the function to following would fix the problem</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// pages/index.tsx</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getStaticProps = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> articles: Articles[] = <span class="hljs-keyword">await</span> (
    <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`<span class="hljs-subst">${API_URL}</span>/articles`</span>)
  ).json();

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      articles,
    },
  };
};
</code></pre>
<p>And in <code>pages/article/[id].tsx</code> change the functions to following to point to our new URL</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// pages/article/[id].tsx</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getStaticProps: GetStaticProps = <span class="hljs-keyword">async</span> (context) =&gt; {
  <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`<span class="hljs-subst">${API_URL}</span>/articles/<span class="hljs-subst">${context.params!.id}</span>`</span>);
  <span class="hljs-keyword">const</span> article: Articles = <span class="hljs-keyword">await</span> res.json();

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      <span class="hljs-attr">article</span>: article,
    },
  };
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getStaticPaths: GetStaticPaths = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`<span class="hljs-subst">${API_URL}</span>/articles`</span>);
  <span class="hljs-keyword">const</span> articles: Articles[] = <span class="hljs-keyword">await</span> res.json();

  <span class="hljs-keyword">const</span> ids = articles.map(<span class="hljs-function">(<span class="hljs-params">article</span>) =&gt;</span> article.id);

  <span class="hljs-keyword">const</span> paths = ids.map(<span class="hljs-function">(<span class="hljs-params">id</span>) =&gt;</span> ({
    <span class="hljs-attr">params</span>: {
      <span class="hljs-attr">id</span>: id.toString(),
    },
  }));
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">paths</span>: paths,
    <span class="hljs-attr">fallback</span>: <span class="hljs-literal">false</span>,
  };
};
</code></pre>
<p>Now the app should work as before, but this time we are fetching the data from the API we created! 🎉</p>
<p>That's it for this article. In the next article, we would be looking at <code>Head</code> by NextJS and we would be deploying the application to Vercel. Until then stay tuned!</p>
<p>As always, linking the <a target="_blank" href="https://github.com/AbhinavRajesh/nextjs-blog/tree/part-3">Github Repository</a>.</p>
<h3 id="support">Support 🙌</h3>
<p>If you're enjoying my articles, consider supporting me with a coffee ☕️ or upvoting the articles. It really motivates me to keep going.</p>
<p><a href="https://www.buymeacoffee.com/abhinavrajesh" target="_blank"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&amp;emoji=&amp;slug=abhinavrajesh&amp;button_colour=FFDD00&amp;font_colour=000000&amp;font_family=Cookie&amp;outline_colour=000000&amp;coffee_colour=ffffff" alt="Buy Me A Coffee" /></a></p>
<h3 id="lets-connect">Lets connect 🌎</h3>
<p><a target="_blank" href="https://github.com/AbhinavRajesh">Github</a> <br />
<a target="_blank" href="https://twitter.com/_AbhinavRajesh_">Twitter</a> <br />
<a target="_blank" href="https://linkedin.com/in/abhinavrajesh">LinkedIn</a> <br /></p>
<h3 id="feedback">Feedback 🎸</h3>
<p>Feedback helps to improve my articles. I'd love to hear feedback and thoughts on the article. Looking forward to your views. </p>
]]></content:encoded></item><item><title><![CDATA[Part 2: How to Build a NextJS App using Typescript and TailwindCSS: The Complete Guide]]></title><description><![CDATA[Hello Everyone 👋
I'm Abhinav Rajesh and this is a series on "Getting started with NextJS using Typescript and TailwindCSS". This is 2nd Part of the series where we would be learning how to fetch data from an API, TailwindCSS and Typescript Interface...]]></description><link>https://blog.abhinavrajesh.com/fetching-from-api-in-nextjs-using-getstaticprops-typescript</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/fetching-from-api-in-nextjs-using-getstaticprops-typescript</guid><category><![CDATA[TypeScript]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Fri, 02 Jul 2021 19:03:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1625250912805/fUK-_8fgz.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="hello-everyone">Hello Everyone 👋</h3>
<p>I'm Abhinav Rajesh and this is a series on "Getting started with NextJS using Typescript and TailwindCSS". This is 2nd Part of the series where we would be learning how to fetch data from an API, TailwindCSS and Typescript Interfaces. in case you missed the <a target="_blank" href="https://blog.abhinavrajesh.xyz/setting-up-nextjs-with-typescript-and-tailwindcss">1st part</a>, checking it out first would be a good idea as I discuss how to set up the project in that article.</p>
<p>In this article, we would be going through a bunch of stuff like</p>
<ul>
<li><a class="post-section-overview" href="#routing">Routing</a> <ul>
<li>Index Routes</li>
<li>Nested Routes
Dynamic Route segments</li>
</ul>
</li>
<li><a class="post-section-overview" href="#fetching-data">Different methods to fetch data</a><ul>
<li>getStaticProps</li>
<li>getStaticPath</li>
<li>getServerSideProps</li>
</ul>
</li>
<li>Module CSS</li>
<li>TailwindCSS<ul>
<li>Classes</li>
<li>@apply directives</li>
</ul>
</li>
<li>Typescript<ul>
<li>interfaces</li>
</ul>
</li>
</ul>
<h3 id="routing">Routing ⛕</h3>
<p>Next.js has a file-system based router built on the concept of pages. When a file is added to the pages directory it's automatically available as a route. The files inside the pages directory can be used to define the most common patterns.</p>
<ul>
<li><p><strong>Index routes</strong></p>
<p>  The router will automatically route files named index to the root of the directory.</p>
<pre><code class="lang-js">pages/index.tsx → /
pages/about.tsx → /about
</code></pre>
</li>
<li><p><strong>Nested routes</strong></p>
<p> The router supports nested files. If you create a nested folder structure files will be automatically routed in the same way still.</p>
<pre><code class="lang-js">pages/blog/first-post.js → /blog/first-post
pages/dashboard/settings/username.js → /dashboard/settings/username
</code></pre>
</li>
<li><p><strong>Dynamic route segments</strong></p>
<p>  To match a dynamic segment you can use the bracket syntax. This allows you to match named parameters.</p>
<pre><code class="lang-js">pages/article/[slug].js → /article/:slug (<span class="hljs-regexp">/article/</span>hello-world)
pages/article/[...all].js → /article<span class="hljs-comment">/* (/article/2020/id/title)</span>
</code></pre>
</li>
</ul>
<h4 id="now-as-the-routing-has-been-explained-now-lets-start-building">Now as the routing has been explained, now let's start building 🛠️</h4>
<p>First, create a <code>components</code> folder in the root directory and your file structure should look something like this</p>
<pre><code>┣ components/
┣ pages/
┣ <span class="hljs-built_in">public</span>/
┣ styles/
</code></pre><p>In the <code>components</code> folder create a <code>Navbar.tsx</code> file, and inside that put the following code</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// components/Navbar.tsx</span>
<span class="hljs-keyword">import</span> Link <span class="hljs-keyword">from</span> <span class="hljs-string">"next/link"</span>;

<span class="hljs-keyword">const</span> Navbar = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">nav</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex px-16 py-8"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex-1 font-bold text-2xl"</span>&gt;</span>Dev Posts<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"flex-1 flex justify-around"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"px-4 py-2"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"px-4 py-2"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/about"</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          <span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Navbar;
</code></pre>
<p>The above code creates a simple navbar. You can see that there are class names which we have used. The style for these classes come directly from TailwindCSS. For Eg. In the above code, </p>
<pre><code class="lang-css"><span class="hljs-selector-tag">flex</span> <span class="hljs-selector-tag">-</span>&gt; <span class="hljs-selector-tag">display</span>: <span class="hljs-selector-tag">flex</span>;
<span class="hljs-selector-tag">px-</span>* <span class="hljs-selector-tag">-</span>&gt; <span class="hljs-selector-tag">padding</span> <span class="hljs-selector-tag">in</span> <span class="hljs-selector-tag">horizontal</span> <span class="hljs-selector-tag">by</span> <span class="hljs-selector-tag">a</span> <span class="hljs-selector-tag">particular</span> <span class="hljs-selector-tag">amount</span> <span class="hljs-selector-tag">in</span> <span class="hljs-selector-tag">rem</span> <span class="hljs-selector-tag">units</span>
<span class="hljs-selector-tag">font-bold</span> <span class="hljs-selector-tag">-</span>&gt; <span class="hljs-selector-tag">font-weight</span>: <span class="hljs-selector-tag">bold</span>;
<span class="hljs-selector-tag">text-2xl</span> <span class="hljs-selector-tag">-</span>&gt; <span class="hljs-selector-tag">font-size</span>: 1<span class="hljs-selector-class">.5rem</span>;
</code></pre>
<p>There are many more different types of utility classes, you can check them out in the  <a target="_blank" href="https://tailwindcss.com">Official TailwindCSS documentation</a>.</p>
<p>The other important thing we used is the <code>Link</code> component exported by <code>next/link</code>. It is used for Client-side transitions between routes. </p>
<p>Now, inside the <code>pages</code> directory inside the <code>index.tsx</code> file, remove everything in the return statement and replace it with the following code</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// pages/index.tsx</span>
<span class="hljs-keyword">import</span> Navbar <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Navbar"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> /&gt;</span></span>;
}
</code></pre>
<p>Now, if you run the server, using the command </p>
<pre><code><span class="hljs-selector-tag">yarn</span> <span class="hljs-selector-tag">dev</span>
<span class="hljs-comment">// or</span>
<span class="hljs-selector-tag">npm</span> <span class="hljs-selector-tag">run</span> <span class="hljs-selector-tag">dev</span>
</code></pre><p>and go to <code>http://localhost:3000</code>(If you have changed the port number, then go to the port you changed to) you can see the navbar we just created! 🎉
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625246751470/tBjBDRO_U.png" alt="image.png" /></p>
<h3 id="fetching-data">Fetching data 🎣</h3>
<p>For data fetching, we have special functions which can be used to fetch the data and pass the data as props to the pages.</p>
<p>Now, there are 3 separate methods to fetch the data.</p>
<ul>
<li><strong>getStaticProps (Static Generation): </strong>Fetch data at build time.</li>
<li><strong>getStaticPaths (Static Generation):</strong> Specify dynamic routes to pre-render pages based on data.</li>
<li><strong>getServerSideProps (Server-side Rendering):</strong> Fetch data on each request.</li>
</ul>
<p>For this example, we would be using the <code>getStaticProps</code> function. We would be fetching data(articles) from a  <a target="_blank" href="https://jsonplaceholder.typicode.com/posts">fake server</a> and display the articles. For this we would be fetching the data in <code>pages/index.tsx</code> file and send the data to a new component in <code>components/Article.tsx</code> as props and display the articles by mapping over the items.</p>
<p>So, create a new file in <code>components/Article.tsx</code> and add the following code</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// components/Article.tsx</span>
<span class="hljs-keyword">import</span> Link <span class="hljs-keyword">from</span> <span class="hljs-string">"next/link"</span>;
<span class="hljs-keyword">import</span> styles <span class="hljs-keyword">from</span> <span class="hljs-string">"../styles/Article.module.css"</span>;

interface Article {
  <span class="hljs-attr">id</span>: number;
  userId: number;
  body: string;
  title: string;
}

<span class="hljs-keyword">const</span> Article = <span class="hljs-function">(<span class="hljs-params">{ id, userId, body, title }: Article</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">{</span>`/<span class="hljs-attr">article</span>/${<span class="hljs-attr">id</span>}`}&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{styles.card}</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>{title} <span class="hljs-symbol">&amp;rarr;</span><span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>{body.length &gt; 50 ? `${body.slice(0, 45)}...` : body}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Article;
</code></pre>
<p>One of TypeScript’s core principles is that type checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”. In TypeScript, <strong>interfaces</strong> fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project. </p>
<p>Here you may also notice that we used objects for class names instead of string. 
That's because by default Next.js supports  <a target="_blank" href="https://github.com/css-modules/css-modules">CSS Modules</a>. CSS Modules locally scope CSS by automatically creating a unique class name. This allows you to use the same CSS class name in different files without worrying about collisions. </p>
<p>Adding the tailwindCSS classes inline may make the <code>tsx files</code> less readable, so instead of that, we can write the tailwind classes in a separate css file using the <code>@apply</code> keyword. So create a new file <code>Article.module.css</code> in the <code>styles</code> folder in the root directory and add the following code</p>
<pre><code class="lang-css"><span class="hljs-comment">/* styles/Article.module.css */</span>
<span class="hljs-selector-class">.grid</span> {
  @apply flex items-center justify-center flex-wrap max-w-3xl mt-12;
}

<span class="hljs-selector-class">.card</span> {
  @apply m-4 p-6 text-left <span class="hljs-attribute">md</span>:w-<span class="hljs-number">11</span>/<span class="hljs-number">12</span> no-underline border border-gray-<span class="hljs-number">100</span> rounded-lg transition-all duration-<span class="hljs-number">150</span> ease-in-out;
}

<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:hover</span>,
<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:focus</span>,
<span class="hljs-selector-class">.card</span><span class="hljs-selector-pseudo">:active</span> {
  @apply text-blue-400 border-blue-400;
}

<span class="hljs-selector-class">.card</span> <span class="hljs-selector-tag">h3</span> {
  @apply mb-4 text-2xl font-semibold;
}

<span class="hljs-selector-class">.card</span> <span class="hljs-selector-tag">p</span> {
  @apply m-0 text-2xl;
}

<span class="hljs-keyword">@media</span> (<span class="hljs-attribute">max-width:</span> <span class="hljs-number">600px</span>) {
  <span class="hljs-selector-class">.grid</span> {
    @apply w-full flex-col;
  }
}
</code></pre>
<p>Now inside the <code>pages/index.tsx</code> file add the following code</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// pages/index.tsx</span>
<span class="hljs-keyword">import</span> { InferGetStaticPropsType } <span class="hljs-keyword">from</span> <span class="hljs-string">"next"</span>;

<span class="hljs-keyword">import</span> Navbar <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/navbar"</span>;
<span class="hljs-keyword">import</span> Article <span class="hljs-keyword">from</span> <span class="hljs-string">"../components/Article"</span>;

interface Articles {
  <span class="hljs-attr">body</span>: string;
  id: number;
  title: string;
  userId: number;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params">{
  articles,
}: InferGetStaticPropsType&lt;typeof getStaticProps&gt;</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"max-w-5xl mx-auto"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"grid grid-cols-1 md:grid-cols-2 space-x-5 space-y-5"</span>&gt;</span>
        {articles.map((article) =&gt; (
          <span class="hljs-tag">&lt;<span class="hljs-name">Article</span>
            <span class="hljs-attr">body</span>=<span class="hljs-string">{article.body}</span>
            <span class="hljs-attr">id</span>=<span class="hljs-string">{article.id}</span>
            <span class="hljs-attr">title</span>=<span class="hljs-string">{article.title}</span>
            <span class="hljs-attr">userId</span>=<span class="hljs-string">{article.userId}</span>
            <span class="hljs-attr">key</span>=<span class="hljs-string">{article.id}</span>
          /&gt;</span>
        ))}
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getStaticProps = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> articles: Articles[] = <span class="hljs-keyword">await</span> (
    <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts?_limit=10"</span>)
  ).json();

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      articles,
    },
  };
};
</code></pre>
<p>You may notice that we are using the same interface in both the files, so what we can do is create a new file in the root directory called <code>types.ts</code> and add the interface there instead</p>
<pre><code class="lang-ts"><span class="hljs-comment">// types.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> Articles {
  id: <span class="hljs-built_in">number</span>;
  userId: <span class="hljs-built_in">number</span>;
  body: <span class="hljs-built_in">string</span>;
  title: <span class="hljs-built_in">string</span>;
}
</code></pre>
<p>And replace the <code>Article interface</code> from both <code>pages/index.tsx</code> and <code>components/Articles.tsx</code> with the following import</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Articles } <span class="hljs-keyword">from</span> <span class="hljs-string">"../types"</span>;
</code></pre>
<p>Now in the browser, your app should look something similar to this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625250379755/VXB_PlQce.png" alt="image.png" /></p>
<p>And that's it for this article. In the next article, we would be learning how to create pages dynamically using different functions offered by NextJS. Until then stay tuned.</p>
<p>As always, linking the <a target="_blank" href="https://github.com/AbhinavRajesh/nextjs-blog/tree/part-2">Github Repository</a>.</p>
<h3 id="series">Series</h3>
<ul>
<li><a target="_blank" href="https://blog.abhinavrajesh.xyz/setting-up-nextjs-with-typescript-and-tailwindcss">Part 1: Setting up NextJS with Typescript and TailwindCSS</a> </li>
</ul>
<h3 id="support">Support 🙌</h3>
<p>If you're enjoying my articles, consider supporting me with a coffee ☕️ or upvoting the articles. It really motivates me to keep going.</p>
<p><a href="https://www.buymeacoffee.com/abhinavrajesh" target="_blank"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&amp;emoji=&amp;slug=abhinavrajesh&amp;button_colour=FFDD00&amp;font_colour=000000&amp;font_family=Cookie&amp;outline_colour=000000&amp;coffee_colour=ffffff" alt="Buy Me A Coffee" /></a></p>
<h3 id="lets-connect">Lets connect 🌎</h3>
<p><a target="_blank" href="https://github.com/AbhinavRajesh">Github</a> <br />
<a target="_blank" href="https://twitter.com/_AbhinavRajesh_">Twitter</a> <br />
<a target="_blank" href="https://linkedin.com/in/abhinavrajesh">LinkedIn</a> <br /></p>
<h3 id="feedback">Feedback 🎸</h3>
<p>Feedback helps to improve my articles. I'd love to hear feedback and thoughts on the article. Looking forward to your views.</p>
]]></content:encoded></item><item><title><![CDATA[Part 1: How to Build a NextJS App using Typescript and TailwindCSS: The Complete Guide]]></title><description><![CDATA[What is Next.js?
 Next.js  is a production-ready framework built on top of React and Node.js. It ships with all the features you need to get your React app up and running in no time.
You can use Next.js to build static or dynamic apps since it suppor...]]></description><link>https://blog.abhinavrajesh.com/setting-up-nextjs-with-typescript-and-tailwindcss</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/setting-up-nextjs-with-typescript-and-tailwindcss</guid><category><![CDATA[Next.js]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[React]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Mon, 28 Jun 2021 16:24:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1624897848048/xC30CPxW-.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="what-is-nextjs">What is Next.js?</h3>
<p> <a target="_blank" href="https://nextjs.org">Next.js</a>  is a <strong>production-ready framework</strong> built on top of <strong>React and Node.js</strong>. It ships with all the features you need to get your React app up and running in no time.</p>
<p>You can use Next.js to build static or dynamic apps since it supports both client-side and server-side rendering. Next.js v9 introduced API routes, which allow you to extend your Next.js app with serverless functions built with Node.js, Express.js, GraphQL, and so on.</p>
<p>Next.js uses <strong>automatic code-splitting (lazy loading)</strong> to render only the JavaScript needed for your website. As an added bonus, this makes <strong>Next.js great for SEO.</strong></p>
<h3 id="what-is-typescript">What is TypeScript?</h3>
<p><a target="_blank" href="https://www.typescriptlang.org">TypeScript </a> is a popular language created and maintained by <strong>Microsoft</strong>. It’s a <strong>superset of JavaScript</strong>, which makes all its features optional.</p>
<p>You can convert your existing JavaScript app to TypeScript and it should work as expected as long as your code is valid JavaScript. TypeScript allows you to set types on your variables and functions so you can <strong>type-check your code statically and catch errors at compile time.</strong></p>
<p>You can also use modern features that are not yet supported in JavaScript. And don’t worry about browser support — TypeScript compiles to plain JavaScript, which means your TypeScript code will never ship in the browser.</p>
<h3 id="what-is-tailwindcss">What is TailwindCSS?</h3>
<p><a target="_blank" href="https://tailwindcss.com">TailwindCSS</a>  is a utility-first CSS framework for rapidly building custom user interfaces. You can say it is a cool way of writing inline styling and achieve an awesome interface without writing a single line of your own CSS! Tailwind isn’t the first utility CSS library, but it is the most popular at the moment and the best in my opinion.</p>
<h3 id="setup">Setup</h3>
<p>I have created a GitHub repository with starter files you can either  <a target="_blank" href="https://github.com/AbhinavRajesh/Nextjs-typescript-tailwindCSS">clone the repository</a>(Can be used as starter files for other amazing projects! Maybe give it a ⭐ while you are at it  😃)  or follow the steps below</p>
<ol>
<li><strong>Setting up a new NextJS app with Typescript</strong> <br />
Setting up a NextJS project with Typescript is actually really easy. Running the following command would create a basic NextJS app with Typescript support.<pre><code>npx <span class="hljs-keyword">create</span>-<span class="hljs-keyword">next</span>-app nextjs-crashcourse <span class="hljs-comment">--ts</span>
<span class="hljs-comment"># or</span>
yarn <span class="hljs-keyword">create</span> <span class="hljs-keyword">next</span>-app nextjs-crashcourse <span class="hljs-comment">--typescript</span>
</code></pre></li>
<li><p><strong>Adding TailwindCSS to the project </strong><br />
Go inside the project folder and install the required dependencies</p>
<pre><code>cd nextjs-crashcourse
<span class="hljs-comment">// using npm</span>
npm install -D <span class="hljs-symbol">tailwindcss@</span>latest <span class="hljs-symbol">postcss@</span>latest <span class="hljs-symbol">autoprefixer@</span>latest
<span class="hljs-comment">// using yarn</span>
yarn add -D <span class="hljs-symbol">tailwindcss@</span>latest <span class="hljs-symbol">postcss@</span>latest <span class="hljs-symbol">autoprefixer@</span>latest
</code></pre><p>Creating the tailwind configuration file</p>
<pre><code>npx tailwindcss <span class="hljs-keyword">init</span> -p
</code></pre><p>This command would create a tailwind configuration file(<code>tailwind.config.js</code>) and a postcss configuration file(<code>postcss.config.js</code>)</p>
</li>
<li><p><strong>Editing the <code>tailwind.config.js</code> file</strong> <br />
Change the file to the following code snippet</p>
<pre><code class="lang-js"><span class="hljs-comment">// tailwind.config.js</span>
<span class="hljs-built_in">module</span>.exports = {
 <span class="hljs-attr">purge</span>: [<span class="hljs-string">'./pages/**/*.{js,ts,jsx,tsx}'</span>, <span class="hljs-string">'./components/**/*.{js,ts,jsx,tsx}'</span>],
 <span class="hljs-attr">darkMode</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">// or 'media' or 'class'</span>
 <span class="hljs-attr">theme</span>: {
   <span class="hljs-attr">extend</span>: {},
 },
 <span class="hljs-attr">variants</span>: {
   <span class="hljs-attr">extend</span>: {},
 },
 <span class="hljs-attr">plugins</span>: [],
}
</code></pre>
</li>
<li><p><strong>Adding tailwind to your CSS file</strong> <br />
Add the following lines of code to the top of the <code>styles/global.css</code> file</p>
<pre><code class="lang-css"><span class="hljs-keyword">@tailwind</span> base;
<span class="hljs-keyword">@tailwind</span> components;
<span class="hljs-keyword">@tailwind</span> utilities;
</code></pre>
</li>
</ol>
<p>And that's it! 🥳 You have successfully set up the files required for the series. Also, note that you could use this as boilerplate code for your "next" application! Meet you in the second part of the series.</p>
<h3 id="support">🙌 Support</h3>
<p>If you're enjoying my articles, consider supporting me with a coffee ☕️. It really helps me a lot.</p>
<p><a href="https://www.buymeacoffee.com/abhinavrajesh" target="_blank"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&amp;emoji=&amp;slug=abhinavrajesh&amp;button_colour=FFDD00&amp;font_colour=000000&amp;font_family=Cookie&amp;outline_colour=000000&amp;coffee_colour=ffffff" alt="Buy Me A Coffee" /></a></p>
<h3 id="lets-connect">🌎 Lets connect</h3>
<p><a target="_blank" href="https://github.com/AbhinavRajesh">Github</a> <br />
<a target="_blank" href="https://twitter.com/_AbhinavRajesh_">Twitter</a> <br />
<a target="_blank" href="https://linkedin.com/in/abhinavrajesh">LinkedIn</a> <br /></p>
<h3 id="feedback">🎸 Feedback</h3>
<p>Feedback helps to improve my articles. I'd love to hear feedback and thoughts on the article. Looking forward to your views.</p>
]]></content:encoded></item><item><title><![CDATA[Adding SASS/SCSS to your React/NextJS Application]]></title><description><![CDATA[What is SASS?
SASS short for Syntactically Awesome StyleSheet (Yes, as the name suggests, it's really awesome), it is just CSS but better (Basically you can say SASS is CSS on steroids!). It is a preprocessor scripting language that is interpreted or...]]></description><link>https://blog.abhinavrajesh.com/adding-sassscss-to-your-reactnextjs-application</link><guid isPermaLink="true">https://blog.abhinavrajesh.com/adding-sassscss-to-your-reactnextjs-application</guid><category><![CDATA[React]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[Sass]]></category><category><![CDATA[scss]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Abhinav Rajesh]]></dc:creator><pubDate>Sun, 27 Jun 2021 15:06:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1624806476868/im5pVbKn5.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-what-is-sass">What is SASS?</h3>
<p>SASS short for <strong>S</strong>yntactically <strong>A</strong>wesome <strong>S</strong>tyle<strong>S</strong>heet (Yes, as the name suggests, it's really awesome), it is just CSS but better (Basically you can say SASS is CSS on steroids!). It is a preprocessor scripting language that is interpreted or compiled into Cascading Style Sheets</p>
<h3 id="heading-why-sass">Why SASS?</h3>
<p>SASS has few options which aren't offered by CSS. Few of them are</p>
<ol>
<li><p><strong>Variables:</strong> With SASS, you can save information in variables to be used again later. So it’s possible, for example, to centrally store a colour value under a catchier variable.</p>
</li>
<li><p>** Mathematical functions:** In SASS, you can also use mathematical operations like +, -, *, /, or %. This allows you to influence size specifications.</p>
</li>
<li><p><strong>Functions:</strong> Other functions also make it easier to work on the design. These allow you to modify colour values or analyze lists, among other things.</p>
</li>
<li><p><strong>Mixins:</strong> Mixins, simply said, are templates. You can either create them yourself or simply integrate them into your own code when using a framework.</p>
</li>
</ol>
<p>There are many more amazing features offered by Sass.</p>
<h3 id="heading-syntax">Syntax</h3>
<p>Sass includes two syntax options:</p>
<ol>
<li><p><strong>SCSS (Sassy CSS):</strong> Using the <code>.scss</code> file extension and is fully adjective with CSS syntax</p>
</li>
<li><p><strong>Indented (simply called ‘Sass’):</strong> using <code>.sass</code> file extension and indentation rather than brackets; it is not fully adjective with CSS syntax, but it’s quicker to write.</p>
</li>
</ol>
<h3 id="heading-adding-it-to-your-react-application">Adding it to your React Application</h3>
<p>Adding it to CRA app and NextJS app is a bit different, I will explain how you can add it to both the applications.</p>
<h4 id="heading-adding-sassscss-to-nextjs-application">Adding SASS/SCSS to NextJS Application</h4>
<p>It is a straightforward process, you just have to install the <code>sass</code> package and you are good to go!</p>
<pre><code class="lang-plaintext">// using npm
npm i sass

// using yarn
yarn add sass
</code></pre>
<h4 id="heading-adding-sassscss-to-cra-application">Adding SASS/SCSS to CRA Application</h4>
<p>React-scripts uses <code>sass-loader v8</code>, which prefers node-sass to sass (which has some syntax not supported by node-sass). So we would be using that package instead</p>
<pre><code class="lang-plaintext">// using npm
npm i node-sass@4.14

// using yarn
yarn add node-sass@4.14
</code></pre>
<p>Version 4.14 is preferred over the latest version of node-sass because it would throw an error. Or you could refer the below image and install the node-sass version according to your Node version!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1624805620676/Y6wY0rSA_.png" alt="Quick guide for minimum and maximum support supported version of node-sass" /></p>
<p>After installing the <code>node-sass/sass</code> package now you just have to rename the .css file extension to sass or scss and change the imports, that's it! You have added the sass/scss to your react application.</p>
<p>I hope this blog post helped you guys.</p>
<h3 id="heading-support">🙌 Support</h3>
<p>If you're enjoying my articles, consider supporting me with a coffee ☕️. It really helps me a lot.</p>
<p><a target="_blank" href="https://www.buymeacoffee.com/abhinavrajesh">![Buy Me A Coffee](https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&amp;emoji=&amp;slug=abhinavrajesh&amp;button_colour=FFDD00&amp;font_colour=000000&amp;font_family=Cookie&amp;outline_colour=000000&amp;coffee_colour=ffffff align="left")</a></p>
<h3 id="heading-lets-connect">🌎 Lets connect</h3>
<p><a target="_blank" href="https://github.com/AbhinavRajesh">Github</a><br /><a target="_blank" href="https://twitter.com/_AbhinavRajesh_">Twitter</a><br /><a target="_blank" href="https://linkedin.com/in/abhinavrajesh">LinkedIn</a>  </p>
<h3 id="heading-feedback">🎸 Feedback</h3>
<p>Feedback helps to improve my articles. I'd love to hear feedback and thoughts on the article. Looking forward to your views.</p>
]]></content:encoded></item></channel></rss>