<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: rashidpbi</title>
    <description>The latest articles on Forem by rashidpbi (@rashidpbi).</description>
    <link>https://forem.com/rashidpbi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F811426%2F1dc75d15-7764-48b1-9933-1208a6b42faa.png</url>
      <title>Forem: rashidpbi</title>
      <link>https://forem.com/rashidpbi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rashidpbi"/>
    <language>en</language>
    <item>
      <title>The Hidden Complexity of Web Authentication: Why Every Developer Should Build Their Own (At Least Once)</title>
      <dc:creator>rashidpbi</dc:creator>
      <pubDate>Thu, 28 Aug 2025 02:07:08 +0000</pubDate>
      <link>https://forem.com/rashidpbi/the-hidden-complexity-of-web-authentication-why-every-developer-should-build-their-own-at-least-2al1</link>
      <guid>https://forem.com/rashidpbi/the-hidden-complexity-of-web-authentication-why-every-developer-should-build-their-own-at-least-2al1</guid>
      <description>&lt;p&gt;Picture this: You're building your next web application, and authentication is on your todo list. Your first instinct? Reach for Clerk, Auth0, or NextAuth.js. They're battle-tested, secure, and save you weeks of development time. But here's the thing—by always taking the easy route, you might be missing out on understanding one of the most critical aspects of web security.&lt;/p&gt;

&lt;p&gt;After implementing my own OAuth 2.0 authentication system from scratch, I discovered that what seems like straightforward user management is actually a minefield of edge cases, security considerations, and subtle gotchas that can break your application in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Authentication Trinity: More Than Just Login Forms
&lt;/h2&gt;

&lt;p&gt;Most developers think of authentication as simply verifying usernames and passwords. But in reality, modern web authentication involves three interconnected concepts that work together:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authentication&lt;/strong&gt; is about identity verification—proving who the user claims to be. This happens when someone enters their credentials or connects through OAuth providers like Google or GitHub.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authorization&lt;/strong&gt; determines what that authenticated user can actually do within your application. Just because someone can log in doesn't mean they should access admin panels or sensitive data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redirection&lt;/strong&gt; ties everything together by controlling the user's journey through your application. It ensures logged-in users don't see login pages and unauthenticated users can't access protected content.&lt;/p&gt;

&lt;p&gt;The magic happens in how these three work together. When a user logs in through Google OAuth, they're redirected to Google's servers for authentication, then back to your app with an authorization code, which you exchange for tokens that determine what they can access. Miss any step in this dance, and your security falls apart.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Token Juggling Act: Where Things Get Complicated
&lt;/h2&gt;

&lt;p&gt;OAuth 2.0 introduces a layer of complexity that catches many developers off guard. Unlike simple session-based authentication, OAuth involves managing two types of tokens with different lifespans and purposes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Access tokens&lt;/strong&gt; are your golden tickets—they prove the user is authenticated and authorized to access resources. But they're intentionally short-lived, typically expiring after just one hour. This creates a user experience problem: nobody wants to log in every hour.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refresh tokens&lt;/strong&gt; solve this by lasting much longer (usually about a week) and can generate new access tokens behind the scenes. But here's where it gets tricky—these refresh tokens are only provided during the initial authorization flow. If something goes wrong and you lose them, the user has to start over.&lt;/p&gt;

&lt;p&gt;This is where understanding beats blindly using libraries. When you know why tokens work this way, you can design your application flow to preserve them properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Battle-Tested Lessons from the Trenches
&lt;/h2&gt;

&lt;p&gt;When I built my own authentication system, I encountered scenarios that no tutorial prepared me for. These real-world edge cases taught me more about web security than any documentation could.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Refresh Token Trap
&lt;/h3&gt;

&lt;p&gt;Google's OAuth 2.0 has a gotcha that bit me hard: refresh tokens are only provided during the first authorization. If a logged-in user accidentally visits your login page and goes through OAuth again, Google won't provide a new refresh token. Your application loses the ability to refresh access tokens, effectively logging the user out after an hour.&lt;/p&gt;

&lt;p&gt;The solution? Implement smart redirection logic that prevents authenticated users from accessing the login flow. This isn't just about user experience—it's about maintaining authentication state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storage Security: The XSS Vulnerability
&lt;/h3&gt;

&lt;p&gt;Where you store tokens matters more than you might think. Local storage seems convenient, but it's vulnerable to XSS attacks. Any malicious script can read and steal tokens, compromising user accounts.&lt;/p&gt;

&lt;p&gt;Server-side storage or secure HTTP-only cookies are the way to go. The tokens never touch client-side JavaScript, making them much harder for attackers to steal.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Graceful Degradation Challenge
&lt;/h3&gt;

&lt;p&gt;What happens when refresh tokens expire? Many developers handle this poorly, showing confusing error messages or breaking the user experience. The elegant solution is to detect token expiry in your API layer and automatically redirect users back to login with a helpful message.&lt;/p&gt;

&lt;p&gt;This requires understanding the token lifecycle well enough to implement proper error handling throughout your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Libraries Can't Teach You Everything
&lt;/h2&gt;

