<?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[Hemant's Engineering Blog]]></title><description><![CDATA[Explore in-depth articles on programming, development, and app building. Stay updated with the latest technologies, coding techniques, and best practices, all in one place.]]></description><link>https://blog.hemantsharma.tech</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 03:30:21 GMT</lastBuildDate><atom:link href="https://blog.hemantsharma.tech/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[What is Docker, Containers, Dockerfile, and Docker Images?]]></title><description><![CDATA[Docker
Docker is a containerization platform that allows developers to break-free from the problems such as - “It works on my machine“ by letting them developing, running and shipping applications seamlessly by containing the applications/code/projec...]]></description><link>https://blog.hemantsharma.tech/what-is-docker-containers-dockerfile-and-docker-images</link><guid isPermaLink="true">https://blog.hemantsharma.tech/what-is-docker-containers-dockerfile-and-docker-images</guid><category><![CDATA[Docker]]></category><category><![CDATA[docker images]]></category><category><![CDATA[Dockerfile]]></category><category><![CDATA[containers]]></category><category><![CDATA[containerization]]></category><category><![CDATA[docker-engine]]></category><category><![CDATA[Developer]]></category><category><![CDATA[development]]></category><category><![CDATA[engineering]]></category><category><![CDATA[tools]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Hemant Sharma]]></dc:creator><pubDate>Thu, 27 Nov 2025 08:08:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764230320984/b14a48cc-c5a1-4f93-b325-503de9d6b008.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-docker">Docker</h1>
<p>Docker is a containerization platform that allows developers to break-free from the problems such as - “It works on my machine“ by letting them developing, running and shipping applications seamlessly by containing the applications/code/project into a container providing it all the resources it ever will to run smoothly and work as expected.</p>
<p>Before we dive into Docker and it’s related technologies we first need to understand the main underlying concept behind Docker. <strong>Containers</strong>. <strong>Containers are the technology that built up the open platform known as Docker</strong>. It’s like Google took the Linux kernel and made Android OS.</p>
<h1 id="heading-containers">Containers</h1>
<p>So, what are containers anyway?<br />Well, Containers in general are nothing but isolated, lightweight, and self-sufficient packaged units that includes an application's code, runtime, libraries, and configuration files.</p>
<p>If I have to summarize a gist of what Containers are actually are, I believe this is the best analogy that works for me and might work for you as well</p>
<blockquote>
<p>Containers are the “just-enough” file-system, environment, kernel or configurations that are required by your Software to run just how it is intended to run. If it needs a file-system to read local files for some reason, Containers include it the “just-enough” requirements.</p>
</blockquote>
<p>Containers indeed are a really really great piece of engineering that allows you to isolate your applications withing the environment they need to operate and perform at it’s fullest capabilities.</p>
<h1 id="heading-dockerfile">Dockerfile</h1>
<p>Now that we know well about what Containers are and how Docker provides you the ease of use while working with containerization technologies, let’s dive deeper into how you can weild this power that Docker has to provide you with.</p>
<p>Dockerfile, it is the spec-sheet of your container, you define all the requirements your application software requires in order to work just how it is intended to and perform at its best without any issues. In other terms, you can say that you want to build a PC and when you do it, you first want to decide upon all the specs you want in your PC like the processor, amount of memory and storage you would want out of your system, so Dockerfile is the file where you write it to Docker Engine all the requirements and setup you need in the container you would be putting your application in.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Dockerfile has no extensions and it is just written in the file - <code>Dockerfile</code></div>
</div>

<pre><code class="lang-dockerfile"><span class="hljs-keyword">FROM</span> node:<span class="hljs-number">22</span>-alpine AS base

<span class="hljs-keyword">FROM</span> base AS deps

<span class="hljs-keyword">WORKDIR</span><span class="bash"> /app</span>

<span class="hljs-keyword">COPY</span><span class="bash"> package.json ./</span>
<span class="hljs-keyword">COPY</span><span class="bash"> index.js ./</span>

<span class="hljs-keyword">RUN</span><span class="bash"> npm i -g pnpm</span>
<span class="hljs-keyword">RUN</span><span class="bash"> pnpm install</span>

<span class="hljs-keyword">EXPOSE</span> <span class="hljs-number">3000</span>

<span class="hljs-keyword">CMD</span><span class="bash"> [<span class="hljs-string">"node"</span>, <span class="hljs-string">"index.js"</span>]</span>
</code></pre>
<h1 id="heading-docker-image">Docker Image</h1>
<p>Now that you have successfully defined all your requirements and needs in the container, you are now ready to move ahead an build an image for your container.</p>
<p>Docker Image is created after all the requirements &amp; configurations you have mentioned in the Dockerfile spec-sheet and build it using the command</p>
<pre><code class="lang-bash">docker build -t myapp .
</code></pre>
<p><code>-t</code> stands for tagname for the Docker Image that you are building so that you can easily refer it in the list of Docker Images you might have in your Docker Desktop application or OrbStack if you prefer that.</p>
<p>The command above tells Docker to create a new Docker Image of you spec-sheet. It’s like a confirmation and contract between you and Docker, that now this Image is the final spec-sheet of your requirements as mentioned in the Dockerfile, like how developers use Git, you first add your changes to the staging area for any modifications and from thereon it is pushed as a commit after one extra step, here as well, Dockerfile let’s you have a customised spec-sheet, but the Docker Image that is built upon the provided Dockerfile.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Docker Images are final contracts of Dockerfile, once a Docker Image is built, you cannot customize or change it at all, in order to customize it, you will have to make changes in the Dockerfile and <strong>rebuild </strong>a new Docker Image.</div>
</div>

