<?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[Gaurab Wagle]]></title><description><![CDATA[Gaurab Wagle]]></description><link>https://blog.gaurabwagle.com.np</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Apr 2026 12:06:57 GMT</lastBuildDate><atom:link href="https://blog.gaurabwagle.com.np/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I Had SSH Access But No Internet. Port forwarding 80 into server, cuts off the internet in server]]></title><description><![CDATA[Before, Let's learn how to forward ports from your router to server and server to your websites
MikroTik Router's login page:
Go to : IP > Firewall > NAT


Things to remember while doing port forwardi]]></description><link>https://blog.gaurabwagle.com.np/how-i-had-ssh-access-but-no-internet-port-forwarding-80-into-server-cuts-off-the-internet-in-server</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/how-i-had-ssh-access-but-no-internet-port-forwarding-80-into-server-cuts-off-the-internet-in-server</guid><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Sat, 14 Mar 2026 02:25:12 GMT</pubDate><content:encoded><![CDATA[<h3>Before, Let's learn how to forward ports from your router to server and server to your websites</h3>
<p>MikroTik Router's login page:</p>
<p>Go to : IP &gt; Firewall &gt; NAT</p>
<img src="https://cdn.hashnode.com/uploads/covers/65cf0b043f77edd06a52edca/ecf643d7-e84c-4cd2-886d-f64d63914f40.png" alt="" style="display:block;margin:0 auto" />

<h3>Things to remember while doing port forwarding:</h3>
<ol>
<li><h3>We need to write the rules for Firewall and NAT ( Network Address Transalation)</h3>
</li>
<li><h3>NAT: is the rule we write for actual port forwarding. Listen to port 'x' in router and pass it to port 'y' in server.</h3>
</li>
<li><h3>Firewall rule should be written to tell our router to allow all traffic on this port which we just opened.</h3>
</li>
</ol>
<h3>NAT rule, that forwards port 80 to 80:</h3>
<img src="https://cdn.hashnode.com/uploads/covers/65cf0b043f77edd06a52edca/1d88e205-fc53-4b64-9601-72a99b18e079.png" alt="" style="display:block;margin:0 auto" />

<img src="https://cdn.hashnode.com/uploads/covers/65cf0b043f77edd06a52edca/ac2eebf1-baec-4c22-a401-f50288948dda.png" alt="" style="display:block;margin:0 auto" />

<p>In General tab ( the first image), write the port your router wants to open,<br />In Action tab ( second image), write the port you want to forward to server.</p>
<h3>Since I was using tailscale to ssh the server ,</h3>
<h2>Problem: When I port forward 80-80, there was no internet access to the internet.</h2>
<p>When you install Tailscale, it tries to be helpful by managing your network settings. It does this by taking over your server’s <strong>DNS (Domain Name System)</strong>.</p>
<p>If you look at your <code>/etc/resolv.conf</code> file, you’ll see it has been hijacked:</p>
<pre><code class="language-python">
~$ cat /etc/resolv.conf
# resolv.conf(5) file generated by tailscale
# For more info, see https://tailscale.com/s/resolvconf-overwrite
# DO NOT EDIT THIS FILE BY HAND -- CHANGES WILL BE OVERWRITTEN
nameserver 100.100.100.100
search tail259a0b.ts.net
</code></pre>
<p><strong>The Conflict:</strong> Tailscale points your server to <code>100.100.100.100</code>—its internal "MagicDNS" resolver. This is great for finding other machines on your private network (like <code>my-laptop.ts.net</code>), but if your Tailscale admin settings aren't configured with a "Global Nameserver," your server suddenly forgets how to find the real internet.</p>
<h3>The Solution:</h3>
<p>To fix this, you need to give your server a "phonebook" it can actually read. We want to keep Tailscale for our SSH access but stop it from blocking the rest of the internet.</p>
<p><strong>Step 1: Tell Tailscale to Back Off</strong> First, run this command to tell Tailscale to stop forcing its own DNS settings on the system:</p>
<div>
<div>💡</div>
<div>tailscale up --accept-dns=false</div>
</div>

<p><strong>Step 2: Manually Set Global Nameservers</strong> Now, we edit the DNS configuration file. Open it with: <code>sudo nano /etc/resolv.conf</code></p>
<p>Delete the internal Tailscale IP or move it to the bottom. Add the world-standard Google and Cloudflare DNS IPs at the very top:</p>
<pre><code class="language-javascript">//new config
nameserver 8.8.8.8
nameserver 1.1.1.1
nameserver 100.100.100.100
search tail259a0b.ts.net
</code></pre>
<p><strong>Step 3: Test the Connection</strong> Now, try to reach the outside world again: <code>ping google.com</code></p>
<p>If you see bytes flying back, you’ve won. Your server can now see your private network via Tailscale <strong>and</strong> fetch your code from GitHub at the same time.</p>
]]></content:encoded></item><item><title><![CDATA[Understanding: OS, UNIX, Kernel, Shell and Terminal and make your terminal attractive ]]></title><description><![CDATA[This is a compilation of best resources and lil summary of them: Highly recommend you to check out those resources
Some of my regrets from bachelors:1. Read “Theory of Computation” (TOC) and Compiler ]]></description><link>https://blog.gaurabwagle.com.np/understanding-os-unix-kernel-shell-and-terminal-and-make-your-terminal-attractive</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/understanding-os-unix-kernel-shell-and-terminal-and-make-your-terminal-attractive</guid><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Sat, 07 Mar 2026 07:35:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/65cf0b043f77edd06a52edca/143c032d-e853-480b-9a92-f177d8f004a1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><mark class="bg-yellow-200 dark:bg-yellow-500/30">This is a compilation of best resources and lil summary of them: Highly recommend you to check out those resources</mark></p>
<p>Some of my regrets from bachelors:<br />1. Read “Theory of Computation” (TOC) and Compiler just to pass the exam.<br />2. Not understanding “Comp Architecture” fully.</p>
<p><em>Anyways</em>,</p>
<p>The more I read and learn about computers, more I become thankful. We are the luckiest generation because a older people have already figured out things like electricity, computers, softwares, graphics blabla… fundamentals are already figured out.</p>
<p>But it raises a question, what’s our purpose? well i don’t know either..<br />Maybe all the inventions that made the current reality possible where, I am laying on my bed with my laptop and writing this blog. Maybe, we are making small progresses in the field of AI and some years later, some other Gaurab will write directly from the brain, thanking our generation for researching in AI.</p>
<p><em>( Where is my contribution in AI ?? lmao)</em></p>
<div>
<div>💡</div>
<div>Along the way in the course of UNIX system developement, Dennis Ritchie created “C” language.</div>
</div>

<h3>UNIX: (one of the greatest step)</h3>
<p>Unix is simply the first developed operating system which really enhanced the interactivity between humans and computers. Seeing it’s features today won’t sound exciting but at that time, it was the most exciting and most wonderful thing every developed.</p>
<h3>About the History (5 min read):</h3>
<p>Read the history, telegraph and starting of the shell. <a href="https://thevaluable.dev/guide-terminal-shell-console/">https://thevaluable.dev/guide-terminal-shell-console</a></p>
<h2>Must watch video: best video</h2>
<p><a href="https://www.youtube.com/watch?v=tc4ROCJYbm0&amp;t=296s">Video Link ——- https://www.youtube.com/watch?v=tc4ROCJYbm0&amp;t=296s</a></p>
<h3>Shell: aka command interpreter</h3>
<p>Shell is from where you interact to the UNIX systems. ( think of it as terminal ). The terminal window in front of you contains shell, and shell allows you by use of commands to interact with your computer, hence retrieve or store data, process information and various other simple or even extremely complex tasks.</p>
<h3>Script:</h3>
<p>The command you write in the shell. commands we run are the prewritten small files in our file system and our shell knows which file to execute when that command/code/programme is run. like "ls" command <strong>Locates</strong> the binary file, typically at <code>/usr/bin/ls</code>, which then executes that binary to list the content.</p>
<p>The shell interacts with shared libraries, mostly the C library, and the libraries make system calls to the kernel. The kernel itself is the operating system. The shell is a piece of software that facilitates interactions between the user and the kernel.</p>
<p>so simply: "<strong>primary interface between you and the operating system's kernel"</strong></p>
<h3>Shell Script:</h3>
<p>It is a file where we write a bunch of programmes (commands) and store in the file. That file runs it form top-bottom. eg: Creating a backup which includes maybe moving file, zipping file and saving somewhere. Best explained at : 15:00 in video.</p>
<h3>Kernel: (the core)</h3>
<p>Kernel is where the system calls happens. System calls is when the programme we wrote, the file we open, actually interacts with the hardware. eg: ReadFile( ), open( ), close( ) …</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771471315613/7ce4ddb3-e508-48c6-9c85-dc405d3d9761.png" alt="" style="display:block;margin:0 auto" />

<p><em>Figure from AT&amp;T Archives</em></p>
<blockquote>
<p><strong><mark class="bg-yellow-200 dark:bg-yellow-500/30">(Outermost is terminal you use like alaricty, kitty, gnome terminal )</mark></strong></p>
</blockquote>
<p><em>Blog to read for writing Shell Scripting:</em> <a href="https://linuxconfig.org/bash-scripting-tutorial-for-beginners#h1-bash-shell-scripting-definition">https://linuxconfig.org/bash-scripting-tutorial-for-beginners#h1-bash-shell-scripting-definition</a></p>
<h3>What are bash, zsh, fish?</h3>
<p>They are the shell programmes.</p>
<h3>What is actually different between shells?</h3>
<p>The differences are mainly in <strong>language and user experience</strong>. (syntax, configurations made easy with fish using web etc)</p>
<h2>Step Example of What Actually Happens</h2>
<p>You enter: "ls"</p>
<p>1️⃣ Terminal sends input<br />2️⃣ Shell reads the command<br />3️⃣ Shell finds <code>/bin/ls</code><br />4️⃣ Shell calls: system calls the functions that makes the system calls</p>
<pre><code class="language-plaintext">fork()
execve("/bin/ls")
</code></pre>
<p>5️⃣ Kernel creates process<br />6️⃣ <code>ls</code> runs<br />7️⃣ Output printed to terminal</p>
<h2>Change the SHELL you use and customize it:</h2>
<ol>
<li><p>cat ./.bashrc is the default bash file, the shell you use and likewise zsh. ./.zshrc</p>
</li>
<li><p>for fish you need to exit this: "~/.config/fish/<a href="http://config.fish">config.fish</a>"</p>
</li>
</ol>
<div>
<div>💡</div>
<div>Inside "ls ~/.config/fish" you will see following files which is you edit as you customize:</div>
</div>

