<?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>DEV Community: Somnath Baidya</title>
    <description>The latest articles on DEV Community by Somnath Baidya (@dessomu).</description>
    <link>https://dev.to/dessomu</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%2F1503034%2Fc78f2761-bc07-43e6-82bb-07b9be4781ce.jpeg</url>
      <title>DEV Community: Somnath Baidya</title>
      <link>https://dev.to/dessomu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dessomu"/>
    <language>en</language>
    <item>
      <title>My Experience Building a Full-Stack App (Next.js + Express + MongoDB)</title>
      <dc:creator>Somnath Baidya</dc:creator>
      <pubDate>Wed, 12 Nov 2025 08:04:03 +0000</pubDate>
      <link>https://dev.to/dessomu/my-experience-building-a-full-stack-app-nextjs-express-mongodb-4bb3</link>
      <guid>https://dev.to/dessomu/my-experience-building-a-full-stack-app-nextjs-express-mongodb-4bb3</guid>
      <description>&lt;p&gt;I am turning to full-stack from a frontend developer. As a React.Js developer, I wanted to stick with the javascript ecosystem. So, intuitively I picked Next.Js to smoothen the transition, reused some of my react code blocks to do so &amp;amp; built a few simple Node.Js apps.&lt;/p&gt;

&lt;p&gt;Problems occurred as I built the frontend in Next.js and the backend with Express+MongoDB Compass, then deployed them on Vercel and Render separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  I ) Deployment Failure Due to Local MongoDB Setup :
&lt;/h2&gt;

&lt;p&gt;The Express + MongoDB application was deployed on &lt;strong&gt;Render&lt;/strong&gt;, but it was still using a &lt;strong&gt;local MongoDB Compass setup&lt;/strong&gt; instead of a cloud database.&lt;/p&gt;

&lt;p&gt;As Render (and services like Vercels) are designed to connect to &lt;strong&gt;hosted databases&lt;/strong&gt;, the deployment failed immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Resolve :&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I learned about the issue and created a MongoDB Atlas cluster, connected it with MongoDB Compass using the atlas connection string to access and manage the database in the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  II ) Incorrect Cookie Handling in Next.js :
&lt;/h2&gt;

&lt;p&gt;Initially, cookies were being &lt;strong&gt;set and verified in Next.js&lt;/strong&gt; rather than in the &lt;strong&gt;Express backend&lt;/strong&gt;. Since both environments were completely separate, it caused conflicts.&lt;/p&gt;