<p>Docker Images are shareable, you can share them by pushing them to the Docker Hub and share it with anyone for them to pull it from there. The reason why Docker Images are untouchable are so that it keeps and maintains the integrity and safety of your software application or whatever you might want to contain in the container through the Docker Image. If you shared the Dockerfile directly, it is easily prone to changes and modifications which in turn would break the integrity and whole purpose of your application software, so this is a feature of Containerization technology that prevents any infringement of your application software.</p>
<p>Docker Images are later run to spin up a container adhering to the configurations, requirements and features that are requested in the Docker Container.</p>
<h1 id="heading-docker-container">Docker Container</h1>
<p>You can spin up containers using the Docker Images that we created in the last step, and it is very very easy and straight up to do. The command below is what helps your spin up a container adhering and following the Docker Image of your custom specs and requirements. You can refer to these docs if you want to <a target="_blank" href="https://docs.docker.com/reference/cli/docker/container/run/">know more about the run command</a>.</p>
<pre><code class="lang-bash">docker run -d myapp
</code></pre>
<p><code>-d</code> in the command stands for running the container in detached mode. Detached mode allows the container to run independently in the background not hindering your terminal where you run it from and only return you the container id of the container you just spun up.</p>
<p>If you have a server in your app, you need to map the host system’s port with the isolated container’s system’s port, meaning you need to map the port of your system to the port of the container running in isolation to make sure that you can access the server running inside the container on your system.</p>
<pre><code class="lang-bash">docker run -d -p 3000:3000 myapp

<span class="hljs-comment"># OR</span>

docker run -dp 3000:3000 myapp
</code></pre>
<p><code>-p</code> stands for port mapping in the said order <code>HOST_PORT:CONTAINER_PORT</code>, meaning, make the port <code>CONTAINER_PORT</code> running inside the container transmit all the data and everything it is working with to the <code>HOST_PORT</code> of the host’s system.</p>
<h1 id="heading-mindmap-visualizing-everything">Mindmap - Visualizing everything</h1>
<p>Let’s Visualize everything that we learnt so far. This is a simple and easy to understand diagram that I built.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764229932411/08afc72b-1018-4aec-93f6-2ae99c1cfafa.png" alt class="image--center mx-auto" /></p>
<p>Congratulations🎉 for making it till the end, I hope I was able to make you understand all the nitty-gritties of what Docker and Containerization technology is.</p>
<h3 id="heading-you-can-find-me-on"><strong>You can find me on</strong></h3>
<p>Twitter: <a target="_blank" href="https://hemantsharma.tech/x"><strong>hemantsharma.tech/x</strong>  
</a>LinkedIn: <a target="_blank" href="https://hemantsharma.tech/linkedin"><strong>hemantsharma.tech/linkedin</strong>  
</a>GitHub: <a target="_blank" href="https://hemantsharma.tech/github"><strong>hemantsharma.tech/github</strong>  
</a>Website: <a target="_blank" href="https://hemantsharma.tech"><strong>hemantsharma.tech</strong></a></p>
]]></content:encoded></item><item><title><![CDATA[Stop Breaking Your Forms: Type-Safe Server Actions in Next.js]]></title><description><![CDATA[💡
Full Working Code: GitHub Link


Problem: Inefficient Forms
I have been building forms in applications for years at this point and after building so many forms, I found out some real issues that always stand in place if you want to scale your appl...]]></description><link>https://blog.hemantsharma.tech/stop-breaking-your-forms-type-safe-server-actions-in-nextjs</link><guid isPermaLink="true">https://blog.hemantsharma.tech/stop-breaking-your-forms-type-safe-server-actions-in-nextjs</guid><category><![CDATA[Next.js]]></category><category><![CDATA[server actions]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[TypeScript Tutorial]]></category><category><![CDATA[TypeSafety]]></category><category><![CDATA[contract]]></category><category><![CDATA[forms]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[html forms]]></category><category><![CDATA[React]]></category><category><![CDATA[ReactHooks]]></category><category><![CDATA[React]]></category><category><![CDATA[Client-side rendering]]></category><category><![CDATA[Server side rendering]]></category><category><![CDATA[server]]></category><dc:creator><![CDATA[Hemant Sharma]]></dc:creator><pubDate>Sat, 11 Oct 2025 15:50:25 GMT</pubDate><content:encoded><![CDATA[<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Full Working Code: <a target="_self" href="https://github.com/hemants1703/blog-demos/tree/main/typesafe-nextjs-forms-and-server-actions">GitHub Link</a></div>
</div>

