<?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: Saurabh Sharma</title>
    <description>The latest articles on DEV Community by Saurabh Sharma (@saurabh_sharma_7a9a61107d).</description>
    <link>https://dev.to/saurabh_sharma_7a9a61107d</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3645391%2F9f1b1885-0e2a-4251-8a99-fe11981f7616.png</url>
      <title>DEV Community: Saurabh Sharma</title>
      <link>https://dev.to/saurabh_sharma_7a9a61107d</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saurabh_sharma_7a9a61107d"/>
    <language>en</language>
    <item>
      <title>I built a GIF compressor that runs 100% in your browser (because Discord's file limits are the worst)</title>
      <dc:creator>Saurabh Sharma</dc:creator>
      <pubDate>Thu, 27 Aug 2026 08:33:26 +0000</pubDate>
      <link>https://dev.to/saurabh_sharma_7a9a61107d/i-built-a-gif-compressor-that-runs-100-in-your-browser-because-discords-file-limits-are-the-3m8j</link>
      <guid>https://dev.to/saurabh_sharma_7a9a61107d/i-built-a-gif-compressor-that-runs-100-in-your-browser-because-discords-file-limits-are-the-3m8j</guid>
      <description>&lt;p&gt;If you've ever tried to upload a GIF as a Discord emoji, you know the drill. Discord wants it under 256KB, your export is 4MB, and now you're bouncing between three different "free" online converters. One of them gates batch processing. Another caps how many files you can run per day. Another quietly uploads your file to a server you never agreed to.&lt;/p&gt;

&lt;p&gt;I got tired of that loop, so I built &lt;a href="https://compressgifs.com" rel="noopener noreferrer"&gt;CompressGIFs&lt;/a&gt;. It's a small GIF toolkit that runs entirely in your browser. No upload, no account, no daily cap.&lt;/p&gt;

&lt;p&gt;Here's what it does and why I built it this way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual problem
&lt;/h2&gt;

&lt;p&gt;"Compress a GIF" sounds like a solved problem. It isn't, once you look at what people actually need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discord emoji: 256KB, 128×128&lt;/li&gt;
&lt;li&gt;Discord stickers: their own size and format quirks&lt;/li&gt;
&lt;li&gt;Slack emoji, WhatsApp stickers, Telegram stickers: all different limits&lt;/li&gt;
&lt;li&gt;And the universal one: "just make this smaller, I don't care about the settings, I just need it to work"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every tool I tried made me guess. Drag a quality slider, export, check the file size, repeat until it's small enough. That's a bad experience for something that should be simple. I already know my target size. The tool should just get me there.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's different here
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. You tell it the target size and it finds the settings for you.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of a lossy quality slider, you type "under 256KB" or pick a Discord, Slack, WhatsApp, or Telegram preset. The tool then runs a binary search across compression parameters until the output lands under your target:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Binary search gifsicle's --lossy value (1 to 200)&lt;/li&gt;
&lt;li&gt;Still too big? Binary search --colors (256 down to a floor)&lt;/li&gt;
&lt;li&gt;Still too big? Fall back to proportional downscaling, step by step&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This runs inside a Web Worker so the tab doesn't freeze while it's working. Some of these searches take a few seconds on bigger files, and you actually see live progress instead of a frozen screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It's genuinely client-side.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The compression engine is &lt;code&gt;gifsicle&lt;/code&gt; compiled to WASM, running right in your browser. Your GIF never touches a server. That's not just a privacy checkbox I'm ticking. It's also the reason the next point is even possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Batch processing isn't a paywall.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I checked what the big converters actually offer on their free tiers. One well-known one caps you at 10 conversions a day and a 5-file batch limit. Batch processing is literally their paid upsell. That makes sense when you're paying for server compute per file. It doesn't make sense here, because there's no server doing the work. Your own machine is. So batch is just unlimited. Drop in a folder of 40 GIFs, walk away, come back to 40 compressed files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. A compliance checker, not just a compressor.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is honestly the tool I wanted most for myself. Upload a GIF, pick "Discord Sticker" or "Slack Emoji," and get a clear pass or fail on size, dimensions, and format all together, with a specific note on what to fix if it fails. If you moderate a Discord server, this is the kind of thing you pin in your assets channel so people stop asking why their upload keeps getting rejected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just build "one more compress gif page"
&lt;/h2&gt;

&lt;p&gt;Before writing any code, I looked at who actually ranks for these terms. The space is dominated by a 13 year old incumbent with hundreds of interlinked tool pages and real domain authority. That's not something a single new landing page beats just by looking nicer. So instead of chasing the generic "compress gif" term head on, I scoped this narrower and deeper. A full GIF workflow: compress, resize, convert, and validate against platform limits, with the Discord specific tools front and center, since that's the highest intent, most underserved corner of this whole space right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stack, if you're curious
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Astro&lt;/strong&gt; (static, zero backend)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gifsicle-wasm-browser&lt;/strong&gt; for the actual compression, lazy loaded so it doesn't bloat the initial page weight&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Workers&lt;/strong&gt; for the target size search loop&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Pages&lt;/strong&gt; for hosting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No database, no API, no account system. Just static files and WASM running on your CPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://compressgifs.com" rel="noopener noreferrer"&gt;compressgifs.com&lt;/a&gt;. Free, no signup, nothing leaves your browser.&lt;/p&gt;

&lt;p&gt;If you run a Discord server, the &lt;a href="https://compressgifs.com/discord-sticker-checker/" rel="noopener noreferrer"&gt;Discord compliance checker&lt;/a&gt; is worth a look on its own. It's the tool I wish had existed before I spent an entire afternoon manually re-exporting stickers at four different sizes.&lt;/p&gt;

&lt;p&gt;Would genuinely love feedback from this crowd, especially if you hit an edge case where the target size search doesn't converge. That's the part I'm most paranoid about getting wrong.&lt;/p&gt;

</description>
      <category>web</category>
      <category>javascript</category>
      <category>showdev</category>
    </item>
    <item>
      <title>What I Learned Building a Payroll Calculator Site Solo (Not Truly Solo 😅)</title>
      <dc:creator>Saurabh Sharma</dc:creator>
      <pubDate>Fri, 14 Aug 2026 07:54:02 +0000</pubDate>
      <link>https://dev.to/saurabh_sharma_7a9a61107d/what-i-learned-building-a-payroll-calculator-site-solo-not-truly-solo--59kn</link>
      <guid>https://dev.to/saurabh_sharma_7a9a61107d/what-i-learned-building-a-payroll-calculator-site-solo-not-truly-solo--59kn</guid>
      <description>&lt;p&gt;PayTimeHub started as one page - a paycheck withholding calculator - because I couldn't find one online that didn't bury the number under three popups and an email gate. It's since grown into a small family of calculators: paycheck withholding by state, a raise calculator, hourly-to-salary conversion, hours-to-decimal timesheet conversion, and time-and-a-half overtime. Nothing behind a signup, nothing sent to a server. A few things stood out along the way that I didn't expect going in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tax logic is the actual product
&lt;/h2&gt;

&lt;p&gt;I assumed the hard part would be the frontend. It wasn't. Federal withholding is a set of published brackets, but state withholding is fifty different rulebooks, several of which don't tax income at all, some of which have their own standard deduction schedules, and a couple that change their brackets more often than you'd think reasonable for a tax table. Getting &lt;code&gt;[state]-paycheck-calculator&lt;/code&gt; right per state meant the actual engineering effort lives in a tax engine, not in a component tree. The UI took a weekend. The tax logic is still the thing I go back and double-check.&lt;/p&gt;

&lt;p&gt;The lesson: for a "calculator" site, the calculator is the product. Everything else - layout, copy, SEO - is packaging around a number that has to be correct, because a wrong number here isn't a cosmetic bug, it's a wrong paycheck estimate someone might actually plan around.&lt;/p&gt;

&lt;h2&gt;
  
  
  Floating-point math will find you eventually
&lt;/h2&gt;

&lt;p&gt;Money math in JavaScript looks fine until it doesn't. &lt;code&gt;0.1 + 0.2&lt;/code&gt; not equaling &lt;code&gt;0.3&lt;/code&gt; is the famous example, but the version that actually bit me was subtler: a raise calculation that produced &lt;code&gt;$53,999.999999999996&lt;/code&gt; instead of a clean &lt;code&gt;$54,000&lt;/code&gt; on one specific input, not because of an obviously bad float, but because the multiplication itself introduced error just below a rounding boundary. I wrote about that one separately, but the broader takeaway was that every calculator that touches money needs to funnel through the exact same rounding function, or you end up with five slightly different &lt;code&gt;.toFixed(2)&lt;/code&gt; calls that quietly disagree with each other on the edges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static-first is a feature, not a shortcut
&lt;/h2&gt;

&lt;p&gt;Astro was the right call, but not for the reason I expected going in. I picked it for the build output - static pages, minimal JS, fast Lighthouse scores. What turned out to matter more is that "no server, no data leaves the browser" isn't just a privacy pitch, it removes an entire category of things I don't have to build: no auth, no database, no rate limiting, no GDPR data-handling story. The calculators run entirely client-side. That constraint made the whole project smaller in a good way - there's less surface area for something to go wrong, and less to maintain six months from now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic routes make "fifty states" tractable
&lt;/h2&gt;

&lt;p&gt;Before I set up &lt;code&gt;[state]-paycheck-calculator&lt;/code&gt; and &lt;code&gt;[value]-salary-to-hourly&lt;/code&gt; as dynamic routes, I was mentally treating "add all 50 states" as fifty separate pages to hand-write. That's the wrong mental model for this kind of site. One template plus a data file per state is the actual shape of the problem, and it's the difference between a task that takes a weekend and one that never gets finished because it feels too big to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shipping something narrow beats shipping something broad
&lt;/h2&gt;

&lt;p&gt;Early on I was tempted to build a general "financial calculator suite" - retirement, mortgage, budgeting, the works. I'm glad I didn't. Payroll and pay math is a coherent enough niche that the calculators reinforce each other: someone converting hourly to salary is plausibly also the kind of person who wants to know their overtime rate or their raise in real terms. A broader suite would have diluted that, and I'd have shipped ten shallow tools instead of five that actually do their one job well.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;More state-specific accuracy passes, and probably a couple more calculators in the same vein - the goal isn't to cover every financial calculation that exists, just to keep doing pay and payroll math well. If you're curious, the whole thing is live at &lt;a href="https://paytimehub.com" rel="noopener noreferrer"&gt;paytimehub.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The rounding bug that almost shipped in a payroll calculator</title>
      <dc:creator>Saurabh Sharma</dc:creator>
      <pubDate>Fri, 14 Aug 2026 07:47:02 +0000</pubDate>
      <link>https://dev.to/saurabh_sharma_7a9a61107d/the-rounding-bug-that-almost-shipped-in-a-payroll-calculator-jm3</link>
      <guid>https://dev.to/saurabh_sharma_7a9a61107d/the-rounding-bug-that-almost-shipped-in-a-payroll-calculator-jm3</guid>
      <description>&lt;p&gt;I've been building &lt;a href="https://paytimehub.com" rel="noopener noreferrer"&gt;PayTimeHub&lt;/a&gt;, a set of free payroll and pay calculators - paycheck withholding, raise calculator, hours-to-decimal, time and a half. Money math looks trivial until you actually ship it, and one bug almost got through that's worth writing up.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Every calculator on the site takes a dollar amount, does some arithmetic on it, and shows the result back to the user. A raise calculator multiplies a salary by a percentage. An overtime calculator multiplies an hourly rate by 1.5. Simple stuff, until you remember that JavaScript does floating-point math.&lt;/p&gt;

&lt;p&gt;Try this in a console:&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="mf"&gt;0.1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;
&lt;span class="c1"&gt;// 0.30000000000000004&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine that showing up on a page that's supposed to tell someone their new salary. A $52,000 salary with a 3.85% raise should read as a clean $54,000. Depending on how you chain the multiplication and division, you can end up with something like $53,999.999999999996, which then gets formatted and displayed as a genuinely wrong number - or worse, rounds inconsistently between two calculators that are supposed to agree with each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix
&lt;/h2&gt;

&lt;p&gt;Nothing exotic, just a single shared rounding function that every calculator on the site routes its output through before display:&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;roundCurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&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="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EPSILON&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&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;The &lt;code&gt;Number.EPSILON&lt;/code&gt; nudge matters more than it looks like it should. Without it, plain &lt;code&gt;Math.round(amount * 100) / 100&lt;/code&gt; still misfires on specific inputs, because the multiplication itself can introduce a floating-point error just below a rounding boundary, so a value that should round up rounds down instead. Adding the smallest possible float before rounding pushes those edge cases back onto the correct side without changing any value that wasn't on the boundary to begin with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it's worth writing down
&lt;/h2&gt;

&lt;p&gt;The interesting part isn't the fix - it's that this exact class of bug is invisible in casual testing. Round numbers like $50,000 and 5% never trigger it. It shows up on the specific combinations that don't divide cleanly, the ones a user actually types in, not the ones a developer thinks to test.&lt;/p&gt;

&lt;p&gt;Every money-handling calculator on the site now funnels through one rounding function instead of each one doing its own &lt;code&gt;.toFixed(2)&lt;/code&gt; inline. Partly for consistency, but mostly so this bug only had one place it could hide.&lt;/p&gt;

&lt;p&gt;If you're building anything that does arithmetic on money in JavaScript and displays the result, it's worth checking whether you have one rounding function or five slightly different ones scattered across the codebase. It's an easy thing to get right once, and an easy thing to get subtly wrong five separate times.&lt;/p&gt;

&lt;p&gt;Built with Astro, if anyone's curious about the stack. The site itself is at &lt;a href="https://paytimehub.com" rel="noopener noreferrer"&gt;paytimehub.com&lt;/a&gt; if you want to see it in action — specifically the &lt;a href="https://paytimehub.com/pay-raise-calculator/" rel="noopener noreferrer"&gt;pay raise calculator&lt;/a&gt;, where this first came up.&lt;/p&gt;

</description>
      <category>astro</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>ai</category>
    </item>
    <item>
      <title>🧭 React Router Crash Course (Beginner Friendly)</title>
      <dc:creator>Saurabh Sharma</dc:creator>
      <pubDate>Thu, 04 Dec 2025 08:29:45 +0000</pubDate>
      <link>https://dev.to/saurabh_sharma_7a9a61107d/react-router-crash-course-beginner-friendly-1bck</link>
      <guid>https://dev.to/saurabh_sharma_7a9a61107d/react-router-crash-course-beginner-friendly-1bck</guid>
      <description>&lt;p&gt;&lt;em&gt;Learn what routing is, why it matters in React, and how to set it up step-by-step — with a mini React demo project.&lt;/em&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  🧐 What Is Routing in React?
&lt;/h2&gt;

&lt;p&gt;So, what the heck is &lt;strong&gt;routing&lt;/strong&gt;?  &lt;/p&gt;

&lt;p&gt;In simple terms, &lt;strong&gt;routing controls what your app shows when a user navigates to different pages&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;That’s it! When you click on something like “About” or “Contact,” routing decides &lt;em&gt;which component&lt;/em&gt; gets displayed on the screen.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🌐 How Traditional Routing Works
&lt;/h2&gt;

&lt;p&gt;Before SPAs (Single Page Applications), websites used normal HTML navigation with the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/about"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Go to About Page&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every time you clicked on that link, the browser &lt;strong&gt;reloaded the page&lt;/strong&gt; from scratch. That means your app reset, and the DOM (Document Object Model) re-rendered completely — not very efficient!  &lt;/p&gt;




&lt;h2&gt;
  
  
  ⚛️ React: The Power of Single Page Applications (SPA)
&lt;/h2&gt;

&lt;p&gt;React builds &lt;strong&gt;Single Page Applications&lt;/strong&gt;, where everything runs inside one main HTML file: &lt;code&gt;index.html&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;When navigation happens, React simply &lt;strong&gt;replaces parts of the UI dynamically&lt;/strong&gt;, rather than reloading the entire page.  &lt;/p&gt;

&lt;p&gt;But to make that navigation magic happen, React needs help — that’s where &lt;strong&gt;&lt;code&gt;react-router-dom&lt;/code&gt;&lt;/strong&gt; comes in.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Installing React Router
&lt;/h2&gt;

&lt;p&gt;React itself doesn’t handle routing, so you’ll need to install a library for it. The most popular one is &lt;strong&gt;&lt;code&gt;react-router-dom&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Use your package manager of choice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;react-router-dom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add react-router-dom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🏗️ Step 1: Setup &lt;code&gt;BrowserRouter&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;After installing, wrap your whole app with &lt;code&gt;BrowserRouter&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
This enables React Router throughout your application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom/client&lt;/span&gt;&lt;span class="dl"&gt;'&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;BrowserRouter&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="s1"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.jsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BrowserRouter&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;BrowserRouter&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s your basic setup! Without this step, your app won’t understand routes.&lt;/p&gt;




&lt;h2&gt;
  
  
  🗺️ Step 2: Define Routes with &lt;code&gt;&amp;lt;Routes&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;Route&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Now it’s time to tell React what to show on each URL path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.jsx&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;Routes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Route&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="s1"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./pages/Home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;About&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./pages/About&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Contact&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./pages/Contact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NotFound&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./pages/NotFound&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Home&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/about"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;About&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/contact"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Contact&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Catch all unknown routes */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NotFound&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;&amp;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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/&lt;/code&gt; → &lt;strong&gt;Home Page&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/about&lt;/code&gt; → &lt;strong&gt;About Page&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/contact&lt;/code&gt; → &lt;strong&gt;Contact Page&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt; → &lt;strong&gt;Not Found / 404 Page&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔗 Step 3: Create Navigation with &lt;code&gt;Link&lt;/code&gt; and &lt;code&gt;NavLink&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Instead of using normal &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tags, React gives us special components: &lt;code&gt;Link&lt;/code&gt; and &lt;code&gt;NavLink&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
These navigate between pages &lt;em&gt;without&lt;/em&gt; reloading the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Navbar.jsx&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;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NavLink&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="s1"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Navbar&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/about"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;About&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NavLink&lt;/span&gt;
        &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/contact"&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;isActive&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;isActive&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&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="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Contact
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;NavLink&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Navbar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;code&gt;Link&lt;/code&gt;: Basic navigation (no reload).&lt;br&gt;&lt;br&gt;
✅ &lt;code&gt;NavLink&lt;/code&gt;: Same as &lt;code&gt;Link&lt;/code&gt;, but automatically adds an “active” class to the current route — perfect for styling active menu items.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧩 Step 4: Nested Routes and &lt;code&gt;&amp;lt;Outlet /&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Sometimes you’ll want routes &lt;em&gt;inside routes&lt;/em&gt;, like for a dashboard that contains multiple sections (e.g., profile, settings).  &lt;/p&gt;

&lt;p&gt;That’s where &lt;strong&gt;nested routes&lt;/strong&gt; come in — and the &lt;code&gt;&amp;lt;Outlet /&amp;gt;&lt;/code&gt; component helps render them in the right place.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.jsx&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Home&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/dashboard"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dashboard&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"profile"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Profile&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"settings"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Settings&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;Dashboard.jsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Dashboard.jsx&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;Outlet&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="s1"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Dashboard&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Child routes will render here */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Outlet&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Dashboard&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when visiting &lt;code&gt;/dashboard/profile&lt;/code&gt;, React automatically renders the &lt;strong&gt;Profile&lt;/strong&gt; component inside the &lt;strong&gt;Dashboard&lt;/strong&gt; layout!&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Mini React Demo Project: "My First Routed App"
&lt;/h2&gt;

&lt;p&gt;Let’s put it all together into a working mini project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File Structure:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
  ├── main.jsx
  ├── App.jsx
  ├── components/
  │     └── Navbar.jsx
  ├── pages/
  │     ├── Home.jsx
  │     ├── About.jsx
  │     ├── Contact.jsx
  │     └── NotFound.jsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example Pages:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/Home.jsx&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome to My React App!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;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="nx"&gt;Home&lt;/span&gt;

&lt;span class="c1"&gt;// pages/About.jsx&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;About&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;About This Project&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;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="nx"&gt;About&lt;/span&gt;

&lt;span class="c1"&gt;// pages/Contact.jsx&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Contact&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Contact Me Anytime!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;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="nx"&gt;Contact&lt;/span&gt;

&lt;span class="c1"&gt;// pages/NotFound.jsx&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NotFound&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;404 — Page Not Found&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;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="nx"&gt;NotFound&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Add the Navbar:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Navbar&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/Navbar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Navbar&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Home&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/about"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;About&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/contact"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Contact&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NotFound&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;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;Now you’ve got a complete, simple React app with modern routing — no page reloads, smooth navigation, and clean URLs.  &lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Bonus: Things to Explore Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://reactrouter.com/en/main" rel="noopener noreferrer"&gt;React Router Docs&lt;/a&gt; — Learn about advanced features like &lt;code&gt;useNavigate&lt;/code&gt;, loaders, lazy loading, and route transitions.
&lt;/li&gt;
&lt;li&gt;Try adding a &lt;strong&gt;404 redirect&lt;/strong&gt; or a &lt;strong&gt;Protected Route&lt;/strong&gt; for authenticated sections.
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;NavLink&lt;/code&gt; styling to highlight the active page.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏁 Wrapping Up
&lt;/h2&gt;

&lt;p&gt;You just learned how to set up &lt;strong&gt;React Router&lt;/strong&gt; from scratch — including how to install it, define routes, use navigation components, and manage nested routes cleanly.  &lt;/p&gt;

&lt;p&gt;Now, whenever you start a new React project, you’ll know exactly how to make it multi-page while keeping it fast and smooth.&lt;/p&gt;

&lt;p&gt;Keep building! 💪  &lt;/p&gt;




</description>
      <category>webdev</category>
      <category>react</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
