<?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[Ishaantek's Blog]]></title><description><![CDATA[My name is Ishaan, and I am a proficient full-stack developer. On this blog, I share valuable insights on various programming topics.]]></description><link>https://blog.ishaangarg.com</link><generator>RSS for Node</generator><lastBuildDate>Mon, 13 Apr 2026 14:43:47 GMT</lastBuildDate><atom:link href="https://blog.ishaangarg.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Debugging 101: Common Techniques and Tools]]></title><description><![CDATA[Debugging is an essential part of the software development process. It can be frustrating, and time-consuming, but it is also an opportunity to improve your code and make it more robust. In this blog post, we will explore some common techniques and t...]]></description><link>https://blog.ishaangarg.com/debugging-101-common-techniques-and-tools</link><guid isPermaLink="true">https://blog.ishaangarg.com/debugging-101-common-techniques-and-tools</guid><category><![CDATA[debugging]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[VS Code]]></category><category><![CDATA[coding]]></category><dc:creator><![CDATA[Ishaan Garg]]></dc:creator><pubDate>Sat, 28 Jan 2023 01:56:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1674870656143/f61c99d1-74e2-4ef1-b156-3ae7e98cccc7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Debugging is an essential part of the software development process. It can be frustrating, and time-consuming, but it is also an opportunity to improve your code and make it more robust. In this blog post, we will explore some common techniques and tools that can help make debugging a little less painful.</p>
<h3 id="heading-1-print-statement">1. Print Statement</h3>
<p>First, let's talk about the most basic debugging technique: using print statements. This is the simplest way to check the value of a variable or the flow of your program. Inserting print statements at key points in your code can help you identify where things are going wrong. For example, if you suspect a problem in a loop, you can print the value of the loop variable at the beginning and end of each iteration to see if it's behaving as expected.</p>
<h3 id="heading-2-debuggers">2. Debuggers</h3>
<p>Another technique is using a debugger. A debugger is a program that allows you to step through your code line by line, pause execution, and inspect variables. Most modern integrated development environments (IDEs) come with a built-in debugger, such as the one in Visual Studio Code, PyCharm, or IntelliJ. Debuggers are especially useful for identifying problems in large, complex codebases, as they allow you to set breakpoints, watch variables, and step through code.</p>
<h3 id="heading-3-logging-library">3. Logging Library</h3>
<p>A third technique is using a logging library. Logging libraries allow you to record information about your program's execution, such as error messages, variable values, and performance metrics. These logs can help identify problems that are not immediately obvious, such as memory leaks or performance bottlenecks. Some popular logging libraries include Python's logging module, Java's log4j, and C#'s log4net.</p>
<h3 id="heading-4-profiler">4. Profiler</h3>
<p>Another common tool used in debugging is the use of a profiler. A profiler is a tool that helps you to understand how your code is performing, and where it's spending most of its time. Profilers can help you identify performance bottlenecks, such as slow functions or excessive memory usage. Some popular profilers include the Python profiler, Xdebug for PHP, and Visual Studio's built-in profiler.</p>
<h3 id="heading-5-assertions">5. Assertions</h3>
<p>Another important technique for debugging is using assertions. Assertions are statements in your code that check if a certain condition is true and raise an exception if it is not. These can be useful in catching bugs early on, as they allow you to specify the expected behavior of your code and ensure that it is happening. For example, you might use an assertion to check that a variable is within a certain range or that a list is not empty.</p>
<h3 id="heading-6-version-control">6. Version Control</h3>
<p>Another technique is using a version control system such as Git. Version control systems allow you to keep track of changes to your code over time and revert to previous versions if necessary. This can be especially useful when debugging, as you can easily revert to a known good version of your code and compare it to the current version to see what has changed. Additionally, many version control systems allow you to view the commit history and see who made specific changes, which can help identify the source of a problem.</p>
<h3 id="heading-7-systematic-approach">7. Systematic Approach</h3>
<p>Finally, it's important to have a systematic approach to debugging. This can help you to stay focused and avoid getting bogged down in minor details. One common approach is the "divide and conquer" method, where you break down a problem into smaller, more manageable pieces and tackle them one at a time. Another approach is the "scientific method", where you form a hypothesis about the problem, test it, and use the results to guide your next steps.</p>
<h3 id="heading-8-have-a-good-understanding">8. Have a Good Understanding</h3>
<p>In addition to the techniques and tools mentioned above, it's also important to have a good understanding of the specific language and framework you are working with. This can help you to understand how the code is supposed to work and where potential issues may arise.</p>
<p>In conclusion, debugging is an essential part of the software development process. By using a combination of techniques such as print statements, assertions, version control, and a systematic approach, as well as tools like debuggers, logging libraries, and profilers, you can make debugging less painful and more effective. Remember, the key is to stay calm, be methodical, and always keep learning.</p>
]]></content:encoded></item><item><title><![CDATA[10 HTML Pro Tricks You Need To Know]]></title><description><![CDATA[What is HTML?
Hypertext Markup Language (HTML) is the standard markup language for documents designed to be displayed in a web browser.
It can be assisted by technologies such as Cascading Style Sheets (CSS) and scripting languages such as JavaScript...]]></description><link>https://blog.ishaangarg.com/10-html-tricks</link><guid isPermaLink="true">https://blog.ishaangarg.com/10-html-tricks</guid><category><![CDATA[HTML5]]></category><category><![CDATA[HTML]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Ishaan Garg]]></dc:creator><pubDate>Thu, 10 Nov 2022 20:46:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1668113021989/DQoIAnQaY.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-what-is-html">What is HTML?</h1>
<p>Hypertext Markup Language (HTML) is the standard markup language for documents designed to be displayed in a web browser.<br />
It can be assisted by technologies such as Cascading Style Sheets (CSS) and scripting languages such as JavaScript.</p>
<h1 id="heading-10-html-pro-tips">10 HTML Pro Tips</h1>
<ul>
<li><strong><code>Start</code> Attribute</strong></li>
</ul>
<p>The <code>start</code> attribute specifies the start value of the first list item in an ordered list. This value is always an integer, even when the numbering type is letters or romans.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668109823603/wnQsyHe2Y.png" alt="image.png" class="image--center mx-auto" /></p>
<ul>
<li><strong><code>&lt;abbr&gt;</code> Tag</strong></li>
</ul>
<p>The <code>&lt;abbr&gt;</code> tag defines an abbreviation or an acronym, like "HTML", "CSS", "Mr.", "Dr.", "ASAP", "ATM".</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668110525151/DXcoLsFEE.png" alt="image.png" class="image--center mx-auto" /></p>
<ul>
<li><strong><code>&lt;meter&gt;</code> Tag</strong></li>
</ul>
<p>The <code>&lt;meter&gt;</code> tag defines a scalar measurement within a known range, or a fractional value. This is also known as a gauge.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668111822310/UeqY0sipx.png" alt="image.png" /></p>
<ul>
<li><strong><code>&lt;fieldset&gt;</code> Tag</strong></li>
</ul>
<p>The <code>&lt;fieldset&gt;</code> tag is used to group related elements in a form.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668111879617/VDDB5E9qa.png" alt="image.png" /></p>
<ul>
<li><strong><code>Window.opener</code> Property</strong></li>
</ul>
<p>The <code>opener</code> property returns a reference to the window that created the window.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668111946427/JLdHZnJn0.png" alt="image.png" /></p>
<ul>
<li><strong><code>&lt;base&gt;</code> Tag</strong></li>
</ul>
<p>The <code>&lt;base&gt;</code> tag specifies the base URL and/or target for all relative URLs in a document.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668112223187/Fwb1ieakM.png" alt="image.png" /></p>
<ul>
<li><strong><code>Accordion</code></strong></li>
</ul>
<p>The <code>accordion</code> is useful when you want to toggle between hiding and showing a large amount of content:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668112261567/p1vjKUeIp.png" alt="image.png" /></p>
<ul>
<li><strong><code>loading=lazy</code> Attribute</strong></li>
</ul>
<p>The <code>loading</code> attribute specifies whether a browser should load an image immediately or to defer loading of off-screen images until for example the user scrolls near them.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668112333545/ZwUabQuAY.png" alt="image.png" /></p>
<ul>
<li><strong><code>&lt;ol&gt; reversed</code> Attribute</strong></li>
</ul>
<p>The <code>reversed</code> attribute specifies that the list order should be descending (9,8,7...), instead of ascending (1, 2, 3...).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668112463766/lw5d55mO_.png" alt="image.png" /></p>
<ul>
<li><strong><code>Download</code> Attribute</strong></li>
</ul>
<p>The <code>reversed</code> attribute specifies that the target (the file specified in the href attribute) will be downloaded when a user clicks on the hyperlink.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668112622724/FI_Xk7Tud.png" alt="image.png" /></p>
<p>I hope you all enjoyed this article and were able to learn some new HTML features! If you have any doubts or questions, make sure to write them in the comments below. Also, please add a reaction to this article and rate it out of 10. I really appreciate it 🙏</p>
<p>Don’t forget to join my <a target="_blank" href="https://discord.gg/cMBSgG4Xd7">Discord server</a>!</p>
<p>#Have a Great Day! Thank you! Happy Coding! 💻⚡</p>
]]></content:encoded></item><item><title><![CDATA[How To Build a Discord Bot with Node.js]]></title><description><![CDATA[Discord bots help you interact with members of a server as well as moderate the server. A discord bot can send messages on the server, message a user directly (DM), ban a user, promote and demote a user and so much more.
As a server owner, you are no...]]></description><link>https://blog.ishaangarg.com/how-to-build-a-discord-bot-with-nodejs</link><guid isPermaLink="true">https://blog.ishaangarg.com/how-to-build-a-discord-bot-with-nodejs</guid><category><![CDATA[discord]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[npm]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[node]]></category><dc:creator><![CDATA[Ishaan Garg]]></dc:creator><pubDate>Thu, 29 Sep 2022 00:44:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1664411991847/uEi_SSzeI.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Discord bots help you interact with members of a server as well as moderate the server. A discord bot can send messages on the server, message a user directly (DM), ban a user, promote and demote a user and so much more.</p>
<p>As a server owner, you are not always going to be present to monitor your server, but a bot can, and it does it way faster.</p>
<p>You may not be a server owner, but if you want to create a bot for a server you belong to or maybe for public use (available for other servers) this article will help you do that.</p>
<p>Before we jump right into code, let's see how Discord bots work.</p>
<h1 id="heading-prerequisites">Prerequisites</h1>
<p>Before you get started, you will need the following:</p>
<ul>
<li>Node.js installed on your development machine. </li>
<li>Any text editor of your choice, such as Visual Studio Code, Atom, Sublime, or nano.</li>
<li>A free Discord account with a verified email account and a free Discord server you will use to test your Discord bot.</li>
</ul>
<h1 id="heading-step-1-setting-up-a-discord-bot">Step 1 — Setting Up a Discord Bot</h1>
<p>In this step, you’ll use the Discord developer's graphical user interface (GUI) to set up a Discord bot and get the bot’s token, which you will pass into your program.</p>
<p>In order to register a bot on the Discord platform, use the <a href="https://discord.com/developers/applications/">Discord application dashboard</a>. Here developers can create Discord applications including Discord bots.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664409894821/y0-N8rczg.png" alt="image.png" class="image--center mx-auto" /></p>
<p>To get started, click <strong>New Application</strong>. Discord will ask you to enter a name for your new application. Then click <strong>Create</strong> to create the application.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664409966105/Cfu9Dwt1d.png" alt="image.png" class="image--center mx-auto" /></p>
<p><em>Note: The name for your application is independent from the name of the bot, and the bot doesn’t have to have the same name as the application.</em></p>
<p>Now open up your application dashboard. To add a bot to the application, navigate to the <strong>Bot</strong> tab on the navigation bar to the left.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664410026062/EXx2LclkW.png" alt="image.png" class="image--center mx-auto" /></p>
<p>Click the <strong>Add Bot</strong> button to add a bot to the application. Click the <strong>Yes, do it!</strong> button when it prompts you for confirmation. You will then be on a dashboard containing details of your bot’s name, authentication token, and profile picture.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664410063131/7rU2ytpf0.png" alt="image.png" class="image--center mx-auto" /></p>
<p>You can modify your bot’s name or profile picture here on the dashboard. You also need to copy the bot’s authentication token by clicking <strong>Click to Reveal Token</strong> and copying the token that appears.</p>
<p><strong>Warning</strong>: <em>Never share or upload your bot token as it allows anyone to log in to your bot.</em></p>
<p>Now you need to create an invite to add the bot to a Discord guild where you can test it. First, navigate to the <strong>URL Generator</strong> page under the <strong>OAuth2</strong> tab of the application dashboard. To create an invite, scroll down and select <strong>bot</strong> under <strong>scopes</strong>. You must also set permissions to control what actions your bot can perform in guilds. For the purposes of this tutorial, select <strong>Administrator</strong>, which will give your bot permission to perform nearly all actions in guilds. Copy the link with the <strong>Copy</strong> button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664410263857/ixyv5snUu.png" alt="image.png" class="image--center mx-auto" /></p>
<p>Next, add the bot to a server. Follow the invite link you just created. You can add the bot to any server you own, or have administrator permissions in, from the drop-down menu.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664410284449/1SSrY3TWD.png" alt="image.png" class="image--center mx-auto" /></p>
<p>Now click <strong>Continue</strong>. Ensure you have the tickbox next to <strong>Administrator</strong> ticked—this will grant the bot administrator permissions. Then click <strong>Authorize</strong>. Discord will ask you to solve a CAPTCHA before the bot joins the server. You’ll now have the Discord bot on the members list in the server you added the bot to under <strong>offline</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664410311959/W8hrfmf8g.png" alt="image.png" class="image--center mx-auto" /></p>
<p>You’ve successfully created a Discord bot and added it to a server. Next, you will write a program to log in to the bot.</p>
<h1 id="heading-step-2-creating-your-project">Step 2 — Creating Your Project</h1>
<p>In this step, you’ll set up the basic coding environment where you will build your bot and log in to the bot programmatically.</p>
<p>First, you need to set up a project folder and necessary project files for the bot.</p>
<p>Create your project folder:</p>
<p><code>mkdir discord-bot</code></p>
<p>Move into the project folder you just created:</p>
<p><code>cd discord-bot</code></p>
<p>Next, create a file named <code>config.json</code> to store your bot’s authentication token.</p>
<p>Then add the following code to the config file, replacing the highlighted text with your bot’s authentication token:</p>
<pre><code class="lang-js">{
    <span class="hljs-string">"BOT_TOKEN"</span>: <span class="hljs-string">"YOUR BOT TOKEN"</span>
}
</code></pre>
<p>Save and exit the file.</p>
<p>Next you’ll create a <code>package.json</code> file, which will store details of your project and information about the dependencies you’ll use for the project. You’ll create a <code>package.json</code> file by running the following <code>npm</code> command:</p>
<p><code>npm init</code></p>
<p>You’ll now install the <code>discord.js</code> package that you will use to interact with the Discord API. You can install <code>discord.js</code> through npm with the following command:</p>
<p><code>npm install discord.js</code></p>
<p>Now that you’ve set up the configuration file and installed the necessary dependency, you’re ready to begin building your bot. In a real-world application, a large bot would be split across many files, but for the purposes of this tutorial, the code for your bot will be in one file.</p>
<p>First, create a file named <code>index.js</code> in the <code>discord-bot</code> folder for the code.</p>
<p>Begin coding the bot by requiring the <code>discord.js</code> dependency and the config file with the bot’s token:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Discord = <span class="hljs-built_in">require</span>(<span class="hljs-string">"discord.js"</span>);
<span class="hljs-keyword">const</span> config = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./config.json"</span>);
</code></pre>
<p>Following this, add the next two lines of code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> Discord.Client({<span class="hljs-attr">intents</span>: [<span class="hljs-string">"GUILDS"</span>, <span class="hljs-string">"GUILD_MESSAGES"</span>]});