<h2 id="heading-problem-inefficient-forms">Problem: Inefficient Forms</h2>
<p>I have been building forms in applications for years at this point and after building so many forms, I found out some real issues that always stand in place if you want to scale your application because then you would need real strict conventions for your entire stack. When I was building one of my side projects, I was simply building the form just how the docs or any other blogpost suggested on the internet but sooner as my project grew in size, I found several difficulties maintaining the form and the engineer in me thought it wasn’t quite OK to be honest. The form gave me no confidence in pushing it to production as there were multiple return statements in places then too many if-else blocks in my client component it just created cognitive load and didn’t quite work well for complex forms handling multiple data types and different situations and that was when I decided I need to find a proper solution to this, I dug deeper over the internet and docs and questioning LLMs everywhere I found almost the same solution that I was already implementing that’s when I decided to think through forms myself and I came upon this really good solution myself.</p>
<h2 id="heading-solution-stateful-contracts">Solution: Stateful Contracts</h2>
<p>Let’s think of forms in the aspect of “<strong>States</strong>“ (like states of matter or even state in React if you would). States are an analogy we can apply on forms as well. Any form can have states, for e.g. a form with just 2 fields has a total of 3 states for it’s fields - none filled, 1 filled, all filled. So that means our forms can be in any state and in order to not flush out the input values from the user, we always try to maintain the input data. So in order to maintain the state of our forms we are going to be using the <strong>useActionState()</strong> hook from React.</p>
<p>Next up, Types!</p>
<p>Types are a really really great way of reducing runtime bugs or even catch bugs in comilation of your code before it hits production ensuring you have a really great developer experience and boosted confidence in your code in production, eventually reducing the 3 AM debuggings you had to do 😂</p>
<p>I have not seen much solutions where developers apply types to React hooks but for a matter of fact and saviour, these hooks do have Types support! I don’t understand why we don’t use types as often, it might increase development time a little bit, but at least after that you have a peace of mind about your code not breaking in production at least without any reason.</p>
<h2 id="heading-lets-see-the-solution-in-action">Let’s see the solution in Action!</h2>
<blockquote>
<p><strong><em>Complete code to copy/refer has been provided at the end of this explanation section</em></strong></p>
</blockquote>
<p>We will create a form where I expect the user to fill in <strong>Name</strong>, <strong>Email</strong>, <strong>Age</strong>. So we have data types of <strong>string</strong> and <strong>number</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760178706993/dde3e7b3-603b-4ef4-9a9d-b721104180db.png" alt class="image--center mx-auto" /></p>
<p>.</p>
<p>Since our forms are states and would be using <strong>useActionState</strong> hook consider extracting away the form from your server component since we will need to make the form a client component, we first create a <strong>TypeScript Interface</strong> that looks something like this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760178437599/900205cd-bb39-4cd5-b6be-1cbcb32effcb.png" alt class="image--center mx-auto" /></p>
<p>remember to <strong>export</strong> the interface since we are going to need it in our server actions as well since this is what is our <strong>Stateful Contract</strong> that will be communicated between the form and the server action.</p>
<p>After this we create a new file where we describe our server action and this is how thing look initially</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760178680632/0c7c155e-fe5a-40d4-ac5a-d99199a0684f.png" alt class="image--center mx-auto" /></p>
<p>Let’s begin by adding the <strong>useActionState</strong> hook for the form</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760178938303/9159cebb-194c-44fb-857f-43eb395f1409.png" alt class="image--center mx-auto" /></p>
<p>as of this, let’s ignore any warnings and errors since we are creating a fully typed form and server action contract this is what’s expected, the TypeScript compiler will definitely throw error at you that is what’s going to force you to write a really good and type-safe code.</p>
<p>I have udpated the server action to be inferring the same types, for the sake of this blog, I won’t be performing any network calls like submitting or anything since that is not our concern in this case</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760189088035/9dc95362-5283-40d8-977d-5ce0072bbc06.png" alt class="image--center mx-auto" /></p>
<p>Notice how I have wrapped the age in <strong>Number</strong> because I have inferred the return type as the contract interface that we defined initially which forced me to make that string value a number since that is what we expect to be.</p>
<p>Now I update the component and add types to my <strong>useActionState</strong> hook to ensure a proper contract between the form and the server action.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760189278138/d0f76831-8b18-49b8-8a61-b88c8173fc53.png" alt class="image--center mx-auto" /></p>
<p>Now that we have completed the solution to the problem, let’s handle the formState using useEffect or you can even handle it in your TSX if you want.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760189471808/9d48ce66-b387-497d-a842-634c29989e07.png" alt class="image--center mx-auto" /></p>
<p>This way we are going to ensure that we don’t exchange any data among the form and the server action that is not present in the interface that we created initially.</p>
<p>I also updated the Server Actions and added some basic validation</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760189616199/576802ac-cd0e-47eb-990c-624ec9d99630.png" alt class="image--center mx-auto" /></p>
<p>This practice of adding type to the <strong>useActionState</strong> hook and the <strong>Server Action</strong> return type, TypeScript forces us to make sure the exchanging the data is not hindering the contract and ensure seamless two-way data binding.</p>
<p><strong>Now if you want to add any new field in the form, you will be prompted through an error in both the places in Server Action and the React form that tells you to add it to the contract lowering your chances of breaking anything in production.</strong></p>
<h2 id="heading-final-code">Final Code</h2>
<h3 id="heading-pagetsx"><code>page.tsx</code></h3>
<pre><code class="lang-typescript"><span class="hljs-string">"use client"</span>;

<span class="hljs-keyword">import</span> { useActionState, useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { submitForm } <span class="hljs-keyword">from</span> <span class="hljs-string">"./action"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> FormState {
  name: <span class="hljs-built_in">string</span>;
  email: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;

  error?: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [formValues, setFormValues] = useState&lt;FormState&gt;({
    name: <span class="hljs-string">""</span>,
    email: <span class="hljs-string">""</span>,
    age: <span class="hljs-number">0</span>,
  });
  <span class="hljs-keyword">const</span> [formState, formAction, isFormPending] = useActionState&lt;FormState, FormData&gt;(submitForm, formValues);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (formState.error) {
      alert(formState.error);
    }
  }, [formState.error]);

  <span class="hljs-keyword">return</span> (
    &lt;form action={formAction} className=<span class="hljs-string">"flex flex-col gap-4 max-w-sm mx-auto py-10"</span>&gt;
      &lt;label htmlFor=<span class="hljs-string">"name"</span>&gt;Name&lt;/label&gt;
      &lt;input
        <span class="hljs-keyword">type</span>=<span class="hljs-string">"text"</span>
        name=<span class="hljs-string">"name"</span>
        id=<span class="hljs-string">"name"</span>
        value={formValues.name}
        onChange={<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> setFormValues({ ...formValues, name: e.target.value })}
      /&gt;
      &lt;label htmlFor=<span class="hljs-string">"email"</span>&gt;Email&lt;/label&gt;
      &lt;input
        <span class="hljs-keyword">type</span>=<span class="hljs-string">"email"</span>
        name=<span class="hljs-string">"email"</span>
        id=<span class="hljs-string">"email"</span>
        value={formValues.email}
        onChange={<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> setFormValues({ ...formValues, email: e.target.value })}
      /&gt;
      &lt;label htmlFor=<span class="hljs-string">"age"</span>&gt;Age&lt;/label&gt;
      &lt;input
        <span class="hljs-keyword">type</span>=<span class="hljs-string">"number"</span>
        name=<span class="hljs-string">"age"</span>
        id=<span class="hljs-string">"age"</span>
        value={formValues.age}
        onChange={<span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> setFormValues({ ...formValues, age: <span class="hljs-built_in">Number</span>(e.target.value) })}
      /&gt;

      &lt;button <span class="hljs-keyword">type</span>=<span class="hljs-string">"submit"</span>&gt;{isFormPending ? <span class="hljs-string">"Submitting..."</span> : <span class="hljs-string">"Submit"</span>}&lt;/button&gt;
    &lt;/form&gt;
  );
}
</code></pre>
<p><code>action.ts</code></p>
<pre><code class="lang-typescript"><span class="hljs-string">"use server"</span>;