<pre><code class="language-javascript">config.fish
functions/
completions/
fish_variables
</code></pre>
<p>Each shell loads <strong>different startup files</strong>.</p>
<table>
<thead>
<tr>
<th>Shell</th>
<th>Config file</th>
</tr>
</thead>
<tbody><tr>
<td>Bash</td>
<td><code>.bashrc</code></td>
</tr>
<tr>
<td>Zsh</td>
<td><code>.zshrc</code></td>
</tr>
<tr>
<td>Fish</td>
<td><code>~/.config/fish/config.fish</code></td>
</tr>
</tbody></table>
<p>So when you switch shells, the <strong>old config is ignored</strong>.</p>
<h2>Since your config is bash I suppose:</h2>
<p>Steps:</p>
<p>a) First check your current shell : echo $SHELL</p>
<pre><code class="language-javascript">if output is : "/usr/bin/bash" Proceed to 1
else enter below command to make bash the default shell:
"chsh -s /usr/bin/bash"
</code></pre>
<p>Now you're default shell is bash:</p>
<ol>
<li>Install these two libraries:</li>
</ol>
<pre><code class="language-javascript">sudo apt-get install fortune cowsay
</code></pre>
<ol>
<li><p>Open the file : "vim ./.bashrc " or "nano ./.bashrc"</p>
</li>
<li><p>inside that in the bottom put the command:</p>
</li>
</ol>
<pre><code class="language-javascript">fortune | cowsay -r
</code></pre>
<ol>
<li>Now everytime you open your terminal, there is something new quote and character in the terminal. its because of the fortune pipe cowsay with -r flag.</li>
</ol>
<blockquote>
<p>Thankyou !! Please comment or reach out to me at : "<a href="mailto:oe.gaurav@gmail.com">oe.gaurav@gmail.com</a>" if there's some improvements or mistakes. Let's do some projects together, I am always willing to learn and work</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Understanding CSR, SSR, and SSG — What Actually Happens Behind the Scenes]]></title><description><![CDATA[Modern web development often talks about three rendering methods:

Client-Side Rendering (CSR)

Server-Side Rendering (SSR)

Static Site Generation (SSG)


Frameworks like React and Next.js support th]]></description><link>https://blog.gaurabwagle.com.np/understanding-csr-ssr-and-ssg-what-actually-happens-behind-the-scenes</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/understanding-csr-ssr-and-ssg-what-actually-happens-behind-the-scenes</guid><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Sat, 07 Mar 2026 07:33:19 GMT</pubDate><content:encoded><![CDATA[<p>Modern web development often talks about three rendering methods:</p>
<ul>
<li><p>Client-Side Rendering (CSR)</p>
</li>
<li><p>Server-Side Rendering (SSR)</p>
</li>
<li><p>Static Site Generation (SSG)</p>
</li>
</ul>
<p>Frameworks like <strong>React</strong> and <strong>Next.js</strong> support these approaches — but many developers are confused about what truly happens under the hood.</p>
<p>This article explains:</p>
<ul>
<li><p>What each method does</p>
</li>
<li><p>When API calls happen</p>
</li>
<li><p>What you see in “View Page Source”</p>
</li>
<li><p>What hydration really means</p>
</li>
<li><p>The real request flow for each approach</p>
</li>
</ul>
<p>Let’s break it down clearly.</p>
<hr />
<h1>Client-Side Rendering (CSR)</h1>
<h2>What It Is</h2>
<p>In Client-Side Rendering:</p>
<blockquote>
<p>The browser builds the page using JavaScript after the initial HTML loads.</p>
</blockquote>
<p>The server does <strong>not</strong> send fully rendered content.<br />It sends a minimal HTML shell and a JavaScript bundle.</p>
<hr />
<h2>What You See in “View Page Source”</h2>
<p>If you right-click → View Page Source, you’ll usually see something like:</p>
<pre><code class="language-plaintext">&lt;div id="root"&gt;&lt;/div&gt;
&lt;script src="/main.js"&gt;&lt;/script&gt;
</code></pre>
<p>There is no real content inside the div.</p>
<p>Why?</p>
<p>Because the server never rendered it.</p>
<hr />
<h2>What Actually Happens (Step-by-Step Flow)</h2>
<ol>
<li><p>Browser sends request to <code>/</code>.</p>
</li>
<li><p>Server returns basic HTML + JS file.</p>
</li>
<li><p>Browser downloads JavaScript.</p>
</li>
<li><p>JavaScript executes.</p>
</li>
<li><p>React runs in the browser.</p>
</li>
<li><p>API requests are made from the browser.</p>
</li>
<li><p>Data returns as JSON.</p>
</li>
<li><p>React maps data into HTML.</p>
</li>
<li><p>DOM updates and content appears.</p>
</li>
</ol>
<hr />
<h2>Where API Calls Happen</h2>
<p>In CSR:</p>
<ul>
<li><p>API calls happen <strong>inside the browser</strong></p>
</li>
<li><p>After JavaScript executes</p>
</li>
<li><p>Usually inside <code>useEffect()</code> or similar logic</p>
</li>
</ul>
<p>The server does not fetch data for the page.</p>
<hr />
<h2>Hydration?</h2>
<p>There is no hydration in CSR.</p>
<p>React builds everything from scratch in the browser.</p>
<hr />
<h1>Server-Side Rendering (SSR)</h1>
<h2>What It Is</h2>
<p>In Server-Side Rendering:</p>
<blockquote>
<p>The server builds the full HTML before sending it to the browser.</p>
</blockquote>
<p>JavaScript runs on the server using Node.js.</p>
<hr />
<h2>What You See in “View Page Source”</h2>
<p>Now when you check View Page Source, you’ll see:</p>
<pre><code class="language-plaintext">&lt;div&gt;
  &lt;div&gt;Phone&lt;/div&gt;
  &lt;div&gt;Laptop&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p>The content is already there.</p>
<p>Because the server rendered it.</p>
<hr />
<h2>What Actually Happens (Step-by-Step Flow)</h2>
<ol>
<li><p>Browser requests <code>/products</code>.</p>
</li>
<li><p>Server receives request.</p>
</li>
<li><p>Server runs JavaScript (Node.js).</p>
</li>
<li><p>Server makes API calls.</p>
</li>
<li><p>API returns JSON.</p>
</li>
<li><p>React renders components on server.</p>
</li>
<li><p>Server converts React output into HTML string.</p>
</li>
<li><p>Server sends complete HTML to browser.</p>
</li>
<li><p>Browser displays content immediately.</p>
</li>
<li><p>JavaScript bundle loads.</p>
</li>
<li><p>React hydrates the page.</p>
</li>
</ol>
<hr />
<h2>Where API Calls Happen</h2>
<p>In SSR:</p>
<ul>
<li><p>API calls happen <strong>on the server</strong></p>
</li>
<li><p>Before the page is sent</p>
</li>
<li><p>The browser never sees those API requests</p>
</li>
</ul>
<hr />
<h2>What Is Hydration?</h2>
<p>Hydration happens after the HTML loads in the browser.</p>
<p>React:</p>
<ul>
<li><p>Re-runs components in the browser</p>
</li>
<li><p>Compares them to existing DOM</p>
</li>
<li><p>Attaches event listeners</p>
</li>
<li><p>Activates state and interactivity</p>
</li>
</ul>
<p>Hydration does <strong>not</strong> rebuild the page.</p>
<p>It connects JavaScript behavior to the already rendered HTML.</p>
<hr />
<h1>Static Site Generation (SSG)</h1>
<h2>What It Is</h2>
<p>In Static Site Generation:</p>
<blockquote>
<p>Pages are rendered at build time, not when users visit.</p>
</blockquote>
<p>The rendering happens once during deployment.</p>
<hr />
<h2>What You See in “View Page Source”</h2>
<p>You will see fully rendered HTML — just like SSR.</p>
<p>Example:</p>
<pre><code class="language-plaintext">&lt;div&gt;
  &lt;div&gt;Phone&lt;/div&gt;
  &lt;div&gt;Laptop&lt;/div&gt;