&lt;p&gt;Don't get me wrong—authentication libraries are fantastic. They handle the heavy lifting of security best practices, token management, and provider integrations. But they also abstract away the underlying mechanics that you need to understand when things go wrong.&lt;/p&gt;

&lt;p&gt;When your production application starts throwing authentication errors at 2 AM, you need to understand whether it's a token expiry issue, a storage problem, or a redirection loop. Libraries can't debug themselves—you need to understand what's happening under the hood.&lt;/p&gt;

&lt;p&gt;Building your own authentication system once gives you this x-ray vision into how modern web authentication actually works. You'll understand why certain design decisions were made, what trade-offs exist between security and user experience, and how to extend or customize library behavior when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Learning Investment That Pays Dividends
&lt;/h2&gt;

&lt;p&gt;I'm not suggesting you reinvent the wheel for every project. Use trusted libraries for production applications. But invest time in building your own authentication flow at least once, perhaps as a side project or learning exercise.&lt;/p&gt;

&lt;p&gt;You'll gain intuition about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How OAuth flows actually work beyond the surface level&lt;/li&gt;
&lt;li&gt;Why certain security practices exist and when to apply them&lt;/li&gt;
&lt;li&gt;How to debug authentication issues in production&lt;/li&gt;
&lt;li&gt;When and how to customize library behavior safely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This knowledge transforms you from a developer who implements authentication to one who understands it. And in a world where security breaches make headlines daily, that understanding is invaluable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;The next time you reach for an authentication library, you'll do so with confidence, knowing not just how to use it, but why it works the way it does. That's the difference between writing code and engineering secure applications.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Ready to dive deeper into web authentication? Start with implementing a simple OAuth 2.0 flow with Google's APIs. The documentation is excellent, and the lessons you'll learn will serve you throughout your career.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>authentication</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Building a Google Calendar Event Handler (and the Chaos Along the Way)</title>
      <dc:creator>rashidpbi</dc:creator>
      <pubDate>Thu, 14 Aug 2025 18:01:42 +0000</pubDate>
      <link>https://forem.com/rashidpbi/building-a-google-calendar-event-handler-and-the-chaos-along-the-way-27kb</link>
      <guid>https://forem.com/rashidpbi/building-a-google-calendar-event-handler-and-the-chaos-along-the-way-27kb</guid>
      <description>&lt;p&gt;This is an update on the Google Calendar event handler I'm building. If you've got a few minutes to spare, come along for the ride — fair warning: some of what follows might be slightly exaggerated for dramatic effect. 😏&lt;/p&gt;

&lt;p&gt;I actually regret not documenting the &lt;em&gt;superhuman&lt;/em&gt; thought processes, weird developer choices, and decision-making detours I went through while building this "simple" event handler.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Idea
&lt;/h2&gt;

&lt;p&gt;The original goal was simple: test the integrability of Google Calendar with Wraft, the product we’re building at my company.&lt;br&gt;
The setup and core functionality are already ✅ done.&lt;/p&gt;

&lt;p&gt;But then I thought… why not polish it further? Add a simple UI, refine the logic, and let it live on as a neat little side project alongside the main product.&lt;br&gt;
Now I'm focusing on &lt;strong&gt;design refinements&lt;/strong&gt; and &lt;strong&gt;performance improvements&lt;/strong&gt; — plus exploring a few custom tweaks to the app's overall logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Developer Confidence Trap
&lt;/h2&gt;

&lt;p&gt;But here's the thing: As developers, over time we gain the confidence that &lt;em&gt;once the basic functionality is done&lt;/em&gt;, we can make &lt;em&gt;any&lt;/em&gt; improvement — whether it's design, performance, or even reshaping the whole workflow. (Sometimes it even feels like pulling a snake out of the code 🐍).&lt;/p&gt;

&lt;p&gt;And yet… I still make wrong turns. Wrong design calls. Wrong performance assumptions. Wrong "this will be easy" moments.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Reality Check
&lt;/h2&gt;

&lt;p&gt;But that's the fun of it — learning, iterating, and continuing down the road.&lt;/p&gt;

&lt;p&gt;So here's to fixing the wrong decisions, improving what's missing, and making this event handler &lt;em&gt;better than it needs to be&lt;/em&gt;. Stay tuned for the next update — it might involve fewer snakes. Or more.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🔑 Figuring Out Authentication in Next.js (While Trying Not to Lose My Sanity 😅)</title>
      <dc:creator>rashidpbi</dc:creator>
      <pubDate>Sat, 09 Aug 2025 10:35:33 +0000</pubDate>
      <link>https://forem.com/rashidpbi/figuring-out-authentication-in-nextjs-while-trying-not-to-lose-my-sanity--29bo</link>
      <guid>https://forem.com/rashidpbi/figuring-out-authentication-in-nextjs-while-trying-not-to-lose-my-sanity--29bo</guid>
      <description>&lt;p&gt;I'm going to be honest — I'm &lt;strong&gt;still figuring out&lt;/strong&gt; the authentication flow in my Next.js app. Right now, I'm using Google OAuth for a Calendar integration, and every time I think I've nailed it… a token expires and my whole "flawless" login flow collapses.&lt;/p&gt;