<span class="hljs-keyword">import</span> { FormState } <span class="hljs-keyword">from</span> <span class="hljs-string">"./page"</span>;

<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">submitForm</span>(<span class="hljs-params">previousState: FormState, formData: FormData</span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">FormState</span>&gt; </span>{
  <span class="hljs-keyword">const</span> submittedFormValues = {
    name: formData.get(<span class="hljs-string">"name"</span>) <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>,
    email: formData.get(<span class="hljs-string">"email"</span>) <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>,
    age: <span class="hljs-built_in">Number</span>(formData.get(<span class="hljs-string">"age"</span>) <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>),
  };

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"submittedFormValues"</span>, submittedFormValues);

  <span class="hljs-keyword">if</span> (submittedFormValues.name === <span class="hljs-string">""</span>) {
    <span class="hljs-keyword">return</span> {
      ...previousState,
      error: <span class="hljs-string">"Name is required"</span>,
    };
  }

  <span class="hljs-keyword">if</span> (submittedFormValues.email === <span class="hljs-string">""</span>) {
    <span class="hljs-keyword">return</span> {
      ...previousState,
      error: <span class="hljs-string">"Email is required"</span>,
    };
  }

  <span class="hljs-keyword">if</span> (submittedFormValues.age === <span class="hljs-number">0</span> || submittedFormValues.age &lt; <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">return</span> {
      ...previousState,
      error: <span class="hljs-string">"Age is required and must be greater than 0"</span>,
    };
  }

  <span class="hljs-keyword">return</span> submittedFormValues;
}
</code></pre>
<p><strong>This way we can handle the errors and the data gracefully while still maintaing the Form State</strong></p>
]]></content:encoded></item><item><title><![CDATA[How to Send Emails Using a Third-Party Provider in Appwrite]]></title><description><![CDATA[When you are developing your application using Appwrite as your BaaS, you will have situations where you will be needing to send emails to your users. Appwrite has a feature called “Messaging“ for this situation where you can setup your mail server i...]]></description><link>https://blog.hemantsharma.tech/how-to-send-emails-using-a-third-party-provider-in-appwrite</link><guid isPermaLink="true">https://blog.hemantsharma.tech/how-to-send-emails-using-a-third-party-provider-in-appwrite</guid><category><![CDATA[Appwrite]]></category><category><![CDATA[zoho]]></category><category><![CDATA[Mail]]></category><category><![CDATA[messaging]]></category><category><![CDATA[message queue]]></category><category><![CDATA[baas]]></category><category><![CDATA[BaaS Integration]]></category><category><![CDATA[BaaS Solutions]]></category><category><![CDATA[backend]]></category><category><![CDATA[backend developments]]></category><category><![CDATA[Backend Development]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[frontend]]></category><category><![CDATA[Front-end Development]]></category><category><![CDATA[front-end]]></category><dc:creator><![CDATA[Hemant Sharma]]></dc:creator><pubDate>Wed, 05 Feb 2025 09:55:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738749560633/6a8740f8-226a-4ec9-b0b7-c2da295205be.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When you are developing your application using Appwrite as your BaaS, you will have situations where you will be needing to send emails to your users. Appwrite has a feature called “<strong>Messaging</strong>“ for this situation where you can setup your mail server into Appwrite as you mail provider and use it to send mails to your users.</p>
<p>Let’s understand how this works</p>
<h1 id="heading-follow-these-steps-to-get-to-the-feature">Follow these steps to get to the feature</h1>
<ol>
<li><p>Go to your Appwrite Admin Console <a target="_blank" href="https://cloud.appwrite.io/console">here</a> and go to your specific project you wish to use the messaging feature in</p>
</li>
<li><p>Go to your project and there you will find a sidebar with some options in it, it should look like this, and go to the option “<strong>Messaging</strong>“.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738746840176/282fd762-c2e1-4f05-b1be-dad96caf94ed.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now this is the <strong>Messaging</strong> section, here you will have all the settings and features to manage everything related to emails, push notifications and SMS to your users.</p>
</li>
</ol>
<p>There are a few terminologies which you will need to understand before we start.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738747105885/af2b6970-0f87-486e-a05d-9876b50501dd.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-messages">Messages</h3>
<p>Messages are the section that keep a log and history of all the messages sent to your users through Appwrite be it Emails, Push Notifications and SMS.</p>
<h3 id="heading-topics">Topics</h3>
<p>Topics are used to deliver messages to groups of users at once. Let’s say that you wish to target a specific group of users, let’s say the users using any paid plan of your app, only those users needs to receive the mail, here in topics you can manage it accordingly.</p>
<h3 id="heading-providers">Providers</h3>
<p>Providers are the mail servers that you are using to send emails, these providers such as Zoho, you will be setting up here and using here in Appwrite to allow Appwrite to send emails to your users.</p>
<h1 id="heading-setup-third-party-email-provider-in-appwrite">Setup Third-Party Email Provider in Appwrite</h1>
<p>In order to setup a third-party provider in Appwrite, we will have to go to the Providers tab and click on the <strong>Create Provider</strong> button as shown below and select the option <strong>Email</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738747535213/496a47d3-567a-45ec-8524-a7a6b870b350.png" alt class="image--center mx-auto" /></p>
<p>Then you will be taken to a new page, there you will have to setup your provider by providing the details, add a name to your provider details and select the option <strong>SMTP (Generic SMTP server)</strong> and click <strong>Next</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738747687312/733dc069-ac42-4e12-8ef2-e2a898775eba.png" alt class="image--center mx-auto" /></p>
<p>After this we will be taken to the next step into the settings section, here we will have to be setting up the rest of the required details of the mail hosting server. In my case, I am using Zoho Mail as my SMTP server, so I will be filling in the details accordingly, you can simply Google your mail provider details and fill it up here.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738747983964/ac7f8f37-8771-4ee6-b04f-3594657a6232.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738747988130/cd98efb7-3d72-4ebe-b261-373ce110d5e3.png" alt class="image--center mx-auto" /></p>
<p>You also need to fill up the <strong>Sender email and name</strong>, this will be the mail ID you wish to use to send the mails from your mail server and then click on the <strong>Create</strong> Button.</p>
<p>Now you will have a mail provider created for your Appwrite Messaging service and it should be looking like this in your console window</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738748179959/881dd3af-04e1-425b-b515-bcdd05775873.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-send-emails-from-the-third-party-email-provider-using-appwrite">Send Emails from the Third-Party Email Provider using Appwrite</h1>
<p>Now that we have setup our third-party email provider in Appwrite, we can use this to send emails to our users. Let move to the <strong>Messages</strong> tab in the console and create and send a new message to our user. Click on the <strong>Create message</strong> Button and select the <strong>Email</strong> option from there</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738748346603/d91d48be-f98a-4db5-ad0c-e81983bd97cb.png" alt class="image--center mx-auto" /></p>
<p>Here we can write out email, we can also send HTML based mails to our users for better UX and a great reach. Let’s user HTML mode to send our first test email.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738748493762/8331c5ff-88de-4302-bb55-5940bd8346be.png" alt class="image--center mx-auto" /></p>
<p>Click on <strong>Next</strong>, and in the next step, we have the option of selecting our targets. Targets are basically the users to whom you wish to send the email to using the option <strong>Select targets</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738748584351/5a6dad41-6549-4039-b09d-b9e080e60302.png" alt class="image--center mx-auto" /></p>
<p>so we simply select a user and click on <strong>Add</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738748668042/bcadd005-311c-4af0-97ad-e4d8bd521645.png" alt class="image--center mx-auto" /></p>
<p>and click on <strong>Next</strong>, in the next page we will be asked to select a schedule when to send the message, since this is a test email, we can simply send this email to our users immediately, do note that <strong>This action is irreversible.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738748778399/a2b4c912-4824-4ac9-999f-01250e9e3df8.png" alt class="image--center mx-auto" /></p>
<p>Your email will be scheduled into processing immediately by Appwrite servers. Since I sent this mail to my own email, we can see that I received the email exactly how I sent it!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738748864645/23a29aaa-eef5-4e09-a47a-0bcffe7c15ba.png" alt class="image--center mx-auto" /></p>
<p>Connect with me on <a target="_blank" href="https://twitter.com/intent/follow?screen_name=hemants1703"><strong>𝕏</strong></a><a target="_blank" href="https://twitter.com/intent/follow?screen_name=hemants1703">,</a> <a target="_blank" href="https://www.linkedin.com/comm/mynetwork/discovery-see-all?usecase=PEOPLE_FOLLOWS&amp;followMember=hemants1703"><strong>LinkedIn</strong></a><a target="_blank" href="https://www.linkedin.com/comm/mynetwork/discovery-see-all?usecase=PEOPLE_FOLLOWS&amp;followMember=hemants1703">, <strong>GitHub</strong></a> and <a target="_blank" href="http://hemantsharma.tech"><strong>hemantsharma.tech</strong></a></p>
<p><a target="_blank" href="https://hemantsharma.tech/"><strong><em>I</em></strong></a> <strong><em>h*</em></strong>ope you found this blog post helpful. Stay tuned for more posts!🙌*  </p>
<p><strong><em>Hope this blog was helpful to you, Please like the blog and write your valuable comment below, you can also ask any queries you have.</em></strong></p>
]]></content:encoded></item><item><title><![CDATA[Custom CSS variables in custom Tailwind Animations Config]]></title><description><![CDATA[How many times have you experienced the need to create custom animations in your project? I have experienced this many times. I have used Tailwind CSS for a long time, and I love it. But sometimes, I need to create custom animations that are not avai...]]></description><link>https://blog.hemantsharma.tech/custom-css-variables-in-custom-tailwind-animations-config</link><guid isPermaLink="true">https://blog.hemantsharma.tech/custom-css-variables-in-custom-tailwind-animations-config</guid><category><![CDATA[CSS]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Hemant Sharma]]></dc:creator><pubDate>Wed, 14 Aug 2024 05:55:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ieic5Tq8YMk/upload/1cf9b4d56ff0791e772661f0dc6ec275.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>How many times have you experienced the need to create custom animations in your project? <em>I have experienced this many times.</em> I have used Tailwind CSS for a long time, and I love it. But sometimes, I need to create custom animations that are not available in the default Tailwind CSS configurations and that too with custom dependable variables, like I want the animations to be updated based on the theme/setting of the website.</p>
<p>In this blog post, I will show you how you can create custom animations in Tailwind CSS using custom CSS variables and how you can update the animations based on the theme/setting of the website using custom CSS variables in the Tailwind CSS configuration.</p>
<h2 id="heading-custom-css-variables"><strong>Custom CSS variables</strong></h2>
<p>Custom CSS variables are a powerful feature in CSS that allows you to define your own variables and use them throughout your CSS. You can define custom CSS variables using the <code>--</code> prefix followed by the variable name. For example, to define a custom CSS variable for the primary color, you can use the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-pseudo">:root</span> {
  <span class="hljs-attribute">--variable-height</span>: <span class="hljs-number">100px</span>;
}
</code></pre>
<p>You can use the custom CSS variable in your CSS using the <code>var()</code> function. For example, to use the custom CSS variable for the primary color, you can use the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.element</span> {
  <span class="hljs-attribute">height</span>: <span class="hljs-built_in">var</span>(--variable-height);
}
</code></pre>
<h2 id="heading-custom-css-animations"><strong>Custom CSS Animations</strong></h2>
<p>To create custom animations in your CSS, you can use the <code>@keyframes</code> directive. For example, to create a custom animation that fades in an element, you can use the following code:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@keyframes</span> fadeIn {
  <span class="hljs-selector-tag">from</span> {
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0</span>;
  }
  <span class="hljs-selector-tag">to</span> {
    <span class="hljs-attribute">opacity</span>: <span class="hljs-number">1</span>;
  }
}
</code></pre>
<p>You can use the custom animation in your CSS using the <code>animation</code> property. For example, to apply the <code>fadeIn</code> animation to an element, you can use the following code:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.element</span> {
  <span class="hljs-attribute">animation</span>: fadeIn <span class="hljs-number">1s</span> ease-in-out;
}
</code></pre>
<h2 id="heading-custom-css-variables-in-tailwind-css-animations"><strong>Custom CSS variables in Tailwind CSS animations</strong></h2>
<p>To create custom animations in Tailwind CSS using custom CSS variables, you can define the custom CSS variables in the Tailwind CSS configuration file. For example, to define a custom CSS variable for the primary color, you can use the following code in your <code>tailwind.config.js</code> file:</p>
<pre><code class="lang-js"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">theme</span>: {
    <span class="hljs-attr">extend</span>: {
      <span class="hljs-attr">animation</span>: {
        <span class="hljs-attr">fadeIn</span>: <span class="hljs-string">`fadeIn 0.5s ease-in-out`</span>,
      },
      <span class="hljs-attr">keyframes</span>: {
        <span class="hljs-attr">fadeIn</span>: {
          <span class="hljs-attr">from</span>: {
            <span class="hljs-attr">opacity</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">transform</span>: <span class="hljs-string">"translateY(var(--variable-height))"</span>,
          },
          <span class="hljs-attr">to</span>: {
            <span class="hljs-attr">opacity</span>: <span class="hljs-number">1</span>,
            <span class="hljs-attr">transform</span>: <span class="hljs-string">"translateY(0)"</span>,
          },
        },
      },
    },
  },
};
</code></pre>
<p>This code defines a custom animation called <code>fadeIn</code> that fades in an element and moves it from the top of the screen to its final position. The animation duration is set to <code>0.5s</code>, and the easing function is set to <code>ease-in-out</code>.</p>
<p>Since our <code>tailwind.config.js</code> file is a using a custom CSS variable <code>--variable-height</code>, we can update the animation based on the theme/setting of the website by updating the value of the custom CSS variable anywhere within our project using simple JavaScript.</p>
<h2 id="heading-example"><strong>Example</strong></h2>
<p>Here is an example of how you can update the value of the custom CSS variable <code>--variable-height</code> based on the theme/setting of the website using JavaScript:</p>
<p>Suppose we have a button that toggles the height of a div element and we want another div element to animate based on the height of the first div element. We can use the following code to achieve this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> button = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".button"</span>);
<span class="hljs-keyword">const</span> div1 = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".div1"</span>);
<span class="hljs-keyword">const</span> div2 = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".div2"</span>);