client.login(config.BOT_TOKEN);
</code></pre>
<p>Save and exit your file.</p>
<p>The first line of code creates a new <code>Discord.Client</code> and assigns it to the constant <code>client</code>. This client is partly how you will interact with the Discord API and how Discord will notify you of events such as new messages. The client, in effect, represents the Discord bot. The object passed into the <code>Client</code> constructor specifies the gateway intents of your bot. This defines which WebSocket events your bot will listen to. Here you have specified <code>GUILDS</code> and <code>GUILD_MESSAGES</code> to enable the bot to receive message events in guilds.</p>
<p>The second line of code uses the <code>login</code> method on the <code>client</code> to log in to the Discord bot you created, using the token in the <code>config.json</code> file as a password. The token lets the Discord API know which bot the program is for and that you’re authenticated to use the bot.</p>
<p>Now, execute the <code>index.js</code> file using Node:</p>
<p><code>node index.js</code></p>
<p>Your bot’s status will change to online in the Discord server you added it to.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664410960403/mAWwFikcT.png" alt="image.png" class="image--center mx-auto" /></p>
<p>You’ve successfully set up a coding environment and created the basic code for logging in to a Discord bot. In the next step, you’ll handle user commands and get your bot to perform actions, such as sending messages.</p>
<h1 id="heading-step-3-handling-your-first-user-command">Step 3 — Handling Your First User Command</h1>
<p>In this step, you will create a bot that can handle user commands. You will implement your first command <code>ping</code>, which will respond with <code>"pong"</code> and the time taken to respond to the command.</p>
<p>First, you need to detect and receive any messages users send so you can process any commands. Using the <code>on</code> method on the Discord client, Discord will send you a notification about new events. The <code>on</code> method takes two arguments: the name of an event to wait for and a function to run every time that event occurs. With this method you can wait for the event <code>message</code>—this will occur every time a message is sent to a guild where the bot has permission to view messages. Therefore you will create a function that runs every time a message is sent to process commands.</p>
<p>First, open your <code>index.js</code>.</p>
<p>Add the following code to your file:</p>
<pre><code class="lang-js">client.on(<span class="hljs-string">"messageCreate"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">message</span>) </span>{ 

});
</code></pre>
<p>This function, which runs on the <code>messageCreate</code> event, takes <code>message</code> as a parameter. message will have the value of a <a href="https://discord.js.org/#/docs/main/stable/class/Message">Discord.js message</a> instance, which contains information about the sent message and methods to help the bot respond.</p>
<p>Now add the following line of code to your command-handling function:</p>
<pre><code class="lang-js">client.on(<span class="hljs-string">"messageCreate"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">message</span>) </span>{
  <span class="hljs-keyword">if</span> (message.author.bot) <span class="hljs-keyword">return</span>;
});
</code></pre>
<p>This line checks if the author of the message is a bot, and if so, stops processing the command. This is important as generally you don’t want to process, or respond to, bots’ messages. Bots usually don’t need to use information from other bots, so ignoring their messages saves processing power and helps prevent accidental replies.</p>
<p>Now you’ll write a command handler. To accomplish this, it’s good to understand the usual format of a Discord command. Typically, the structure of a Discord command contains three parts in the following order: a prefix, a command name, and (sometimes) command arguments.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664411152017/8NEqRzMWl.png" alt="image.png" class="image--center mx-auto" /></p>
<ul>
<li>Prefix: the prefix can be anything, but is typically a piece of punctuation or abstract phrase that wouldn’t normally be at the start of a message. This means that when you include the prefix at the start of the message, the bot will know that the intention for this command is for a bot to process it.</li>
<li>Command name: The name of the command the user wants to use. This means the bot can support multiple commands with different functionality and allow users to choose between them by supplying a different command name.</li>
<li><p>Arguments: Sometimes if the command requires or uses extra information from the user, the user can supply arguments after the command name, with each argument separated by a space.</p>
</li>
<li><p>Note: There is no enforced command structure and bots can process commands how they like, but the structure presented here is an efficient structure that the vast majority of bots use.*</p>
</li>
</ul>
<p>To begin creating a command parser that handles this format, add the following lines of code to the message handling function:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> prefix = <span class="hljs-string">"!"</span>;