&lt;/div&gt;
</code></pre>
<p>But the difference is:</p>
<p>This HTML was created earlier — during build.</p>
<hr />
<h2>What Actually Happens (Step-by-Step Flow)</h2>
<p>During build:</p>
<ol>
<li><p>Build process runs.</p>
</li>
<li><p>API calls are made.</p>
</li>
<li><p>Data is fetched.</p>
</li>
<li><p>React renders HTML.</p>
</li>
<li><p>HTML files are saved to disk.</p>
</li>
</ol>
<p>When a user visits:</p>
<ol>
<li><p>Browser requests page.</p>
</li>
<li><p>Server sends pre-built HTML file.</p>
</li>
<li><p>Browser displays instantly.</p>
</li>
<li><p>JavaScript loads.</p>
</li>
<li><p>React hydrates.</p>
</li>
</ol>
<hr />
<h2>Where API Calls Happen</h2>
<p>In SSG:</p>
<ul>
<li><p>API calls happen at <strong>build time</strong></p>
</li>
<li><p>Not when users visit</p>
</li>
<li><p>Not in the browser</p>
</li>
</ul>
<hr />
<h1>Clear Comparison of API Behavior</h1>
<table>
<thead>
<tr>
<th>Method</th>
<th>Where API Calls Happen</th>
<th>When</th>
</tr>
</thead>
<tbody><tr>
<td>CSR</td>
<td>Browser</td>
<td>After page loads</td>
</tr>
<tr>
<td>SSR</td>
<td>Server</td>
<td>On every request</td>
</tr>
<tr>
<td>SSG</td>
<td>Server (build process)</td>
<td>During deployment</td>
</tr>
</tbody></table>
<hr />
<h1>What “View Page Source” Really Shows</h1>
<p>This is important:</p>
<ul>
<li><p>View Page Source shows only the <strong>original HTML sent by server</strong>.</p>
</li>
<li><p>It does NOT show changes made by JavaScript after page loads.</p>
</li>
</ul>
<p>So:</p>
<ul>
<li><p>CSR → Mostly empty HTML</p>
</li>
<li><p>SSR → Fully rendered HTML</p>
</li>
<li><p>SSG → Fully rendered HTML</p>
</li>
</ul>
<p>If you want to see live DOM changes, use:</p>
<p>Developer Tools → Elements tab</p>
<hr />
<h1>Final Simple Mental Model</h1>
<p>Think in terms of <em>when HTML is created</em>:</p>
<ul>
<li><p>CSR → HTML created in browser</p>
</li>
<li><p>SSR → HTML created on server (every request)</p>
</li>
<li><p>SSG → HTML created during build</p>
</li>
</ul>
<p>Hydration happens only in SSR and SSG.</p>
<p>CSR does not hydrate — it renders from scratch.</p>
<hr />
<h1>The True Flow of Modern Web Apps</h1>
<p>Today, most modern frameworks mix these methods:</p>
<ul>
<li><p>Static pages use SSG</p>
</li>
<li><p>Dynamic pages use SSR</p>
</li>
<li><p>Dashboards use CSR</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[2025 (mid) -Thoughts about rejection in job @arbyte]]></title><description><![CDATA[Date: 12 Nov, 2025
Accept the defeat and build from it. Don’t neglect but never doubt about your worth.
This feeling of, maybe i know nothing comes very often in my mind, but then I realize, learning never ends and if I am to be in this field, i need...]]></description><link>https://blog.gaurabwagle.com.np/2025-mid-thoughts-about-rejection-in-job-arbyte</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/2025-mid-thoughts-about-rejection-in-job-arbyte</guid><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Tue, 30 Dec 2025 14:38:51 GMT</pubDate><content:encoded><![CDATA[<p>Date: 12 Nov, 2025</p>
<p>Accept the defeat and build from it. Don’t neglect but never doubt about your worth.</p>
<p>This feeling of, maybe i know nothing comes very often in my mind, but then I realize, learning never ends and if I am to be in this field, i need to have that mentality until I am old and lazy.</p>
<p>One person once said, you are just another person to those company people.<br />Long story short: It is simple, <em>“I got rejected in the job at internship and I felt like the world ended”</em></p>
<h3 id="heading-during-intern">During intern:</h3>
<p>I simply took 2.. months challenge to learn about the product development form frontend to backend through “The Odin Project” and while not even completing it, i landed this small little intern.<br />The protest gen-z made the internship duration longer but I had so much free time, and I am naturally curious, I always feel time is running out, that’s why i decided to work on some other problem that was more real to me.</p>
<p>I was told to do a project <a target="_blank" href="https://hikebud-self.vercel.app/">https://hikebud-self.vercel.app/</a> I completed it but I had a lot of time like 15-18 days. Then I decided to work on another project with my friend, leaving the hikebud just functional without adding anything extra fancy because honestly I was told, just make it working, you don’t need to have whole lot of everything but just make it working and problem solving.</p>
<p>I followed that and I started working on another https://hamrofund.org , a project I am proud of because I feel I am actually doing something for society.</p>
<h3 id="heading-presentation-day">Presentation day</h3>
<p>2 days before presentation, my laptop completely died. I had my project, i had my everything inside of it. I felt devastated and even told maybe I won’t be able to make it . I tried repairing whole night and another day thankfully I found old laptop of Milan dai, which was half broken. Installed new OS (omarchy), setup the project, made presentation and gave demo.</p>
<p>Had to buy a new laptop.</p>
<p>The projector in arch linux was a bit off and my presentation was not good and compared to others, my project was so simple and minimal but it was a problem solving one, and I learned quite a lot of things. And i guess it matters more than impressing others.</p>
<h3 id="heading-rejection-process">Rejection Process</h3>
<p>I was not invited for the first round of interview and there I thought ok this is over. But they called and I gave an interview, which was supposed to be technical but it was normal conversation and looking back, they just took that interview to make my intern complete. They interviewed to reject.</p>
<h3 id="heading-honest-opinion">Honest Opinion</h3>
<p>I used to submit the assigned tasks by documenting in LaTeX, while my other friends didn’t know what LaTeX was. I used to even deploy my project and always used to do it fully, by completely adding new functionalities and new tech stack everytime. (eg: sometimes i would use postgres, sometimes mongo, prisma, drizzle) I tried every technologies to work with just to get experience. Because, I was scared when they showed me the production level code of the “tangible” platform they were working on.<br />I was asking questions, i was learning and yea I was doing everything all right, except for the final project which I made it just fine only.</p>
<p>I can still say, I was the most deserving. Just because i didn’t do much on the project that doesn’t mean I was doing nothing, i was working on hamrofund which is now launched and is something that I am proud og. I remember one dai saying, you can be selected before closing before dashain. I was honestly, exicted to take the opportunity and even after the interview I thought ok, it’s late I am getting a job. They replied a week late and I rejected 2 other internships just because I was sure about getting this job.</p>
<p>But yea, I got disappointed and haha … let’s see where this goes But since this was my first experience, I feel bad.</p>
<h3 id="heading-is-this-a-sign">Is this a sign?</h3>
]]></content:encoded></item><item><title><![CDATA[Create a Tinyurl, short shareable URL without any shortner packages on your own.]]></title><description><![CDATA[I wrote the entire post myself and then used AI to redirect so no doubt on the originality of the post
Building Short, Shareable URLs in Your Application (Base62 + Drizzle ORM)
When building modern applications, long URLs can look messy — especially ...]]></description><link>https://blog.gaurabwagle.com.np/create-a-tinyurl-short-shareable-url-without-any-shortner-packages-on-your-own</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/create-a-tinyurl-short-shareable-url-without-any-shortner-packages-on-your-own</guid><category><![CDATA[urls]]></category><category><![CDATA[Url Shortener]]></category><category><![CDATA[React]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[PostgreSQL]]></category><category><![CDATA[Base64]]></category><category><![CDATA[GoFundMe ]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[full stack]]></category><category><![CDATA[Python]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Databases]]></category><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Fri, 05 Dec 2025 10:09:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764916721631/180c4b04-9d00-4c5b-a507-ef789cfc39f6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><em><mark>I wrote the entire post myself and then used AI to redirect so no doubt on the originality of the post</mark></em></p>
<h1 id="heading-building-short-shareable-urls-in-your-application-base62-drizzle-orm"><strong>Building Short, Shareable URLs in Your Application (Base62 + Drizzle ORM)</strong></h1>
<p>When building modern applications, long URLs can look messy — especially when sharing them on social media or messaging apps. For example, your post URL might currently look like:</p>
<pre><code class="lang-javascript">http:<span class="hljs-comment">//localhost:3000/users/posts/?postid=2</span>
</code></pre>
<p>or</p>
<pre><code class="lang-javascript">https:<span class="hljs-comment">//yourdomain.com/users/posts/?postid=2</span>
</code></pre>
<p>This exposes unnecessary route structure like <code>/users/posts/</code>. Instead, wouldn’t it be much cleaner if you could share something like:</p>
<pre><code class="lang-javascript">https:<span class="hljs-comment">//yourdomain.com/f4sxdx</span>
</code></pre>
<p>Just like GoFundMe, each post can have multiple short, unique URLs generated any time a user clicks <strong>Share</strong>.</p>
<p>In this guide, we’ll walk through how to build this entire system using:</p>
<ul>
<li><p><strong>Base62 encoding</strong> for generating short codes</p>
</li>
<li><p><strong>Drizzle ORM</strong></p>
</li>
<li><p><strong>Next.js API Routes</strong></p>
</li>
<li><p><strong>PostgreSQL</strong></p>
</li>
</ul>
<hr />
<h1 id="heading-what-we-need-to-achieve">🎯 What We Need to Achieve</h1>
<p>Each short URL must:</p>
<ol>
<li><p><strong>Uniquely identify a post or record</strong></p>
</li>
<li><p><strong>Redirect to the correct full/original URL</strong></p>
</li>
<li><p><strong>Allow multiple different short URLs for the same post</strong></p>
</li>
<li><p><strong>Store visit history for analytics</strong></p>
</li>
</ol>
<p>We’ll use the popular library <strong>base62-ts</strong>:<br /><a target="_blank" href="https://www.npmjs.com/package/base62-ts">https://www.npmjs.com/package/base62-ts</a></p>
<p>Base62 encoding converts the numeric ID from the database (1, 2, 3…) into a compact, shareable string like:<br /><code>0 → 0</code>, <code>10 → A</code>, <code>61 → z</code>, <code>125 → 21</code>, etc.</p>
<hr />
<h1 id="heading-step-1-create-the-database-table">🗄️ Step 1 — Create the Database Table</h1>
<p>We’ll store each short link in its own row:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { serial, varchar, integer, timestamp, jsonb } <span class="hljs-keyword">from</span> <span class="hljs-string">"drizzle-orm/pg-core"</span>;
<span class="hljs-keyword">import</span> { pgTable } <span class="hljs-keyword">from</span> <span class="hljs-string">"drizzle-orm/pg-core"</span>;
<span class="hljs-keyword">import</span> { posts } <span class="hljs-keyword">from</span> <span class="hljs-string">"./posts"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> urls = pgTable(<span class="hljs-string">"urls"</span>, {
  <span class="hljs-attr">id</span>: serial(<span class="hljs-string">"id"</span>).primaryKey(),
  <span class="hljs-attr">short_url</span>: varchar(<span class="hljs-string">"short_url"</span>),
  <span class="hljs-attr">redirect_url</span>: varchar(<span class="hljs-string">"redirect_url"</span>),
  <span class="hljs-attr">visited_history</span>: jsonb(<span class="hljs-string">"visited_history"</span>).$type&lt;string[]&gt;().default([]),
  <span class="hljs-attr">post_id</span>: integer(<span class="hljs-string">"post_id"</span>)
    .notNull()
    .references(<span class="hljs-function">() =&gt;</span> posts.id, { <span class="hljs-attr">onDelete</span>: <span class="hljs-string">"cascade"</span> }),
  <span class="hljs-attr">created_at</span>: timestamp(<span class="hljs-string">"created_at"</span>).defaultNow().notNull()
});
</code></pre>
<h3 id="heading-meaning-of-each-column">Meaning of each column:</h3>
<ul>
<li><p><strong>short_url</strong> → The Base62 + padded string (e.g., <code>/fundA12</code>)</p>
</li>
<li><p><strong>redirect_url</strong> → The original full URL</p>
</li>
<li><p><strong>visited_history</strong> → Array of timestamps (useful for analytics)</p>
</li>
<li><p><strong>post_id</strong> → Foreign key to your posts table</p>
</li>
<li><p><strong>id</strong> → Auto-incremented number we will encode</p>
</li>
</ul>
<hr />
<h1 id="heading-step-2-generate-a-short-url">⚙️ Step 2 — Generate a Short URL</h1>
<p>When the user triggers <strong>Share</strong>, we hit a POST endpoint that:</p>
<ol>
<li><p>Inserts a row containing the <strong>full redirect URL</strong></p>
</li>
<li><p>Reads the inserted row’s ID</p>
</li>
<li><p>Encodes that ID using Base62</p>
</li>
<li><p>Pads the string to a fixed length (optional)</p>
</li>
<li><p>Updates the row with the generated <code>short_url</code></p>
</li>
<li><p>Returns the new short URL</p>
</li>
</ol>
<p>Ready-to-use API code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { NextRequest, NextResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">"next/server"</span>;
<span class="hljs-keyword">import</span> base62 <span class="hljs-keyword">from</span> <span class="hljs-string">"base62-ts"</span>;
<span class="hljs-keyword">import</span> { db } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/lib/drizzle-client"</span>;
<span class="hljs-keyword">import</span> { urls } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/db/schema/urls"</span>;
<span class="hljs-keyword">import</span> { eq } <span class="hljs-keyword">from</span> <span class="hljs-string">"drizzle-orm"</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">POST</span>(<span class="hljs-params">req: NextRequest</span>) </span>{
  <span class="hljs-keyword">const</span> reqPostID = <span class="hljs-keyword">await</span> req.json();
  <span class="hljs-keyword">const</span> { postID } = reqPostID;

  <span class="hljs-keyword">if</span> (!postID) {
    <span class="hljs-keyword">return</span> NextResponse.json(
      { <span class="hljs-attr">error</span>: <span class="hljs-string">"Post ID is required"</span> },
      { <span class="hljs-attr">status</span>: <span class="hljs-number">400</span> }
    );
  }

  <span class="hljs-comment">// Construct the original redirect URL</span>
  <span class="hljs-keyword">const</span> redirect_url = <span class="hljs-string">`<span class="hljs-subst">${process.env.BASE_URL}</span>/donate/<span class="hljs-subst">${postID}</span>`</span>;

  <span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// Insert row and get the unique auto-incremented ID</span>
    <span class="hljs-keyword">const</span> [row] = <span class="hljs-keyword">await</span> db
      .insert(urls)
      .values({ redirect_url, <span class="hljs-attr">post_id</span>: postID })
      .returning({ <span class="hljs-attr">insertedId</span>: urls.id });

    <span class="hljs-keyword">const</span> insertedId = <span class="hljs-built_in">Number</span>(row.insertedId);

    <span class="hljs-comment">// Encode the ID using Base62</span>
    <span class="hljs-keyword">let</span> encoded62 = base62.encode(insertedId);
    encoded62 = encoded62.toString();

    <span class="hljs-comment">// Ensure a fixed length (e.g., 6 chars)</span>
    <span class="hljs-keyword">const</span> encoded = encoded62.padStart(<span class="hljs-number">6</span>, <span class="hljs-string">"fund"</span>);

    <span class="hljs-comment">// Update with the short URL</span>
    <span class="hljs-keyword">await</span> db
      .update(urls)
      .set({ <span class="hljs-attr">short_url</span>: <span class="hljs-string">`/<span class="hljs-subst">${encoded}</span>`</span> })
      .where(eq(urls.id, insertedId));

    <span class="hljs-keyword">return</span> NextResponse.json({
      <span class="hljs-attr">message</span>: <span class="hljs-string">"Short URL created"</span>,
      <span class="hljs-attr">shortURL</span>: <span class="hljs-string">`/<span class="hljs-subst">${encoded}</span>`</span>
    });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> NextResponse.json(
      { <span class="hljs-attr">error</span>: error <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Error</span> ? error.message : <span class="hljs-string">"Unknown error"</span> },
      { <span class="hljs-attr">status</span>: <span class="hljs-number">500</span> }
    );
  }
}
</code></pre>
<h3 id="heading-why-padstart6-fund">Why <code>padStart(6, "fund")</code>?</h3>
<p><code>padStart</code> ensures that even tiny Base62 values (like <code>"1"</code>) become 6-character strings:</p>
<pre><code class="lang-javascript"><span class="hljs-string">"1"</span> → <span class="hljs-string">"fundf1"</span>
<span class="hljs-string">"23"</span> → <span class="hljs-string">"fund23"</span>
<span class="hljs-string">"i8"</span> → <span class="hljs-string">"fundi8"</span>
</code></pre>
<p>This makes URLs consistent and harder to guess.</p>
<hr />
<h1 id="heading-step-3-redirect-short-url-original-url">🔗 Step 3 — Redirect Short URL → Original URL</h1>
<p>Your redirect route must:</p>
<ol>
<li><p>Extract the short code from the URL</p>
</li>
<li><p>Look it up in the <code>urls</code> table</p>
</li>
<li><p>Log the visit time</p>
</li>
<li><p>Redirect the user to the real page</p>
</li>
</ol>
<p>Example:</p>
<pre><code class="lang-javascript">interface ResponseData {
  <span class="hljs-attr">id</span>: number;
  short_url: string | <span class="hljs-literal">null</span>;
  redirect_url: string | <span class="hljs-literal">null</span>;
  visited_history: string[] | <span class="hljs-literal">null</span>;
  created_at: <span class="hljs-built_in">Date</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">GET</span>(<span class="hljs-params">
  req: NextRequest,
  { params }: { params: Promise&lt;{ shortURL: string }&gt; }
</span>) </span>{
  <span class="hljs-keyword">const</span> { shortURL } = <span class="hljs-keyword">await</span> params;

  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> result: ResponseData[] = <span class="hljs-keyword">await</span> db
      .select()
      .from(urls)
      .where(eq(urls.short_url, <span class="hljs-string">`/<span class="hljs-subst">${shortURL}</span>`</span>));

    <span class="hljs-keyword">if</span> (result.length === <span class="hljs-number">0</span>) {
      <span class="hljs-keyword">return</span> NextResponse.json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"No URL found"</span> }, { <span class="hljs-attr">status</span>: <span class="hljs-number">404</span> });
    }

    <span class="hljs-keyword">const</span> row = result[<span class="hljs-number">0</span>];

    <span class="hljs-comment">// Append visit timestamp</span>
    <span class="hljs-keyword">const</span> updatedHistory = [
      ...(row.visited_history || []),
      <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toISOString()
    ];

    <span class="hljs-keyword">await</span> db
      .update(urls)
      .set({ <span class="hljs-attr">visited_history</span>: updatedHistory })
      .where(eq(urls.id, row.id));

    <span class="hljs-keyword">if</span> (!row.redirect_url) {
      <span class="hljs-keyword">return</span> NextResponse.json(
        { <span class="hljs-attr">message</span>: <span class="hljs-string">"Invalid redirect URL"</span> },
        { <span class="hljs-attr">status</span>: <span class="hljs-number">500</span> }
      );
    }

    <span class="hljs-keyword">return</span> NextResponse.redirect(row.redirect_url);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-keyword">return</span> NextResponse.json(
      { <span class="hljs-attr">message</span>: <span class="hljs-string">"Unexpected error"</span> },
      { <span class="hljs-attr">status</span>: <span class="hljs-number">500</span> }
    );
  }
}
</code></pre>
<hr />
<h1 id="heading-summary-of-the-redirect-logic">🧠 Summary of the Redirect Logic</h1>
<ol>
<li><p>Receive the short code from the URL</p>
</li>
<li><p>Query the database</p>
</li>
<li><p>Drizzle always returns an <strong>array</strong>, even for one record</p>
</li>
<li><p>If found → log the visit timestamp</p>
</li>
<li><p>Redirect the user</p>
</li>
</ol>
<p>If the short URL doesn’t exist, simply return a 404.</p>
]]></content:encoded></item><item><title><![CDATA[Implementing Cursor-Based Pagination in Next.js + Drizzle ORM]]></title><description><![CDATA[Pagination helps load data efficiently without fetching everything at once.While offset-based pagination (using page and limit) is simple, it can become inefficient with large datasets.
That’s where cursor-based pagination comes in, it’s faster, more...]]></description><link>https://blog.gaurabwagle.com.np/implementing-cursor-based-pagination-in-nextjs-drizzle-orm</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/implementing-cursor-based-pagination-in-nextjs-drizzle-orm</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[webdev]]></category><category><![CDATA[Python]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[SEO]]></category><category><![CDATA[seo services]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[web developers]]></category><category><![CDATA[Web Design]]></category><category><![CDATA[React]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[pagination in ReactJS]]></category><category><![CDATA[pagination backend]]></category><category><![CDATA[DrizzleORM]]></category><category><![CDATA[next js]]></category><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Sat, 08 Nov 2025 06:26:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762583154964/b5e715b2-422e-4a70-bb7f-119a8aba1ded.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Pagination helps load data efficiently without fetching everything at once.<br />While <em>offset-based pagination</em> (using <code>page</code> and <code>limit</code>) is simple, it can become inefficient with large datasets.</p>
<p>That’s where <strong>cursor-based pagination</strong> comes in, it’s faster, more stable, and widely used in APIs like Twitter or GitHub.</p>
<hr />
<h2 id="heading-what-is-cursor-based-pagination">What Is Cursor-Based Pagination?</h2>
<p>Instead of asking:</p>
<blockquote>
<p>“Give me page 2”</p>
</blockquote>
<p>We say:</p>
<blockquote>
<p>“Give me the next 3 items <strong>after this record (cursor)</strong>.”</p>
</blockquote>
<p>Each response includes:</p>
<ul>
<li><p><code>data</code> → list of results</p>
</li>
<li><p><code>next_cursor</code> → the next record’s ID</p>
</li>
<li><p><code>hasNextPage</code> → whether more data exists</p>
</li>
</ul>
<p>This makes it more reliable when data is constantly changing.</p>
<hr />
<h2 id="heading-backend-nextjs-api-route-drizzle-orm">Backend — Next.js API Route + Drizzle ORM</h2>
<p>Let’s start with the backend logic.</p>
<p>We’ll handle both initial and subsequent requests from the frontend.<br />When no <code>cursor</code> is provided → fetch the first batch.<br />When <code>cursor</code> exists → fetch results after that cursor.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { posts } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/db/schema"</span>;
<span class="hljs-keyword">import</span> db <span class="hljs-keyword">from</span> <span class="hljs-string">"@/lib/drizzle"</span>;
<span class="hljs-keyword">import</span> { desc, lte } <span class="hljs-keyword">from</span> <span class="hljs-string">"drizzle-orm"</span>;
<span class="hljs-keyword">import</span> { NextRequest, NextResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">"next/server"</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">GET</span>(<span class="hljs-params">req: NextRequest</span>) </span>{
  <span class="hljs-keyword">const</span> { searchParams } = <span class="hljs-keyword">new</span> URL(req.url);

  <span class="hljs-keyword">const</span> cursor = <span class="hljs-built_in">Number</span>(searchParams.get(<span class="hljs-string">"cursor"</span>)) || <span class="hljs-literal">null</span>;
  <span class="hljs-keyword">const</span> limit = <span class="hljs-built_in">Number</span>(searchParams.get(<span class="hljs-string">"page_size"</span>)) || <span class="hljs-number">3</span>;

  <span class="hljs-comment">// Fetch one extra to check if more results exist</span>
  <span class="hljs-keyword">const</span> effectiveLimit = limit + <span class="hljs-number">1</span>;

  <span class="hljs-keyword">let</span> hasNextPage = <span class="hljs-literal">false</span>;
  <span class="hljs-keyword">let</span> next_cursor = <span class="hljs-literal">null</span>;

  <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> db
    .select()
    .from(posts)
    .where(cursor ? lte(posts.id, cursor) : <span class="hljs-literal">undefined</span>)
    .orderBy(desc(posts.id))
    .limit(effectiveLimit);

  <span class="hljs-comment">// If we got more data than limit, that means there’s a next page</span>
  <span class="hljs-keyword">if</span> (data.length &gt; limit) {
    hasNextPage = <span class="hljs-literal">true</span>;
    next_cursor = data[data.length - <span class="hljs-number">1</span>].id;
    data.pop(); <span class="hljs-comment">// remove the extra fetched item</span>
  }

  <span class="hljs-keyword">return</span> NextResponse.json({
    data,
    next_cursor,
    hasNextPage,
    <span class="hljs-attr">message</span>: <span class="hljs-string">"Fetched successfully"</span>,
  });
}
</code></pre>
<p><strong>Backend logic summary:</strong></p>
<ul>
<li><p>Fetch <code>(limit + 1)</code> rows.</p>
</li>
<li><p>If extra data exists → <code>hasNextPage = true</code>.</p>
</li>
<li><p>Remove the extra record and send the remaining ones.</p>
</li>
<li><p>Return <code>next_cursor</code> for the next request.</p>
</li>
</ul>
<hr />
<h2 id="heading-frontend-react-nextjs-client-component">Frontend - React (Next.js Client Component)</h2>
<p>The frontend keeps track of:</p>
<ul>
<li><p><code>data</code></p>
</li>
<li><p><code>cursor</code></p>
</li>
<li><p><code>hasNextPage</code></p>
</li>
<li><p>loading state</p>
</li>
</ul>
<p>Each time we fetch, we append new results to the existing list.</p>
<pre><code class="lang-javascript"><span class="hljs-string">"use client"</span>;

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

interface Post {
  <span class="hljs-attr">id</span>: number;
  title: string;
  description: string;
}

<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">Page</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState&lt;Post[]&gt;([]);
  <span class="hljs-keyword">const</span> [cursor, setCursor] = useState&lt;number | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [hasNextPage, setHasNextPage] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchPosts</span>(<span class="hljs-params">cursor: number | null, page_size = <span class="hljs-number">3</span></span>) </span>{
    <span class="hljs-keyword">try</span> {
      setLoading(<span class="hljs-literal">true</span>);
      <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">`/api/fetchPosts?cursor=<span class="hljs-subst">${cursor}</span>&amp;page_size=<span class="hljs-subst">${page_size}</span>`</span>);
      setData(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> [...prev, ...res.data.data]);
      setCursor(res.data.next_cursor);
      setHasNextPage(res.data.hasNextPage);
    } <span class="hljs-keyword">finally</span> {
      setLoading(<span class="hljs-literal">false</span>);
    }
  }

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetchPosts(<span class="hljs-literal">null</span>);
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {data.map((post) =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-gray-100 p-3 mb-2 rounded-md"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-semibold text-lg"</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-sm text-gray-700"</span>&gt;</span>{post.description}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      ))}

      {hasNextPage &amp;&amp; (
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
          <span class="hljs-attr">disabled</span>=<span class="hljs-string">{loading}</span>
          <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> fetchPosts(cursor)}
          className="bg-blue-500 text-white px-4 py-2 rounded-md"
        &gt;
          {loading ? "Loading..." : "Load More"}
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      )}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Frontend logic summary:</strong></p>
<ul>
<li><p>On first render → fetch initial data.</p>
</li>
<li><p>On “Load More” click → send the last <code>cursor</code>.</p>
</li>
<li><p>Append new results to the state.</p>
</li>
<li><p>Hide the button if there are no more pages.</p>
</li>
</ul>
<hr />
<h2 id="heading-why-cursor-pagination-is-better">Why Cursor Pagination Is Better</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>Offset Pagination</td><td>Cursor Pagination</td></tr>
</thead>
<tbody>
<tr>
<td>Speed</td><td>Slower for large data</td><td>Faster and consistent</td></tr>
<tr>
<td>Data stability</td><td>Can skip or duplicate data</td><td>Reliable order</td></tr>
<tr>
<td>Implementation</td><td>Easier</td><td>Slightly complex</td></tr>
<tr>
<td>Best for</td><td>Static data</td><td>Dynamic feeds (e.g. social media, posts)</td></tr>
</tbody>
</table>
</div><p>Cursor pagination is <strong>ideal for real-time apps</strong> like feeds, dashboards, or infinite scrolls.</p>
<hr />
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>Cursor-based pagination gives you both performance and consistency.<br />It ensures you always fetch the right data even when your dataset changes frequently.</p>
<p>If you’re building a product with constantly updating data, like posts, comments, or stock market lists, this approach will scale much better than traditional offset-based pagination.</p>
<p>💬 Have any questions or improvements? Drop a comment below!</p>
]]></content:encoded></item><item><title><![CDATA[Pagination Concepts Made Easy with SQL Query and React/Next JS]]></title><description><![CDATA[What is Pagination? (skip if you already know)Pagination means dividing the contents/document into discrete pages. It is a user interface design pattern.

You just need 2 patterns of implementing pagination as dev’s while starting out:

Off-Set based...]]></description><link>https://blog.gaurabwagle.com.np/pagination-concepts-made-easy-with-sql-query-and-reactnext-js</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/pagination-concepts-made-easy-with-sql-query-and-reactnext-js</guid><category><![CDATA[React]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[webdev]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[Developer Tools]]></category><category><![CDATA[learning]]></category><category><![CDATA[#codenewbies]]></category><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Sat, 08 Nov 2025 06:22:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762582902902/bd126313-3f3d-40ba-a1db-17375d08caab.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<details><summary>What is Pagination? (skip if you already know)</summary><div data-type="detailsContent">Pagination means dividing the contents/document into discrete pages. It is a user interface design pattern.</div></details>

