<?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: Zahra Mirkazemi</title>
    <description>The latest articles on DEV Community by Zahra Mirkazemi (@zahra_mirkazemi).</description>
    <link>https://dev.to/zahra_mirkazemi</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%2F2829685%2Fa2f413e9-047e-470a-b10c-901ceb715d57.jpeg</url>
      <title>DEV Community: Zahra Mirkazemi</title>
      <link>https://dev.to/zahra_mirkazemi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zahra_mirkazemi"/>
    <language>en</language>
    <item>
      <title>How to Pass Data into a Static JavaScript File Using data-* Attributes</title>
      <dc:creator>Zahra Mirkazemi</dc:creator>
      <pubDate>Sat, 24 May 2025 08:32:11 +0000</pubDate>
      <link>https://dev.to/zahra_mirkazemi/how-to-pass-data-into-a-static-javascript-file-using-data-attributes-2im7</link>
      <guid>https://dev.to/zahra_mirkazemi/how-to-pass-data-into-a-static-javascript-file-using-data-attributes-2im7</guid>
      <description>&lt;p&gt;As a front-end developer, one of the common challenges you'll encounter when working with embeddable scripts or static widgets is how to inject dynamic configuration into a static JavaScript file.&lt;/p&gt;

&lt;p&gt;Since static files can't fetch data from a backend or receive props like React components, they must rely on what's available in the DOM.&lt;/p&gt;

&lt;p&gt;One elegant and widely supported solution is to use HTML data-* attributes.&lt;/p&gt;

&lt;p&gt;In this article, I'll walk through how this pattern works, when to use it, and why it's a reliable choice for flexible, embeddable scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 The Problem
&lt;/h2&gt;

&lt;p&gt;Let's say you're distributing a static script — for example, a survey button, a help widget, or a third-party plugin. You want other developers (or non-dev users) to embed your script and be able to customize things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Color scheme&lt;/li&gt;
&lt;li&gt;Position (left/right/bottom)&lt;/li&gt;
&lt;li&gt;Icon&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But your JavaScript file is hosted on a CDN and cannot be dynamically modified.&lt;/p&gt;

&lt;p&gt;So, how do you make it configurable?&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ The data-* Attribute Pattern
&lt;/h2&gt;

&lt;p&gt;HTML data-* attributes let you attach custom metadata to elements. These values are accessible via JavaScript using the &lt;code&gt;.dataset&lt;/code&gt; API.&lt;/p&gt;

&lt;p&gt;Here's how it works:&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;div&lt;/span&gt;
  &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"my-widget"&lt;/span&gt;
  &lt;span class="na"&gt;data-theme=&lt;/span&gt;&lt;span class="s"&gt;"dark"&lt;/span&gt;
  &lt;span class="na"&gt;data-position=&lt;/span&gt;&lt;span class="s"&gt;"right"&lt;/span&gt;
  &lt;span class="na"&gt;data-lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.example.com/widget.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;widget.js&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&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="s2"&gt;my-widget&lt;/span&gt;&lt;span class="dl"&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;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;left&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Use the config to customize your widget&lt;/span&gt;
&lt;span class="nf"&gt;initializeWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern is clean, readable, and doesn't require any global variables or external communication.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧰 Why Use This Pattern?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fully decoupled&lt;/strong&gt;: Your static JS doesn't rely on server-side rendering or build-time variables.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declarative&lt;/strong&gt;: Easy for developers and non-developers to understand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple instances&lt;/strong&gt;: You can use this pattern for multiple widgets on the same page, each with its own configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe &amp;amp; flexible&lt;/strong&gt;: Works across browsers, respects caching, and doesn't interfere with global scope.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Data is limited to string values — you'll need to manually parse JSON or booleans if needed.&lt;/li&gt;
&lt;li&gt;Relies on correct HTML structure (e.g., an element with the right id or class).&lt;/li&gt;
&lt;li&gt;If not documented properly, consumers may miss available options.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✍️ Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use clear naming&lt;/strong&gt;: Stick to data- attributes like &lt;code&gt;data-color&lt;/code&gt;, &lt;code&gt;data-user-id&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set safe defaults&lt;/strong&gt;: In your JS, always provide fallback values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate input values&lt;/strong&gt; (e.g., allowed themes or positions).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid sensitive data&lt;/strong&gt;: Don't pass secrets, tokens, or anything private via data-*.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🤔 But Wait… This Isn't the Only Way
&lt;/h2&gt;

