<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Nauman Majeed</title>
    <description>The latest articles on Forem by Nauman Majeed (@inaumanmajeed).</description>
    <link>https://forem.com/inaumanmajeed</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%2F3454508%2Fdb6b5d3d-e81d-487f-a963-717b2a6c6779.jpeg</url>
      <title>Forem: Nauman Majeed</title>
      <link>https://forem.com/inaumanmajeed</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/inaumanmajeed"/>
    <language>en</language>
    <item>
      <title>No More Broken Image Paths! Meet assets-mapper for React &amp; Next.js 🚀</title>
      <dc:creator>Nauman Majeed</dc:creator>
      <pubDate>Thu, 09 Oct 2025 11:47:20 +0000</pubDate>
      <link>https://forem.com/inaumanmajeed/no-more-broken-image-paths-meet-assets-mapper-for-react-nextjs-1acg</link>
      <guid>https://forem.com/inaumanmajeed/no-more-broken-image-paths-meet-assets-mapper-for-react-nextjs-1acg</guid>
      <description>&lt;p&gt;Have you ever changed an image in your project and suddenly half your UI broke because of that one annoying error?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Module not found: Can't resolve '../assets/logo.png'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yeah, me too 😩&lt;br&gt;
After facing this frustration again and again, I decided to automate the entire process.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In React or Next.js projects, developers often face:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tedious manual imports for every image&lt;/li&gt;
&lt;li&gt;Long relative paths like (../../../assets/...)&lt;/li&gt;
&lt;li&gt;Errors when moving or renaming image files&lt;/li&gt;
&lt;li&gt;Inconsistent paths across components&lt;/li&gt;
&lt;li&gt;Time wasted fixing broken imports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every time you reorganize your assets folder, something breaks. It’s messy, repetitive, and completely avoidable.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;The Solution — assets-mapper 🚀&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;assets-mapper automatically scans your image folders and generates a TypeScript-safe asset map — so you never have to deal with broken paths again.&lt;/p&gt;

&lt;p&gt;Instead of writing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import logo from '../../assets/images/logo.png';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { logo } from 'assets-mapper';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it.&lt;br&gt;
No configuration. No path issues. Works beautifully with both &lt;strong&gt;React&lt;/strong&gt; and &lt;strong&gt;Next.js&lt;/strong&gt;.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Why assets-mapper?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ No more broken paths — catch missing assets at build time&lt;br&gt;
✅ TypeScript autocomplete — IntelliSense for your images&lt;br&gt;
✅ Smart duplicate handling — adds folder prefixes only when needed&lt;br&gt;
✅ File watching — automatically regenerates when assets change&lt;br&gt;
✅ Framework agnostic — works with React, Next.js, Vue, and more&lt;br&gt;
✅ Zero configuration — works out of the box&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Installation&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;npm install assets-mapper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Quick Start&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI Usage&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;# Basic usage
npx assets-mapper --src src/assets --out src/assetsMap.js

# With file watching (recommended for development)
npx assets-mapper --src src/assets --out src/assetsMap.js --watch

# For Next.js public folder
npx assets-mapper --src public/images --out src/assetsMap.js --public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Programmatic Usage&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;const { generateAssetsMap } = require('assets-mapper');

const result = generateAssetsMap({
  src: 'src/assets',
  out: 'src/assetsMap.js'
});

console.log(`✅ Generated map with ${result.totalFiles} assets`);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your folder structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/assets/
├── logo.png
├── hero.jpg
├── icons/
│   ├── home.svg
│   └── logo.png
└── images/
    └── banner.webp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generated &lt;code&gt;assetsMap.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import logo from "./assets/logo.png";
import hero from "./assets/hero.jpg";
import home from "./assets/icons/home.svg";
import icons_logo from "./assets/icons/logo.png";
import banner from "./assets/images/banner.webp";

const assetsMap = {
  logo,
  hero,
  home,
  icons_logo,
  banner
};

export default assetsMap;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it in your components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import assetsMap from './assetsMap.js';