<p>You just need 2 patterns of implementing pagination as dev’s while starting out:</p>
<ol>
<li><p>Off-Set based pagination — (recommended if small data)</p>
</li>
<li><p>Cursor based pagination — (recommended if you have large data)</p>
</li>
</ol>
<h3 id="heading-offset-based-pagination">Offset-based pagination</h3>
<p>In offset-based pagination, we use SQL’s LIMIT and OFFSET to fetch only a specific chunk of records.</p>
<p><strong>page_size</strong> = how many items to show per page<br /><strong>page_number</strong> = which page to fetch (e.g., if page_size = 10, then page 3 returns items 21–30)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762582598152/a0216f39-f97f-4a17-a723-2b5bbf9e121c.webp" alt class="image--center mx-auto" /></p>
<p>The client (frontend) sends these values to the backend, like:</p>
<p><code>/posts?page_size=3&amp;page_number=2</code></p>
<p>The backend reads those parameters and runs a query such as:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> posts <span class="hljs-keyword">LIMIT</span> <span class="hljs-number">3</span> <span class="hljs-keyword">OFFSET</span> <span class="hljs-number">3</span>;
</code></pre>
<p><strong>Advantage</strong>:</p>
<ul>
<li><p>It allows the clients to view the total number of pages.</p>
</li>
<li><p>It allows clients to jump to a specific page by passing the page number.</p>
</li>
</ul>
<p><strong>Disadvantage:</strong></p>
<ul>
<li><p>The database looks up for (offset + limit) number of records before discarding the unwanted ones and returning the remaining.<br />  Hence, the query time increases drastically as the offset increase</p>
</li>
<li><p>If an item in a previous page is deleted, data will shift forward, causing some results to be skipped.</p>
</li>
</ul>
<h2 id="heading-cursor-based-pagination">Cursor Based Pagination</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762581923365/2a01f898-6f90-44a0-93f5-5a6a0caca968.webp" alt class="image--center mx-auto" /></p>
<p>In cursor-based pagination, instead of using page numbers, we use a cursor, a unique pointer that refers to a specific record in the database.</p>
<p>The client sends a cursor (like a record ID) and a page_size to fetch data that comes after or before that record.</p>
<p><code>GET /api/users?cursor=12345&amp;page_size=10</code></p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> <span class="hljs-keyword">users</span>
<span class="hljs-keyword">WHERE</span> <span class="hljs-keyword">id</span> &lt;= <span class="hljs-number">12345</span>
<span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> <span class="hljs-keyword">id</span> <span class="hljs-keyword">DESC</span>
<span class="hljs-keyword">LIMIT</span> <span class="hljs-number">11</span>;  <span class="hljs-comment">-- (page_size + 1)</span>
</code></pre>
<p>The backend fetches page_size + 1 records.<br />If there’s an extra record, it means there’s another page, and that extra record’s ID becomes the next_cursor, we don’t return the extra record (11th record) but we verify that another page/record is still available, <strong>store the</strong> <code>next_cursor</code> <strong>value and</strong> <code>hasNextPage</code> <strong>named boolean value.</strong></p>
<p><strong><mark>What do we return?</mark></strong></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// json return</span>
{
    <span class="hljs-attr">data</span>: [{...data}],
    <span class="hljs-attr">next_cursor</span>: (<span class="hljs-number">11</span>th record id) or <span class="hljs-literal">null</span> <span class="hljs-keyword">if</span> no another record
    <span class="hljs-attr">hasNextPage</span>: True/ False (according to condition),
}
</code></pre>
<p><strong>Advantage:</strong></p>
<ul>
<li><p>Since we are fetching from a stable reference point, the addition or deletion of record will not affect the pagination window.</p>
</li>
<li><p><strong><em>The database jumps directly to the record without iterating through the unwanted data. Hence, making it more efficient. <mark>——most important——</mark></em></strong></p>
<p>  <strong>Disadvantage:</strong></p>
</li>
<li><p>The cursor pagination doesn’t allow clients to jump to a specific page.</p>
</li>
<li><p>Limited sort features. If the requirement is to sort based on a non-unique column (E.g. first name), it will be challenging to implement using cursor pagination. Concatenating multiple columns to get a unique key leads to slower time complexity.</p>
<h2 id="heading-encoded-cursor"><strong>Encoded Cursor</strong></h2>
</li>
<li><p>The encoded cursor suggests returning an encoded base64 string regardless of the underlying pagination solution.</p>
<p>  When using offset pagination, we encode the page_number and total_page into a base64 string and return it as a cursor to the clients.</p>
<pre><code class="lang-javascript">  response: {
      <span class="hljs-comment">// "page=3|offset=20|total_pages=30"</span>
      <span class="hljs-attr">next_cursor</span>: <span class="hljs-string">"dcjadfaXMDdQTQ"</span>
  }