client.on(<span class="hljs-string">"messageCreate"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">message</span>) </span>{
  <span class="hljs-keyword">if</span> (message.author.bot) <span class="hljs-keyword">return</span>;
  <span class="hljs-keyword">if</span> (!message.content.startsWith(prefix)) <span class="hljs-keyword">return</span>;
});
</code></pre>
<p>You add the first line of code to assign the value <code>"!"</code>to the constant <code>prefix</code>, which you will use as the bot’s prefix.</p>
<p>The second line of code you add checks if the content of the message the bot is processing begins with the prefix you set, and if it doesn’t, stops the message from continuing to process.</p>
<p>Now you must convert the rest of the message into a command name and any arguments that may exist in the message. Add the following highlighted lines:</p>
<pre><code class="lang-js">client.on(<span class="hljs-string">"messageCreate"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">message</span>) </span>{
  <span class="hljs-keyword">if</span> (message.author.bot) <span class="hljs-keyword">return</span>;
  <span class="hljs-keyword">if</span> (!message.content.startsWith(prefix)) <span class="hljs-keyword">return</span>;

  <span class="hljs-keyword">const</span> commandBody = message.content.slice(prefix.length);
  <span class="hljs-keyword">const</span> args = commandBody.split(<span class="hljs-string">' '</span>);
  <span class="hljs-keyword">const</span> command = args.shift().toLowerCase();
});
</code></pre>
<p>You use the first line here to remove the prefix from the message content and assign the result to the constant <code>commandBody</code>. This is necessary as you don’t want to include the prefix in the parsed command name.</p>
<p>The second line takes the message with the removed prefix and uses the <code>split</code> method on it, with a space as the separator. This splits it into an array of sub-strings, making a split wherever there is a space. This results in an array containing the command name, then, if included in the message, any arguments. You assign this array to the constant <code>args</code>.</p>
<p>The third line removes the first element from the <code>args</code> array (which will be the command name provided), converts it to lowercase, and then assigns it to the constant <code>command</code>. This allows you to isolate the command name and leave only arguments in the array. You also use the method <code>toLowerCase</code> as commands are typically case insensitive in Discord bots.</p>
<p>You’ve completed building a command parser, implementing a required prefix, and getting the command name and any arguments from messages. You will now implement and create the code for the specific commands.</p>
<p>Add the following code to start implementing the ping command:</p>
<pre><code class="lang-js">  <span class="hljs-keyword">const</span> args = commandBody.split(<span class="hljs-string">' '</span>);
  <span class="hljs-keyword">const</span> command = args.shift().toLowerCase();

  <span class="hljs-keyword">if</span> (command === <span class="hljs-string">"ping"</span>) {

  }                        
});
</code></pre>
<p>This if statement checks if the command name you parsed (assigned to the <code>constant</code> command) matches <code>"ping"</code>. If it does, that indicates the user wants to use the "ping" command. You will nest the code for the specific command inside the <code>if</code> statement block. You will repeat this pattern for other commands you want to implement.</p>
<p>Now, you can implement the code for the <code>"ping"</code>command:</p>
<pre><code class="lang-js">  <span class="hljs-keyword">if</span> (command === <span class="hljs-string">"ping"</span>) {
    <span class="hljs-keyword">const</span> timeTaken = <span class="hljs-built_in">Date</span>.now() - message.createdTimestamp;
    message.reply(<span class="hljs-string">`Pong! This message had a latency of <span class="hljs-subst">${timeTaken}</span>ms.`</span>);
  }
</code></pre>
<p>Save and exit your file.</p>
<p>You add the <code>"ping"</code> command block that calculates the difference between the current time—found using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now">now method</a> on the <code>Date</code> object—and the timestamp when the message was created in milliseconds. This calculates how long the message took to process and the <code>"ping"</code> of the bot.</p>
<p>The second line responds to the user’s command using the <code>reply</code> method on the message constant. The <a href="https://discord.js.org/#/docs/main/stable/class/Message?scrollTo=reply">reply method</a> pings (which notifies the user and highlights the message for the specified user) the user who invoked the command, followed by the content provided as the first argument to the method. You provide a template literal containing a message and the calculated ping as the response that the <code>reply</code> method will use.</p>
<p>This concludes implementing the <code>"ping"</code> command.</p>
<p>Run your bot using the following command (in the same folder as index.js):</p>
<p><code>node index.js</code></p>
<p>You can now use the command <code>"!ping"</code> in any channel the bot can view and message in, resulting in a response.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664411583114/7PpmUDhZN.png" alt="image.png" class="image--center mx-auto" /></p>
<p>You have successfully created a bot that can handle user commands and you have implemented your first command. In the next step, you will continue developing your bot by implementing a sum command.</p>
<h1 id="heading-step-4-implementing-the-sum-command">Step 4 — Implementing the Sum Command</h1>
<p>Now you will extend your program by implementing the <code>"!sum"</code> command. The command will take any number of arguments and add them together, before returning the sum of all the arguments to the user.</p>
<p>If your Discord bot is still running, you can stop its process with <code>CTRL + C</code>.</p>
<p>Open your index.js file again.</p>
<p>To begin implementing the <code>"!sum"</code> command you will use an <code>else-if</code> block. After checking for the ping command name, it will check if the command name is equal to <code>"sum"</code>. You will use an <code>else-if</code> block since only one command will process at a time, so if the program matches the command name <code>"ping"</code>, it doesn’t have to check for the <code>"sum"</code> command. Add the following highlighted lines to your file:</p>
<pre><code class="lang-js">  <span class="hljs-keyword">if</span> (command === <span class="hljs-string">"ping"</span>) {
    <span class="hljs-keyword">const</span> timeTaken = <span class="hljs-built_in">Date</span>.now() - message.createdTimestamp;
    message.reply(<span class="hljs-string">`Ping! This message had a latency of <span class="hljs-subst">${timeTaken}</span>ms.`</span>);
  }

  <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (command === <span class="hljs-string">"sum"</span>) {

  }                            
});
</code></pre>
<p>You can begin implementing the code for the <code>"sum"</code> command. The code for the <code>"sum"</code> command will go inside the <code>else-if</code> block you just created. Now, add the following code:</p>
<pre><code class="lang-js">  <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (command === <span class="hljs-string">"sum"</span>) {
    <span class="hljs-keyword">const</span> numArgs = args.map(<span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> <span class="hljs-built_in">parseFloat</span>(x));
    <span class="hljs-keyword">const</span> sum = numArgs.reduce(<span class="hljs-function">(<span class="hljs-params">counter, x</span>) =&gt;</span> counter += x);
    message.reply(<span class="hljs-string">`The sum of all the arguments you provided is <span class="hljs-subst">${sum}</span>!`</span>);
  }