&lt;p&gt;While data-* attributes are great, they're definitely not the only option. Depending on your use case, you might consider one of these too:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Global Variables
&lt;/h3&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;script&amp;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;myWidgetConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;right&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.example.com/widget.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works well for more structured data, but it pollutes the global namespace — which can be risky in large apps or when multiple scripts are involved.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Query Parameters in Script URL
&lt;/h3&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;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.example.com/widget.js?theme=dark&amp;amp;lang=fa"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then parse these inside the script using &lt;code&gt;document.currentScript.src&lt;/code&gt;. This is quick and easy for small config values, but can get messy fast if your configuration grows.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. JSON Inside &lt;code&gt;&amp;lt;script type="application/json"&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Another trick is embedding configuration data as JSON in a special script 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;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"my-widget-config"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;theme&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;dark&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;lang&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;fa&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in your JS:&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;raw&lt;/span&gt; &lt;span class="o"&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="s2"&gt;my-widget-config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&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;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A bit more setup, but great for complex configs.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏁 Conclusion
&lt;/h2&gt;

&lt;p&gt;If you're building embeddable JavaScript for third-party use, data-* attributes offer a simple, scalable, and standards-compliant way to receive configuration from the host HTML.&lt;/p&gt;

&lt;p&gt;This pattern strikes the right balance between flexibility and safety — especially in environments where your script is embedded across many contexts and domains.&lt;/p&gt;

&lt;p&gt;Next time you're working on a static JS file that needs to behave dynamically, consider this technique. It's declarative, reliable, and works in every browser that matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  💬 Got thoughts, questions, or your own favorite tricks?
&lt;/h2&gt;

&lt;p&gt;Let's continue the conversation in the comments.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have you implemented something like this before? Which method did you go with, and why?&lt;/li&gt;
&lt;li&gt;Have you tried more advanced techniques like Web Components or JSON-LD-based configurations?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd love to hear your take. Let's share ideas — there's always something new to learn 🌱&lt;/p&gt;

&lt;p&gt;🙌 If you found this useful, feel free to share it with your team or give it a clap!&lt;/p&gt;

</description>
      <category>staticfile</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Query Strings vs. Hash Fragments: What’s the Real Difference?</title>
      <dc:creator>Zahra Mirkazemi</dc:creator>
      <pubDate>Fri, 23 May 2025 17:48:12 +0000</pubDate>
      <link>https://dev.to/zahra_mirkazemi/query-strings-vs-hash-fragments-whats-the-real-difference-597n</link>
      <guid>https://dev.to/zahra_mirkazemi/query-strings-vs-hash-fragments-whats-the-real-difference-597n</guid>
      <description>&lt;h1&gt;
  
  
  Understanding URL Query Strings vs Hash Fragments
&lt;/h1&gt;

&lt;p&gt;The other day, I stumbled upon something interesting. I was checking out a survey and noticed two URLs that looked like they pointed to the same place:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://example.com/page?panel_view=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://example.com/page#/?panel_view=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At a glance, you might think: &lt;strong&gt;"Same link, right?"&lt;/strong&gt; Well… not exactly.&lt;/p&gt;

&lt;p&gt;Let's dig into what's going on here — and why this small detail might actually matter, especially if you're working with modern web apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Curious "#"
&lt;/h2&gt;

&lt;p&gt;In the second URL, you'll notice a hash (&lt;code&gt;#&lt;/code&gt;) followed by a slash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#/?panel_view=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That little hashtag, also called a &lt;strong&gt;hash fragment&lt;/strong&gt;, plays a special role in web development.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 TL;DR:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Everything &lt;strong&gt;before the&lt;/strong&gt; &lt;code&gt;#&lt;/code&gt; = sent to the &lt;strong&gt;server&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Everything &lt;strong&gt;after the&lt;/strong&gt; &lt;code&gt;#&lt;/code&gt; = stays in the &lt;strong&gt;browser&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words: the server doesn't care about anything after the &lt;code&gt;#&lt;/code&gt;. It never even sees it. But if your app is a &lt;strong&gt;single-page application (SPA)&lt;/strong&gt; — built with something like React, Vue, or Angular — it &lt;em&gt;might&lt;/em&gt; care a lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, Why Use the Hash at All?
&lt;/h2&gt;