</code></pre>
<p>  This allows the server to implement different underlying pagination solutions while providing a consistent interface to the API consumers.</p>
<pre><code class="lang-javascript">  request: {
      <span class="hljs-attr">cursor</span>: <span class="hljs-string">"dcjadfaXMDdQTQ"</span>,
      <span class="hljs-attr">page_size</span>: <span class="hljs-number">10</span>
  }
</code></pre>
</li>
</ul>
<h1 id="heading-code-implementation-in-nextjs">Code Implementation in NextJS:</h1>
<h1 id="heading-implementing-cursor-based-pagination-in-nextjs-drizzle-orm">Implementing Cursor-Based Pagination in Next.js + Drizzle ORM</h1>
<p>Pagination helps load data efficiently without fetching everything at once.<br />While <em>offset-based pagination</em> (using <code>page</code> and <code>limit</code>) is simple, it can become inefficient with large datasets.</p>
<p>That’s where <strong>cursor-based pagination</strong> comes in — it’s faster, more stable, and widely used in APIs like Twitter or GitHub.</p>
<hr />
<h2 id="heading-what-is-cursor-based-pagination">What Is Cursor-Based Pagination?</h2>
<p>Instead of asking:</p>
<blockquote>
<p>“Give me page 2”</p>
</blockquote>
<p>We say:</p>
<blockquote>
<p>“Give me the next 3 items <strong>after this record (cursor)</strong>.”</p>
</blockquote>
<p>Each response includes:</p>
<ul>
<li><p><code>data</code> → list of results</p>
</li>
<li><p><code>next_cursor</code> → the next record’s ID</p>
</li>
<li><p><code>hasNextPage</code> → whether more data exists</p>
</li>
</ul>
<p>This makes it more reliable when data is constantly changing.</p>
<hr />
<h2 id="heading-backend-nextjs-api-route-drizzle-orm">Backend — Next.js API Route + Drizzle ORM</h2>
<p>Let’s start with the backend logic.</p>
<p>We’ll handle both initial and subsequent requests from the frontend.<br />When no <code>cursor</code> is provided → fetch the first batch.<br />When <code>cursor</code> exists → fetch results after that cursor.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { posts } <span class="hljs-keyword">from</span> <span class="hljs-string">"@/db/schema"</span>;
<span class="hljs-keyword">import</span> db <span class="hljs-keyword">from</span> <span class="hljs-string">"@/lib/drizzle"</span>;
<span class="hljs-keyword">import</span> { desc, lte } <span class="hljs-keyword">from</span> <span class="hljs-string">"drizzle-orm"</span>;
<span class="hljs-keyword">import</span> { NextRequest, NextResponse } <span class="hljs-keyword">from</span> <span class="hljs-string">"next/server"</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">GET</span>(<span class="hljs-params">req: NextRequest</span>) </span>{
  <span class="hljs-keyword">const</span> { searchParams } = <span class="hljs-keyword">new</span> URL(req.url);

  <span class="hljs-keyword">const</span> cursor = <span class="hljs-built_in">Number</span>(searchParams.get(<span class="hljs-string">"cursor"</span>)) || <span class="hljs-literal">null</span>;
  <span class="hljs-keyword">const</span> limit = <span class="hljs-built_in">Number</span>(searchParams.get(<span class="hljs-string">"page_size"</span>)) || <span class="hljs-number">3</span>;

  <span class="hljs-comment">// Fetch one extra to check if more results exist</span>
  <span class="hljs-keyword">const</span> effectiveLimit = limit + <span class="hljs-number">1</span>;

  <span class="hljs-keyword">let</span> hasNextPage = <span class="hljs-literal">false</span>;
  <span class="hljs-keyword">let</span> next_cursor = <span class="hljs-literal">null</span>;

  <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> db
    .select()
    .from(posts)
    .where(cursor ? lte(posts.id, cursor) : <span class="hljs-literal">undefined</span>)
    .orderBy(desc(posts.id))
    .limit(effectiveLimit);

  <span class="hljs-comment">// If we got more data than limit, that means there’s a next page</span>
  <span class="hljs-keyword">if</span> (data.length &gt; limit) {
    hasNextPage = <span class="hljs-literal">true</span>;
    next_cursor = data[data.length - <span class="hljs-number">1</span>].id;
    data.pop(); <span class="hljs-comment">// remove the extra fetched item</span>
  }

  <span class="hljs-keyword">return</span> NextResponse.json({
    data,
    next_cursor,
    hasNextPage,
    <span class="hljs-attr">message</span>: <span class="hljs-string">"Fetched successfully"</span>,
  });
}
</code></pre>
<p><strong>Backend logic summary:</strong></p>
<ul>
<li><p>Fetch <code>(limit + 1)</code> rows.</p>
</li>
<li><p>If extra data exists → <code>hasNextPage = true</code>.</p>
</li>
<li><p>Remove the extra record and send the remaining ones.</p>
</li>
<li><p>Return <code>next_cursor</code> for the next request.</p>
</li>
</ul>
<hr />
<h2 id="heading-frontend-react-nextjs-client-component">Frontend — React (Next.js Client Component)</h2>
<p>The frontend keeps track of:</p>
<ul>
<li><p><code>data</code></p>
</li>
<li><p><code>cursor</code></p>
</li>
<li><p><code>hasNextPage</code></p>
</li>
<li><p>loading state</p>
</li>
</ul>
<p>Each time we fetch, we append new results to the existing list.</p>
<pre><code class="lang-javascript"><span class="hljs-string">"use client"</span>;

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