&lt;p&gt;If you've been down this road, you already know the &lt;em&gt;fun&lt;/em&gt; parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cookies disappearing like socks in the dryer&lt;/li&gt;
&lt;li&gt;Google's &lt;code&gt;invalid_grant&lt;/code&gt; error appearing out of nowhere&lt;/li&gt;
&lt;li&gt;That feeling when your API route works &lt;strong&gt;only if you log in 5 seconds ago&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This post isn't "Here's the perfect authentication guide." It's more like "Here's what I'm doing &lt;em&gt;right now&lt;/em&gt; so my app works — but I know there are better ways."&lt;/p&gt;

&lt;h2&gt;
  
  
  The messy reality of OAuth
&lt;/h2&gt;

&lt;p&gt;Most OAuth tutorials basically stop after:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click "Sign in with Google"&lt;/li&gt;
&lt;li&gt;Get &lt;code&gt;access_token&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Call an API 🎉&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's fine for a demo. In real life:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tokens expire (sometimes faster than you expect)&lt;/li&gt;
&lt;li&gt;Refresh tokens aren't always provided&lt;/li&gt;
&lt;li&gt;You have to decide &lt;em&gt;where&lt;/em&gt; to handle expiry — server, client, or both&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Spoiler: I learned you actually need &lt;strong&gt;both&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  My current API route (work in progress)
&lt;/h2&gt;

&lt;p&gt;Here's the route I'm using to fetch Google Calendar events. It's not perfect, but it's keeping my app from falling apart (most of the time).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// /pages/api/eventList.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;google&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;googleapis&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;oauth2Client&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/utils/google-auth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getFirstDayOfLastMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;google_access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;expiry_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;refresh_token_expires_in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;refresh_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;oauth2Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCredentials&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;google_access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;expiry_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;refresh_token_expires_in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;refresh_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;calendar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calendar&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;v3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;oauth2Client&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;calendar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;oauth2Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;calendarId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// maxResults:13,&lt;/span&gt;
         &lt;span class="na"&gt;timeMin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getFirstDayOfLastMonth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;// timeMin: "2025-07-01T00:00:00.000Z",&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Google API error:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Normalize error&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;normalizedError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unknown error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;normalizedError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;normalizedError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;normalizedError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;normalizedError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Allow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;405&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Method &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; Not Allowed`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The good:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If there's no token, I stop immediately.&lt;/li&gt;
&lt;li&gt;If Google says the token is bad, I return a &lt;code&gt;401&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The "still figuring out" parts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don't refresh tokens automatically yet.&lt;/li&gt;
&lt;li&gt;I don't update cookies when I do get a new token.&lt;/li&gt;
&lt;li&gt;My error handling works, but it's not super descriptive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Client-side "bail out" strategy
&lt;/h2&gt;

&lt;p&gt;Right now, my frontend just looks for &lt;code&gt;401&lt;/code&gt; and punts the user back to &lt;code&gt;/login&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchEvents&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/eventList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loggedOutDueToTokenIssue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's simple, and it works… but it also means the user gets kicked out even in cases where I &lt;em&gt;could&lt;/em&gt; have refreshed the token in the background.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things I know I need to improve
&lt;/h2&gt;