button.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
  div1.style.height = div1.style.height === <span class="hljs-string">"100px"</span> ? <span class="hljs-string">"200px"</span> : <span class="hljs-string">"100px"</span>;
  div2.style.setProperty(<span class="hljs-string">"--variable-height"</span>, div1.style.height);
});
</code></pre>
<p>In this code, we are updating the value of the custom CSS variable <code>--variable-height</code> based on the height of the first div element whenever the button is clicked.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Custom CSS variables are a powerful feature in CSS that allows you to define your own variables and use them throughout your CSS. You can use custom CSS variables to create custom animations in Tailwind CSS and update the animations based on the theme/setting of the website.</p>
<p>Connect with me on <a target="_blank" href="https://twitter.com/intent/follow?screen_name=hemants1703">𝕏</a>, <a target="_blank" href="https://www.linkedin.com/comm/mynetwork/discovery-see-all?usecase=PEOPLE_FOLLOWS&amp;followMember=hemants1703">LinkedIn</a>, <a target="_blank" href="https://github.com/hemants1703">GitHub</a> and <a target="_blank" href="https://hemantsharma.tech">hemantsharma.tech</a></p>
<p><em>I hope you found this blog post helpful. Stay tuned for more posts!🙌</em></p>
]]></content:encoded></item><item><title><![CDATA[Access Windows File System in WSL Ubuntu]]></title><description><![CDATA[Introduction
As you might have been using WSL to harness the power of Linux within your Windows Operating System, it might be true that you might not be knowing how to access the windows file system (files basically) through WSL Ubuntu and it's also ...]]></description><link>https://blog.hemantsharma.tech/access-windows-file-system-in-wsl-ubuntu</link><guid isPermaLink="true">https://blog.hemantsharma.tech/access-windows-file-system-in-wsl-ubuntu</guid><category><![CDATA[WSL]]></category><category><![CDATA[wsl2]]></category><category><![CDATA[Windows]]></category><category><![CDATA[windows 11]]></category><category><![CDATA[Linux]]></category><category><![CDATA[unix]]></category><category><![CDATA[wsl ubuntu]]></category><dc:creator><![CDATA[Hemant Sharma]]></dc:creator><pubDate>Fri, 05 Jul 2024 12:55:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1720184002120/f9441fe1-2b56-410a-900c-c33b1339a015.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>As you might have been using WSL to harness the power of Linux within your Windows Operating System, it might be true that you might not be knowing how to access the windows file system (files basically) through WSL Ubuntu and it's also true that the regular CMD in Windows is not a really liked one by the developers or programmers and is actually not that great when compared to Unix so WSL is actually a savior for Windows users who cannot really switch to Linux due to some applications maybe not working on Linux and only support Windows. In this blog, I will be guiding you through how you can achieve the same.</p>
<p>So, let's begin...</p>
<h3 id="heading-follow-these-steps-to-gain-access-to-windows-file-system-using-wsl-ubuntu">Follow these steps to gain access to Windows File System using WSL Ubuntu</h3>
<ol>
<li><p>Open Windows Terminal, and open your WSL terminal</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720181123839/b35c2002-bae3-4c23-a2d9-3115fa1f774c.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now that your WSL terminal starts at this location <code>&lt;username&gt;@YourPC</code> you must be trying to check if the Windows File System is present in this directory or not using the <code>ls</code> command but must have been seeing an empty directory and might think how you should go from here as it is the root directory, but let me tell you one thing, you can actually go back from this location which you can checkout using the <code>ls -a</code> command and you will see that you can actually go back from this present working directory.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720181485758/60dc47bd-2ea0-4aef-8e9d-f079a0ca4fd4.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>After you go back from this location to two directories back, you will see that you have a directory present in the location that is the <code>/mnt</code> directory and that is what we need, that is the directory that you need to go in in order to access the Windows File System!</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720181719968/45356c29-11d3-44a2-8cb0-103893c94d66.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now, we enter the <code>/mnt</code> directory and we can see our Windows File System, we can here see all the drives that are present in our machine with the <strong>directory names are equivalent to your drive letters like the</strong> <code>Local Disk (C:)</code> <strong>will be the</strong> <code>/c</code> <strong>directory</strong>.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1720181931472/24b752b9-66db-462f-8576-8556a174b2c9.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p>So, here you have it! You can now access any of the required drives from your Windows File System through WSL Ubuntu and still use the Linux commands on Windows Files!</p>
<p>If you like my blog, please do like it!!!</p>
<p>You can connect with me on the following:</p>
<ul>
<li><p><a target="_blank" href="https://x.com/hemants1703">X</a></p>
</li>
<li><p><a target="_blank" href="https://hemantsharma.tech/linkedin">LinkedIn</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Emmet in ReactJS JavaScript JSX]]></title><description><![CDATA[Learn how you can enable using Emmet in ReactJS JavaScript.
Follow the mentioned steps

Open Visual Studio Code.

Open Settings using the following commands,

Mac: Command (⌘) + ,

Windows: Ctrl + ,



The settings page would look like this
 

Make s...]]></description><link>https://blog.hemantsharma.tech/emmet-in-reactjs-javascript-jsx</link><guid isPermaLink="true">https://blog.hemantsharma.tech/emmet-in-reactjs-javascript-jsx</guid><category><![CDATA[VS Code]]></category><category><![CDATA[Emmet]]></category><category><![CDATA[React]]></category><category><![CDATA[vscode extensions]]></category><category><![CDATA[vscode]]></category><dc:creator><![CDATA[Hemant Sharma]]></dc:creator><pubDate>Sat, 15 Jul 2023 15:30:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1689434553454/8fd24edc-0bd5-428d-9573-6991b8459681.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Learn how you can enable using Emmet in ReactJS JavaScript.</p>
<h2 id="heading-follow-the-mentioned-steps">Follow the mentioned steps</h2>
<ol>
<li><p>Open Visual Studio Code.</p>
</li>
<li><p>Open Settings using the following commands,</p>
<ol>
<li><p>Mac: <code>Command (⌘) + ,</code></p>
</li>
<li><p>Windows: <code>Ctrl + ,</code></p>
</li>
</ol>
</li>
<li><p>The settings page would look like this</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689433098416/fb8baa7c-0aef-42e8-bd9e-e7d1f0a7189c.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Make sure to head over to the <code>Workspace</code> tab,</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689433253816/289c9473-b7b5-43e8-9474-292b448cac88.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now search for the "Emmet" option by typing in the emmet in the search field,</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689433362705/bd4a08c8-af3c-481e-bb7f-656cb964abd2.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Now search for the section: "Emmet: Include Languages" as shown in the picture,</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689433590344/6449cc80-19c8-4d85-b0ba-0d8a8da37720.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>Here you can add a new item to tell emmet what are the areas you want it to work in, now click the <code>Add Item</code> button and type the following in and press the OK button</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689433776327/20053cb1-7ea4-491d-bf91-c93aecf4c05d.png" alt class="image--center mx-auto" /></p>
</li>
</ol>
<p>Congratulations 🎉 !!! Now you will be able to use emmet in JavaScript in React just like you do it in the HTML files.</p>
<h3 id="heading-connect-with-me">Connect with Me🔗👾</h3>
<p>Twitter: <a target="_blank" href="https://hemantsharma.tech/x">https://hemantsharma.tech/x</a><br />LinkedIn: <a target="_blank" href="https://hemantsharma.tech/linkedin">https://hemantsharma.tech/linkedin</a><br />GitHub: <a target="_blank" href="https://hemantsharma.tech/github">https://hemantsharma.tech/github</a><br />Website: <a target="_blank" href="https://hemantsharma.tech/">hemantsharma.tech</a></p>
]]></content:encoded></item><item><title><![CDATA[Get YouTube API and build projects👾]]></title><description><![CDATA[Do you want to get YouTube Data API? Well, you're at the right place, I'll let you know how you can get and YouTube API key so that you can use it however you wish...
Step 1: Make a Google Developer Account🧾
To get access to YouTube's API you'll fir...]]></description><link>https://blog.hemantsharma.tech/get-youtube-api-and-build-projects</link><guid isPermaLink="true">https://blog.hemantsharma.tech/get-youtube-api-and-build-projects</guid><category><![CDATA[youtube]]></category><category><![CDATA[youtube learning]]></category><category><![CDATA[api]]></category><category><![CDATA[APIs]]></category><category><![CDATA[API basics ]]></category><dc:creator><![CDATA[Hemant Sharma]]></dc:creator><pubDate>Mon, 12 Jun 2023 04:50:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1686502612176/b942d17f-c948-41ff-817c-cf750d13f569.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Do you want to get YouTube Data API? Well, you're at the right place, I'll let you know how you can get and YouTube API key so that you can use it however you wish...</p>
<h3 id="heading-step-1-make-a-google-developer-account">Step 1: Make a Google Developer Account🧾</h3>
<p>To get access to YouTube's API you'll first need to make a Google Developer Account which is as easy as logging in to your Google Account, you can easily build one <a target="_blank" href="https://developers.google.com">from here</a>.</p>
<h3 id="heading-step-2-log-in-to-google-developer-console">Step 2: Log In to Google Developer Console🎮</h3>
<p>Go to this link console.cloud.google.com, then log in with your Developer Account that you have just created.</p>
<p>Now that you're logged in to your Google Developer Console, you will see this screen after logging in.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686542859210/2bcf0e11-ee70-4300-bcc1-f313b79ce04d.png" alt class="image--center mx-auto" /></p>
<p>After you log in, click on this button</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686542980885/da8cb6cb-9852-4915-a0c6-3952c6127e2d.png" alt class="image--center mx-auto" /></p>
<p>After you click on that button, you'll have a dialog box open up like this,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686543099198/8f7c5fa0-c726-44a8-aa07-1a5559153c26.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-3-create-a-new-project">Step 3: Create a new project🆕</h3>
<p>On the dialogue box opened above, click on the "New Project" button and you will be taken to this page for the registration and creation of the new project,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686543270936/e58c77b2-d164-41c2-951b-35a681ad7213.png" alt class="image--center mx-auto" /></p>
<p>Create the project and once you are into your new project, head over to the navbar and select the API &amp; Services section, here you will see every detail regarding your project's API scenario, on that page you will see this button "Enable APIs and Services" click on it,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686543472567/c4c09958-1f52-44f0-b28e-2b05f8adb62f.png" alt class="image--center mx-auto" /></p>
<p>You will be taken to a new page, scroll down to find this option,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686543598741/a6d71c5d-0e5c-43b1-9deb-f9ce852ccfe2.png" alt class="image--center mx-auto" /></p>
<p>Select "YouTube Data API v3".</p>
<h3 id="heading-step-4-get-your-api-key">Step 4: Get your API key🔑</h3>
<p>On selecting the option for "YouTube Data API v3", you will see an option of enabling the API, enable it.</p>
<p>After you enable it, you'll see this page,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686543762547/8c134a22-bcb2-4aad-b98d-4990b160c94f.png" alt class="image--center mx-auto" /></p>
<p>On this page, select the option "Create Credentials", on selecting the option, you'll see this page,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686543946774/3884472f-f50a-44a0-9c1e-163fe0bb7828.png" alt class="image--center mx-auto" /></p>
<p>Select the API and select the option "Public data" and click on Next, then you will be taken to the next step. <strong><mark>Congratulations, you just got your new YouTube API.🎉</mark></strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686544162302/c3db5078-3a6c-4c42-a8b8-10bb42f4843f.png" alt class="image--center mx-auto" /></p>
<p>Now you should copy and keep your API safely and use it however you wish to, now that you have learned how to generate an API Google Developer Console, you can also manage and tinker with the details of the API on the console.</p>
<h3 id="heading-step-5-read-the-docs-optional">Step 5: Read the docs (Optional)</h3>
<p>If you wish to use the API to its fullest potential, read the docs for YouTube Data API v3 <a target="_blank" href="https://developers.google.com/youtube/v3/getting-started">here</a>.</p>
<p><strong><em>Happy Coding!👨‍💻</em></strong></p>
]]></content:encoded></item><item><title><![CDATA[Use Intel architecture terminal shell on Apple Silicon Macs💻]]></title><description><![CDATA[To use the Intel-based terminal on an Apple Silicon Mac, we need Rosetta, to install using the command given below to install Rosetta on your Mac:
Install Rosetta
softwareupdate --install-rosetta

Now, that Rosetta is installed on your Mac, you can e...]]></description><link>https://blog.hemantsharma.tech/use-intel-architecture-terminal-shell-on-apple-silicon-macs</link><guid isPermaLink="true">https://blog.hemantsharma.tech/use-intel-architecture-terminal-shell-on-apple-silicon-macs</guid><category><![CDATA[Apple]]></category><category><![CDATA[Intel]]></category><category><![CDATA[terminal]]></category><category><![CDATA[Bash]]></category><category><![CDATA[M1 Mac]]></category><dc:creator><![CDATA[Hemant Sharma]]></dc:creator><pubDate>Wed, 01 Feb 2023 11:03:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ehyV_XOZ4iA/upload/8c156e237add2b94b29f4ac3773b834f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>To use the Intel-based terminal on an Apple Silicon Mac, we need Rosetta, to install using the command given below to install Rosetta on your Mac:</p>
<h3 id="heading-install-rosetta">Install Rosetta</h3>
<pre><code class="lang-bash">softwareupdate --install-rosetta
</code></pre>
<p>Now, that Rosetta is installed on your Mac, you can execute any command on your Mac terminal through the Intel architecture using the prefix <code>arch -x86_64</code>. To check out which architecture you're currently using type the following command on your terminal</p>
<pre><code class="lang-bash">arch
</code></pre>
<p>After typing the above command your terminal might have returned the value <code>arm64</code> which means that you are currently using Apple Silicon-based terminal as such.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675248363054/2a038cdb-a53b-484a-b101-12a8ce668dae.png" alt class="image--center mx-auto" /></p>
<p>Now, If you wish to use the Intel architecture only once you can use the <code>arch -x86_64</code> followed by the command you wish to execute for example</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675248615370/bcbde79d-1d0d-4e7c-9ec9-9f2a8c2f28f8.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-use-the-intel-architecture-terminal">Use the Intel architecture terminal</h3>
<p>Now, If you wish to completely use the terminal on Intel architecture without needing to type the prefix <code>arch -x86_64</code> all the time for every command, we can simply log in to the Intel terminal through the command:</p>
<pre><code class="lang-bash">arch -x86_64 <span class="hljs-variable">$SHELL</span> --login
</code></pre>
<p>To confirm whether you are successfully logged in to the Intel architecture terminal, you just need to type the <code>arch</code> command again and if it returns <code>i386</code> then congratulations you've successfully made your Apple Silicon Mac run the Intel architecture terminal🎉</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675248875017/c82ee4d4-7b60-4e7d-8c95-985180df6579.png" alt class="image--center mx-auto" /></p>
<p>A like is appreciated if this blog helped you with your required topic :)</p>
]]></content:encoded></item></channel></rss>