interface Post {
  <span class="hljs-attr">id</span>: number;
  title: string;
  description: string;
}

<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">Page</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> [data, setData] = useState&lt;Post[]&gt;([]);
  <span class="hljs-keyword">const</span> [cursor, setCursor] = useState&lt;number | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [hasNextPage, setHasNextPage] = useState(<span class="hljs-literal">false</span>);
  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">false</span>);

  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchPosts</span>(<span class="hljs-params">cursor: number | null, page_size = <span class="hljs-number">3</span></span>) </span>{
    <span class="hljs-keyword">try</span> {
      setLoading(<span class="hljs-literal">true</span>);
      <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">`/api/fetchPosts?cursor=<span class="hljs-subst">${cursor}</span>&amp;page_size=<span class="hljs-subst">${page_size}</span>`</span>);
      setData(<span class="hljs-function">(<span class="hljs-params">prev</span>) =&gt;</span> [...prev, ...res.data.data]);
      setCursor(res.data.next_cursor);
      setHasNextPage(res.data.hasNextPage);
    } <span class="hljs-keyword">finally</span> {
      setLoading(<span class="hljs-literal">false</span>);
    }
  }

  useEffect(<span class="hljs-function">() =&gt;</span> {
    fetchPosts(<span class="hljs-literal">null</span>);
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {data.map((post) =&gt; (
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{post.id}</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bg-gray-100 p-3 mb-2 rounded-md"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h2</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"font-semibold text-lg"</span>&gt;</span>{post.title}<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"text-sm text-gray-700"</span>&gt;</span>{post.description}<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      ))}

      {hasNextPage &amp;&amp; (
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span>
          <span class="hljs-attr">disabled</span>=<span class="hljs-string">{loading}</span>
          <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> fetchPosts(cursor)}
          className="bg-blue-500 text-white px-4 py-2 rounded-md"
        &gt;
          {loading ? "Loading..." : "Load More"}
        <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
      )}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p><strong>Frontend logic summary:</strong></p>
<ul>
<li><p>On first render → fetch initial data.</p>
</li>
<li><p>On “Load More” click → send the last <code>cursor</code>.</p>
</li>
<li><p>Append new results to the state.</p>
</li>
<li><p>Hide the button if there are no more pages.</p>
</li>
</ul>
<hr />
<h2 id="heading-why-cursor-pagination-is-better">Why Cursor Pagination Is Better</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>Offset Pagination</td><td>Cursor Pagination</td></tr>
</thead>
<tbody>
<tr>
<td>Speed</td><td>Slower for large data</td><td>Faster and consistent</td></tr>
<tr>
<td>Data stability</td><td>Can skip or duplicate data</td><td>Reliable order</td></tr>
<tr>
<td>Implementation</td><td>Easier</td><td>Slightly complex</td></tr>
<tr>
<td>Best for</td><td>Static data</td><td>Dynamic feeds (e.g. social media, posts)</td></tr>
</tbody>
</table>
</div><p>Cursor pagination is <strong>ideal for real-time apps</strong> like feeds, dashboards, or infinite scrolls.</p>
<hr />
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>Cursor-based pagination gives you both performance and consistency.<br />It ensures you always fetch the right data even when your dataset changes frequently.</p>
<p>If you’re building a product with constantly updating data — like posts, comments, or stock market lists —<br />this approach will scale much better than traditional offset-based pagination.</p>
]]></content:encoded></item><item><title><![CDATA[Next time when someone asks you, What happens when you enter google.com in your browser?]]></title><description><![CDATA[🧩 Step 0: The Goal
Your browser needs to find the IP address of google.com so it can connect to the web server.DNS is the system that helps it find that IP.

⚙️ Step 1: Browser & OS Local Cache
When you type google.com:

Your browser first checks it...]]></description><link>https://blog.gaurabwagle.com.np/next-time-when-someone-asks-you-what-happens-when-you-enter-googlecom-in-your-browser</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/next-time-when-someone-asks-you-what-happens-when-you-enter-googlecom-in-your-browser</guid><category><![CDATA[internet]]></category><category><![CDATA[Google]]></category><category><![CDATA[google search]]></category><category><![CDATA[Google]]></category><category><![CDATA[interview]]></category><category><![CDATA[interview questions]]></category><category><![CDATA[dns]]></category><category><![CDATA[server]]></category><category><![CDATA[internships]]></category><category><![CDATA[jobs]]></category><category><![CDATA[technology]]></category><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Mon, 27 Oct 2025 14:50:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761576257956/4408a592-b726-46a7-80ba-ecc6299822ea.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-step-0-the-goal">🧩 Step 0: The Goal</h3>
<p>Your browser needs to find the <strong>IP address</strong> of <a target="_blank" href="http://google.com"><code>google.com</code></a> so it can connect to the web server.<br />DNS is the system that helps it find that IP.</p>
<hr />
<h3 id="heading-step-1-browser-amp-os-local-cache">⚙️ Step 1: Browser &amp; OS Local Cache</h3>
<p>When you type <a target="_blank" href="http://google.com"><code>google.com</code></a>:</p>
<ol>
<li><p>Your <strong>browser</strong> first checks its <strong>own cache</strong> (recently visited sites).</p>
</li>
<li><p>If not found, your <strong>operating system</strong> checks its <strong>local DNS cache</strong> (for example, your <code>/etc/hosts</code> file on Linux or Windows DNS resolver cache).</p>
</li>
</ol>
<p>If found → done (no network query needed).<br />If <strong>not found</strong> → move to the next level.</p>
<hr />
<h3 id="heading-step-2-the-resolver-usually-your-isp-or-a-custom-one">⚙️ Step 2: The Resolver (Usually Your ISP or a Custom One)</h3>
<p>Your computer sends the DNS query (like “What is the IP of <a target="_blank" href="http://google.com">google.com</a>?”) to a <strong>recursive resolver</strong>.<br />This is typically:</p>
<ul>
<li><p>your <strong>ISP’s DNS resolver</strong>, or</p>
</li>
<li><p>a <strong>public resolver</strong> like <code>8.8.8.8</code> (Google DNS) or <code>1.1.1.1</code> (Cloudflare DNS).</p>
</li>
</ul>
<p>This resolver’s job is to <strong>find the answer</strong> for you — it does all the hard work by asking other DNS servers in the hierarchy.</p>
<p>If it already has the answer cached → returns it immediately.</p>
<p>If <strong>not cached</strong> → it starts the <strong>DNS resolution process</strong> below.</p>
<hr />
<h3 id="heading-step-3-root-dns-servers">⚙️ Step 3: Root DNS Servers</h3>
<p>The resolver sends a query to a <strong>Root DNS Server</strong>:</p>
<blockquote>
<p>“Hey, where can I find info about <code>.com</code> domains?”</p>
</blockquote>
<p>Root servers don’t know about individual domains like <a target="_blank" href="http://google.com"><code>google.com</code></a>,<br />but they <strong>do know where the Top-Level Domain (TLD) servers</strong> are.</p>
<p>So the root server replies:</p>
<blockquote>
<p>“I don’t know <a target="_blank" href="http://google.com">google.com</a>, but here’s a list of <code>.com</code> TLD name servers.”</p>
</blockquote>
<p>It returns a <strong>referral</strong> to the <code>.com</code> TLD servers.</p>
<hr />
<h3 id="heading-step-4-tld-top-level-domain-name-servers">⚙️ Step 4: TLD (Top-Level Domain) Name Servers</h3>
<p>Now, the resolver contacts one of the <code>.com</code> TLD servers:</p>
<blockquote>
<p>“Hey, I need info about <a target="_blank" href="http://google.com"><code>google.com</code></a> — who’s the authoritative server for it?”</p>
</blockquote>
<p>The TLD server replies:</p>
<blockquote>
<p>“The authoritative name servers for <a target="_blank" href="http://google.com">google.com</a> are <a target="_blank" href="http://ns1.google.com"><code>ns1.google.com</code></a>, <a target="_blank" href="http://ns2.google.com"><code>ns2.google.com</code></a>, etc.”</p>
</blockquote>
<p>This is another <strong>referral</strong> — now we know where the <strong>actual zone</strong> for <a target="_blank" href="http://google.com">google.com</a> is managed.</p>
<hr />
<h3 id="heading-step-5-authoritative-dns-server">⚙️ Step 5: Authoritative DNS Server</h3>
<p>Finally, the resolver asks <strong>Google’s authoritative name server</strong>:</p>
<blockquote>
<p>“What is the IP address (A record) for <a target="_blank" href="http://google.com">google.com</a>?”</p>
</blockquote>
<p>This server owns the actual DNS records for <a target="_blank" href="http://google.com">google.com</a>.<br />It replies with something like:</p>
<blockquote>
<p>“<a target="_blank" href="http://google.com"><code>google.com</code></a> → 142.250.190.14”</p>
</blockquote>
<hr />
<h3 id="heading-step-6-returning-the-result">⚙️ Step 6: Returning the Result</h3>
<p>The recursive resolver now:</p>
<ul>
<li><p>Stores this result in its <strong>cache</strong> for some time (defined by the TTL).</p>
</li>
<li><p>Sends the IP address back to your <strong>computer</strong>.</p>
</li>
</ul>
<p>Your OS also caches it for a while.<br />Then your browser uses that IP to make an <strong>HTTP(S)</strong> request to <a target="_blank" href="https://142.250.190.14"><code>https://142.250.190.14</code></a>.</p>
<h3 id="heading-short-hierarchy">Short Hierarchy:</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Step</td><td>Who</td><td>What it does</td></tr>
</thead>
<tbody>
<tr>
<td>1</td><td>Browser/OS</td><td>Check local cache</td></tr>
<tr>
<td>2</td><td>Recursive resolver (ISP/8.8.8.8)</td><td>Does the lookup chain</td></tr>
<tr>
<td>3</td><td>Root DNS</td><td>Points to TLD (.com) servers</td></tr>
<tr>
<td>4</td><td>TLD DNS</td><td>Points to authoritative server (for domain)</td></tr>
<tr>
<td>5</td><td>Authoritative server</td><td>Returns real IP</td></tr>
<tr>
<td>6</td><td>Response &amp; Cache</td><td>Resolver → OS → Browser → You see the website</td></tr>
</tbody>
</table>
</div><p>Question :<br />Why Caching Matters and what happens when cached?</p>
<p>Because of all following steps below, caching is critical for performance:</p>
<ul>
<li><p>Browser and OS caches: avoid repeated lookups.</p>
</li>
<li><p>Resolver caches: millions of users share results.</p>
</li>
<li><p>Each record has a TTL (time-to-live) after which it expires and must be re-fetched.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How to make your website look good while sharing the link? A link preview guide with "The Open Graph protocol"]]></title><description><![CDATA[From above ^^ to below \

“It is basicaly a link preview, like you get a small card like view of the link that you are sharing”
Case*: If you are asked to improve the* SEO of your website, you will have to provide specific metadata and other dynamic ...]]></description><link>https://blog.gaurabwagle.com.np/how-to-make-your-website-look-good-while-sharing-the-link-a-link-preview-guide-with-the-open-graph-protocol</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/how-to-make-your-website-look-good-while-sharing-the-link-a-link-preview-guide-with-the-open-graph-protocol</guid><category><![CDATA[webdev]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[SEO]]></category><category><![CDATA[SEO for Developers]]></category><category><![CDATA[seo services]]></category><category><![CDATA[SEO tools]]></category><category><![CDATA[React]]></category><category><![CDATA[React Native]]></category><category><![CDATA[react js]]></category><category><![CDATA[React js Development]]></category><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Tue, 21 Oct 2025 17:08:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/yIRdUr6hIvQ/upload/fe4377088dc823bc521d3e463a71b55c.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761066009434/9271bf8c-a1f0-4020-845f-1c6edf2fb17d.png" alt class="image--center mx-auto" /></p>
<p>From above ^^ to below \</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761065962193/5ad177b6-40bb-472b-b380-6efcc14d2b15.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-it-is-basicaly-a-link-preview-like-you-get-a-small-card-like-view-of-the-link-that-you-are-sharing">“It is basicaly a link preview, like you get a small card like view of the link that you are sharing”</h2>
<p>Case*: If you are asked to improve the* SEO <em>of your website, you will have to provide specific metadata and other dynamic meta tags for better results. Open Graph makes it possible for you by providing this link preview.</em></p>
<p><em>(Notice the <mark>og</mark> prefix added to each of them. This ‘<mark>og</mark> is what helps <mark>Open Graph protocol </mark> know that the developer wants to convert his</em> webpage <em>into a</em> graph object.<em>)</em></p>
<ul>
<li><p>og:title - The title of your object as it should appear within the graph.</p>
</li>
<li><p>og:image - An image URL which should represent your object within the graph.</p>
</li>
<li><p>og:type - The <a target="_blank" href="https://ogp.me/#types">type of</a> your object, e.g., "<a target="_blank" href="http://video.movie">video.movie</a>". Depending on the type you specify, other properties may also be required.</p>
</li>
<li><p>og:url - The canonical URL of your object that will be used as its permanent ID in the graph, e.g., "<a target="_blank" href="https://www.imdb.com/title/tt0117500/">https://www.imdb.com/title/tt0117500/</a>".</p>
</li>
<li><p>og:description - A one to two sentence description of your object.</p>
</li>
</ul>
<pre><code class="lang-xml">#Example code I wrote for my portfolio website
<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>
    //compare this to the attached image
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:title"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Gaurab's portfolio website"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"By clicking onto the website you know a little about me, my life and my projects. Let's make some projects together !!"</span>/&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:image"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"https://avatars.githubusercontent.com/u/41935487?v=4"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:url"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"https://gaurabme.vercel.app/"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:type"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"website"</span> /&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"twitter:card"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"summary_large_image"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"twitter:title"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Gaurab's portfolio website"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"twitter:description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"By clicking onto the website you know a little about me, my life and my projects. Let's make some projects together !!"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"twitter:image"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"https://avatars.githubusercontent.com/u/41935487?v=4"</span> /&gt;</span>
// twitter has it's own way of writing, see on it's docs 

    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"icon"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"image/svg+xml"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/vite.svg"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/src/style.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</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">title</span>&gt;</span>Gaurab Wagle<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">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"root"</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">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/src/main.tsx"</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>Compare: <strong><em>&lt;meta property="og:title" content="Gaurab's portfolio website" /&gt;</em></strong> to the title that is showing</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1761065962193/5ad177b6-40bb-472b-b380-6efcc14d2b15.png" alt class="image--center mx-auto" /></p>