</code></pre>
<p>You use the map method on the arguments list to create a new list by using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseFloat">parseFloat</a> function on each item in the <code>args</code> array. This creates a new array (assigned to the constant <code>numArgs</code>) in which all of the items are numbers instead of strings. This means later you can successfully find the sum of the numbers by adding them together.</p>
<p>The second line uses the reduce method on the constant <code>numArgs</code> providing a function that totals all the elements in the list. You assign the sum of all the elements in <code>numArgs</code> to the constant <code>sum</code>.</p>
<p>You then use the <code>reply</code> method on the message object to reply to the user’s command with a template literal, which contains the sum of all the arguments the user sends to the bot.</p>
<p>This concludes implementing the <code>"sum"</code> command. Now run the bot using the following command (in the same folder as <code>index.js</code>):</p>
<p><code>node index.js</code></p>
<p>You can now use the <code>"!sum"</code> command in any channel the bot can view and message in.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1664411817737/7QM7Uz91M.png" alt="image.png" class="image--center mx-auto" /></p>
<p>The following is a completed version of the <code>index.js</code> bot script:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Discord = <span class="hljs-built_in">require</span>(<span class="hljs-string">"discord.js"</span>);
<span class="hljs-keyword">const</span> config = <span class="hljs-built_in">require</span>(<span class="hljs-string">"./config.json"</span>);

<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> Discord.Client({<span class="hljs-attr">intents</span>: [<span class="hljs-string">"GUILDS"</span>, <span class="hljs-string">"GUILD_MESSAGES"</span>]});

<span class="hljs-keyword">const</span> prefix = <span class="hljs-string">"!"</span>;

client.on(<span class="hljs-string">"messageCreate"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">message</span>) </span>{
  <span class="hljs-keyword">if</span> (message.author.bot) <span class="hljs-keyword">return</span>;
  <span class="hljs-keyword">if</span> (!message.content.startsWith(prefix)) <span class="hljs-keyword">return</span>;

  <span class="hljs-keyword">const</span> commandBody = message.content.slice(prefix.length);
  <span class="hljs-keyword">const</span> args = commandBody.split(<span class="hljs-string">' '</span>);
  <span class="hljs-keyword">const</span> command = args.shift().toLowerCase();

  <span class="hljs-keyword">if</span> (command === <span class="hljs-string">"ping"</span>) {
    <span class="hljs-keyword">const</span> timeTaken = <span class="hljs-built_in">Date</span>.now() - message.createdTimestamp;
    message.reply(<span class="hljs-string">`Pong! This message had a latency of <span class="hljs-subst">${timeTaken}</span>ms.`</span>);
  }

  <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (command === <span class="hljs-string">"sum"</span>) {
    <span class="hljs-keyword">const</span> numArgs = args.map(<span class="hljs-function"><span class="hljs-params">x</span> =&gt;</span> <span class="hljs-built_in">parseFloat</span>(x));
    <span class="hljs-keyword">const</span> sum = numArgs.reduce(<span class="hljs-function">(<span class="hljs-params">counter, x</span>) =&gt;</span> counter += x);
    message.reply(<span class="hljs-string">`The sum of all the arguments you provided is <span class="hljs-subst">${sum}</span>!`</span>);
  }
});

client.login(config.BOT_TOKEN);
</code></pre>
<p>In this step, you have further developed your Discord bot by implementing the <code>sum</code>command.</p>
<p>You have successfully implemented a Discord bot that can handle multiple, different user commands and command arguments. If you want to expand on your bot, you could possibly implement more commands or try out more parts of the Discord API to craft a powerful Discord bot. You can review the <a href="https://discord.js.org/#/docs/main/stable/general/welcome">Discord.js documentation</a> or the <a href="https://discord.com/developers/docs/intro">Discord API documentation</a> to expand your knowledge of the Discord API. In particular, you could convert your bot commands to <a href="https://discordjs.guide/interactions/registering-slash-commands.html#guild-commands">slash commands</a>, which is a best practice for Discord.js v13.</p>
<p>Hope you all enjoyed this article and were able to make your very own Discord bot! If you have any doubts or questions, make sure to write them in the comments below. Also, please add a reaction to this article and rate it out of 10. I appreciate it 🙏</p>
<p>Don’t forget to join my Discord server!</p>
<p>#Have a Great Day! Thank you! Happy Coding! 💻⚡</p>
]]></content:encoded></item><item><title><![CDATA[Let's Create a Markdown Blog Powered by Next.js in Under an Hour]]></title><description><![CDATA[I’m pretty sure 99% of the developers out there just love markdown. It’s such a fantastic format to write in.
For those not familiar with markdown, it’s a flat text format that looks like this:
# Heading

Some text

- list item 1
- list item 2
- list...]]></description><link>https://blog.ishaangarg.com/lets-create-a-markdown-blog</link><guid isPermaLink="true">https://blog.ishaangarg.com/lets-create-a-markdown-blog</guid><category><![CDATA[Next.js]]></category><category><![CDATA[markdown]]></category><category><![CDATA[Blogging]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Tutorial]]></category><dc:creator><![CDATA[Ishaan Garg]]></dc:creator><pubDate>Sun, 04 Sep 2022 23:05:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1662332467480/u2RTpXtjt.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I’m pretty sure 99% of the developers out there just love markdown. It’s such a fantastic format to write in.</p>
<p>For those not familiar with markdown, it’s a flat text format that looks like this:</p>
<pre><code class="lang-md"><span class="hljs-section"># Heading</span>

Some text

<span class="hljs-bullet">-</span> list item 1
<span class="hljs-bullet">-</span> list item 2
<span class="hljs-bullet">-</span> list item 3