&lt;h3&gt;
  
  
  A quick recap :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Only the &lt;strong&gt;backend&lt;/strong&gt; should create and remove secure cookies (&lt;code&gt;httpOnly&lt;/code&gt;, &lt;code&gt;secure&lt;/code&gt;, &lt;code&gt;sameSite&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;frontend&lt;/strong&gt; should not handle sensitive cookie logic due to potential &lt;strong&gt;XSS&lt;/strong&gt; &lt;strong&gt;attack&lt;/strong&gt; risks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the ideal way is to &lt;strong&gt;set and clear cookies from the backend&lt;/strong&gt; during login and logout, while the frontend simply managed routing logic.&lt;/p&gt;

&lt;p&gt;Also I was trying to verify cookie in &lt;strong&gt;Next.js Middleware&lt;/strong&gt;, which runs in an &lt;strong&gt;Edge Runtime environment — not Node.js&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This environment can only check &lt;strong&gt;if a cookie exists&lt;/strong&gt;, not verify it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolve :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Removed &lt;code&gt;app/api/session&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Only conditional redirection logic (&lt;code&gt;if-else&lt;/code&gt; checks) was kept in &lt;code&gt;middleware.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;middleware&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;session_marker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;value&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;path&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;nextUrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;path&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&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;URL&lt;/span&gt;&lt;span class="p"&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="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="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;session&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;path&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&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;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/home&lt;/span&gt;&lt;span class="dl"&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="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;III ) Cross-Origin Cookie Issue :&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;New issue appeared as I deployed them.&lt;/p&gt;

&lt;p&gt;While testing locally, both frontend and backend shared the same origin, so cookies persisted correctly.&lt;br&gt;&lt;br&gt;
But, in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Frontend&lt;/strong&gt; &lt;strong&gt;:&lt;/strong&gt; deployed on &lt;code&gt;vercel.app&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backend&lt;/strong&gt; &lt;strong&gt;:&lt;/strong&gt; deployed on &lt;code&gt;onrender.com&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In production when a user logged in, the backend generated a cookie correctly using the firebase token. The cookie was visible in the browser’s DevTools for a fraction of sec but disappeared immediately as the page reloaded.&lt;/p&gt;

&lt;p&gt;Now the user is redirected back to the login page, as if never authenticated.&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;// Login (set)&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;cookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auth_token&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;httpOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
  &lt;span class="na"&gt;sameSite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&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;none&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;lax&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;maxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&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;// expires in 7 days&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&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="c1"&gt;// Logout (clear)&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;clearCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auth_token&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="na"&gt;httpOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sameSite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&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;none&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;lax&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&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;h3&gt;
  
  
  &lt;strong&gt;Attempts to fix the issue :&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Using&lt;/strong&gt; &lt;strong&gt;CHIPS (Cookies Having Independent Partitioned State).&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Setting&lt;/strong&gt; &lt;code&gt;domain&lt;/code&gt; &lt;strong&gt;attributes for cookies explicitly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But that won’t work, as &lt;code&gt;vercel.app&lt;/code&gt; &amp;amp; &lt;code&gt;onrender.com&lt;/code&gt; are completely different top-level domains&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&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;cookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auth_token&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="na"&gt;partitioned&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// CHIPS&lt;/span&gt;
  &lt;span class="na"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://mern-todo-8f4w.onrender.com/&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;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Adding proxy routes in&lt;/strong&gt; &lt;code&gt;next.config.js&lt;/code&gt; to simulate same-origin behaviour, which worked only on development.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** @type {import('next').NextConfig} */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;rewrites&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="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;source&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/:path*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://mern-todo-8f4w.onrender.com/:path*&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="p"&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Fact :&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Cross-origin cookies between different deployment domains are unreliable and often blocked by browsers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Implementing a Hybrid JWT + Session Authentication&lt;/strong&gt; :
&lt;/h2&gt;

&lt;p&gt;Here is how it works,&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Login request :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The frontend sends a &lt;strong&gt;Firebase token&lt;/strong&gt; to the backend.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The backend verifies it using &lt;code&gt;firebase-admin&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;JWT&lt;/strong&gt; is signed with verified user details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;sessionId&lt;/strong&gt; is generated using &lt;code&gt;crypto&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Both JWT and sessionId are sent back to the frontend, and the session is stored in the database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Frontend handling :&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JWT is saved in &lt;code&gt;localStorage&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A client-side cookie is created containing the &lt;code&gt;sessionId&lt;/code&gt;, used only for routing logic in middleware.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Middleware routing :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Checks if the &lt;code&gt;sessionId&lt;/code&gt; cookie exists.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redirects the user to the home page if it does, otherwise to the login/signup page.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Authenticated requests :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Every request includes both JWT (from &lt;code&gt;localStorage&lt;/code&gt;) and &lt;code&gt;sessionId&lt;/code&gt; (from cookies) in the headers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Authentication in backend :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The JWT is verified.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The sessionId is checked against the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If both are valid, the user data is attached to the request and proceed to server.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I learned that cross-origin setups rarely have a conventional fix — you often need to experiment, blending a few ideas to obtain the right fit that works for you.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>jwt</category>
      <category>cookie</category>
    </item>
    <item>
      <title>Virtual DOM &amp; what is its role in React?</title>
      <dc:creator>Somnath Baidya</dc:creator>
      <pubDate>Wed, 21 May 2025 13:15:05 +0000</pubDate>
      <link>https://dev.to/dessomu/virtual-dom-what-is-its-role-in-react-dh9</link>
      <guid>https://dev.to/dessomu/virtual-dom-what-is-its-role-in-react-dh9</guid>
      <description>&lt;p&gt;&lt;strong&gt;First, let’s understand what is DOM&lt;/strong&gt;: DOM stands for Document Object Model. DOM is a tree-like structure that represents the HTML elements of a webpage. It’s like a blueprint for a webpage. &lt;em&gt;&lt;strong&gt;(i) Document&lt;/strong&gt;&lt;/em&gt;- It’s the file where the HTML elements are stored. &lt;em&gt;&lt;strong&gt;(ii) Object&lt;/strong&gt;&lt;/em&gt;- Each HTML element/tag is an object. &lt;strong&gt;&lt;em&gt;(iii) Model&lt;/em&gt;&lt;/strong&gt;- The model is the hierarchy/sequence of the HTML elements.&lt;/p&gt;

&lt;p&gt;A developer accesses this DOM to modify/change the structure, style, and content to update the webpage layout using a programming language like Javascript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40arx4138byghjdt2p6i.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F40arx4138byghjdt2p6i.webp" alt="Image description" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Virtual DOM:&lt;/strong&gt; Direct manipulation of real DOM is slow, inefficient and reduces performance. While direct manipulation, the browser recalculates the layout of the webpage and repaints it. So multiple or small frequent DOM changes may lead to frame drop, delayed interaction or freezing. Virtual DOM resolves these issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Virtual DOM:&lt;/strong&gt; Virtual refers to something that has the characteristics of something real but not the real thing itself. So virtual DOM resembles the actual/real DOM but is not the actual DOM itself. We can define virtual DOM like this: Virtual DOM is a lightweight, in-memory representation of the actual(real) DOM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Role of Virtual DOM in React:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1) Initial Render:&lt;/strong&gt; When a React component renders, it creates a Virtua DOM tree that mirrors the structure of real/actual DOM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2) State/Props change:&lt;/strong&gt; When state or props update, React creates a new Virtual DOM tree.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3) Diffing:&lt;/strong&gt; Now React compares this newly generated Virtual DOM with the previous Virtual DOM to identify the differences and determine the minimal set of changes needed to avoid unnecessary updates to the real DOM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4) Reconciliation:&lt;/strong&gt; Only the differences like updated text and added elements are applied to the actual DOM. This is called reconciliation.&lt;/p&gt;

&lt;p&gt;This way react avoids unnecessary rerenders &amp;amp; updates the webpage quickly &amp;amp; efficiently.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy2wx8w3f86x5t7kwk74h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy2wx8w3f86x5t7kwk74h.png" alt="Image description" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>CSS conflict in React</title>
      <dc:creator>Somnath Baidya</dc:creator>
      <pubDate>Thu, 29 Aug 2024 04:39:57 +0000</pubDate>
      <link>https://dev.to/dessomu/css-conflict-in-react-38i7</link>
      <guid>https://dev.to/dessomu/css-conflict-in-react-38i7</guid>
      <description>&lt;p&gt;UI is the first step before we start typing logic to complete our front end. So we write the markup followed by the essential styles required to get the desired ui. While writing the markup we have to create meaningful class names to address and access the HTML tag and add style to it. With simple UI and distinct tags we can do so more or less easily. While writing repeating and complex UI, giving meaningful and distinct names becomes a disaster as there are only a few generic names. So we create components and style sheets for individual components. As shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8zz6ulavolx975xpi9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh8zz6ulavolx975xpi9b.png" alt="The components and their respective style sheets" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see two components, GreenContainer and RedContainer are being imported to the App.js from the components folder inside src. Their respective style sheets are RedContainer.css and GreenContainer.css, which are imported from the styles folder. Let's look at both the component and their style sheets one by one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The first component, RedContainer.jsx&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1g8wa5onw6d0tvopqav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1g8wa5onw6d0tvopqav.png" alt="First Component" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The respective style sheet is - RedContainer.css&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x7zltqgicrbqvcbiz31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8x7zltqgicrbqvcbiz31.png" alt="Style sheet for first component" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now have a look at the second component, GreenContainer.js -&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cshmdlk8w3llb9a22vm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4cshmdlk8w3llb9a22vm.png" alt="Second Component" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS file for the second component, GreenContainer.css&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fan5aqutj8q44okhm1dcy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fan5aqutj8q44okhm1dcy.png" alt="Style sheet for second component" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both style sheets contain distinct CSS properties for their respective components. So the expected UI outcome may be a screen where there are two blocks, one is a red square with 150px arms and another one is a green square with 200px arms. Let's have a look at the rendered React app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcb3fbykz6yw1jiwba3yy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcb3fbykz6yw1jiwba3yy.png" alt="Rendered react app" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why is this happening? The CSS properties from the last container have been applied to both containers. But how? The answer is just before the React app is rendered all the style sheets are compiled into a single CSS file, where there are two class selectors with the same name - ".container" and this is why CSS properties from the last ".container{}" have been applied to all the containers globally. This issue can be fixed by using CSS Modules. CSS Modules are CSS files where all class names are scoped locally by default. This helps us in the following ways&lt;/p&gt;

&lt;p&gt;1) Localizing the styles to specific components prevents this global scope conflict.&lt;/p&gt;

&lt;p&gt;2) Allow the use of the same class names in different modules and promote modular styling.&lt;/p&gt;

&lt;p&gt;To use modular styling we have to replace ".css" with ".module.css" and import 'styles' from those files.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvlzrakhvfp6l0cml502f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvlzrakhvfp6l0cml502f.png" alt="using CSS Module" width="630" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Importing the styles to their respective components. For RedContainer -&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feuhvp0ju6i3ba92eyk6p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feuhvp0ju6i3ba92eyk6p.png" alt="Importing styles to first component" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For the GreenContainer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi14gqajx1euegk58kaef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi14gqajx1euegk58kaef.png" alt="Importing styles to second component" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In general, we write className as a string like this, if the className is "container" we will write &lt;strong&gt;className = "container"&lt;/strong&gt;. For CSS Modules we will write the class name like this &lt;strong&gt;&lt;em&gt;className = {styles.container}&lt;/em&gt;&lt;/strong&gt; in jsx files. Now let's see the react app rendered -&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8js4dplar8o34op5cnl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy8js4dplar8o34op5cnl.png" alt="Rendered react app after using CSS Module" width="800" height="665"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now there are no issues of CSS conflict and the styles are applied to the respective components appropriately.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>css</category>
      <category>react</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