<p>For a better understanding please refer to this official website and get detailed understanding.<br />I will further upload the blog about writing the dynamic og tags because as our app grows bigger, we need dynamic descriptions.</p>
<p>Click: <a target="_blank" href="https://ogp.me/">Open Graph Protocol, og, official website</a></p>
<p>Like/Comment if you want to know how to setup dynamic og’s for different pages.</p>
]]></content:encoded></item><item><title><![CDATA[90% of Uni classes are a waste of time and energy]]></title><description><![CDATA[Image: A photo representation of an empty classroom
Context: Nepal, Kathmandu University
As a frustrated Computer Science student at KU, I can say that most university classes are a waste of time and energy. Few students actually pay attention to the...]]></description><link>https://blog.gaurabwagle.com.np/90-of-uni-classes-are-a-waste-of-time-and-energy</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/90-of-uni-classes-are-a-waste-of-time-and-energy</guid><category><![CDATA[university]]></category><category><![CDATA[#universityexperience]]></category><category><![CDATA[Study ]]></category><category><![CDATA[Computer Science]]></category><category><![CDATA[CS]]></category><category><![CDATA[Classroom]]></category><category><![CDATA[time]]></category><category><![CDATA[value]]></category><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Wed, 06 Aug 2025 17:38:11 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1754502025958/519379b3-d095-4ca6-a3e3-f37f63811ad9.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754501792831/a6a88b5f-f2dd-4dcc-9b64-e732e831858e.webp" alt class="image--center mx-auto" /></p>
<p>Image: A photo representation of an empty classroom</p>
<p>Context: Nepal, Kathmandu University</p>
<p>As a frustrated Computer Science student at KU, I can say that most university classes are a waste of time and energy. Few students actually pay attention to the teacher.I wake up early, travel a long distance,6 km(3 km of walk) only to learn very little from under-qualified professors in terms of the thinking and teaching capabilities. Education is free on internet, I find better resources for free on the internet like YouTube, online sites, and ChatGPT.I believe only 10% of my success until now is due to my teachers.</p>
<p>The current trend is gradually shifting, and I believe that in the next 3-5 years, colleges in Nepal will begin to close due to brain drain after high school. The primary reason for this brain drain is the outdated curriculum in Nepal, as a four-year degree holds little relevance in the real world.</p>
<p>In the near future, universities like KU, TU, and PU may experience this issue. As a result, there is increasing interest in colleges affiliated with foreign universities because they offer a 3 year( shorter duration ) course with concise syllabus focused on job, skill and readiness and internships upon completion.</p>
<p>As a concluding remark, I strongly advise against studying in Nepal and wasting your 4 year time period for any programmes in bachelors, particularly the four-year engineering program. My question to the readers is:</p>
<p>What percentage of students would attend university classes if there wasn't an attendance requirement of 80%?<br />Would you still attend your classes????</p>
]]></content:encoded></item><item><title><![CDATA[Pintu: A Heartbreak]]></title><description><![CDATA[The dog we're currently (2025) petting was born in our house, along with six other siblings, by his mother, named Pintu. She unexpectedly came to our house one night, the night Daddy came back home after 2 years, and started settling in. Maybe she wa...]]></description><link>https://blog.gaurabwagle.com.np/</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/</guid><category><![CDATA[DOGS]]></category><category><![CDATA[#dogsgrooming]]></category><category><![CDATA[dog treats]]></category><category><![CDATA[pets]]></category><category><![CDATA[#petslifyreview]]></category><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Wed, 06 Aug 2025 17:27:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1754500830745/7fe45b12-1929-49e9-8f60-17b4d334a9b1.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The dog we're currently (2025) petting was born in our house, along with six other siblings, by his mother, named Pintu. She unexpectedly came to our house one night, the night Daddy came back home after 2 years, and started settling in. Maybe she was looking for a place to stay, and she chose ours. She was friendly, and we named her Pintu.</p>
<hr />
<p>It's often said that female dogs exhibit greater loyalty towards their home and owners. We took good care of her. At the time, I was in 5th or 6th grade, and it was then that I began to develop a feeling for dogs. She gave birth right beside our house, which was convenient as there was a good spot for her to deliver the puppies – an old bed that provided warmth. When I first saw the litter of seven, they were smaller than average mice. For about two months, they grew, developed fur, opened their eyes, and came out of the bed. Realizing that it would be impossible for anyone to take care of all eight of them, Sabin, the owner of the attached house, decided to remove the bed and clean the area. We had a bench underneath was a small warm spot for her to live, which my dad had designed for himself to enjoy coffee, admiring the garden view. All eight puppies began to reside under that bench. For a month, we took care of them all. These black and white pups began to explore the house garden and even came indoors. They developed a good habit of going far away from the house to poop, away from their mother (Pintu). Among them, there were three males and four females. Unfortunately, being born female meant there was no hope of them finding adoptive homes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754501094848/ed04aad2-7bcc-4bc6-a7fc-aae3cfd2c832.webp" alt class="image--center mx-auto" /></p>
<hr />
<p>One dark day, the decision was made to move all of them. It was a rainy night, and as I held the light and umbrella, Sabin dai carried the box containing the seven puppies. Meanwhile, Dai, who lived in the neighbouring rented house, tied the rope to Pintu. Together, we went towards the jungle to release them. Lightning and the rain poured down relentlessly, creating a scene that now feels of a movie. We traveled about 4 km's away from home into the jungle, where we unboxed the pups and unleashed the mother. My last glimpse of them was seeing those tiny puppies coming out from the box into the rain, scattering around the area in that dark rainy night. The mother looked at me with a sense of helplessness, I still remember vividly. Deciding to return home from a different route, each step heavier than the last, stumbling along the way. The rain fell relentlessly, as if the sky itself was shedding tears of pain. Pintu followed us along the jungle road, but we threw stones at her to prevent her from following us further.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754500894998/f397c63e-3baf-4cf8-8629-6fed8e463ebb.webp" alt class="image--center mx-auto" /></p>
<p>That day, we left a mother stranded alone in the jungle with her seven little innocent puppies, who were scattering from the box. She never imagined such a fate for her family. <em>Whom to handle? My owners are going a different way, and my kids are scattered in a jungle on a dark, rainy night. Helpless and scared of other animals.</em></p>
<hr />
<p>Who would've guessed that same night, Pintu would bring those kids back home? She grabbed the puppies by their neck and carried them all the way to our house. She managed to carry four of them through the night. At one point, she left one about two-thirds of the way home, then went back for the others, one by one. The next morning, we learned from my sister that one of the males had been adopted by her friend, who lived near the area where they were left. The other four puppies made it back home. We were amazed and didn't know what to do next after witnessing such an incredible feat of love and determination.</p>
<p>All of them used to reside under our bench, and one night, there was an attack by jackals. I could hear Pintu's cries from inside, but I was too small to fight out, and it seemed too dangerous. Little did I know, it was a jackal attack. The next morning, we found all the others dead, except for the mother, Pintu, and the current dog we own. The jackals had eaten the bodies of the small pups, leaving only their heads behind. I suspect the others were also killed by jackals. Fortunately, Pintu 2 (our current dog) survived. It had hidden under a few iron window frames that were kept in the neighbouring house, as they were doing some construction. I still remember seeing Pintu 2 there, beside those steel bars, staying up all night.</p>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754501001245/e8f16da1-e6a8-47e0-a4f2-8c5d079243ff.webp" alt class="image--center mx-auto" /></p>
<p>From 8 down to just 2. We made the decision to keep the surviving one, whom we named after his mother. In this story, I have called him Pintu 2, which is our current dog. He received all the love and care, milk from his mother, and he grew up to be a beautiful and healthy dog.<br />Pintu helped his mother overcome the dark memories of her six other children and the difficult phase she had gone through.</p>
<p>One day, the mother fell ill, and it was truly terrible, I mean, very dreadful. It was a few months after she had gone through those darkest times of her life. She developed a strange wound in her ear region, which spread all over her body. The smell was so strong that we could detect it from the road when she came home to feed the baby. Insects covered her body. Now, my mother wasn't much of a pet lover. She wouldn't allow the mother dog inside the house because she feared it would transfer the wound and insects to Pintu 2, and the whole house would get infected, and so did I. I could see the pain, but I was helpless. To ease her suffering, we even gave her poison mixed with milk. It was painful to witness others throwing kerosene at her. I could see her crying day and night for nearly a month ++, crying until her last breath. After one or two months, she passed away far from home. She never returned to our house after we stopped letting her in those first few times.<br />She didn't want to burden us with the difficulty of handling her death. Oh dear, how deeply I feel sorry for your pain, my love.</p>
<hr />
<p>We didn't know where you came from, didn’t know where you lived before that, didn’t know where you went after that disease, and didn’t know the place you died. Remembering your pain, your cries all day and all night, I hate myself.</p>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754500861625/90225daa-a4c0-4010-b7a2-bf32abad407d.webp" alt class="image--center mx-auto" /></p>
<p>I hope you’re watching this and your soul is happy seeing us taking care of Pintu. I have no words, I am sorry, and I ask for your forgiveness, all of us. All those things we did were so hard on you. Remembering you now, we have Pintu in our house; we've given him the same name, he is a living reminder of your presence, a part of you.</p>
<p>The pictures are of Pintu, who has braved through it all and truly deserves all the love and happiness in the world. &lt;3 💛❤️</p>
]]></content:encoded></item><item><title><![CDATA[Create a Virtual Environment -Python- Windows/Linux]]></title><description><![CDATA[Let’s go straight:

A virtual environment is a Python environment such that the Python interpreter, libraries and scripts installed into it are isolated from those installed in other virtual environments, and (by default) any libraries installed in a...]]></description><link>https://blog.gaurabwagle.com.np/create-a-virtual-environment-python-windowslinux</link><guid isPermaLink="true">https://blog.gaurabwagle.com.np/create-a-virtual-environment-python-windowslinux</guid><category><![CDATA[Python]]></category><category><![CDATA[python beginner]]></category><category><![CDATA[Python virtual environment setup]]></category><category><![CDATA[python projects]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Windows]]></category><dc:creator><![CDATA[Gaurab Wagle]]></dc:creator><pubDate>Wed, 06 Aug 2025 17:02:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1754499620078/d32a4b51-cd32-43f1-b9fc-3a7f97f43eb8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let’s go straight:</p>
<blockquote>
<p><em>A virtual environment is a Python environment such that the Python interpreter, libraries and scripts installed into it are isolated from those installed in other virtual environments, and (by default) any libraries installed in a “system” Python, i.e., one which is installed as part of your operating system.</em></p>
<p>eg: You might need a python version of 10.5 for your project then you will install that python version by making a virtual environment. When you use the vir env you will be using 10.5 version but when you are outside of the vir env you will be using the other version(latest) maybe 20.1 ...</p>
</blockquote>
<p>Make sure to install the following things:</p>
<ul>
<li><p>Python<br />  https://www.python.org/downloads/</p>
</li>
<li><p>pip, which is a Python package installer.</p>
</li>
<li><pre><code class="lang-python">  python --version  //to see python version
  python -m ensurepip --upgrade // to install pip