&lt;p&gt;Back in the day, &lt;code&gt;#&lt;/code&gt; was mostly used for scrolling to sections within a page (like &lt;code&gt;#about-us&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Now, in modern SPAs, it's often used for &lt;strong&gt;routing&lt;/strong&gt;. When you see something like &lt;code&gt;#/dashboard&lt;/code&gt; or &lt;code&gt;#/login&lt;/code&gt;, that's your front-end framework deciding what content to show — without refreshing the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do They Work the Same?
&lt;/h2&gt;

&lt;p&gt;They might! Or they might not.&lt;/p&gt;

&lt;p&gt;If the app is a traditional server-rendered page, it likely uses query strings (&lt;code&gt;?&lt;/code&gt;) to load different content.&lt;/p&gt;

&lt;p&gt;If it's an SPA, the app might rely entirely on the hash (&lt;code&gt;#/&lt;/code&gt;) to trigger internal views.&lt;/p&gt;

&lt;p&gt;Using the wrong one could lead to weird issues — like skipping required steps, not loading the right view, or even breaking analytics.&lt;/p&gt;

&lt;h2&gt;
  
  
  What About Caching?
&lt;/h2&gt;

&lt;p&gt;Great question. Here's where things get even more interesting:&lt;/p&gt;

&lt;p&gt;🧠 &lt;strong&gt;Browsers and CDNs treat query strings and hash fragments very differently when it comes to caching&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Query strings&lt;/strong&gt; (&lt;code&gt;?panel_view=true&lt;/code&gt;) affect the full URL — including server-side caching and CDN behavior. So: Different query strings = different cached versions. This can be good (for dynamic content), but sometimes bad (if it busts the cache unnecessarily).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hash fragments&lt;/strong&gt; (&lt;code&gt;#&lt;/code&gt;), on the other hand: Do &lt;strong&gt;not&lt;/strong&gt; affect caching. The browser sees &lt;code&gt;https://example.com/page#about&lt;/code&gt; and &lt;code&gt;https://example.com/page#contact&lt;/code&gt; as &lt;strong&gt;the same resource&lt;/strong&gt; — it just scrolls to a different part or changes state &lt;em&gt;after&lt;/em&gt; the page loads.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 &lt;strong&gt;If you want to bust cache or serve different content from the server, use query strings.&lt;/strong&gt; &lt;strong&gt;If you only need to affect front-end behavior, use hash fragments.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Catching These in Next.js
&lt;/h2&gt;

&lt;p&gt;If you're using &lt;strong&gt;Next.js&lt;/strong&gt;, here's how you grab each type:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Query Strings
&lt;/h3&gt;

&lt;p&gt;Next.js handles query strings natively using the &lt;code&gt;useRouter&lt;/code&gt; hook:&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRouter&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;next/router&lt;/span&gt;&lt;span class="dl"&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;Page&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRouter&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;panel_view&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;panel_view&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;panel_view&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📦 Hash Fragments
&lt;/h3&gt;

&lt;p&gt;Hash values aren't part of Next.js routing — they live only in the browser. You'll need to use &lt;code&gt;window.location.hash&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&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&lt;/span&gt;&lt;span class="dl"&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;Page&lt;/span&gt; &lt;span class="o"&gt;=&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;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setHash&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="dl"&gt;''&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;setHash&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;hash&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;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Current&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="na"&gt;is&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just remember: since this uses &lt;code&gt;window&lt;/code&gt;, it must run &lt;strong&gt;client-side only&lt;/strong&gt; (e.g., inside &lt;code&gt;useEffect&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  A Tiny Detail, A Bigger Lesson
&lt;/h2&gt;

&lt;p&gt;This small difference is a great reminder that URLs are more than just links — they carry instructions. And depending on how your app is built, the format of those instructions can change what users see (or don't see).&lt;/p&gt;

&lt;p&gt;Next time you copy-paste a link, give it a second look. That tiny &lt;code&gt;#&lt;/code&gt; could be doing a lot more than you think. 😉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ever been bitten by a query string or hash behavior in a project? Drop a comment — I'd love to hear your story!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