function Header() {
  return (
    &amp;lt;header&amp;gt;
      &amp;lt;img src={assetsMap.logo} alt="Logo" /&amp;gt;
      &amp;lt;img src={assetsMap.hero} alt="Hero" /&amp;gt;
    &amp;lt;/header&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Smart Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Duplicate Handling:&lt;/strong&gt; Adds folder prefixes only when filenames conflict&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File Watching:&lt;/strong&gt; Automatically regenerates when you add, remove, or rename assets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-cleanup:&lt;/strong&gt; Removes generated files when the package is uninstalled&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript support:&lt;/strong&gt; Full autocomplete and safety in editors&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js 14+&lt;/li&gt;
&lt;li&gt;Works with React, Next.js, Vue, Svelte, and any JavaScript or TypeScript project&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Made for Developers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Built with one simple goal:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Save developers from the pain of broken image paths.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Made with ❤️ for developers who just want things to work smoothly.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/assets-mapper" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/assets-mapper&lt;/a&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/inaumanmajeed/assets-mapper" rel="noopener noreferrer"&gt;https://github.com/inaumanmajeed/assets-mapper&lt;/a&gt;&lt;/p&gt;




</description>
      <category>react</category>
      <category>nextjs</category>
      <category>npm</category>
      <category>opensource</category>
    </item>
    <item>
      <title>From Business Student to Frontend Developer: Building My First Open-Source Project</title>
      <dc:creator>Nauman Majeed</dc:creator>
      <pubDate>Sat, 23 Aug 2025 20:14:09 +0000</pubDate>
      <link>https://forem.com/inaumanmajeed/from-business-student-to-frontend-developer-building-my-first-open-source-project-150k</link>
      <guid>https://forem.com/inaumanmajeed/from-business-student-to-frontend-developer-building-my-first-open-source-project-150k</guid>
      <description>&lt;p&gt;Two years ago, I was a business student following the “safe” path. But something didn’t feel right — I wanted to &lt;strong&gt;build things&lt;/strong&gt;, not just study them. So I took a leap, switched careers, and started teaching myself web development.&lt;/p&gt;

&lt;p&gt;Fast forward to today, I’m excited to share my &lt;strong&gt;first open-source project&lt;/strong&gt; on npm:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.npmjs.com/package/filters-query-params" rel="noopener noreferrer"&gt;filters-query-params&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A lightweight TypeScript library for effortless URL state management in web apps.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🌱 My Journey in a Nutshell
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Quit my business career to pursue software development.&lt;/li&gt;
&lt;li&gt;Learned the fundamentals through tutorials, docs, and small projects.&lt;/li&gt;
&lt;li&gt;Got my first chance as an intern.&lt;/li&gt;
&lt;li&gt;Thanks to amazing mentorship from from my seniors, I learned not just coding but problem-solving.&lt;/li&gt;
&lt;li&gt;Earned a promotion and officially kickstarted my development career.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ⚡ The Problem I Wanted to Solve
&lt;/h2&gt;

&lt;p&gt;Managing &lt;strong&gt;URL query parameters&lt;/strong&gt; for filters (think search filters, dashboards, e-commerce, etc.) can get messy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Syncing state with the URL&lt;/li&gt;
&lt;li&gt;Validating query parameters&lt;/li&gt;
&lt;li&gt;Debouncing to avoid unnecessary calls&lt;/li&gt;
&lt;li&gt;Keeping code clean and maintainable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted a &lt;strong&gt;framework-agnostic, TypeScript-first solution&lt;/strong&gt; that just works.&lt;/p&gt;


&lt;h2&gt;
  
  
  🛠️ Introducing &lt;code&gt;filters-query-params&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A simple but powerful library to handle URL filters in your applications.&lt;/p&gt;
&lt;h3&gt;
  
  
  Features:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Sync filters with URL query parameters automatically&lt;/li&gt;
&lt;li&gt;✅ Full &lt;strong&gt;TypeScript&lt;/strong&gt; support&lt;/li&gt;
&lt;li&gt;✅ Built-in &lt;strong&gt;Zod validation&lt;/strong&gt; for runtime safety&lt;/li&gt;
&lt;li&gt;✅ Framework agnostic (works with React, Next.js, or vanilla JS)&lt;/li&gt;
&lt;li&gt;✅ Automatic &lt;strong&gt;debouncing&lt;/strong&gt; &amp;amp; smart data handling&lt;/li&gt;
&lt;li&gt;✅ Zero configuration for quick adoption&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🚀 Installation &amp;amp; Usage
&lt;/h2&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;filters-query-params zod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Example with React + Zod&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;useFilters&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;filters-query-params&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zod&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;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;search&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;optional&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="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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFilter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFilters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;schema&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;input&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChange&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Search..."&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;button&lt;/span&gt; &lt;span class="na"&gt;onClick&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;category&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;books&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;
        Books
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it — your filters now sync with the URL and validate automatically!&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Why This Project Matters to Me
&lt;/h2&gt;

&lt;p&gt;This isn’t just about code.&lt;br&gt;
Every function, every test, and every line represents my journey:&lt;br&gt;
from a &lt;strong&gt;business student&lt;/strong&gt; ➝ &lt;strong&gt;frontend developer&lt;/strong&gt; ➝ &lt;strong&gt;open-source contributor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s proof that with passion, persistence, and mentorship, you can reinvent yourself.&lt;/p&gt;




&lt;h2&gt;
  
  
  🙌 How You Can Help
&lt;/h2&gt;

&lt;p&gt;If you find this useful, I’d love your support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⭐ Star it on &lt;a href="https://github.com/inaumanmajeed/filters-query-params" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔄 Try it in your project&lt;/li&gt;
&lt;li&gt;💬 Share feedback, issues, or suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, let’s make filter state management simple for everyone.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>npm</category>
    </item>
  </channel>
</rss>