[<span class="hljs-string">My website</span>](<span class="hljs-link">https://ishaantek.com</span>)
</code></pre>
<p>This would result in the following HTML:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"Heading_0"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>Heading<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Some text<span class="hljs-tag">&lt;/<span class="hljs-name">p</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">li</span>&gt;</span>list item 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>list item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>list item 3<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">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://ishaantek.com"</span>&gt;</span>My website<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</code></pre>
<p>Sounds lovely, right? And yes, it is lovely, so how cool would it be if we could make a blog in Next.js that allows us to write markdown formatted posts?</p>
<p>If you are wondering what the result is for this article, here is a little demo video:</p>
<p><img src="https://blog.openreplay.com/e1cc2f782465335eaa502ce1562d9de3/img1.gif" alt="image.png" class="image--center mx-auto" /></p>
<h2 id="heading-project-setup">Project Setup</h2>
<p>If you are new to markdown or Next.js, don’t worry. This article will guide you completely through setting this project up from start to finish!</p>
<p>Let’s start by creating a new blank Next.js project. We’ll open up our favorite terminal and run the following command.</p>
<pre><code>npx <span class="hljs-keyword">create</span>-<span class="hljs-keyword">next</span>-app <span class="hljs-keyword">next</span>-blog
</code></pre><p>This command will create a blank next application in the next-blog folder.</p>
<p>Once it’s done installing, you can navigate to the project and run it. (This will show the basic Next.js starter)</p>
<pre><code>cd <span class="hljs-keyword">next</span>-blog

<span class="hljs-comment"># Run the project</span>
npm run dev
</code></pre><h2 id="heading-adding-tailwind-css-for-our-styling">Adding Tailwind CSS for our styling</h2>
<p>Tailwind CSS is a perfect CSS framework to make styling super easy for us, and it works super well in a Next.js project.</p>
<p>The first step we have to do is, install the dependencies that are required for Tailwind.</p>
<pre><code><span class="hljs-built_in">npm</span> install -D tailwindcss@latest postcss@latest autoprefixer@latest
</code></pre><p>Then we can initialize Tailwind by running the following command. It will create all the side files we need.</p>
<pre><code>npx tailwindcss <span class="hljs-keyword">init</span> -p
</code></pre><p>Now head over to the tailwind.config.js file that the command above created for us. Modify the content: array to look like this:</p>
<pre><code class="lang-js">content: [
    <span class="hljs-string">'./pages/**/*.{js,ts,jsx,tsx}'</span>,
    <span class="hljs-string">'./components/**/*.{js,ts,jsx,tsx}'</span>,
],
</code></pre>
<p>The last step to making everything work is modifying the existing styles/global.scss file. Remove everything in this file and only add the following three lines.</p>
<pre><code class="lang-js">@<span class="hljs-keyword">import</span> <span class="hljs-string">'tailwindcss/base'</span>;
@<span class="hljs-keyword">import</span> <span class="hljs-string">'tailwindcss/components'</span>;
@<span class="hljs-keyword">import</span> <span class="hljs-string">'tailwindcss/utilities'</span>;
</code></pre>
<p>And that’s it. We can now leverage the power of Tailwind in our application.</p>
<h2 id="heading-creating-a-reusable-nextjs-layout">Creating a Reusable Next.js Layout</h2>
<p>Next.js supports different pages out of the box, but we want to have one main layout that wraps around this.</p>
<p>We will define a header and footer in this layout, which means we don’t need to add them in all the separate files.</p>
<p>To create a layout in Next.js, create a components folder in your project.</p>
<p>Inside that folder, create a layout.js file.</p>
<p>The layout is a component, which looks like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> Link <span class="hljs-keyword">from</span> <span class="hljs-string">'next/link'</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">Layout</span>(<span class="hljs-params">{ children }</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">'flex flex-col min-h-screen'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'bg-fuchsia-100 mb-8 py-4'</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container mx-auto flex justify-center'</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>🏡<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">span</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'mx-auto'</span>&gt;</span>Welcome to my blog<span class="hljs-tag">&lt;/<span class="hljs-name">span</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">header</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">main</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container mx-auto flex-1'</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">footer</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'bg-fuchsia-100 mt-8 py-4'</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container mx-auto flex justify-center'</span>&gt;</span>
          <span class="hljs-symbol">&amp;copy;</span> 2022 IshaanTek
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>For this article, I decided not to extract any further, but you could go ahead and move the header and footer into their components for better readability.</p>
<p>The critical part here is that we accept children as property and render them in the main element.</p>
<p>This allows us to render any component inside there.</p>
<p>We have to open up our _app.js file to use this newly created layout. This file is the entry point for your entire application.</p>
<p>By default, you will see it renders a Component with specific properties.</p>
<p>We want to wrap that component in our layout.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> Layout <span class="hljs-keyword">from</span> <span class="hljs-string">'../components/layout'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'../styles/globals.css'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyApp</span>(<span class="hljs-params">{ Component, pageProps }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Layout</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Component</span> {<span class="hljs-attr">...pageProps</span>} /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Layout</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> MyApp;
</code></pre>
<p>And that’s it. Any page we create now will be wrapped in our layout component, making it show the header and footer.</p>
<p>Let’s try this quickly before moving on.</p>
<p>Modify the index.js file and add the following markup for now:</p>
<pre><code class="lang-js"><span class="hljs-keyword">return</span> (<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Hello world 👋<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>);
</code></pre>
<p>When you rerun the application you should see the following:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662263684579/gny6z8LKv.png" alt="image.png" class="image--center mx-auto" /></p>
<p>You see, the header and footer are automatically applied. We didn’t need to say they should be used in any way.</p>
<h2 id="heading-creating-the-posts">Creating The Posts</h2>
<p>Since we’ll be using markdown for our posts, create a new folder at the root of your project called <em>posts</em>.</p>
<p>Inside, you can start by creating your post items. Each file will also become the URL of the article, so keep this in mind.</p>
<p>One example of my articles looks like this: <em>nextjs-page-options-and-how-they-work.md</em></p>
<p>Then inside the file, you have two sections.</p>
<p>The top part, called <em>frontmatter</em>, it’s a way to add non-rendered elements to your post.</p>
<p>They are divided by three dashes. And below that is all the content that you want.</p>
<p>For example:</p>
<pre><code class="lang-md">---
title: 'Next.js page options and how they work'
metaTitle: 'Next.js page options and how they work'
metaDesc: 'How to use pages in Next.js exploring the options'
socialImage: images/22-09-2021.jpg
date: '2021-09-22'
tags:
<span class="hljs-section">  - nextjs
---</span>

<span class="hljs-section"># The main content</span>
</code></pre>
<p>You can add anything you want in the frontmatter, so you don’t have to use this example specifically.</p>
<p>We’ll only be using the following for this article:</p>
<ul>
<li>title</li>
<li>socialImage</li>
</ul>
<p>It’s up to you to enhance the website with other cool elements.</p>
<p><strong><em>Note: Add the images in the public/images directory.</em></strong></p>
<p>Create a couple of markdown posts (or use the ones from the demo). This makes it easier to test what we are building.</p>
<h2 id="heading-loading-the-markdown-posts-on-the-homepage">Loading the Markdown Posts on the Homepage</h2>
<p>Now that we have our markdown posts in place, we want to retrieve them and show them on the homepage.</p>
<p>We want to show the image and the title and link to the actual post.</p>
<p>Since the image and title are defined in the markdown file’s frontmatter section, we need to find a way to extract them.</p>
<p>Luckily for us, there is a fantastic <a target="_blank" href="https://www.npmjs.com/package/gray-matter">NPM package</a> that can help us with this. Let’s install it.</p>
<pre><code class="lang-js">npm install gray-matter
</code></pre>
<p>This package allows us to parse the frontmatter section and the content section from a content string.</p>
<p>Then we want to open up our index.js file and start importing the packages we will need.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> fs <span class="hljs-keyword">from</span> <span class="hljs-string">'fs'</span>;
<span class="hljs-keyword">import</span> matter <span class="hljs-keyword">from</span> <span class="hljs-string">'gray-matter'</span>;
<span class="hljs-keyword">import</span> Image <span class="hljs-keyword">from</span> <span class="hljs-string">'next/image'</span>;
<span class="hljs-keyword">import</span> Link <span class="hljs-keyword">from</span> <span class="hljs-string">'next/link'</span>;
</code></pre>
<p>Then we need to leverage the Next.js <em>getStaticProps</em> method, which allows us to define variables the page can use on build time.</p>
<p>Note: Check out this article for more information on the <a target="_blank" href="https://daily-dev-tips.com/posts/nextjs-page-options-and-how-they-work/">rendering modes of Next.js</a></p>
<p>The main frame for this function looks like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getStaticProps</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Get all our posts</span>
}
</code></pre>
<p>We need to work on retrieving all the posts from our posts folder.</p>
<p>We can leverage the fs (filesystem) module.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> files = fs.readdirSync(<span class="hljs-string">'posts'</span>);
</code></pre>
<p>Then we want to loop over all those posts to extract the frontmatter part to get the title and image.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> posts = files.map(<span class="hljs-function">(<span class="hljs-params">fileName</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> slug = fileName.replace(<span class="hljs-string">'.md'</span>, <span class="hljs-string">''</span>);
    <span class="hljs-keyword">const</span> readFile = fs.readFileSync(<span class="hljs-string">`posts/<span class="hljs-subst">${fileName}</span>`</span>, <span class="hljs-string">'utf-8'</span>);
    <span class="hljs-keyword">const</span> { <span class="hljs-attr">data</span>: frontmatter } = matter(readFile);

    <span class="hljs-keyword">return</span> {
      slug,
      frontmatter,
    };
});
</code></pre>
<p>There is quite a lot going on here, so let’s look step by step.</p>
<p>First, we define the slug (URL) for the page, which is the filename without the .md part.</p>
<p>Then we read the file by using the fs module again. And once it’s loaded, we use the matter package to read the file and extract the data object, but we destructure it as the variable frontmatter.</p>
<p>Basically, we change the data variable to <em>frontmatter</em>.</p>
<p>The last thing we need to do is return the props that our component will receive.</p>
<pre><code class="lang-js"><span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      posts,
    },
};
</code></pre>
<p>This sends the posts variable to our component.</p>
<p>So let’s modify our Home component to receive this variable.</p>
<pre><code class="lang-js"><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">{ posts }</span>) </span>{
</code></pre>
<p>That’s it! Yes, super simple, right? We now have access to the posts inside the component.</p>
<p>Let’s create a grid and render our posts there.</p>
<pre><code class="lang-js"><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">{ posts }</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">'grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 p-4 md:p-0'</span>&gt;</span>
      {posts.map(({ slug, frontmatter }) =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>
          <span class="hljs-attr">key</span>=<span class="hljs-string">{slug}</span>
          <span class="hljs-attr">className</span>=<span class="hljs-string">'border border-gray-200 m-2 rounded-xl shadow-lg overflow-hidden flex flex-col'</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>`/<span class="hljs-attr">post</span>/${<span class="hljs-attr">slug</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">Image</span>
                <span class="hljs-attr">width</span>=<span class="hljs-string">{650}</span>
                <span class="hljs-attr">height</span>=<span class="hljs-string">{340}</span>
                <span class="hljs-attr">alt</span>=<span class="hljs-string">{frontmatter.title}</span>
                <span class="hljs-attr">src</span>=<span class="hljs-string">{</span>`/${<span class="hljs-attr">frontmatter.socialImage</span>}`}
              /&gt;</span>
              <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'p-4'</span>&gt;</span>{frontmatter.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</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 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>The CSS part is rendering a grid, where we show one post on mobile and up to four for big screens.</p>
<p>Then we loop over each of the posts using the map method.</p>
<p>Each post will be one big link, including the image of the posts and the title. And on click, it links to /post/{slug}, which we’ll start working on next.</p>
<p>Let’s quickly look at and admire what we have made so far:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662264056335/VMxl2awan.png" alt="image.png" class="image--center mx-auto" /></p>
<h2 id="heading-creating-individual-markdown-posts-in-nextjs">Creating Individual Markdown posts in Next.js</h2>
<p>Now that we have a list of our posts on the homepage, we want to show more details and the actual content on each page.</p>
<p>We can leverage Next.js dynamic routing, allowing one file to render all our posts!</p>
<p>To create this file, create a post directory inside the pages directory and inside this folder, add a file called [slug].js.</p>
<p>The brackets define the file as a dynamic file.</p>
<p>This file will also use the <em>getStaticProps</em> to retrieve the data for a single post.</p>
<p>But it needs another function called <em>getStaticPaths</em> to create each path (URL).</p>
<p>Let’s start by importing the modules we need.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> fs <span class="hljs-keyword">from</span> <span class="hljs-string">'fs'</span>;
<span class="hljs-keyword">import</span> matter <span class="hljs-keyword">from</span> <span class="hljs-string">'gray-matter'</span>;
</code></pre>
<p>And from here, we can work on the getStaticPaths function to ensure all our files get their URL.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getStaticPaths</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Retrieve all our slugs</span>
}
</code></pre>
<p>Again, the first thing we need to do is get all our posts.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> files = fs.readdirSync(<span class="hljs-string">'posts'</span>);
</code></pre>
<p>And you guessed it right, map the filenames to get the slugs.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> paths = files.map(<span class="hljs-function">(<span class="hljs-params">fileName</span>) =&gt;</span> ({
    <span class="hljs-attr">params</span>: {
      <span class="hljs-attr">slug</span>: fileName.replace(<span class="hljs-string">'.md'</span>, <span class="hljs-string">''</span>),
    },
}));
</code></pre>
<p>Then the critical part here is this function should return all valid paths, so we simply need to return them.</p>
<p>I also included a <em>fallback: false</em>, which ensures non-existing URLs will fail and show a 404.</p>
<pre><code class="lang-js"><span class="hljs-keyword">return</span> {
    paths,
    <span class="hljs-attr">fallback</span>: <span class="hljs-literal">false</span>,
};
</code></pre>
<p>The static part is much like what we did on the homepage. But for this one, we also want to retrieve the data from the file. This is because the file contains all our actual content.</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getStaticProps</span>(<span class="hljs-params">{ params: { slug } }</span>) </span>{
  <span class="hljs-keyword">const</span> fileName = fs.readFileSync(<span class="hljs-string">`posts/<span class="hljs-subst">${slug}</span>.md`</span>, <span class="hljs-string">'utf-8'</span>);
  <span class="hljs-keyword">const</span> { <span class="hljs-attr">data</span>: frontmatter, content } = matter(fileName);
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      frontmatter,
      content,
    },
  };
}
</code></pre>
<p>Before we start working on the component for this page, we want to install another NPM package called <em>markdown-it</em>. This package can convert markdown into HTML.</p>
<pre><code class="lang-js">npm install markdown-it
</code></pre>
<p>Then load it on this page:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> md <span class="hljs-keyword">from</span> <span class="hljs-string">'markdown-it'</span>;
</code></pre>
<p>Now we can start working on the actual component, which is super simple as it only renders the title and the content.</p>
<pre><code class="lang-js"><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">PostPage</span>(<span class="hljs-params">{ frontmatter, content }</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">'prose mx-auto'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>{frontmatter.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">dangerouslySetInnerHTML</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">__html:</span> <span class="hljs-attr">md</span>()<span class="hljs-attr">.render</span>(<span class="hljs-attr">content</span>) }} /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>As you can see, we need to use <em>dangerouslySetInnerHTML</em> as we are setting HTML. Don’t be scared by the name, as it’s only HTML we allow to be in there.</p>
<p>Almost there!</p>
<p>Let’s quickly try it out and see what we got. Run your app and open a page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662264246259/H8N6q0ngQ.png" alt="image.png" class="image--center mx-auto" /></p>
<p>Cool, all our data is there, but it doesn’t look great yet.</p>
<p>Luckily we decided to use Tailwind CSS, and they have a fantastic plugin: <a target="_blank" href="https://daily-dev-tips.com/posts/make-your-life-easy-with-the-tailwind-typography-plugin/">Typography plugin</a></p>
<p>Let’s install this plugin and see what happens.</p>
<pre><code class="lang-js">npm install -D @tailwindcss/typography
</code></pre>
<p>Open the tailwind.config.js file and add it under the plugins section.</p>
<pre><code class="lang-js">plugins: [<span class="hljs-built_in">require</span>(<span class="hljs-string">'@tailwindcss/typography'</span>)],
</code></pre>
<p>Now reload your app and see what happens.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1662264310638/GQfuaXqRG.png" alt="image.png" class="image--center mx-auto" /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>And that’s it. We now have a super cool markdown-powered Next.js blog!</p>
<p>This is only a basic starter, but enough to get your blogging career started.</p>
<p>Not bad for an hour worth of work!</p>
<p>Not it’s up to you to make this blog even more unique and share with the world what you created.</p>
<p>Some ideas to make it more excellent:</p>
<ul>
<li>SEO aspect, add meta titles/description</li>
<li>Add a tag overview</li>
<li>Add some coolers to the code blocks</li>
<li>Refactor elements into components
push </li>
</ul>
<p>Hope you all enjoyed this article and were able to make your very own blog powered by Next.js! If you have any doubts or questions, make sure to write them in the comments below. Also, please add a reaction to this article and rate it out of 10. I really appreciate it 🙏</p>
<p>Don’t forget to join my <a target="_blank" href="https://discord.gg/cMBSgG4Xd7">Discord server</a>!</p>
<p>#Have a Great Day! Thank you! Happy Coding! 💻⚡</p>
]]></content:encoded></item><item><title><![CDATA[How to Build a Chrome Extension with Vanilla JavaScript from Scratch]]></title><description><![CDATA[Hello, I'm Ishaan, A 13-year-old passionate Full Stack Web Developer. Today, I'm going to show you guys how to build a local Chrome extension from scratch. The extension helps to copy any webpage's URL so you can save for fast access. 
This blog post...]]></description><link>https://blog.ishaangarg.com/how-to-build-a-chrome-extension</link><guid isPermaLink="true">https://blog.ishaangarg.com/how-to-build-a-chrome-extension</guid><category><![CDATA[Google]]></category><category><![CDATA[Google Chrome]]></category><category><![CDATA[chrome extension]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[HTML5]]></category><dc:creator><![CDATA[Ishaan Garg]]></dc:creator><pubDate>Mon, 08 Aug 2022 21:30:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1659994185551/94JMXG_AL.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello, I'm Ishaan, A 13-year-old passionate Full Stack Web Developer. Today, I'm going to show you guys how to build a local Chrome extension from scratch. The extension helps to copy any webpage's URL so you can save for fast access. </p>
<p>This blog post will teach you how to build a local Chrome extension for personal use from scratch. The extension helps to copy any webpage's URL so you can save for fast access. You can also use it as a bookmark to jot things down for quick usage elsewhere.</p>
<p>We have all done something similar, copying links of pages and saving them in Notepad. There's nothing bad in that really, that's even the usefulness of Notepad - to keep notes.</p>
<p>But as we save links in Notepad, it gets pretty messed up with all our old notes. This extension will make saving URLs very easy.</p>
<p>Let's begin.</p>
<h1 id="heading-prerequisite">Prerequisite</h1>
<p>Basic knowledge of these is required:</p>
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
<p>We will call this project Savelinks, because it is a Chrome extension for saving links. The links will be saved in our browser's local storage.</p>
<h1 id="heading-building">Building</h1>
<p><strong>Step 1 - Project set up</strong><br />
Create a folder named Savelinks. Inside it, create index.html, style.css, and script.js files.</p>
<p><strong>Step 2 - HTML code</strong><br />
Input this code in your index.html</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</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">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"style.css"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Savelinks Extension<span class="hljs-tag">&lt;/<span class="hljs-name">title</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">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"input-el"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"input-btn"</span>&gt;</span>SAVE LINK<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"save-btn"</span>&gt;</span>SAVE TAB<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"delete-btn"</span>&gt;</span>DELETE ALL<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"ul-el"</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">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>We have linked our CSS file and created an input tag to create new links to save. We have also created three buttons for saving inputs, saving tab, and deleting all saved links respectively. We also have an empty <code>&lt;ul&gt;</code> element. We will use JavaScript to put all our saved links in this <code>&lt;ul&gt;</code> element.</p>
<p><strong>Step 3 - CSS code</strong><br />
Input this code in your style.css</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;
    <span class="hljs-attribute">font-family</span>: Arial, Helvetica, sans-serif;
    <span class="hljs-attribute">min-width</span>: <span class="hljs-number">400px</span>;
}

<span class="hljs-selector-tag">input</span> {
    <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;
    <span class="hljs-attribute">box-sizing</span>: border-box;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#5f9341</span>;
    <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">4px</span>;
}
</code></pre>
<p>The CSS code above will set the styles for the extension body, we have also styled the input box. It has a width of 100%, 10px padding, and a border.</p>
<p>Add the next lines of CSS code.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">button</span> {
    <span class="hljs-attribute">background</span>: <span class="hljs-number">#5f9341</span>;
    <span class="hljs-attribute">color</span>: white;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span> <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#5f9341</span>;
    <span class="hljs-attribute">font-weight</span>: bold;
}

<span class="hljs-selector-id">#delete-btn</span> {
    <span class="hljs-attribute">background</span>: white;
    <span class="hljs-attribute">color</span>: <span class="hljs-number">#5f9341</span>;
}
</code></pre>
<p>This will style all our 3 buttons while the delete button will have a background color of white with a different text color (hex code = #5f9341).</p>
<p>Add the next lines of CSS code.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">ul</span> {
    <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">20px</span>;
    <span class="hljs-attribute">list-style</span>: none;
    <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">0</span>;
}

<span class="hljs-selector-tag">li</span> {
    <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">5px</span>;
}

<span class="hljs-selector-tag">a</span> {
    <span class="hljs-attribute">color</span>: <span class="hljs-number">#5f9341</span>;
}
</code></pre>
<p>This will style our list by giving it margins, the displayed links by JavaScript will have a color with hex code = #5f9341.</p>
<p><strong>Step 4 - JavaScript code</strong><br />
Now let's add some JavaScript code.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> savedLinks = []
<span class="hljs-keyword">const</span> inputEl = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"input-el"</span>)
<span class="hljs-keyword">const</span> inputBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"input-btn"</span>)
<span class="hljs-keyword">const</span> deleteBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"delete-btn"</span>)
<span class="hljs-keyword">const</span> saveBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"tab-btn"</span>)
<span class="hljs-keyword">const</span> ulEl = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"ul-el"</span>)
<span class="hljs-keyword">const</span> linksFromLocalStorage = <span class="hljs-built_in">JSON</span>.parse( <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">"savedLinks"</span>) )
</code></pre>
<p>We have created an empty array called savedLinks and created a variable to hold the input and buttons elements, we are also getting savedLinks items from local storage, parsing them into JSON format, and saving it into a variable. We haven't initialized local storage yet, just saving the command in a variable called linksFromLocalStorage.</p>
<p>Let's add more JavaScript code.</p>
<pre><code class="lang-js"><span class="hljs-keyword">if</span> (linksFromLocalStorage) {
    savedLinks = linksFromLocalStorage
    render(savedLinks)
}
</code></pre>
<p>If linksFromLocalStorage exist, that is if we have savedLinks in local storage, render function will be called to display the links. Note that we have also passed savedLinks as an arguments in the render function.</p>
<p>Let's move on, add this code too.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">render</span>(<span class="hljs-params">links</span>) </span>{
    <span class="hljs-keyword">let</span> listItem = <span class="hljs-string">""</span>

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; links.length; i++) {
            listItem += <span class="hljs-string">`
                &lt;li&gt;
                    &lt;a target='_blank' href='<span class="hljs-subst">${links[i]}</span>'&gt;
                        <span class="hljs-subst">${links[i]}</span>
                    &lt;/a&gt;
                &lt;/li&gt;
            `</span>
    }
    ulEl.innerHTML = listItem
}
</code></pre>
<p>The function above is called render with a parameter called links. The function will take in an array as an argument. A variable called listItem is defined and has an empty string "" value for now. A <code>for loop</code> is defined, it will loop through the array passed in <code>let i = 0; i &lt; links.length; i++</code> and create a <code>&lt;li&gt;</code> list of each item and add each to listItem. Each <code>&lt;li&gt;</code>will contain the saved links and the <code>href</code> is also set to the link. The list of links in the listItem variable will be embedded inside the <code>&lt;ul&gt;</code> element with <code>ulEl.innerHTML = listItem</code>. This will render the list to our index.html.</p>
<p>Let's add some code.</p>
<pre><code class="lang-js">saveBtn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    chrome.tabs.query({<span class="hljs-attr">active</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">currentWindow</span>: <span class="hljs-literal">true</span>}, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">tabs</span>) </span>{
        savedLinks.push(tabs[<span class="hljs-number">0</span>].url)
        <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">"savedLinks"</span>, <span class="hljs-built_in">JSON</span>.stringify(savedLinks))
        render(savedLinks)
    })
})
</code></pre>
<p>The save button has an <code>addEventListener</code> method that takes in two parameters here, the type of the event to listen to ("click") and a callback function to call.</p>
<p>The function contains the <code>chrome.tabs</code> API that is only available when we are running the code in the context of the extension. The API allows us to interact with the browser's tab system and can be used to create, modify, and rearrange tabs in the browser.</p>
<p>We attached a <code>query()</code> method to the <code>tabs</code> object to verify the tab we are working on. The <code>query()</code> method takes in an object and a function as an argument. The object has two properties, <code>active</code> and <code>currentWindow</code>. <code>active</code> is set to true to specify that we are in the current tab and <code>currentWindow</code> is set to true to specify that we are in the current window.</p>
<p>The function takes a tabs parameter and navigates to the tab's URL with <code>tabs[0].url</code>. The tabs are an array that has the first item as an object that contains the URL of the current tab. The URL property is gotten with <code>tabs[0].url</code>.</p>
<p>Next is the delete button.</p>
<pre><code class="lang-js">deleteBtn.addEventListener(<span class="hljs-string">"dblclick"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">localStorage</span>.clear()
    savedLinks = []
    render(savedLinks)
})
</code></pre>
<p>On double click, the local storage that contains the saved links is cleared with <code>localStorage.clear()</code>, the <code>savedLinks</code> rendering to the page is set to null, <code>render(savedLinks)</code> is called to run which returns no list of links.</p>
<p>What if we want to put links manually?</p>
<p>Here's the code handling that.</p>
<pre><code class="lang-js">inputBtn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    savedLinks.push(inputEl.value)
    inputEl.value = <span class="hljs-string">""</span>
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">"savedLinks"</span>, <span class="hljs-built_in">JSON</span>.stringify(savedLinks))
    render(savedLinks)
})
</code></pre>
<p>The <code>savedLinks</code> array gets the input value pushed to it, then the input box is cleared with <code>inputEl.value = ""</code>. The <code>savedLinks</code> array re-saves to the local storage to include the input value. The <code>savedLinks</code> array is rendered into the browser with the <code>render</code> function.</p>
<p>Copy the full JavaScript code here:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> savedLinks = []
<span class="hljs-keyword">const</span> inputEl = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"input-el"</span>)
<span class="hljs-keyword">const</span> inputBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"input-btn"</span>)
<span class="hljs-keyword">const</span> deleteBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"delete-btn"</span>)
<span class="hljs-keyword">const</span> saveBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"tab-btn"</span>)
<span class="hljs-keyword">const</span> ulEl = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"ul-el"</span>)
<span class="hljs-keyword">const</span> linksFromLocalStorage = <span class="hljs-built_in">JSON</span>.parse( <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">"savedLinks"</span>) )

<span class="hljs-keyword">if</span> (linksFromLocalStorage) {
    savedLinks = linksFromLocalStorage
    render(savedLinks)
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">render</span>(<span class="hljs-params">links</span>) </span>{
    <span class="hljs-keyword">let</span> listItem = <span class="hljs-string">""</span>

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; links.length; i++) {
            listItem += <span class="hljs-string">`
                &lt;li&gt;
                    &lt;a target='_blank' href='<span class="hljs-subst">${links[i]}</span>'&gt;
                        <span class="hljs-subst">${links[i]}</span>
                    &lt;/a&gt;
                &lt;/li&gt;
            `</span>
            <span class="hljs-comment">// SAME</span>
            <span class="hljs-comment">// const li = document.createElement("li")</span>
            <span class="hljs-comment">// li.textContent = savedLinks[i]</span>
            <span class="hljs-comment">// ulEl.append(li)</span>
    }
    ulEl.innerHTML = listItem
}

saveBtn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    chrome.tabs.query({<span class="hljs-attr">active</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">currentWindow</span>: <span class="hljs-literal">true</span>}, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">tabs</span>) </span>{
        savedLinks.push(tabs[<span class="hljs-number">0</span>].url)
        <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">"savedLinks"</span>, <span class="hljs-built_in">JSON</span>.stringify(savedLinks))
        render(savedLinks)
    })
})

deleteBtn.addEventListener(<span class="hljs-string">"dblclick"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">localStorage</span>.clear()
    savedLinks = []
    render(savedLinks)
})

inputBtn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    savedLinks.push(inputEl.value)
    inputEl.value = <span class="hljs-string">""</span>
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">"savedLinks"</span>, <span class="hljs-built_in">JSON</span>.stringify(savedLinks))
    render(savedLinks)
})
</code></pre>
<p><strong>Step 5 - Setting the metadata</strong><br />
The metadata is the information sent to the Chrome browser about the extension. manifest.json file is used to configure the extension and provide metadata about it. The file is a .json file so it uses the object structure but with "" in the key-value pairs. The manifest_version, version, name, action, and action are in "" because we are using JSON. Read more about JavaScript JSON <a target="_blank" href="https://www.w3schools.com/js/js_json.asp">here</a>.</p>
<pre><code class="lang-js">{
    <span class="hljs-string">"manifest_version"</span>: <span class="hljs-number">3</span>,
    <span class="hljs-string">"version"</span>: <span class="hljs-string">"1.1"</span>,
    <span class="hljs-string">"name"</span>: <span class="hljs-string">"Savelinks"</span>,
    <span class="hljs-string">"action"</span>: {
        <span class="hljs-string">"default_popup"</span>: <span class="hljs-string">"index.html"</span>,
        <span class="hljs-string">"default_icon"</span>: <span class="hljs-string">"link.png"</span>
    },
    <span class="hljs-string">"permissions"</span>: [
        <span class="hljs-string">"tabs"</span>
    ]
}
</code></pre>
<p>manifest_version tells Chrome which version of JSON we are using, the version lets us set the version of our extension, the name provides the name of the extension, action provides objects in JSON format with two values, and the default_popup provides the home page of the index, it is set to the index.html while the default_icon sets the extension icon, there is an icon named link.png, it will display on our Chrome interface when we deploy the extension, the permissions arpermits ussion to access the URL so we have declared the "tabs" permission.</p>
<h1 id="heading-deployment">Deployment</h1>
<p>To deploy our extension, follow these steps:</p>
<ol>
<li><p>Click on the Chrome extension icon by the top right icon, your current extensions should pop up, click the Manage extension at the end of the list. The direct link is <a target="_blank">chrome://extentions</a></p>
</li>
<li><p>Trigger the developer mode at the top right corner</p>
</li>
<li><p>Navigate to load unpacked at the top right corner</p>
</li>
<li><p>It prompts you to choose your extension project, and choose the savelinks folder to deploy.</p>
</li>
<li><p>Open a new tab and in your extensions bar, pin Savelinks.</p>
</li>
<li><p>You can now start to use the new extension.</p>
</li>
</ol>
<p>If deployment is successful, the index.html page should pop up and the savelinks extension should work fine.</p>
<p>That will be all. Hope you found any value here as you learn to build more projects effectively.</p>
<p>Hope you all enjoyed this article and were able to make your very own Chrome extension! If you have any doubts or questions, make sure to write them in the comments below. Also, please add a reaction to this article and rate it out of 10. I appreciate it 🙏</p>
<p>Don’t forget to join my Discord server!</p>
<p>#Have a Great Day! Thank you! Happy Coding! 💻⚡</p>
]]></content:encoded></item><item><title><![CDATA[Let's build an emoji switcher like Discord in just 5 minutes]]></title><description><![CDATA[Hello there, I'm Ishaan, A 13-year-old passionate Full Stack Web Developer. Today, I'm going to make something super awesome and in-demand In Just 5 minutes.
You all may have noticed the emoji switcher effect on Discord. It is a super awesome idea an...]]></description><link>https://blog.ishaangarg.com/lets-make-an-emoji-switcher</link><guid isPermaLink="true">https://blog.ishaangarg.com/lets-make-an-emoji-switcher</guid><category><![CDATA[CSS]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[js]]></category><category><![CDATA[code]]></category><category><![CDATA[webdev]]></category><dc:creator><![CDATA[Ishaan Garg]]></dc:creator><pubDate>Sat, 30 Jul 2022 20:02:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1659209759010/PI3BHiq4K.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hello there, <strong>I'm Ishaan</strong>, A 13-year-old passionate Full Stack Web Developer. Today, I'm going to make something super awesome and in-demand In Just 5 minutes.</p>
<p>You all may have noticed the <strong>emoji switcher effect</strong> on <strong>Discord</strong>. It is a super awesome idea and provides a neat <strong>User Interface (UI)</strong> to the user with good <strong>micro-interaction</strong>.</p>
<p>Let's Build this <strong>emoji switcher</strong> using <strong>Vanilla Javascript</strong> in just <strong>5 minutes</strong>. So, let's get started ✌️🔥</p>
<h1 id="heading-lets-get-started">Let's get started</h1>
<p>Our project consists of a total of 3 files.</p>
<ol>
<li><strong>index.html</strong></li>
<li><strong>style.css</strong></li>
<li><strong>index.js</strong></li>
</ol>
<pre><code>root<span class="hljs-operator">/</span>
├── index.html
├── style.css
└── index.js
</code></pre><h1 id="heading-lets-start-coding">Let's start coding</h1>
<p>First of all, we can start with the HTML. The HTML is so simple, it just consists of a simple button with an emoji inside it. </p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</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">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"X-UA-Compatible"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"IE=edge"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Emoji Switcher like Discord 😎<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">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1"</span>&gt;</span>

     <span class="hljs-comment">&lt;!--Importing CSS --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"style.css"</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">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">'emoji-btn'</span>&gt;</span>😀<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>

    <span class="hljs-comment">&lt;!--Importing Javascript --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"index.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>Our next part is the CSS. The CSS is also very simple, we just have to align our emoji button to the center and give some basic styling to our app and make it look clean to the users. We also need to provide cool micro-interactions like hovering over the grayscale emoji and turning to the color emoji also scales a bit big.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span>{
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
  <span class="hljs-attribute">height</span>:<span class="hljs-number">100vh</span>;
  <span class="hljs-attribute">overflow</span>: hidden;
  <span class="hljs-attribute">width</span>:<span class="hljs-number">100%</span>;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#222</span>;
  <span class="hljs-attribute">align-items</span>: center;
  <span class="hljs-attribute">justify-content</span>: center;
}

<span class="hljs-selector-id">#emoji-btn</span> {
  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">3rem</span>;
  <span class="hljs-attribute">filter</span>: <span class="hljs-built_in">grayscale</span>(<span class="hljs-number">1</span>);
  <span class="hljs-attribute">transition</span>: .<span class="hljs-number">1s</span>;
  <span class="hljs-attribute">border</span>: none;
  <span class="hljs-attribute">cursor</span>: pointer;
}

<span class="hljs-selector-id">#emoji-btn</span><span class="hljs-selector-pseudo">:hover</span> {
  <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">scale</span>(<span class="hljs-number">1.23</span>);
  <span class="hljs-attribute">filter</span>: <span class="hljs-built_in">grayscale</span>(<span class="hljs-number">0</span>);
}
</code></pre>
<p>Now the HTML and CSS part of our app is completed. Let's move on to the last part, which is our index.js. The index.js controls the functionality of changing the emoji on every mouse hover.</p>
<pre><code class="lang-js"><span class="hljs-comment">// Get emojis from https://emojipedia.org/</span>

<span class="hljs-keyword">const</span> btn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"emoji-btn"</span>);
<span class="hljs-keyword">const</span> emojis = [ 
    <span class="hljs-string">"😆"</span>,  <span class="hljs-string">"😅"</span>,  <span class="hljs-string">"🤣"</span>,  <span class="hljs-string">"😂"</span>,  <span class="hljs-string">"😀"</span>,  <span class="hljs-string">"🤑"</span>,  <span class="hljs-string">"🤨"</span>,  <span class="hljs-string">"🙂"</span>,
    <span class="hljs-string">"😊"</span>,  <span class="hljs-string">"😗"</span>,  <span class="hljs-string">"😛"</span>,  <span class="hljs-string">"😏"</span>,  <span class="hljs-string">"🤥"</span>,  <span class="hljs-string">"😴"</span>,  <span class="hljs-string">"🥺"</span>, <span class="hljs-string">"😧"</span>,
    <span class="hljs-string">"🤗"</span>,  <span class="hljs-string">"🤩"</span>,  <span class="hljs-string">"😎"</span>,  <span class="hljs-string">"🥳"</span>,  <span class="hljs-string">"😍"</span>,  <span class="hljs-string">"😱"</span>,  <span class="hljs-string">"🤓"</span>, <span class="hljs-string">"😷"</span>,
    <span class="hljs-string">"🥴"</span>,  <span class="hljs-string">"😳"</span>,  <span class="hljs-string">"🤯"</span>,  <span class="hljs-string">"🤫"</span>,  <span class="hljs-string">"🤑"</span>,  <span class="hljs-string">"😪"</span>,  <span class="hljs-string">"😴"</span>, <span class="hljs-string">"😵"</span>
];

btn.addEventListener(<span class="hljs-string">"mouseover"</span>, <span class="hljs-function">() =&gt;</span> {
  btn.innerText = emojis[<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * emojis.length)];
});
</code></pre>
<p>Hurray, we have successfully finished our app! The app is looking great and has some really cool micro-interactions. </p>
<p>Here is the demo of the working app. ✌️😅</p>
<iframe height="300" style="width:100%" src="https://codepen.io/ishaantek/embed/YzaYWGW?default-tab=html%2Cresult&amp;theme-id=dark">
  See the Pen <a href="https://codepen.io/ishaantek/pen/YzaYWGW">
  Discord Emoji Switcher</a> by Ishaan Garg (<a href="https://codepen.io/ishaantek">@ishaantek</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>

<p>The full source code is on the CodePen, but try to code it on your own to boost up your skills. 🚀</p>
<p>Hope you all enjoyed this article and were able to make your very own emoji switcher! If you have any doubts or questions, make sure to write them in the comments below. Also, please add a reaction to this article and rate it out of 10. I really appreciate it 🙏</p>
<p>Don’t forget to join my <a target="_blank" href="https://discord.gg/cMBSgG4Xd7">Discord server</a>!</p>
<p>#Have a Great Day! Thank you! Happy Coding! 💻⚡</p>
]]></content:encoded></item></channel></rss>