&lt;p&gt;✅ Automatic token refresh on the server (before hitting Google's API)&lt;br&gt;&lt;br&gt;
✅ Updating cookies when I refresh a token&lt;br&gt;&lt;br&gt;
✅ Returning more structured error messages so the client knows exactly what happened&lt;br&gt;&lt;br&gt;
✅ Maybe centralizing all token logic so I don't repeat it in every route&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts (for now)
&lt;/h2&gt;

&lt;p&gt;I'm sharing this because sometimes dev posts make it sound like people go from "I want OAuth" to "I have the perfect auth system" in one weekend. The truth is, I'm still tripping over my own code, but each small improvement makes the whole thing &lt;em&gt;less fragile&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you've built a rock-solid Google OAuth flow in Next.js — especially one that gracefully handles token refresh — please drop your tips in the comments. I could really use them. 🙃&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding Middleware in Express.js (With Simple Implementation)</title>
      <dc:creator>rashidpbi</dc:creator>
      <pubDate>Wed, 06 Aug 2025 09:15:13 +0000</pubDate>
      <link>https://forem.com/rashidpbi/understanding-middleware-in-expressjs-with-simple-implementation-5eoc</link>
      <guid>https://forem.com/rashidpbi/understanding-middleware-in-expressjs-with-simple-implementation-5eoc</guid>
      <description>&lt;p&gt;If you've worked with &lt;strong&gt;Express.js&lt;/strong&gt;, you've probably seen &lt;code&gt;app.use()&lt;/code&gt; everywhere. But what exactly is middleware? How does &lt;code&gt;app.use(fn)&lt;/code&gt; work behind the scenes?&lt;/p&gt;

&lt;p&gt;In this post, let's break down &lt;strong&gt;what middleware is&lt;/strong&gt; and  how it works in Express.js&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑 What is Middleware?
&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;Express.js&lt;/strong&gt;, middleware is simply a &lt;strong&gt;function&lt;/strong&gt; that runs during the &lt;strong&gt;request-response cycle&lt;/strong&gt;. It has access to the &lt;strong&gt;request object&lt;/strong&gt; (&lt;code&gt;req&lt;/code&gt;), the &lt;strong&gt;response object&lt;/strong&gt; (&lt;code&gt;res&lt;/code&gt;), and a special &lt;code&gt;next()&lt;/code&gt; function that passes control to the next middleware.&lt;/p&gt;

&lt;p&gt;Express uses middleware to handle &lt;strong&gt;logging, authentication, error handling, CORS, body parsing&lt;/strong&gt;, and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗 The Syntax of Middleware
&lt;/h2&gt;

&lt;p&gt;Middleware is typically added using &lt;code&gt;app.use()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Middleware executed!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Pass control to the next middleware&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't call &lt;code&gt;next()&lt;/code&gt;, the request will &lt;strong&gt;hang&lt;/strong&gt; and never reach the final route handler.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌐 Common Use Cases of Middleware
&lt;/h2&gt;

&lt;p&gt;Here are a few examples of middleware in action:&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ &lt;strong&gt;Logging Every Request&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; at &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ This runs for every request and logs request info.&lt;/p&gt;

&lt;h3&gt;
  
  
  2️⃣ &lt;strong&gt;Applying Middleware to Specific Routes&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Admin route accessed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Runs &lt;strong&gt;only&lt;/strong&gt; for &lt;code&gt;/admin&lt;/code&gt; and its sub-routes.&lt;/p&gt;

&lt;h3&gt;
  
  
  3️⃣ &lt;strong&gt;Using Third-Party Middleware (e.g., CORS)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Enables &lt;strong&gt;CORS&lt;/strong&gt; for all requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  4️⃣ &lt;strong&gt;Serving Static Files&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;static&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Serves HTML, CSS, JS, and images directly from the &lt;code&gt;public&lt;/code&gt; folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚨 Error-Handling Middleware
&lt;/h2&gt;

&lt;p&gt;In Express, error-handling middleware looks slightly different—it has &lt;strong&gt;4 parameters&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Something broke!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Express automatically detects this pattern and uses it to catch errors.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Key Takeaways
&lt;/h2&gt;

&lt;p&gt;✅ Middleware is at the &lt;strong&gt;heart of Express.js&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
✅ It allows preprocessing of requests before they hit route handlers.&lt;br&gt;&lt;br&gt;
✅ &lt;code&gt;app.use(fn)&lt;/code&gt; registers middleware functions in a chain-like system.&lt;br&gt;&lt;br&gt;
✅ Calling &lt;code&gt;next()&lt;/code&gt; is crucial to move to the next middleware.  &lt;/p&gt;

</description>
    </item>
    <item>
      <title>🧵 Understanding JavaScript Promises, Callbacks &amp; Handling Multiple Async Tasks</title>
      <dc:creator>rashidpbi</dc:creator>
      <pubDate>Tue, 05 Aug 2025 20:03:22 +0000</pubDate>
      <link>https://forem.com/rashidpbi/understanding-javascript-promises-callbacks-handling-multiple-async-tasks-4326</link>
      <guid>https://forem.com/rashidpbi/understanding-javascript-promises-callbacks-handling-multiple-async-tasks-4326</guid>
      <description>&lt;p&gt;JavaScript is single-threaded, yet it handles tasks like API calls, timers, and user interactions efficiently — thanks to &lt;strong&gt;callbacks&lt;/strong&gt; and &lt;strong&gt;promises&lt;/strong&gt;. Let's explore how these tools work together and how to manage multiple async operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Callback &amp;amp; Asynchronicity
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;callback&lt;/strong&gt; is a function passed into another function to run later — perfect for async tasks like fetching data or waiting for a timeout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This runs later&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But callbacks can lead to &lt;strong&gt;callback hell&lt;/strong&gt;, making code hard to read and maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Enter Promises
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Promise&lt;/strong&gt; represents a value that may be available now, later, or never.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Done!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;code&gt;async/await&lt;/code&gt; improves readability even more:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔄 Handling Multiple Promises
&lt;/h2&gt;

&lt;p&gt;JavaScript provides powerful utilities for handling &lt;strong&gt;multiple&lt;/strong&gt; promises at once:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ &lt;code&gt;Promise.all([...])&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Waits for &lt;strong&gt;all&lt;/strong&gt; promises to resolve. Fails fast if any reject.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧘 &lt;code&gt;Promise.allSettled([...])&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Waits for &lt;strong&gt;all&lt;/strong&gt; to settle (resolve or reject) and returns results for each.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allSettled&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p3&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🏁 &lt;code&gt;Promise.race([...])&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Returns the &lt;strong&gt;first&lt;/strong&gt; settled (resolve or reject) promise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;race&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🥇 &lt;code&gt;Promise.any([...])&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Returns the &lt;strong&gt;first fulfilled&lt;/strong&gt; promise. Ignores rejections unless all fail.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;p1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;p2&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧩 Final Thoughts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Callbacks&lt;/strong&gt; introduced async flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promises&lt;/strong&gt; simplified it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Promise combinators&lt;/strong&gt; (&lt;code&gt;all&lt;/code&gt;, &lt;code&gt;allSettled&lt;/code&gt;, &lt;code&gt;race&lt;/code&gt;, &lt;code&gt;any&lt;/code&gt;) give us flexible control over multiple tasks.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;async/await&lt;/code&gt; for cleaner, more readable code.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>From Imposter Syndrome to Progress: A Developer's Mental Journey</title>
      <dc:creator>rashidpbi</dc:creator>
      <pubDate>Thu, 31 Jul 2025 05:43:29 +0000</pubDate>
      <link>https://forem.com/rashidpbi/from-imposter-syndrome-to-progress-a-developers-mental-journey-27l9</link>
      <guid>https://forem.com/rashidpbi/from-imposter-syndrome-to-progress-a-developers-mental-journey-27l9</guid>
      <description>&lt;p&gt;In my experience so far, almost every developer goes through &lt;strong&gt;imposter syndrome&lt;/strong&gt;—except a rare few.&lt;/p&gt;

&lt;p&gt;I've seen many talented people quit, believing they &lt;em&gt;"may not be able to make it."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But here's the truth:&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Things start making sense only after periods of consistent effort.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The journey is often frustrating but rewarding along the way (and honestly, there's no real &lt;em&gt;"end point"&lt;/em&gt; to learning in this field 🙂). I've been there too—moments of self-doubt, overthinking, and negative spirals.&lt;br&gt;
&lt;br&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Strategies That Helped Me (and Might Help You Too) &lt;br&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔹 1. Take a Short Break
&lt;/h3&gt;

&lt;p&gt;Sometimes stepping away is the best move. Go for a walk. Clear your mind. Often, solutions "click" when you're no longer stuck in the same thought loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 2. Redefine Your Goal
&lt;/h3&gt;

&lt;p&gt;Instead of saying, &lt;em&gt;"I must solve this now,"&lt;/em&gt; change your goal to:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"I'll spend 10 more minutes exploring this."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Draw a line for every 10 minutes spent or for every small bit of progress made. ✅ &lt;strong&gt;Micro-wins add up and build momentum.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 3. Look Back to Move Forward
&lt;/h3&gt;

&lt;p&gt;Remind yourself how far you've already come. If you've overcome past hurdles, you can overcome this one too.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 4. Switch Context
&lt;/h3&gt;

&lt;p&gt;Solve a different problem for a while. A small win elsewhere can recharge your motivation and perspective.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💭 Final Words
&lt;/h2&gt;

&lt;p&gt;If you're feeling stuck or doubting yourself—know this: You're not alone. Most developers have been there.&lt;/p&gt;

&lt;p&gt;What matters is staying &lt;strong&gt;consistent&lt;/strong&gt;, &lt;strong&gt;patient&lt;/strong&gt;, and &lt;strong&gt;kind to yourself&lt;/strong&gt; during the journey.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Keep going. Things will click. They always do.&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🚀 A Practical Guide to TypeScript in Next.js (For Real-World Devs)</title>
      <dc:creator>rashidpbi</dc:creator>
      <pubDate>Tue, 29 Jul 2025 15:06:10 +0000</pubDate>
      <link>https://forem.com/rashidpbi/a-practical-guide-to-typescript-in-nextjs-for-real-world-devs-4a62</link>
      <guid>https://forem.com/rashidpbi/a-practical-guide-to-typescript-in-nextjs-for-real-world-devs-4a62</guid>
      <description>&lt;p&gt;I recently dove deep into integrating TypeScript with a Next.js project, and while the official docs are helpful, I wanted to consolidate my understanding in a way that actually clicks — for myself and for anyone else walking the same path. This post captures everything I wish I'd known earlier: not just the how, but also the why behind TypeScript's behavior in a Next.js setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 Setting Up TypeScript in a Next.js Project
&lt;/h2&gt;

&lt;p&gt;If you're starting from scratch, here's how to set up TypeScript with a Next.js app:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create a Next.js Project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest my-next-app
&lt;span class="nb"&gt;cd &lt;/span&gt;my-next-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Install TypeScript and Type Definitions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add &lt;span class="nt"&gt;-D&lt;/span&gt; typescript @types/react @types/node
&lt;span class="c"&gt;# or&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; typescript @types/react @types/node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Run the Dev Server
&lt;/h3&gt;

&lt;p&gt;When you run &lt;code&gt;pnpm dev&lt;/code&gt; or &lt;code&gt;npm run dev&lt;/code&gt;, Next.js detects TypeScript and automatically generates a basic &lt;code&gt;tsconfig.json&lt;/code&gt; for you. You don't need to configure compilation separately — Next.js handles that under the hood.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤖 So… What Does TypeScript Actually Do?
&lt;/h2&gt;

&lt;p&gt;TypeScript brings static typing to JavaScript. Think of it as a spell checker for your logic. It catches errors like these:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;25&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Error: Type 'string' is not assignable to type 'number'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This kind of feedback before running your app is what makes TS shine — especially as your codebase grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 End Goal of Using TypeScript?
&lt;/h2&gt;

&lt;p&gt;After proper integration, your TypeScript setup should:&lt;/p&gt;

&lt;p&gt;✅ Catch bugs before runtime&lt;/p&gt;

&lt;p&gt;✅ Improve code readability and maintainability&lt;/p&gt;

&lt;p&gt;✅ Boost IDE features like autocomplete and refactoring&lt;/p&gt;

&lt;p&gt;✅ Make large projects safer to work on (hello, refactors!)&lt;/p&gt;

&lt;p&gt;And the best part? You don't need to run any special build command for TS in Next.js. The framework handles compilation transparently.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 Does TypeScript Compilation Actually Happen?
&lt;/h2&gt;

&lt;p&gt;Yes, but you rarely see it directly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In dev mode (&lt;code&gt;pnpm dev&lt;/code&gt;), TypeScript is compiled on the fly.&lt;/li&gt;
&lt;li&gt;In production builds (&lt;code&gt;pnpm build&lt;/code&gt;), Next.js compiles everything to pure JavaScript inside the &lt;code&gt;.next/&lt;/code&gt; directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So ultimately, browsers only see JavaScript. TypeScript helps us during development and build time.&lt;/p&gt;

&lt;h2&gt;
  
  
  ❓ Do You Need to Manually Compile .ts Files?
&lt;/h2&gt;

&lt;p&gt;Nope. Not in Next.js.&lt;/p&gt;

&lt;p&gt;If you're curious, you can compile TS with &lt;code&gt;tsc&lt;/code&gt; manually in plain TypeScript projects, but with Next.js, it's all baked in.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 Type Errors &amp;amp; Editor Support
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does TS stop you from assigning wrong types?
&lt;/h3&gt;

&lt;p&gt;Yes, and that's its superpower.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Error: Argument of type 'number' is not assignable to type 'string'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Does this error handling come from a VS Code extension?
&lt;/h3&gt;

&lt;p&gt;No. VS Code has built-in TypeScript support — you get error squiggles, IntelliSense, and quick fixes out of the box. Extensions like ESLint or Prettier can enhance it, but aren't necessary to use TypeScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧾 What Is tsconfig.json and Do You Need It?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;tsconfig.json&lt;/code&gt; file is TypeScript's configuration brain. While VS Code can run without it, having one:&lt;/p&gt;

&lt;p&gt;📁 Controls which files to include/exclude&lt;/p&gt;

&lt;p&gt;🔐 Enables strict type checking&lt;/p&gt;

&lt;p&gt;✨ Supports path aliases (e.g. &lt;code&gt;@/components&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Example config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"preserve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"baseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"paths"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@/*"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"src/*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noEmit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"include"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"next-env.d.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"**/*.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"**/*.tsx"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node_modules"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📄 What Are Type Declaration Files (.d.ts)?
&lt;/h2&gt;

&lt;p&gt;A Type Declaration File is like telling TypeScript:&lt;/p&gt;

&lt;p&gt;"Hey, this function/variable exists — trust me — and here's what its type looks like."&lt;/p&gt;

&lt;h3&gt;
  
  
  Use case:
&lt;/h3&gt;

&lt;p&gt;You're working with a global JavaScript library that's not typed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// global library: myLib.js&lt;/span&gt;
&lt;span class="nx"&gt;myLib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of TS screaming at you, you declare its shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// global.d.ts&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nx"&gt;myLib&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;makeGreeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;numberOfGreetings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now TypeScript understands how to treat &lt;code&gt;myLib&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: Overloaded Functions
&lt;/h3&gt;

&lt;p&gt;TS can also handle functions that behave differently based on input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Widget&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Widget&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So &lt;code&gt;getWidget(1)&lt;/code&gt; returns one widget, and &lt;code&gt;getWidget("all")&lt;/code&gt; returns an array.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Final Words
&lt;/h2&gt;

&lt;p&gt;TypeScript isn't about writing more code — it's about writing safer code. In a modern stack like Next.js, it integrates seamlessly, improves DX (Developer Experience), and saves you from a ton of head-scratching bugs down the line.&lt;/p&gt;

&lt;p&gt;If you're still unsure whether to go all-in with TS, try enabling it in just one file — you might not go back.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🔀 Maintaining a Linear Commit History in Git</title>
      <dc:creator>rashidpbi</dc:creator>
      <pubDate>Sat, 26 Jul 2025 17:58:10 +0000</pubDate>
      <link>https://forem.com/rashidpbi/maintaining-a-linear-commit-history-in-git-4gff</link>
      <guid>https://forem.com/rashidpbi/maintaining-a-linear-commit-history-in-git-4gff</guid>
      <description>&lt;p&gt;While working with Git branches like &lt;code&gt;develop&lt;/code&gt; and &lt;code&gt;main&lt;/code&gt;, it's common to frequently merge changes. But did you know that doing so with regular merges can &lt;strong&gt;break a linear commit history&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Here's what I learned today 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Problem
&lt;/h2&gt;

&lt;p&gt;If you keep merging from &lt;code&gt;develop&lt;/code&gt; to &lt;code&gt;main&lt;/code&gt; using regular &lt;code&gt;git merge&lt;/code&gt;, Git will create &lt;strong&gt;merge commits&lt;/strong&gt;, leading to a &lt;strong&gt;non-linear (branched)&lt;/strong&gt; commit history.&lt;/p&gt;

&lt;p&gt;This can make &lt;code&gt;git log&lt;/code&gt; harder to read, especially in large projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ How to Maintain a Linear History
&lt;/h2&gt;

&lt;p&gt;To ensure a clean, straight commit history on &lt;code&gt;main&lt;/code&gt;, use one of these strategies:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Rebase Before Merge&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout develop
git rebase main &lt;span class="c"&gt;# Replay develop commits on top of main&lt;/span&gt;
git checkout main
git merge &lt;span class="nt"&gt;--ff-only&lt;/span&gt; develop &lt;span class="c"&gt;# Fast-forward only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ This avoids merge commits and keeps the history linear.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Use Squash Merging (Optional)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you want to combine all develop changes into a single commit before merging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main
git merge &lt;span class="nt"&gt;--squash&lt;/span&gt; develop
git commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎯 Useful for condensing work into one clean commit.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Use Fast-Forward Merges Only&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Prevent accidental merge commits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git merge &lt;span class="nt"&gt;--ff-only&lt;/span&gt; develop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📌 Final Tip
&lt;/h2&gt;

&lt;p&gt;🔁 Repeat this pattern consistently to keep &lt;code&gt;main&lt;/code&gt; clean and linear — great for production branches and readable history.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tags: #git #github #versioncontrol #devtips #100DaysOfDev&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🔄 React Lifecycle, useEffect, and What’s Really Happening in Next.js</title>
      <dc:creator>rashidpbi</dc:creator>
      <pubDate>Fri, 25 Jul 2025 16:13:45 +0000</pubDate>
      <link>https://forem.com/rashidpbi/react-lifecycle-useeffect-and-whats-really-happening-in-nextjs-3pb3</link>
      <guid>https://forem.com/rashidpbi/react-lifecycle-useeffect-and-whats-really-happening-in-nextjs-3pb3</guid>
      <description>&lt;p&gt;When I started learning React and Next.js, I wanted to understand not just how to use hooks like &lt;code&gt;useEffect&lt;/code&gt;, but what's really happening under the hood. Here's a beginner-friendly breakdown of what I learned — and how it ties together with core JavaScript concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 Understanding &lt;code&gt;useEffect&lt;/code&gt; with React Lifecycle
&lt;/h2&gt;

&lt;p&gt;React components go through three main phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mounting&lt;/strong&gt; – inserted into the DOM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Updating&lt;/strong&gt; – re-render due to props/state change&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unmounting&lt;/strong&gt; – removed from the DOM&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In functional components, &lt;code&gt;useEffect&lt;/code&gt; acts as a replacement for old class lifecycle methods like &lt;code&gt;componentDidMount&lt;/code&gt;, &lt;code&gt;componentDidUpdate&lt;/code&gt;, and &lt;code&gt;componentWillUnmount&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// runs once on mount&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// cleanup before unmount&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Common patterns&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;useEffect usage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Run once on mount&lt;/td&gt;
&lt;td&gt;&lt;code&gt;useEffect(() =&amp;gt; {...}, [])&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run on update&lt;/td&gt;
&lt;td&gt;&lt;code&gt;useEffect(() =&amp;gt; {...}, [deps])&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cleanup&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;return () =&amp;gt; {...}&lt;/code&gt; inside useEffect&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Think of &lt;code&gt;useEffect&lt;/code&gt; as a way to handle side effects (like API calls, subscriptions) after the DOM is updated.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ Can I Use useState Inside useEffect?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;No&lt;/strong&gt; — calling &lt;code&gt;useState()&lt;/code&gt; inside &lt;code&gt;useEffect()&lt;/code&gt; violates the Rules of Hooks.&lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;Invalid&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ❌ Not allowed&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Valid&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// ✅ Allowed&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔍 JavaScript Concepts Behind Next.js
&lt;/h2&gt;

&lt;p&gt;Next.js is a powerful React framework, but it's built on top of vanilla JavaScript and Node.js. Here are the core JS concepts powering it:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Why It Matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;import/export&lt;/td&gt;
&lt;td&gt;Modular code structure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;async/await &amp;amp; Promises&lt;/td&gt;
&lt;td&gt;Data fetching &amp;amp; API routes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Closures&lt;/td&gt;
&lt;td&gt;Powering hooks and handlers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Array methods (map, filter)&lt;/td&gt;
&lt;td&gt;Rendering lists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spread/Rest &amp;amp; Destructuring&lt;/td&gt;
&lt;td&gt;Cleaner state updates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File system APIs&lt;/td&gt;
&lt;td&gt;Routing and API creation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Environment variables&lt;/td&gt;
&lt;td&gt;App config (.env.local)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js concepts&lt;/td&gt;
&lt;td&gt;Server-side logic in API routes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The more you understand JavaScript fundamentals, the easier Next.js becomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Learning React and Next.js by diving into the underlying JS helped me gain real clarity. Instead of memorizing patterns, I now understand why things work — and when to use them.&lt;/p&gt;

&lt;p&gt;If you're a beginner, my tip: spend time understanding hooks, lifecycle, and JS concepts like promises, closures, and modules. It pays off quickly 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🤯 Understanding Google OAuth2 Token Refresh in Node.js (with googleapis)</title>
      <dc:creator>rashidpbi</dc:creator>
      <pubDate>Thu, 24 Jul 2025 18:22:16 +0000</pubDate>
      <link>https://forem.com/rashidpbi/understanding-google-oauth2-token-refresh-in-nodejs-with-googleapis-157</link>
      <guid>https://forem.com/rashidpbi/understanding-google-oauth2-token-refresh-in-nodejs-with-googleapis-157</guid>
      <description>&lt;p&gt;When integrating Google OAuth2 in your Node.js / Next.js app using the googleapis library, a key question is:&lt;/p&gt;

&lt;p&gt;🧠 &lt;strong&gt;"How do I handle access token expiration and refresh automatically?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Turns out — you don't need to handle much at all. But understanding why and how took me down a rabbit hole. Here's what I learned so you don't get stuck like I did.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑 The Basics
&lt;/h2&gt;

&lt;p&gt;When you authorize a user via the OAuth2 web server flow (&lt;code&gt;access_type: "offline"&lt;/code&gt;), Google returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;access_token&lt;/strong&gt; – short-lived, used for API requests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;refresh_token&lt;/strong&gt; – used to get a new access token&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;expiry_date&lt;/strong&gt; – timestamp (in ms) when the access token expires&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The good news? You can make Google auto-refresh tokens just by doing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;oauth2Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCredentials&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;refresh_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;expiry_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, call the API like normal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;calendar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calendar&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;v3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;oauth2Client&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;calendar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;calendarId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;eventId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the &lt;code&gt;access_token&lt;/code&gt; is expired, the client automatically refreshes it using the &lt;code&gt;refresh_token&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;🎉 &lt;strong&gt;No need to manually check expiry or refresh!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Then Why Do People Use getAccessToken()?
&lt;/h2&gt;

&lt;p&gt;Great question!&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;getAccessToken()&lt;/code&gt; only when you need the raw token string, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding it to custom headers&lt;/li&gt;
&lt;li&gt;Injecting into a GraphQL/WebSocket context&lt;/li&gt;
&lt;li&gt;Logging / debugging
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;oauth2Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAccessToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otherwise, skip it. Google handles everything internally during requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 How I Tested the Refresh Behavior
&lt;/h2&gt;

&lt;p&gt;Want to test token refresh manually without waiting for expiration?&lt;/p&gt;

&lt;p&gt;Just fake the expiry like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;oauth2Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setCredentials&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;refresh_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;expiry_date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// fake it as expired&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then make a normal API call — it will refresh in the background.&lt;/p&gt;

&lt;h2&gt;
  
  
  👀 Bonus: Log When Token Refresh Happens
&lt;/h2&gt;

&lt;p&gt;You can log when a refresh happens using the &lt;code&gt;tokens&lt;/code&gt; event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;oauth2Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tokens&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🔄 Refreshed tokens:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect for debugging or confirming it's working.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The docs are technically right, but don't show everything clearly&lt;/li&gt;
&lt;li&gt;The googleapis package uses google-auth-library internally, which handles refresh logic&lt;/li&gt;
&lt;li&gt;Set a past &lt;code&gt;expiry_date&lt;/code&gt; + make a request = auto-refresh&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;getAccessToken()&lt;/code&gt; only when you need the token string&lt;/li&gt;
&lt;li&gt;You don't need to memorize class hierarchies — but checking inheritance (like OAuth2Client → AuthClient) helps&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏁 Final Tip
&lt;/h2&gt;

&lt;p&gt;If you're ever unsure about how a client like OAuth2Client behaves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look for event hooks (like &lt;code&gt;tokens&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Check method docs (&lt;code&gt;getAccessToken&lt;/code&gt;, &lt;code&gt;request&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Look at class inheritance&lt;/li&gt;
&lt;li&gt;Test locally with fake expiry&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>googleapis</category>
      <category>oauth</category>
      <category>webdev</category>
      <category>node</category>
    </item>
  </channel>
</rss>