</code></pre>
</li>
</ul>
<blockquote>
<h3 id="heading-for-linux">For Linux:</h3>
<pre><code class="lang-python">python3 -m venv myenv
source myenv/bin/activate
</code></pre>
<p>"myenv" is the name of the virtual environment folder.<br />Source is how we activate the vir env we created.</p>
<h3 id="heading-for-windows">For Windows:</h3>
<pre><code class="lang-python">python3 -m venv myenv
myenv\Scripts\activate
</code></pre>
<h3 id="heading-the-code-we-put-are-just-the-folders-inside-of-the-myenv-folder-you-can-check-them">The code we put are just the folders inside of the myenv folder. You can check them.</h3>
<pre><code class="lang-python">C://User/Gaurab/Desktop : 
(myenv)
</code></pre>
<p>Once activated, your terminal prompt will show (myenv) to indicate the virtual environment is active as shown above ^^.</p>
</blockquote>
<h3 id="heading-deactivate">Deactivate:</h3>
<pre><code class="lang-python">deactivate
</code></pre>
<p>Just type deactivate and you will see the (myenv) disappear and you're out of the virtual environment.</p>
<p>Some tips:<br /><strong>Always activate</strong> the virtual environment before installing any packages. This keeps your project’s dependencies isolated.</p>
<ul>
<li><p><strong>Install packages</strong> using pip after activating the environment:</p>
<pre><code class="lang-python">  pip install package-name
</code></pre>
</li>
<li><p><strong>Keep your virtual environment</strong> folder out of version control (e.g., add myenv/ to .gitignore).</p>
</li>
<li><p><strong>Deactivate</strong> the environment when you're done working by running:</p>
<pre><code class="lang-python">  deactivate
</code></pre>
</li>
<li><p><strong>Use</strong> requirements.txt to list your project's dependencies:</p>
<pre><code class="lang-python">  pip freeze &gt; requirements.txt
</code></pre>
<p>  Others can install these dependencies using:</p>
<pre><code class="lang-python">  pip install -r requirements.txt
</code></pre>
</li>
<li><p><strong>Avoid using</strong> sudo with pip install inside a virtual environment; it's unnecessary and can cause issues.</p>
</li>
</ul>
]]></content:encoded></item></channel></rss>