<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/feeds/atom-style.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://gauravadhikari.com</id>
    <title>Gaurav Adhikari</title>
    <updated>2026-01-17T16:44:51.556Z</updated>
    <generator>Astro-Theme-Retypeset with Feed for Node.js</generator>
    <author>
        <name>Gaurav Adhikari</name>
        <uri>https://gauravadhikari.com</uri>
    </author>
    <link rel="alternate" href="https://gauravadhikari.com"/>
    <link rel="self" href="https://gauravadhikari.com/atom.xml"/>
    <subtitle>Hands-on tutorials and coding tips for ReactJS, web development, Docker, Strapi, and more — packed with real projects and practical guides.</subtitle>
    <rights>Copyright © 2026 Gaurav Adhikari</rights>
    <entry>
        <title type="html"><![CDATA[React Project Ideas for 2026 (Part 2) – From beginner to job ready]]></title>
        <id>https://gauravadhikari.com/react-project-ideas-2026-part-2/</id>
        <link href="https://gauravadhikari.com/react-project-ideas-2026-part-2/"/>
        <updated>2026-01-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A fresh batch of beginner, intermediate, and advanced React project ideas for 2026 focusing on real-world UX patterns, backend integration, and SaaS-ready workflows.]]></summary>
        <content type="html"><![CDATA[<p><img src="https://gauravadhikari.com/images/articles/react-project-ideas-2026/react-project-ideas-2026.webp" alt="React Project Ideas series cover" /></p>
<h2>React Project Ideas 2026: Part 2</h2>
<p>The first part of this series covered 60 React ideas that teach the fundamentals. This sequel leans into <strong>deeper UX problems, smarter state management, and SaaS-style features</strong> so you can keep leveling up. Feel free to mix these ideas with the ones from <a href="/react-project-ideas-2026/">Part 1</a> or pair them with backend/AI services for extra points.</p>
<p>Use the list like a menu:</p>
<ul>
<li>Pick a feature pattern you have never built (RBAC, multi-step forms, presence indicators).</li>
<li>Set a constraint (ship it with TypeScript, or use React Server Components).</li>
<li>Write a mini case study to document the architecture.</li>
</ul>
<hr />
<h2>Beginner React Projects (19 Ideas)</h2>
<p>Quick builds that sharpen UI state, form handling, and component composition.</p>
<ol>
<li><strong>Password Strength Checker</strong> – Color-coded meter that explains why a password is weak or strong.</li>
<li><strong>File Upload &amp; Preview App</strong> – Local preview for images, PDFs, and text plus drag-and-drop support.</li>
<li><strong>Tip Calculator</strong> – Split bill logic with sliders, custom percentages, and rounding toggles.</li>
<li><strong>Color Palette Picker</strong> – Generate palettes, copy HEX/RGB, and lock favorite swatches.</li>
<li><strong>Text Case Converter</strong> – Transform casing (title, sentence, kebab) and track history.</li>
<li><strong>Word &amp; Character Counter</strong> – Real-time stats with reading time estimates.</li>
<li><strong>Number Guessing Game</strong> – Difficulty levels, hint system, and scoreboard persistence.</li>
<li><strong>Stopwatch with Laps</strong> – Pause/resume, lap list, and keyboard shortcuts.</li>
<li><strong>Simple Poll App</strong> – Anonymous voting with shareable links and live percentages.</li>
<li><strong>Random Name Picker</strong> – Shuffle participants with celebration animation for workshops.</li>
<li><strong>Emoji Search App</strong> – Filter emoji by keywords and copy to clipboard instantly.</li>
<li><strong>File Size Converter</strong> – Convert between KB/MB/GB with history chips.</li>
<li><strong>Simple Pagination Demo</strong> – Custom hook that paginates arrays and fetch results.</li>
<li><strong>Accordion Component</strong> – Accessible accordion with keyboard navigation baked in.</li>
<li><strong>Star Rating Component</strong> – Hover preview, half-stars, and form integration.</li>
<li><strong>URL Shortener</strong> – Integrate bit.ly or a serverless API plus click analytics.</li>
<li><strong>URL Metadata Preview Tool</strong> – Fetch Open Graph tags and render preview cards.</li>
<li><strong>Notes App with Tags</strong> – Filter notes by tag, color-code labels, and sync with localStorage.</li>
<li><strong>Simple CMS Dashboard</strong> – Editable tables, bulk actions, and fake auth for demos.</li>
</ol>
<hr />
<h2>Intermediate React Projects (18 Ideas)</h2>
<p>Each of these ideas goes beyond CRUD by adding collaborative UI, performance tweaks, or API orchestration.</p>
<ol>
<li><strong>Expense Splitter App</strong> – Let groups add shared costs, split them evenly or by weight, and export balances.</li>
<li><strong>Habit Tracker</strong> – Daily/weekly streaks with charts, reminders, and optimistic UI for quick logging.</li>
<li><strong>Kanban Board</strong> – Drag-and-drop columns, swimlanes, and persistent filters for backlog grooming.</li>
<li><strong>Bookmark Manager</strong> – Save URLs, tag them, and auto-fetch favicon/metadata for better previews.</li>
<li><strong>Movie Recommendation App</strong> – Combine TMDB data with user ratings to generate collaborative playlists.</li>
<li><strong>GitHub Profile Analyzer</strong> – Pull repos, contributions, and language charts via GraphQL API.</li>
<li><strong>Weather Forecast App</strong> – Show hourly/daily forecasts, radar layers, and alert banners.</li>
<li><strong>Product Comparison Tool</strong> – Table compare specs, highlight differences, and shareable URLs.</li>
<li><strong>Resume Builder</strong> – Drag blocks, live preview PDF, and export tailored resumes in one click.</li>
<li><strong>Multi-step Form Wizard</strong> – Save partial progress, validate per step, and show progress indicators.</li>
<li><strong>Online Polling App</strong> – Real-time vote counts, anonymous + authenticated modes, and embed widgets.</li>
<li><strong>Notification Center</strong> – Toast feed with grouping, snoozing, and cross-device sync.</li>
<li><strong>Chat UI with Message Threads</strong> – Slack-style threaded replies, emoji reactions, and typing states.</li>
<li><strong>Appointment Booking App</strong> – Calendar slots, timezone handling, and ICS/email confirmations.</li>
<li><strong>Learning Progress Tracker</strong> – Track lessons, quizzes, and achievements with streak-based retention.</li>
<li><strong>Role-Based Access Control System</strong> – Visualize roles/permissions and preview what each sees.</li>
<li><strong>Knowledge Base Platform</strong> – Markdown docs with search, tagging, and AI answer suggestions.</li>
<li><strong>Customer Support Ticket System</strong> – Ticket queues, SLA timers, and collision detection for agents.</li>
</ol>
<hr />
<h2>Advanced React Projects (16 Ideas)</h2>
<p>Ready for architecture conversations? These ideas combine routing, data modeling, and integration with external APIs or workers.</p>
<ol>
<li><strong>Multi-Tenant SaaS App</strong> – Tenant-aware routing, custom domains, and role-scoped data isolation.</li>
<li><strong>Real-time Chat with Presence</strong> – WebSockets + presence indicators and message retention policies.</li>
<li><strong>Payment Subscription Dashboard</strong> – Stripe billing, upgrade/downgrade flows, and dunning emails.</li>
<li><strong>Admin Panel Generator</strong> – Upload schema definitions and auto-generate CRUD dashboards.</li>
<li><strong>Micro-frontend Demo App</strong> – Showcase module federation or Web Components for isolated teams.</li>
<li><strong>Analytics &amp; Reporting Platform</strong> – Query builder, chart library, and scheduled PDF exports.</li>
<li><strong>Real-time Notification System</strong> – Server-sent events for system alerts plus delivery receipts.</li>
<li><strong>Online Whiteboard App</strong> – Canvas drawing, collaborative cursors, and undo/redo history.</li>
<li><strong>Headless CMS Frontend</strong> – Build a starter UI for Payload, Sanity, or Contentful with live preview.</li>
<li><strong>Task Automation Builder</strong> – Zapier-style flow designer with draggable workflow nodes.</li>
<li><strong>Form Builder Platform</strong> – Drag fields, configure validation, and deliver submissions via webhooks.</li>
<li><strong>Feature Flag Management Tool</strong> – Targeting rules, rollout percentages, and SDK docs.</li>
<li><strong>Real-time Stock Trading Simulator</strong> – Mock order book, candlestick charts, and challenge leaderboards.</li>
<li><strong>Workflow Automation Tool</strong> – Multi-step approvals, SLA timers, and audit logging.</li>
<li><strong>Document Signing Platform</strong> – Upload documents, add signature fields, and send tracked invites.</li>
<li><strong>SSR Marketplace</strong> – Server-rendered storefront, search filters, and seller dashboards.</li>
</ol>
<hr />
<p>Once you wrap a few of these, circle back to <a href="/react-project-ideas-2026/">Part 1</a> to mix-and-match ideas or explore the <a href="/docker-beginner-to-advanced/">Docker for beginners guide</a> to level up your DevOps foundation.</p>
<p>Happy building! Let me know which project you’re tackling first.</p>
]]></content>
        <author>
            <name>Gaurav Adhikari</name>
            <uri>https://gauravadhikari.com</uri>
        </author>
        <published>2026-01-17T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Roadmap 2026: From Beginner to Job-Ready]]></title>
        <id>https://gauravadhikari.com/react-roadmap-2026/</id>
        <link href="https://gauravadhikari.com/react-roadmap-2026/"/>
        <updated>2025-10-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Learn React step by step with this 2026 React Roadmap. A complete practical guide to becoming a front-end developer and building real-world React apps.]]></summary>
        <content type="html"><![CDATA[<p><img src="https://gauravadhikari.com/images/articles/react-roadmap-2026/react-roadmap-2026.webp" alt="React Roadmap 2026" /></p>
<p>2026 is already here and React JS is still one of most demanded programming language to get yourself hired. So here I am, writing this blog for those who are looking to learn react to become a frontend developer, or someone who is a backend developer and aspires to become a full stack developer, or anyone looking for a clear roadmap to become a react js developer.</p>
<p>No wonder why react is still most popular choice for companies because of its flexibility, vast npm libraries ecosystem, and strong community support. So lets dive in and learn the react in most practical way in order to avoid confusion, stay on track and be focused.</p>
<hr />
<h2>React Roadmap 2026</h2>
<p>This roadmap guides you step-by-step from learning the basics of web and becoming a react pro. Then extending your skills to Next.js, and TypeScript and building and deploying professional projects.</p>
<h2>0. HTML, CSS, and JavaScript Basics</h2>
<p>In short, HTML is skeleton, CSS is styling and JS is the interactions on a web page.</p>
<p>So in order to create react apps, we first need to understand how to create skeleton of a page, then how to make the skeleton look beautiful using CSS and finally add some interactivity to the page like button clicks, form submission, etc.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li><strong>HTML:</strong> semantic tags, forms, accessibility, SEO basics</li>
<li><strong>CSS:</strong> flexbox, grid, responsive layouts, animations, variables</li>
<li><strong>JavaScript:</strong> data types, loops, functions, arrays, DOM manipulation, ES6+ features</li>
</ul>
<p>When I started learning HTML, I created a calculator using html table tag, then I styled it using CSS, then I added operations using JavaScript.</p>
<p><strong>Goal:</strong> Be confident building simple, interactive web pages using only HTML, CSS, and JavaScript.
Try small projects like a weather widget, calculator, or responsive landing page.</p>
<h2>1. More on JavaScript</h2>
<p>Before you move on to React, I would highly recommended you to check out and practice JS arrays and its manipulation, ES6 features so that it becomes easy to move into react.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Arrays and array methods (map, filter, reduce, forEach)</li>
<li>Rest and spread operators (...)</li>
<li>Template literals and destructuring</li>
<li>ES6+ features: modules, promises, async/await</li>
</ul>
<p><strong>Goal:</strong> In react apps, you will extensively use array manipulation so it is a must to learn.</p>
<h2>2. React Basics (JSX, Components, Props)</h2>
<p>Once you’re solid on JavaScript, start exploring React and the best way to start with react is its <a href="https://react.dev/learn">official docs</a>.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Understanding JSX and component-based architecture</li>
<li>Creating reusable functional components</li>
<li>Passing data with props</li>
<li>Component tree, rendering, and state basics</li>
</ul>
<p><strong>Goal:</strong> Build small apps like a counter, todo list, or calculator to practice component logic and rendering.</p>
<h2>3. Hooks and State Management</h2>
<p>React hooks are the foundation of modern React development. Everything you do inside react app will be directly or indirectly done using react hooks.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li><code>useState</code>, <code>useEffect</code>, <code>useRef</code>, <code>useContext</code>, <code>useReducer</code></li>
<li>Controlled vs uncontrolled components</li>
<li>Pure Components and sharing state up between components</li>
<li>Using Context API for global state</li>
</ul>
<p><strong>Goal:</strong> Understand how React updates the UI, manages data flow, and handles user interactions effectively.</p>
<h2>4. Routing and APIs</h2>
<p>Real world apps are dynamic and so they have multiple pages and load data dynamically. Learn how to make your React apps interactive and data-driven.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li><strong>React Router:</strong> navigation, nested routes, dynamic routes, &amp; protected routes</li>
<li><strong>APIs:</strong> fetching data using Fetch API or Axios</li>
<li>Handling loading states, errors, and pagination</li>
</ul>
<p><strong>Goal:</strong> Build an app that fetches and displays data from a public API (e.g., a GitHub user search or movie app).</p>
<h2>5. Advanced Concepts (Next.js, TypeScript, Redux Toolkit)</h2>
<p>Let me tell you very clearly that production apps always use TypeScript. So you must side by side keep brushing up TypeScript knowledge.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li><strong>Next.js:</strong> server-side rendering (SSR), static site generation (SSG), API routes, SEO best practices</li>
<li><strong>TypeScript:</strong> typing props, components, and hooks</li>
<li><strong>Redux Toolkit:</strong> creating stores, slices, and handling async logic with thunks</li>
</ul>
<p><strong>Goal:</strong> Build scalable, maintainable applications that mimic real production setups.</p>
<h2>6. Project Building and Deployment</h2>
<p>Now is the time to put your knowledge into GitHub and show it off to the world. Live projects are the best way to tell someone that you are capable!</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Build <strong><a href="/react-project-ideas-2026/">3–5 polished portfolio projects</a></strong> (e-commerce site, blog, admin dashboard, etc.)</li>
<li>Connect to real APIs or Firebase for authentication and data storage</li>
<li>Deploy using <strong>Vercel</strong>, <strong>Netlify</strong>, or <strong>GitHub Pages</strong></li>
<li>Learn <strong>Git</strong>, <strong>GitHub</strong>, and version control best practices</li>
</ul>
<p><strong>Goal:</strong> Have a strong portfolio to show employers you can build and ship complete React apps.</p>
<p>The next important skill that employers love is Docker and here is your way to <a href="/docker-beginner-to-advanced/">learn Docker for beginners</a>.</p>
<h2>Wrapping Up</h2>
<p>Becoming a React developer in 2026 is about practicing regularly and learning step by step. You don’t have to learn everything at once. Start with the basics, then move to React, and try building small projects. The more you build, the better you’ll get.</p>
<p>React changes over time, but the main ideas stay the same. Once you understand components, state, and how data moves in your app, learning new tools like Next.js will be much easier.</p>
<p>Keep coding and keep creating. Remember, every React developer started with a simple app that said, “Hello, React!”</p>
<hr />
<h2>Frequently Asked Questions</h2>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Why learn React in 2026?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;React remains one of the most in-demand front-end libraries, used by companies worldwide. Its ecosystem keeps evolving with tools like Next.js and React Server Components, making it a strong career choice for developers.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Do I need to know JavaScript before learning React?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes. A solid understanding of JavaScript fundamentals — arrays, objects, functions, and ES6 features — is essential before diving into React.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How long does it take to become job-ready in React?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Most learners can become job-ready within 2-3 months by following a roadmap, building small apps, and completing a few strong portfolio projects.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Should I learn Next.js with React?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Absolutely. Next.js adds server-side rendering, routing, and SEO benefits to React, which are critical for production-ready applications.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Is TypeScript required for React in 2026?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;While not mandatory, TypeScript has become a standard for professional React projects. It helps catch errors early and makes your code more predictable.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Which state management tool should I learn first?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Start with the Context API and React hooks. Once you’re comfortable, explore Redux Toolkit for managing larger or more complex applications.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I get a job with just React knowledge?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes. Many front-end roles focus heavily on React. If you also know HTML, CSS, and JavaScript fundamentals, plus some deployment skills, you can land an entry-level role.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What projects should I build for my React portfolio?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Focus on real-world examples like a Todo app, movie search app, e-commerce frontend, or a SaaS dashboard. Showcase projects that demonstrate your understanding of components, APIs, and deployment.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Where can I host my React projects?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Vercel and Netlify are great free options for deploying React or Next.js apps with custom domains and continuous deployment.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I learn React without a CS degree?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Definitely. Many successful React developers are self-taught. What matters most is consistent learning, practice, and building real projects.&lt;/p&gt;
&lt;/details&gt;</p>
]]></content>
        <author>
            <name>Gaurav Adhikari</name>
            <uri>https://gauravadhikari.com</uri>
        </author>
        <published>2025-10-29T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Java Developer Roadmap 2026: Your Complete Practical Guide]]></title>
        <id>https://gauravadhikari.com/java-developer-roadmap-2026/</id>
        <link href="https://gauravadhikari.com/java-developer-roadmap-2026/"/>
        <updated>2025-10-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Learn Java step by step with this 2026 Java Developer Roadmap. Here’s how to become a skilled Java developer and grow your career.]]></summary>
        <content type="html"><![CDATA[<p><img src="https://gauravadhikari.com/images/articles/java-developer-roadmap-2026/java-developer-roadmap-2026.webp" alt="Java Developer Roadmap 2026" /></p>
<p>If you’re wondering whether Java is still worth learning in 2026, based on my personal experience as working in big tech company is a big <strong>yes</strong>.</p>
<p>Java remains one of the most trusted programming languages for backend systems, enterprise applications, and Android development. With modern updates like <strong>virtual threads</strong> and frameworks like <strong>Spring Boot</strong>, Java is faster, more efficient, and beginner-friendly.</p>
<p>So if you want to build powerful web apps or secure enterprise systems, learning Java in 2026 is a smart career investment and that is what the companies also demand from software engineers (check any job platform).</p>
<hr />
<h2>Java Roadmap 2026</h2>
<p><img src="https://gauravadhikari.com/images/articles/java-developer-roadmap-2026/java-roadmap-2026.webp" alt="Java Developer Roadmap 2026" /></p>
<p>This roadmap is your step-by-step path from complete beginner to job-ready Java developer, covering everything from syntax and OOP to frameworks, databases, and testing.</p>
<p>Whether you’re just starting to learn programming or coming from another language like JavaScript, this guide will help you stay on track and not feel stressed. You can also check out <a href="/react-project-ideas-2026/">60 React Project Ideas for 2026</a> to practice your frontend skills alongside learning Java.</p>
<h2>1. Learn the Basics</h2>
<p>Everything in Java starts here. These fundamentals help you understand how code runs and interacts.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Syntax, keywords, and structure of a Java program</li>
<li>Data types, variables, and type casting</li>
<li>Loops, conditionals, and arrays</li>
<li>Strings and math operations</li>
<li>Variables and scopes</li>
</ul>
<p><strong>Tip:</strong> Practice writing small programs daily. Build a calculator, a simple number guessing game, or a pattern printer.</p>
<h2>2. Object-Oriented Programming (OOP)</h2>
<p>OOP makes Java clean, organized, and reusable which is the core part of every Java project.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Classes, objects, and constructors</li>
<li>Inheritance, encapsulation, and polymorphism</li>
<li>Method overloading and overriding</li>
<li>Interfaces and abstraction</li>
<li>Enums, static keyword, and nested classes</li>
</ul>
<p><strong>Tip:</strong> Think in real-world terms. For example, a <code>Car</code> class with <code>Engine</code> and <code>Wheel</code> objects helps you visualize OOP.</p>
<h2>3. Collections Framework</h2>
<p>Collections make it easy to store and manipulate groups of data efficiently.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Lists, Sets, Maps, Queues, and Stacks</li>
<li>ArrayList vs LinkedList</li>
<li>Generics and Iterators</li>
<li>Optionals and Exception Handling</li>
</ul>
<p><strong>Tip:</strong> Try solving small problems like counting word frequency or finding duplicates using a <code>HashMap</code>.</p>
<h2>4. Functional Programming &amp; Streams</h2>
<p>Very Important. Modern Java embraces a functional style for cleaner, more readable code.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Lambda expressions</li>
<li>Functional interfaces</li>
<li>Stream API and Optional</li>
<li>Higher-order and composition functions</li>
</ul>
<p><strong>Tip:</strong> Try changing your old for-loops into Streams. It looks cleaner and works better once you get the hang of it.</p>
<h2>5. Concurrency and Threads</h2>
<p>Threads let your program do more than one thing at the same time, which makes it run faster (performance).</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Basics of Threads and Runnable</li>
<li>Virtual Threads (Project Loom)</li>
<li>Synchronization and volatile keyword</li>
<li>Java Memory Model</li>
</ul>
<p><strong>Tip:</strong> Start simple. Make two threads that print numbers, then learn about thread pools and concurrent utilities.</p>
<p>Bonus: Once you start building real applications, learning how to containerize them is next skill to get. Check out our <a href="/docker-beginner-to-advanced/">Docker Deep Dive: Beginner to Advanced</a> to see how to build, ship, and run apps efficiently.</p>
<h2>6. Build Tools (Maven | Gradle)</h2>
<p>Build tools help you manage dependencies and automate builds.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Maven basics: pom.xml, dependencies, plugins</li>
<li>Gradle scripts for modern automation</li>
<li>Running builds and managing versions</li>
</ul>
<p><strong>Tip:</strong> Begin with Maven because it’s simpler for beginners and widely used in enterprise projects.</p>
<h2>7. Frameworks: Spring Boot</h2>
<p>Frameworks help you build production-level apps faster and cleaner.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Spring Core and Dependency Injection</li>
<li>REST APIs with Spring Boot</li>
<li>Profiles, Configuration, and Spring Security basics</li>
</ul>
<p><strong>Tip:</strong> Build a REST API that returns “Hello Java" in JSON.</p>
<h2>8. Databases and ORM</h2>
<p>Every application needs to store data somewhere.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>JDBC basics</li>
<li>Hibernate and JPA for ORM</li>
<li>Spring Data JPA for modern access</li>
<li>SQL basics (MySQL, PostgreSQL)</li>
</ul>
<p><strong>Tip:</strong> Connect your Spring Boot app to a local database and perform CRUD (Create, Read, Update, Delete) operations.</p>
<h2>9. Testing</h2>
<p>Testing ensures your code is reliable and bug-free.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>JUnit for unit testing</li>
<li>Mockito for mocking dependencies</li>
<li>REST Assured for API testing</li>
<li>Integration and load testing</li>
</ul>
<p><strong>Tip:</strong> Write at least one test for every important class. It will save you hours of debugging later.</p>
<h2>10. Other Essentials</h2>
<p>These extra tools make you a complete Java developer.</p>
<p><strong>Focus on:</strong></p>
<ul>
<li>Logging: Logback, Log4j2, SLF4J</li>
<li>Networking and Regular Expressions</li>
<li>File I/O and Stream handling</li>
<li>Date &amp; Time API and basic Cryptography</li>
</ul>
<p><strong>Tip:</strong> Explore gradually because these skills will naturally come as you build real projects.</p>
<h2>Wrapping Up</h2>
<p>Becoming a Java developer takes time, but it is worth it. You do not need to learn everything at once. Take one step at a time. Build small projects and keep getting better.</p>
<p>Java changes fast, but the basic ideas stay the same. When you know how to use objects and classes, frameworks, and databases, you can build a strong career.</p>
<p><strong>Keep coding and stay curious. Remember, every Java pro once started with <code>System.out.println("Hello, World!")</code>.</strong></p>
<h2>Frequently Asked Questions</h2>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Why learn Java in 2026?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Java continues to power enterprise systems, Android apps, and backend services. With updates like virtual threads and modern frameworks such as Spring Boot, it remains highly relevant for developers.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;I’m a JavaScript developer — can I switch to Java easily?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Your existing knowledge of programming logic and OOP concepts will help you transition quickly. Start with Java syntax and OOP before exploring frameworks like Spring Boot.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How long does it take to become job-ready in Java?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;With consistent effort, you can become job-ready in 5-6 months by following a roadmap, building small projects, and learning tools like Maven, Spring Boot, and JUnit.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Which framework should I start with?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Spring Boot is the best choice for beginners. It simplifies configuration, helps you build REST APIs quickly, and is widely used in the industry.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Do I need to learn all topics before applying for a job?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Focus first on Java basics, OOP, collections, and Spring Boot. You can learn testing, databases, and concurrency gradually while working on projects.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Do I need to learn databases?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Learning SQL and basic ORM with Hibernate or JPA is important for most real-world projects.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I get a job with just Java knowledge?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, especially if you know Spring Boot, REST APIs, and have a few practical projects to showcase on GitHub.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Why choose Java over Python?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Python is great for quick scripts and AI, but Java is better for large, scalable applications. It offers strong typing, higher performance, and is preferred by many companies for backend and financial systems.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I learn Java and Python at the same time?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;It’s possible, but not recommended for beginners. Focus on Java first to understand programming fundamentals deeply. Once confident, learning Python becomes much easier.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I learn Java in one month?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;You can learn the basics — syntax, loops, and simple programs in a month. But mastering Java, including frameworks like Spring Boot, requires consistent practice over several months.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How can I learn Java step by step?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Follow a roadmap: start with syntax and OOP, move to collections and functional programming, then learn frameworks like Spring Boot and database access. Build small projects to practice along the way.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Which is harder to learn — Java or JavaScript?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;They are very different. Java has stricter syntax and more structure, which is useful for large applications. Once you understand Java, learning JavaScript feels easier.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Where can I learn Java for free?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Start with free resources like Oracle’s official Java tutorials, W3Schools, or GeeksforGeeks. Combine these with coding practice on platforms like LeetCode or HackerRank.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Which should I learn first — Java or C++?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Start with Java. It’s simpler, has automatic memory management, and helps you grasp OOP concepts clearly. Once comfortable, learning C++ becomes easier.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How can I learn Java in an easy way?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Code daily, use visual roadmaps, build mini projects, and test your knowledge with small coding challenges. The more you practice, the faster Java will make sense.&lt;/p&gt;
&lt;/details&gt;</p>
]]></content>
        <author>
            <name>Gaurav Adhikari</name>
            <uri>https://gauravadhikari.com</uri>
        </author>
        <published>2025-10-18T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[60 React Project Ideas for 2026 – Beginner to Advanced]]></title>
        <id>https://gauravadhikari.com/react-project-ideas-2026/</id>
        <link href="https://gauravadhikari.com/react-project-ideas-2026/"/>
        <updated>2025-09-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A curated list of 60 React project ideas from beginner to advanced, with short summaries to help you practice JSX, hooks, APIs, state management, and advanced concepts like Redux, Next.js, and GraphQL.]]></summary>
        <content type="html"><![CDATA[<p><img src="https://gauravadhikari.com/images/articles/react-project-ideas-2026/react-project-ideas-2026.webp" alt="React Project Ideas from Beginner to Advanced" /></p>
<h2>60 React Project Ideas for 2026</h2>
<p>Whether you’re just starting with React or already know how to make apps, the best way to really learn React is by building projects. The problem is, sometimes you don’t know what to build.</p>
<p>That’s why I made a list of 60 React project ideas, split into Beginner, Intermediate, and Advanced levels. Each idea has a short description to help you pick where to start and how to push yourself.</p>
<p>Let’s dive in!</p>
<hr />
<h2>Beginner React Projects (20 Ideas)</h2>
<p>These focus on <strong>JSX, props, state, events, and basic hooks</strong>. A good place to start.</p>
<p><img src="https://gauravadhikari.com/images/articles/react-project-ideas-2026/react-beginner-project-ideas.webp" alt="React Beginner Project Ideas" /></p>
<ol>
<li><strong>Counter App</strong> – Increment, decrement, and reset buttons.</li>
<li><strong>Todo List</strong> – Add, delete, and mark tasks as completed.</li>
<li><strong>Weather App (API)</strong> – Fetch real-time weather data from OpenWeather API.</li>
<li><strong>Calculator</strong> – Basic arithmetic with clear/reset.</li>
<li><strong>Stopwatch/Timer</strong> – Start, stop, and reset a timer.</li>
<li><strong>Digital Clock</strong> – Live clock showing date &amp; time.</li>
<li><strong>Quote Generator</strong> – Fetch random quotes from an API.</li>
<li><strong>BMI Calculator</strong> – Input weight/height to calculate BMI.</li>
<li><strong>Expense Tracker</strong> – Track income &amp; expenses with charts.</li>
<li><strong>Image Gallery</strong> – Display images with filters &amp; search.</li>
<li><strong>Form Validation App</strong> – Login/Signup form with validation.</li>
<li><strong>Movie App</strong> – Fetch movies using the OMDB API.</li>
<li><strong>Notes App</strong> – Sticky notes with add &amp; delete.</li>
<li><strong>Quiz App</strong> – Multiple-choice questions with scoring.</li>
<li><strong>Currency Converter</strong> – Convert currencies with an API.</li>
<li><strong>Markdown Previewer</strong> – Convert markdown to HTML in real-time.</li>
<li><strong>Random Color Generator</strong> – Generate random HEX/RGB colors.</li>
<li><strong>Typing Speed Test</strong> – Calculate WPM with a timer.</li>
<li><strong>Joke Generator</strong> – Fetch random jokes from an API.</li>
<li><strong>Light/Dark Mode Toggle</strong> – Theme switcher with Context or state.</li>
</ol>
<p><em>Tip: For most of these, try building them first with plain state/hooks, then later refactor with Context or Redux when you’re comfortable.</em></p>
<hr />
<h2>Intermediate React Projects (20 Ideas)</h2>
<p>At this stage, you’ll need <strong>React Router, Context API, custom hooks, authentication, and performance optimizations</strong>.</p>
<p><img src="https://gauravadhikari.com/images/articles/react-project-ideas-2026/react-intermediate-project-ideas.webp" alt="React Intermediate Project Ideas" /></p>
<ol>
<li><strong>E-commerce Store (Frontend)</strong> – Product listing, cart, and checkout flow.</li>
<li><strong>Blog Platform</strong> – CRUD posts, comments, and categories.</li>
<li><strong>Chat App (Basic)</strong> – Real-time messaging with WebSockets.</li>
<li><strong>Recipe Finder App</strong> – Search recipes via API.</li>
<li><strong>Music Player</strong> – Play, pause, and skip with progress bar.</li>
<li><strong>Task Manager (Drag-and-Drop)</strong> – Trello-style kanban board.</li>
<li><strong>Portfolio Website</strong> – Personal interactive portfolio.</li>
<li><strong>Fitness Tracker</strong> – Track workouts &amp; calories.</li>
<li><strong>Job Board App</strong> – Search &amp; filter jobs via API.</li>
<li><strong>Photo Editor App</strong> – Basic filters, cropping, resizing.</li>
<li><strong>Survey/Feedback App</strong> – Create, submit, and analyze surveys.</li>
<li><strong>E-learning Platform (Mini)</strong> – Video lessons with progress.</li>
<li><strong>Stock Market Tracker</strong> – Fetch live stock data via API.</li>
<li><strong>Multilingual App</strong> – i18n support for multiple languages.</li>
<li><strong>Crypto Dashboard</strong> – Live cryptocurrency updates.</li>
<li><strong>Collaborative Notes App</strong> – Shared notes with Firebase.</li>
<li><strong>Flight Search App</strong> – Search flights via API.</li>
<li><strong>News Aggregator</strong> – Fetch &amp; categorize news.</li>
<li><strong>E-voting App (Mock)</strong> – Create polls and tally votes.</li>
<li><strong>Recipe Meal Planner</strong> – Weekly meal planning with saved recipes.</li>
</ol>
<p><em>Tip: These projects are perfect to add to your portfolio. Try integrating <strong>Firebase, MongoDB, and Express.js APIs</strong> for persistence.</em></p>
<p>Want to add social-style features? Check out my tutorial on <a href="/react-mentions-implementation-guide-with-typescript-in-2025/">building Hashtags and Mentions in React with TypeScript</a>.</p>
<hr />
<h2>Advanced React Projects (20 Ideas)</h2>
<p>These will push you into <strong>Redux, Next.js, SSR, GraphQL, authentication, testing, and scalability</strong>. Think like a production-ready engineer here.</p>
<p><img src="https://gauravadhikari.com/images/articles/react-project-ideas-2026/react-advanced-project-ideas.webp" alt="React Advanced Project Ideas" /></p>
<ol>
<li><strong>Full E-commerce App</strong> – Authentication, payments, admin panel.</li>
<li><strong>Social Media App</strong> – Profiles, posts, likes, comments &amp; follows.</li>
<li><strong>SaaS Dashboard</strong> – Subscription management &amp; analytics.</li>
<li><strong>Project Management Tool</strong> – Like Asana/Trello/Jira.</li>
<li><strong>Video Streaming Platform</strong> – Upload, play, &amp; comment.</li>
<li><strong>Learning Management System (LMS)</strong> – Courses, quizzes &amp; certificates.</li>
<li><strong>Real-time Collaboration Tool</strong> – Google Docs–style editor.</li>
<li><strong>AI Chatbot Interface</strong> – Connect with ChatGPT API.</li>
<li><strong>Travel Booking App</strong> – Hotels, flights &amp; itineraries.</li>
<li><strong>Healthcare Portal</strong> – Appointments, prescriptions, &amp; reports.</li>
<li><strong>Real Estate Platform</strong> – Property listings with maps.</li>
<li><strong>Food Delivery App (Frontend)</strong> – Menu &amp; orders.</li>
<li><strong>CRM System</strong> – Manage leads &amp; sales pipelines.</li>
<li><strong>Video Conferencing App</strong> – Like Zoom with WebRTC.</li>
<li><strong>Banking Dashboard</strong> – Transactions &amp; analytics.</li>
<li><strong>Event Ticketing App</strong> – Book/manage tickets.</li>
<li><strong>NFT Marketplace</strong> – Mint, buy &amp; sell NFTs.</li>
<li><strong>Online Code Editor</strong> – Run HTML, CSS, JS in browser.</li>
<li><strong>Voice Assistant App</strong> – Voice commands with APIs.</li>
<li><strong>Next.js SaaS Boilerplate</strong> – Authentication, billing, dashboard.</li>
</ol>
<p><em>Tip: These projects involve <strong>backend integration, authentication (JWT, OAuth), payments (Stripe), and deployment (Vercel, AWS, etc.)</strong>. Perfect for interviews and portfolios.</em></p>
<p>Once your projects are ready, here’s a guide on <a href="/how-to-deploy-node-react-app-on-web-hosting/">deploying a Node + React app on cPanel hosting</a>.</p>
<hr />
<h2>Final Thoughts</h2>
<p>That’s the end of 60 React project ideas for 2026! Whether you start with a simple Counter App or try something harder like a Next.js SaaS Boilerplate, the most important thing is to keep going. Don’t just copy tutorials. Try things out, break stuff, and add your own ideas to each project.</p>
<p>Pro tip: Write down what you learn. After each project, make a short blog post or add a README on GitHub. It helps other people and makes your portfolio look better.</p>
<p>The next important skill to learn after React is <a href="/docker-beginner-to-advanced/">Docker for beginners</a>.</p>
<h2>Frequently Asked Questions</h2>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How do I choose the right React project as a beginner?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Start small with projects like a Counter App or Todo List to grasp the basics of JSX, props, state, and events. Once comfortable, move on to projects that involve fetching data from APIs.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Do I need TypeScript for these projects?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;No, you can build all of them using plain JavaScript. However, using TypeScript makes your projects more robust and is highly recommended if you want to pursue React professionally.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How long does it take to finish these projects?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Beginner projects usually take 1–3 hours, intermediate projects can take a couple of days, and advanced ones may take 1–2 weeks depending on features like backend, authentication, or deployment.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Where should I deploy my React projects?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;You can use Vercel or Netlify for beginner projects. For advanced apps that require APIs or databases, platforms like Render, Heroku, or cloud providers such as AWS, GCP, and Azure are better choices.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Do these projects require a backend?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Not all. Beginner apps like Calculator or Digital Clock are purely frontend. Intermediate and advanced apps, such as chat apps or e-commerce platforms, typically need a backend with APIs or databases.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How can I make my projects stand out in a portfolio?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Enhance them with good UI using TailwindCSS or Material UI, add extra features like dark mode, host them online with a live demo, and write clear documentation or blog posts explaining your approach.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Are these projects useful for interviews?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, recruiters value practical projects. Even a Todo App shows your understanding of state management, while advanced apps like e-commerce stores or SaaS dashboards showcase job-ready skills.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I use AI tools like ChatGPT to build these projects?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, AI can help generate boilerplate code, debug issues, and suggest optimizations. But ensure you understand the implementation fully, since interviews will test your problem-solving skills, not just the output.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Should I use Redux in these projects?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;For smaller apps, React hooks like useState and useContext are sufficient. For larger projects with complex state management, Redux, Zustand, or Recoil can make your code more scalable and maintainable.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What’s the best way to track my progress?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Maintain a GitHub repository with each project in a separate folder, use a personal checklist to mark completed projects, and share updates on LinkedIn or Twitter to stay accountable and showcase growth.&lt;/p&gt;
&lt;/details&gt;</p>
]]></content>
        <author>
            <name>Gaurav Adhikari</name>
            <uri>https://gauravadhikari.com</uri>
        </author>
        <published>2025-09-28T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Mentions Implementation Guide with TypeScript in 2025]]></title>
        <id>https://gauravadhikari.com/react-mentions-implementation-guide-with-typescript-in-2025/</id>
        <link href="https://gauravadhikari.com/react-mentions-implementation-guide-with-typescript-in-2025/"/>
        <updated>2025-09-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Learn how to implement @mentions and #tags in React apps using react-mentions, Vite, and TypeScript. Includes code, hooks, and performance tips.]]></summary>
        <content type="html"><![CDATA[<p><img src="https://gauravadhikari.com/images/articles/react-mentions-implementation-guide-with-typescript-in-2025/react-mentions-implementation-guide-with-typescript-in-2025.webp" alt="React Mentions with TypeScript" /></p>
<p>If you are looking to implement mentions and hashtags in your React app, this guide is the one stop for all answers on how to add mentions using the react-mentions library.</p>
<p>I have organized this blog into two parts, first half is beginner friendly which explains the minimal setup to render mentions textarea, its UI customization and styling, and previewing content.</p>
<p>In the next half, we dive deeper into advanced concepts like fetching suggestions from api asynchronously, debouncing, saving new hashtags to database and safely rendering the html content in browser.</p>
<p><em>Before we move further, note that this tutorial uses React with TypeScript, with Vite as builder.</em></p>
<p>Let’s start the show now!</p>
<h2>Rendering a textarea for mentions using hardcoded data</h2>
<p>The simplest way to add mentions or hashtags in your React app is by using the <strong><code>MentionsInput</code></strong> component from the <strong><code>react-mentions</code></strong> library. This is essentially a textarea input field that works like any standard input which it accepts <strong><code>value</code></strong> and <strong><code>onChange</code></strong> props.</p>
<p>Then to show the suggestions dropdown when typing <code>@</code> symbol, we have to use <code>Mention</code> component from <code>react-mentions</code>.</p>
<p>Now, to work it as expected, it requires few more attributes to be passed as shown below:</p>
<ul>
<li>
<p>trigger: the symbol which should open suggestions box</p>
</li>
<li>
<p>data: the array of objects {id, display} to show in suggestions box</p>
</li>
<li>
<p>displayTransform: how should the selected mention look like</p>
</li>
<li>
<p>markup: useful to extract mentions from the raw input</p>
</li>
<li>
<p>appendSpaceOnAdd: if true, adds a space after a mention is selected</p>
</li>
</ul>
<p>Now let’s look at the very basic implementation of mentions in react:</p>
<pre><code>import { useState } from 'react'
import { Mention, MentionsInput } from 'react-mentions'
import './App.css'

function App() {
  const [value, setValue] = useState('')

  const handleChange = (e: {
    target: {
      value: string
    }
  }) =&gt; {
    setValue(e.target.value)
  }

  return (
    &lt;div&gt;
      &lt;h1&gt;Mentions and Hashtags in React&lt;/h1&gt;
      &lt;MentionsInput
        className="mentions"
        value={value}
        onChange={handleChange}
        placeholder="What's on your mind?"
      &gt;
        &lt;Mention
          className="mention"
          trigger="@"
          data={[
            {
              id: '1',
              display: 'John Doe',
            },
            {
              id: '2',
              display: 'Jane Smith',
            },
          ]}
          displayTransform={(_: string, display: string) =&gt; `@${display}`}
          markup="@[__display__](__id__)"
          appendSpaceOnAdd
        /&gt;
      &lt;/MentionsInput&gt;

      &lt;h3&gt;Raw value:&lt;/h3&gt;
      &lt;p&gt;{value}&lt;/p&gt;
    &lt;/div&gt;
  )
}

export default App
</code></pre>
<p>And this is what we get, looks cool, right?</p>
<p><img src="https://gauravadhikari.com/images/articles/react-mentions-implementation-guide-with-typescript-in-2025/react-mentions-hardcoded-demo.webp" alt="React mentions hardcoded demo" /></p>
<h2>Styling the suggestions dropdown list</h2>
<p>Just to be on the same page, let me share the css for styling the Mentions. This will be same throughout the tutorial, and we will focus on functionality.</p>
<pre><code>.mentions--singleLine .mentions__control {
  display: inline-block;
}
.mentions--singleLine .mentions__higlighter {
  padding: 1px;
  border: 2px inset transparent;
}
.mentions--singleLine .mentions__input {
  padding: 5px;
  border: 2px inset;
}
.mentions--multiLine .mentions__control {
  font-family: monospace;
  font-size: 11pt;
  border: 1px solid silver;
  height: 300px;
  overflow-y: auto;
}
.mentions--multiLine .mentions__highlighter {
  padding: 9px;
}
.mentions--multiLine .mentions__input {
  padding: 9px;
  min-height: 63px;
  outline: 0;
  border: 0;
}
.mentions__suggestions__list {
  background-color: white;
  border: 1px solid rgba(0, 0, 0, 0.15);
  font-size: 10pt;
}
.mentions__suggestions__item {
  padding: 5px 15px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.15);
}
.mentions__suggestions__item--focused {
  background-color: #dcd185;
}
.mentions__mention {
  background-color: #dcd185;
}
.mention {
  background-color: #dcd185;
}
.suggestion {
  display: flex;
  justify-content: start;
  gap: 10px;
}
</code></pre>
<h2>Customizing Suggestions with <code>renderSuggestion</code> in react-mentions</h2>
<p>We have another prop called <code>renderSuggestion</code> to have more control over how the suggestion list looks like.</p>
<p>Let's say you want to show an avatar before the username, so this will help.</p>
<pre><code>&lt;Mention
  trigger="@"
  data={[
    { id: '1', display: 'John Doe', avatar: '👨‍💻' },
    { id: '2', display: 'Jane Smith', avatar: '👩‍🎨' }
  ]}
  displayTransform={(_: string, display: string) =&gt; `@${display}`}
  markup="@[__display__](__id__)"
  appendSpaceOnAdd
  renderSuggestion={(suggestion) =&gt; {
    const user = suggestion as User

    return (
      &lt;div className="suggestion"&gt;
        &lt;div&gt;{user.avatar}&lt;/div&gt;
        &lt;div&gt;{user.display}&lt;/div&gt;
      &lt;/div&gt;
    )
  }}
/&gt;
</code></pre>
<p>And voila, we get to see the username with avatar now!</p>
<p><img src="https://gauravadhikari.com/images/articles/react-mentions-implementation-guide-with-typescript-in-2025/react-mentions-custom-suggestion-avatar.webp" alt="React mentions custom suggestion avatar" /></p>
<h2>Previewing mentions and hashtags as links</h2>
<p>Until now we have been viewing the input value as a raw string, but that doesn't make much sense to the user.</p>
<p>For a good user experience, you should show the mentions as a links, just like we see on platforms like Twitter or LinkedIn, and this is what we are going to achieve in this section.</p>
<p>Let's first understand how the raw input value is shown, remember we had a <code>markup</code> property in <code>Mention</code> component, that defines how our mention would look like in the raw input.</p>
<p>In our case, it was <code>@[__display__](__id__)"</code> which is why our raw input includes the mentions as <code>@[John Doe](1)</code>.</p>
<p>Now, to show these as links, we essentially replace the markup part in the string with html anchor tag. We have also correctly mapped the href of link to the id of user.</p>
<pre><code>const formattedInput = useMemo(() =&gt; {
  let formatted = value

  // format mentions
  formatted = formatted.replace(
    /@\[(.+?)\]\((.+?)\)/g,
    (_, display, id) =&gt; `&lt;a href="/user/${id}"&gt;@${display}&lt;/a&gt;`
  )

  return formatted
}, [value])
</code></pre>
<p>Finally, to render it on UI, we will simply add this in div as <code>dangerouslySetInnerHTML</code></p>
<pre><code>&lt;div
  dangerouslySetInnerHTML={{
    __html: formattedInput,
  }}
/&gt;
</code></pre>
<p><img src="https://gauravadhikari.com/images/articles/react-mentions-implementation-guide-with-typescript-in-2025/react-mentions-preview-as-links.webp" alt="React mentions preview as links" /></p>
<p>With this setup, we have successfully added the mentions feature in our React app and displayed it correctly in the preview. In the next sections, we will deep dive into advanced concepts which you must follow to implement the mentions and hashtags in a production React app.</p>
<h2><strong>Fetching mention suggestions from an API</strong></h2>
<p>In the previous sections, we have been using hard-coded users array for showing the suggestions list, but in a real world application, you must be using a web service to get the data.</p>
<p>If you don’t have an API URL for testing, feel free to use <code>[https://hashtags-and-mentions-server.vercel.app](https://hashtags-and-mentions-server.vercel.app/)</code>.</p>
<pre><code>const [users, setUsers] = useState&lt;User[]&gt;([])

useEffect(() =&gt; {
  (async () =&gt; {
    try {
      const res = await axios.get(`${API_URL}/api/users`)
      setUsers(
        res.data.users.map((user: { name: string, _id: string }) =&gt; ({
          id: user._id,
          display: user.name,
        }))
      )
    }
    catch (error) {
      console.error(error)
    }
  })()
}, [])
</code></pre>
<h2>Fetching suggestion dropdown list asynchronously while typing</h2>
<p>One of the best practices when calling a web service is to ask only what you need, that makes it fast, efficient and improves UX.</p>
<p>In this section, we will understand how to fetch the suggestion dropdown data asynchronously as the user types.</p>
<p>In the <code>Mention</code> component, instead of passing the users as array, you can pass a function to fetch the data. This function receives two arguments, <code>query</code> and <code>callback</code>, the <code>query</code> contains the input by user, and the callback is supposed to be called after our processing.</p>
<p>In this hands-on example, let’s change the trigger to <code>#</code> and try to load the hashtags asynchronously.</p>
<pre><code>import axios from 'axios'
import { useCallback, useMemo, useState } from 'react'
import { Mention, MentionsInput } from 'react-mentions'
import './App.css'

const API_URL = 'https://hashtags-and-mentions-server.vercel.app'

function App() {
  const [value, setValue] = useState('')

  const asyncTags = useCallback(
    (
      query: string,
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      callback: any
    ) =&gt; {
      if (!query)
        return

      axios
        .get(`${API_URL}/api/tags/search?name=${query}`)
        .then((res) =&gt; {
          if (res.data?.tags?.length) {
            const suggestion = { id: query, display: query }
            const tagsArray = res.data.tags.map((tag: { name: string }) =&gt; ({
              id: tag.name,
              display: tag.name,
            }))
            return [...tagsArray, suggestion]
          }

          return [{ id: query, display: query }]
        })
        .then(callback)
    },
    []
  )

  const handleChange = (e: {
    target: {
      value: string
    }
  }) =&gt; {
    setValue(e.target.value)
  }

  const formattedInput = useMemo(() =&gt; {
    let formatted = value

    // format hashtags
    formatted = formatted.replace(
      /#\[(.+?)\]\((.+?)\)/g,
      (_, display) =&gt; `&lt;a href="/tag/${display}"&gt;#${display}&lt;/a&gt;`
    )

    return formatted
  }, [value])

  return (
    &lt;div&gt;
      &lt;h1&gt;Mentions and Hashtags in React&lt;/h1&gt;
      &lt;MentionsInput
        className="mentions"
        value={value}
        onChange={handleChange}
        placeholder="What's on your mind?"
      &gt;
        &lt;Mention
          className="mention"
          trigger="#"
          data={asyncTags}
          displayTransform={(_: string, display: string) =&gt; `#${display}`}
          markup="# [__display__](__id__)"
          appendSpaceOnAdd
        /&gt;
      &lt;/MentionsInput&gt;

      &lt;h3&gt;Preview:&lt;/h3&gt;
      &lt;div
        dangerouslySetInnerHTML={{
          __html: formattedInput,
        }}
      /&gt;
    &lt;/div&gt;
  )
}

export default App
</code></pre>
<p><img src="https://gauravadhikari.com/images/articles/react-mentions-implementation-guide-with-typescript-in-2025/react-mentions-async-hashtag-suggestions.webp" alt="React mentions async hashtag suggestions" /></p>
<p>In the screenshot above, you can see that the API calls are being made as the user types and the list keeps filtering based on the input.</p>
<h2>Debounce API call</h2>
<p>In the previous section, we achieved displaying the suggestion list based on the user’s input, but there is a major issue with that implementation which is the number of API calls being made on each keystroke. This overloads the server with unnecessary requests and is a bad pattern for a production application.</p>
<p>We can fix this using a concept called <strong>debouncing</strong>, which basically holds a function for a given time and it only allows the function to execute if that time is passed, but if the user interrupts the timer by pressing a new key, the timer resets, and the function is again on hold. This approach improves the UX, keeps our app lightweight and saves server resources.</p>
<pre><code>const timerRef = useRef&lt;ReturnType&lt;typeof setTimeout&gt; | null&gt;(null);

const asyncTags = useCallback(
  (
    query: string,
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    callback: any
  ) =&gt; {
    if (!query) return;

    if (timerRef.current) {
      clearTimeout(timerRef.current);
    }

    timerRef.current = setTimeout(() =&gt; {
      axios
        .get(`${API_URL}/api/tags/search?name=${query}`)
        .then((res) =&gt; {
          if (res.data?.tags?.length) {
            const suggestion = { id: query, display: query };
            const tagsArray = res.data.tags.map((tag: { name: string }) =&gt; ({
              id: tag.name,
              display: tag.name,
            }));
            return [...tagsArray, suggestion];
          }

          return [{ id: query, display: query }];
        })
        .then(callback);
    }, 500);
  },
  []
);
</code></pre>
<p><img src="https://gauravadhikari.com/images/articles/react-mentions-implementation-guide-with-typescript-in-2025/react-mentions-debounce-api-call.webp" alt="React mentions debounce api call" /></p>
<p>In the screenshot above, you will notice that API calls are no longer spammed and the API request is only sent when the user stopped typing for 500 ms.</p>
<h2>Saving new hashtags to database</h2>
<p>In our app, the users to mention are coming from database and they are fixed, means the user can not be created while typing but hashtags can be used from the database or the user can add new hashtags. These new hashtags must be added to the database so that they appear in the suggestions list if used again.</p>
<p>To handle this, you can use <code>onAdd</code> prop from <code>Mention</code> component. This callback function receives the hashtag which was added, you can store this in local state and when the user clicks submit button, just save these hashtags to database.</p>
<p>Tip: Use Set to keep the unique hashtag values in array.</p>
<pre><code>import axios from "axios";
import { useCallback, useEffect, useRef, useState } from "react";
import { Mention, MentionsInput } from "react-mentions";
import "./App.css";

function App() {
	// ... existing code
  const [hashtags, setHashtags] = useState&lt;string[]&gt;([]);

  const onAddHashtag = (hashtag: string | number) =&gt; {
    setHashtags((prev) =&gt; [...prev, String(hashtag)]);
  };

  const onSave = () =&gt; {
    // save added hashtags to db
    axios.post("/hashtags", { hashtags });

    // save post to db
    axios.post("/post", { value: formatInput() });
  };

  return (
    &lt;div&gt;
      &lt;h1&gt;Mentions and Hashtags in React&lt;/h1&gt;
      &lt;MentionsInput className="mentions" value={value} onChange={handleChange} placeholder="What's on your mind?"&gt;
        &lt;Mention
          trigger="#"
          data={asyncTags}
          displayTransform={(_: string, display: string) =&gt; `#${display}`}
          markup="# [__display__](__id__)"
          appendSpaceOnAdd
          onAdd={onAddHashtag}
          style={{ backgroundColor: "#dcd185" }}
        /&gt;
      &lt;/MentionsInput&gt;

			&lt;h3&gt;Preview:&lt;/h3&gt;
      &lt;div
        dangerouslySetInnerHTML={{
          __html: formattedInput,
        }}
      /&gt;

      &lt;button onClick={onSave}&gt;Submit&lt;/button&gt;
    &lt;/div&gt;
  );
}

export default App;
</code></pre>
<h2>Safely render HTML using dompurify and html-react-parser</h2>
<p>When displaying user-generated HTML in your React app, it's important to protect against Cross-Site Scripting (XSS) attacks and ensure that links are correctly rendered as Link component from react-router-dom.</p>
<p>There are two well maintained libraries which we will use and the code snippet on how to do it.</p>
<ol>
<li><strong>dompurify</strong>: Cleans user entered HTML preventing XSS attacks.</li>
<li><strong>html-react-parser</strong>: Converts sanitized HTML into React elements (like converting <strong><code>&lt;a&gt;</code></strong> tag to <strong><code>&lt;Link&gt;</code></strong>).</li>
</ol>
<pre><code>npm install dompurify html-react-parser
</code></pre>
<pre><code>import axios from "axios";
import DOMPurify from "dompurify";
import parse, { domToReact, Element, type DOMNode } from "html-react-parser";
import { useCallback, useMemo, useRef, useState } from "react";
import { Mention, MentionsInput } from "react-mentions";
import { Link } from "react-router-dom";
import "./App.css";

const API_URL = "https://hashtags-and-mentions-server.vercel.app";

function App() {
  const timerRef = useRef&lt;ReturnType&lt;typeof setTimeout&gt; | null&gt;(null);
  const [value, setValue] = useState("");

  const asyncTags = useCallback(
    (
      query: string,
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      callback: any
    ) =&gt; {
      if (!query) return;

      if (timerRef.current) {
        clearTimeout(timerRef.current);
      }

      timerRef.current = setTimeout(() =&gt; {
        axios
          .get(`${API_URL}/api/tags/search?name=${query}`)
          .then((res) =&gt; {
            if (res.data?.tags?.length) {
              const suggestion = { id: query, display: query };
              const tagsArray = res.data.tags.map((tag: { name: string }) =&gt; ({
                id: tag.name,
                display: tag.name,
              }));
              return [...tagsArray, suggestion];
            }

            return [{ id: query, display: query }];
          })
          .then(callback);
      }, 500);
    },
    []
  );

  const handleChange = (e: {
    target: {
      value: string;
    };
  }) =&gt; {
    setValue(e.target.value);
  };

  const formattedInput = useMemo(() =&gt; {
    let formatted = value;

    // format hashtags
    formatted = formatted.replace(
      /#\[(.+?)\]\((.+?)\)/g,
      (_, display) =&gt; `&lt;a href="/tag/${display}"&gt;#${display}&lt;/a&gt;`
    );

    return formatted;
  }, [value]);

  const sanitizedValue = useMemo(() =&gt; {
    return DOMPurify.sanitize(formattedInput);
  }, [formattedInput]);

  const parsedContent = parse(sanitizedValue, {
    replace: (domNode) =&gt; {
      if (domNode.type === "tag" &amp;&amp; domNode.name === "a") {
        const el = domNode as Element;
        const href = el.attribs.href;
        const children = domToReact(el.children as DOMNode[]);

        return &lt;Link to={href}&gt;{children}&lt;/Link&gt;;
      }
    },
  });

  return (
    &lt;&gt;
      &lt;h1&gt;Mentions and Hashtags in React&lt;/h1&gt;
      &lt;MentionsInput
        className="mentions"
        value={value}
        onChange={handleChange}
        placeholder="What's on your mind?"
      &gt;
        &lt;Mention
          className="mention"
          trigger="#"
          data={asyncTags}
          displayTransform={(_: string, display: string) =&gt; `#${display}`}
          markup="# [__display__](__id__)"
          appendSpaceOnAdd
        /&gt;
      &lt;/MentionsInput&gt;

      &lt;h3&gt;Preview:&lt;/h3&gt;
      {parsedContent}
    &lt;/&gt;
  );
}

export default App;
</code></pre>
<p>The final version of the code snippet can be found on GitHub here https://gist.github.com/gauravadhikari1997/3aeb6a38b990fa1169c80b64609e5241</p>
<p>Once you’ve mastered @mentions and #tags in React, take your skills further by building one of these <a href="/react-project-ideas-2026/">React Project Ideas for 2026</a>.</p>
<p>I hope this guide helps you understand the react-mentions library and how add mentions or hashtags to your own React apps with proper types.</p>
<h2>Frequently Asked Questions</h2>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is the react-mentions library used for?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;react-mentions is a lightweight React component for adding @mentions and #hashtags functionality inside textarea or input. It provides a suggestions dropdown and handles insertion, formatting, and styling of mentions.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How do I install react-mentions in my React project?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Run &lt;code&gt;npm install react-mentions&lt;/code&gt; or &lt;code&gt;yarn add react-mentions&lt;/code&gt;. Then import &lt;code&gt;{ MentionsInput, Mention }&lt;/code&gt; from &lt;code&gt;react-mentions&lt;/code&gt; and use them inside your React component.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How do I add @mentions support with react-mentions?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Wrap your textarea with &lt;code&gt;&lt;MentionsInput&gt;&lt;/code&gt; and include a &lt;code&gt;&lt;Mention trigger='@' data={users} /&gt;&lt;/code&gt;. The &lt;code&gt;data&lt;/code&gt; prop can be a static array of &lt;code&gt;{ id, display }&lt;/code&gt; objects or a function that fetches suggestions dynamically.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I also implement #hashtags using react-mentions?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes. Add another &lt;code&gt;&lt;Mention trigger='#' data={tags} /&gt;&lt;/code&gt; to handle hashtags separately. You can configure its styling, formatting, and API source independently from @mentions.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How do I customize how suggestions look in react-mentions?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Use the &lt;code&gt;renderSuggestion&lt;/code&gt; prop on the &lt;code&gt;&lt;Mention&gt;&lt;/code&gt; component to render custom JSX, such as showing an avatar or role alongside the username.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is the purpose of the markup property in react-mentions?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The &lt;code&gt;markup&lt;/code&gt; prop defines how mentions are stored in the raw value (e.g., &lt;code&gt;@<a href="__id__"><strong>display</strong></a>&lt;/code&gt;). This makes it easier to extract IDs and safely reconstruct mentions later for previews or saving to the database.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How do I fetch suggestions from an API in react-mentions?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Instead of passing a static array to &lt;code&gt;data&lt;/code&gt;, provide a function &lt;code&gt;(query, callback)&lt;/code&gt; that makes an API call and returns results to the &lt;code&gt;callback&lt;/code&gt;. This enables search-as-you-type suggestions.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How can I prevent too many API calls in react-mentions?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Use debouncing with &lt;code&gt;setTimeout&lt;/code&gt; and &lt;code&gt;clearTimeout&lt;/code&gt; in your data fetch function. This ensures the API is only called after the user pauses typing, reducing server load.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How do I style the mentions and suggestions dropdown?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;react-mentions provides BEM-style class names like &lt;code&gt;.mentions__suggestions__list&lt;/code&gt; and &lt;code&gt;.mentions__suggestions__item&lt;/code&gt;. You can override these in your CSS or pass &lt;code&gt;className&lt;/code&gt; props for custom styling.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Is it safe to render raw mention markup directly?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;No. Always sanitize before rendering with libraries like DOMPurify to prevent XSS attacks. You can then parse sanitized HTML with &lt;code&gt;html-react-parser&lt;/code&gt; and convert &lt;code&gt;&lt;a&gt;&lt;/code&gt; tags into React Router &lt;code&gt;&lt;Link&gt;&lt;/code&gt; components.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I prefill react-mentions with existing mentions?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes. Store the raw value with &lt;code&gt;markup&lt;/code&gt; format in your database. When reloaded into &lt;code&gt;&lt;MentionsInput&gt;&lt;/code&gt;, react-mentions will render mentions correctly in the input.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How do I capture new hashtags typed by users?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Use the &lt;code&gt;onAdd&lt;/code&gt; prop of &lt;code&gt;&lt;Mention trigger='#'&gt;&lt;/code&gt;. This callback provides the added tag, which you can store in local state and later persist to your database.&lt;/p&gt;
&lt;/details&gt;</p>
]]></content>
        <author>
            <name>Gaurav Adhikari</name>
            <uri>https://gauravadhikari.com</uri>
        </author>
        <published>2025-07-21T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Docker Deep Dive: Beginner To Advanced]]></title>
        <id>https://gauravadhikari.com/docker-beginner-to-advanced/</id>
        <link href="https://gauravadhikari.com/docker-beginner-to-advanced/"/>
        <updated>2025-06-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Build, ship, and run apps using docker - with code, implementation & cheatsheet]]></summary>
        <content type="html"><![CDATA[<p><img src="https://gauravadhikari.com/images/articles/docker-beginner-to-advanced/docker-beginner-to-advanced.webp" alt="Docker Deep Dive: Beginner To Advanced" /></p>
<p>If you've ever said:</p>
<ul>
<li>"Why does this app work on your machine and not mine?"</li>
<li>"How do I test this microservice without setting up an environment?"</li>
<li>"Why does my local build pass but CI fails?"</li>
</ul>
<p>Then my friend, it's time to welcome Docker into your life. Think of it as your app's personal travel agent - it packages everything your app needs and ensures it works the same way everywhere.</p>
<p>Let's go through practical examples, gotchas, and setups you can try right now on your machine.</p>
<p>Performance optimization goes hand-in-hand with containerization. You can also explore these <a href="/reduce-page-load-time-5-techniques/">5 techniques to reduce page load time.</a>.</p>
<h2>What is Docker, really?</h2>
<p>Docker is a platform to build, ship, and run apps in an isolated, consistent environment — across machines, clouds, and even timezones.</p>
<p>It's like a neatly packed tiffin box. Everything your app needs — libraries, settings, OS flavor — bundled and ready to go.</p>
<h2>Containers</h2>
<p>A container is an isolated environment that runs an application.</p>
<p>Why they're awesome:</p>
<ul>
<li>lightweight</li>
<li>uses OS(kernel) of host</li>
<li>start quickly</li>
<li>need less hardware resources</li>
<li>can be stopped &amp; restarted</li>
<li>just a process</li>
</ul>
<h2>Docker Image</h2>
<p>A Docker image is like a read-only snapshot of your app.</p>
<p>It includes:</p>
<ul>
<li>application files</li>
<li>third party libraries</li>
<li>environment variables</li>
<li>cut down OS</li>
</ul>
<pre><code>Application Code + Dependencies + Config + Base OS = Image
</code></pre>
<blockquote>
<p>You build containers from images.</p>
</blockquote>
<blockquote>
<p>Note: To do hands-on, make sure you have installed <a href="https://www.docker.com/products/docker-desktop/">Docker Desktop</a>.</p>
</blockquote>
<h2>Dockerfile</h2>
<p>This is your image's blueprint. Let's say you want to run a basic NodeJS app:</p>
<h3>Example 1: Dockerizing a Node App</h3>
<pre><code>// app.js

console.log('Hello from docker container!')
</code></pre>
<pre><code># Dockerfile

# Use the latest version of NodeJS
FROM node:24-slim

# Set the working directory
WORKDIR /app

# Copy files
COPY . .

# Start the app
CMD ["node", "app.js"]
</code></pre>
<p>Then to build the docker image and run the docker container, execute the following commands in your terminal:</p>
<pre><code># Syntax: docker build -t &lt;image-name&gt; &lt;build-context&gt;
docker build -t hello-node .
docker run hello-node
</code></pre>
<p>See "Hello from docker container!" in your terminal. It's working. Yay!</p>
<h3>Tips</h3>
<ul>
<li>Use <code>COPY ["file", "destination"]</code> for JSON-safe copy.</li>
<li>Ignore unnecessary files using <code>.dockerignore</code>:</li>
</ul>
<pre><code># .dockerignore

node_modules
.git
Dockerfile*
*.log
</code></pre>
<h3>Example 2: Dockerizing a React App</h3>
<p>Let's turn a React app into a container:</p>
<pre><code># Dockerfile

# Use the latest version of NodeJS
FROM node:24-slim

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the files
COPY . .

# Expose the port
EXPOSE 3000

# Run the app
CMD ["npm", "start"]
</code></pre>
<p>Let's again build the docker image and run the docker container:</p>
<pre><code>docker build -t react-app .
docker run react-app
</code></pre>
<blockquote>
<p>Note: 'slim' is smaller than full Node images.</p>
</blockquote>
<h3>RUN vs CMD</h3>
<p>&lt;details&gt;
&lt;summary&gt;Click to read more&lt;/summary&gt;</p>
<table>
<thead>
<tr>
<th>Command</th>
<th>Purpose</th>
<th>Runs during</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>RUN</td>
<td>Executes at build time to build the image (e.g., install packages).</td>
<td>Docker image build</td>
<td><code>RUN npm install</code></td>
</tr>
<tr>
<td>CMD</td>
<td>Specifies the default command when a container starts.</td>
<td>When container is run</td>
<td><code>CMD ["node", "app.js"]</code></td>
</tr>
</tbody>
</table>
<blockquote>
<p>Note: Only one CMD is allowed per Dockerfile; last one overrides previous.
&lt;/details&gt;</p>
</blockquote>
<h3>Setting environment variables</h3>
<p>This is how we can add environment variables in our Dockerfile.</p>
<pre><code>ENV PUBLIC_URL=https://gauravadhikari.com
</code></pre>
<h2>Port Mapping</h2>
<p>By now you can build your docker image and run the docker container, but you can not access the react app in your system. That's because the react app is running on an isolated environment and its ports aren't exposed to your system.</p>
<p>This is where port publishing comes in.</p>
<p>You can map ports using the -p flag:</p>
<pre><code># Syntax: -p &lt;host_port&gt;:&lt;container_port&gt;
docker run -d -p 3000:3000 react-app
</code></pre>
<p>Now, try to open <a href="http://localhost:3000"><code>localhost:3000</code></a>  tada.., you can access your react app!</p>
<h2>Tagging Images</h2>
<p>You can tag images to organize them with names and versions:</p>
<pre><code># Tag image during build
# Syntax: -t &lt;image-name&gt;:&lt;tag&gt; &lt;build-context&gt;

docker build -t my-app:1.0 .

# Tag an existing image with another tag
docker tag my-app:1 my-app:latest
</code></pre>
<h2>Manage, Inspect, Debug &amp; Explore</h2>
<p>Here are some essential commands to help you manage your Docker environment:</p>
<h3>List Docker Images</h3>
<pre><code>docker images
</code></pre>
<h3>Check Running Containers</h3>
<pre><code>docker ps
</code></pre>
<h3>List All Containers (Including Stopped)</h3>
<pre><code>docker ps -a
</code></pre>
<h3>Run Container in Background</h3>
<pre><code>docker run -d react-app
</code></pre>
<h3>Access Container Shell</h3>
<pre><code>docker exec -it &lt;container_id&gt; bash
</code></pre>
<h3>View Container Logs</h3>
<pre><code>docker logs &lt;container_id&gt;
</code></pre>
<h3>Watch Logs in Real-time</h3>
<pre><code>docker logs -f &lt;container_id&gt;
</code></pre>
<h3>Stop a Container</h3>
<pre><code>docker stop &lt;container_id&gt;
</code></pre>
<h3>Start a Container</h3>
<pre><code>docker start &lt;container_id&gt;
</code></pre>
<h3>Restart a Container</h3>
<pre><code>docker restart &lt;container_id&gt;
</code></pre>
<h3>Remove a Container</h3>
<pre><code>docker rm &lt;container_id&gt;
</code></pre>
<h3>Clean Up Unused Images</h3>
<pre><code>docker image prune
docker image rm hello-node
</code></pre>
<h3>Clean Up Stopped Containers</h3>
<pre><code>docker container prune
</code></pre>
<p>I hope you enjoyed running the above commands in your terminal, now let's learn another important topic in Docker, that is Volumes.</p>
<h2>Docker Volumes</h2>
<p>When a container shuts down or gets deleted, everything inside it usually disappears - so in order to persist important data like databases, log files etc we need Docker Volumes.</p>
<p>To create a docker volume:</p>
<pre><code>docker volume create app-data
</code></pre>
<p>To create / use a volume while running container:</p>
<pre><code>docker run -v app-data:/app/data react-app
</code></pre>
<p>To view / inspect volume:</p>
<pre><code>docker volume inspect app-data
</code></pre>
<p>This ensures your data survives even if the container is removed. For example - databases, logs, uploads.</p>
<h2>Copying Files Between Host and Containers</h2>
<p>While we are here, let's quickly learn how to copy files to and from a docker container.</p>
<table>
<thead>
<tr>
<th>Direction</th>
<th>Command</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>Container → Host</td>
<td><code>docker cp SOURCE DESTINATION</code></td>
<td><code>docker cp my_container:/app/logs.txt .</code></td>
</tr>
<tr>
<td>Host → Container</td>
<td><code>docker cp SOURCE DESTINATION</code></td>
<td><code>docker cp secret.txt my_container:/app</code></td>
</tr>
</tbody>
</table>
<h2>Docker Hub</h2>
<p>Docker Hub is like the App Store or Play Store, but for Docker containers. You can download ready-made images from Docker Hub — like Node, Nginx, MongoDB etc, you can upload your own images to the Docker Hub so that others can use them.</p>
<h3>Publish to Docker Hub</h3>
<pre><code>docker login
docker tag react-app username/react-app:1
docker push username/react-app:1
</code></pre>
<h3>Share Locally</h3>
<pre><code># Create tar of the image
docker image save -o react.tar react-app

# Use it like this now
docker image load -i react.tar
</code></pre>
<h2>Multi-stage Builds</h2>
<p>Multi-stage builds in Docker let you use multiple FROM statements in a single Dockerfile to build your app in stages.</p>
<p>Why ?</p>
<ul>
<li>
<p>Smaller Final Image — The final image uses <code>nginx:alpine</code>, not node, which means you're not shipping node_modules, source code, or the Node.js runtime — just the static files.</p>
</li>
<li>
<p>Better Security — Fewer packages = fewer vulnerabilities. You're only exposing what's absolutely needed to serve the app.</p>
</li>
<li>
<p>Faster Deployments — Smaller images are faster to pull, push, and deploy.</p>
</li>
<li>
<p>Cleaner Separation — One stage handles building (node), another handles serving (nginx), keeping concerns neatly separated.</p>
</li>
</ul>
<pre><code># Stage 1: Build
FROM node:24-slim AS build
WORKDIR /app
COPY . .
RUN npm install &amp;&amp; npm run build

# Stage 2: Serve
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
</code></pre>
<h2>TL;DR Cheat Sheet</h2>
<table>
<thead>
<tr>
<th>Action</th>
<th>Command</th>
</tr>
</thead>
<tbody>
<tr>
<td>Build image</td>
<td><code>docker build -t &lt;name&gt; .</code></td>
</tr>
<tr>
<td>Run container</td>
<td><code>docker run &lt;name&gt;</code></td>
</tr>
<tr>
<td>Run with port mapping</td>
<td><code>docker run -p 3000:3000 &lt;name&gt;</code></td>
</tr>
<tr>
<td>Run and auto-remove</td>
<td><code>docker run --rm -it &lt;name&gt;</code></td>
</tr>
<tr>
<td>Enter running container</td>
<td><code>docker exec -it &lt;container_id&gt; sh</code></td>
</tr>
<tr>
<td>See logs</td>
<td><code>docker logs -f &lt;container_id&gt;</code></td>
</tr>
<tr>
<td>List containers</td>
<td><code>docker ps -a</code></td>
</tr>
<tr>
<td>List images</td>
<td><code>docker images</code></td>
</tr>
<tr>
<td>Stop/start container</td>
<td><code>docker stop &lt;id&gt;</code> / <code>docker start &lt;id&gt;</code></td>
</tr>
<tr>
<td>Remove container/image</td>
<td><code>docker rm &lt;id&gt;</code> / <code>docker rmi &lt;image&gt;</code></td>
</tr>
<tr>
<td>Remove stopped containers</td>
<td><code>docker container prune</code></td>
</tr>
<tr>
<td>Pull image</td>
<td><code>docker pull &lt;image&gt;</code></td>
</tr>
<tr>
<td>Persist data (volume)</td>
<td><code>docker run -v &lt;vol_name&gt;:/app/data &lt;img&gt;</code></td>
</tr>
<tr>
<td>Save/load image file</td>
<td><code>docker image save -o file.tar &lt;img&gt;</code> / <code>docker image load -i file.tar</code></td>
</tr>
<tr>
<td>Push to Docker Hub</td>
<td><code>docker push &lt;username&gt;/&lt;image&gt;</code></td>
</tr>
</tbody>
</table>
<h2>Frequently Asked Questions</h2>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is Docker and why is it essential for modern application development?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Docker is a platform for building, shipping, and running applications in an isolated, consistent environment. It packages your app with all its dependencies (libraries, settings, OS flavor) into a 'container,' ensuring it works identically across different machines, clouds, and environments. This eliminates common issues like 'it works on my machine' and simplifies testing and deployment.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is the key difference between a Docker Image and a Docker Container?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;A Docker Image is a read-only blueprint or snapshot of your application, including its code, dependencies, configuration, and a cut-down OS. It's what you build. A Docker Container, on the other hand, is a runnable instance of an image. It's an isolated, lightweight process that runs your application, utilizing the host OS kernel and starting quickly.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How do I create a Docker image for my application using a Dockerfile?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;A Dockerfile is a text file containing instructions for building a Docker image. You define the base image (e.g., &lt;code&gt;FROM node:24-slim&lt;/code&gt;), set the working directory, copy your application files, install dependencies (using &lt;code&gt;RUN&lt;/code&gt; commands), and specify the command to run your application (using &lt;code&gt;CMD&lt;/code&gt;). You then build the image with &lt;code&gt;docker build -t &lt;image-name&gt; .&lt;/code&gt;&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How can I run my Dockerized application and access it from my browser?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;After building your image (e.g., &lt;code&gt;my-app&lt;/code&gt;), you can run it using &lt;code&gt;docker run my-app&lt;/code&gt;. To access web applications (like a React app), you need to map ports between the container and your host machine using the &lt;code&gt;-p&lt;/code&gt; flag. For example, &lt;code&gt;docker run -p 3000:3000 my-app&lt;/code&gt; maps the container's port 3000 to your host's port 3000, allowing you to access it via &lt;code&gt;localhost:3000&lt;/code&gt;.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What are the essential Docker commands for managing images and containers?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Key commands include: &lt;code&gt;docker build&lt;/code&gt; (to create images), &lt;code&gt;docker run&lt;/code&gt; (to start containers), &lt;code&gt;docker ps&lt;/code&gt; (to list running containers), &lt;code&gt;docker ps -a&lt;/code&gt; (to list all containers), &lt;code&gt;docker images&lt;/code&gt; (to list images), &lt;code&gt;docker stop &lt;id&gt;&lt;/code&gt; (to stop a container), &lt;code&gt;docker rm &lt;id&gt;&lt;/code&gt; (to remove a container), &lt;code&gt;docker rmi &lt;image&gt;&lt;/code&gt; (to remove an image), &lt;code&gt;docker logs &lt;id&gt;&lt;/code&gt; (to view container logs), and &lt;code&gt;docker exec -it &lt;id&gt; bash&lt;/code&gt; (to access a container's shell).&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How do Docker Volumes help in persisting data for containers?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Docker Volumes are used to store important data (like databases or log files) outside of the container's writable layer. This ensures that your data survives even if the container is stopped, removed, or replaced. You can create a volume with &lt;code&gt;docker volume create &lt;name&gt;&lt;/code&gt; and then mount it to a container using the &lt;code&gt;-v&lt;/code&gt; flag: &lt;code&gt;docker run -v &lt;volume_name&gt;:&lt;container_path&gt; &lt;image&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What are multi-stage builds in Docker and what are their benefits?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Multi-stage builds allow you to use multiple &lt;code&gt;FROM&lt;/code&gt; statements in a single Dockerfile, where each &lt;code&gt;FROM&lt;/code&gt; statement starts a new build stage. This is beneficial because you can use an intermediate stage to build your application (e.g., compile code, install dependencies) and then copy only the necessary artifacts to a much smaller final image. This results in smaller final image sizes, improved security (fewer packages), and faster deployments.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How can I share my Docker images with other developers or deploy them?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;You can share images by pushing them to Docker Hub (a public registry) after logging in and tagging your image: &lt;code&gt;docker login&lt;/code&gt;, &lt;code&gt;docker tag &lt;local_image&gt; &lt;username&gt;/&lt;repo_name&gt;:&lt;tag&gt;&lt;/code&gt;, &lt;code&gt;docker push &lt;username&gt;/&lt;repo_name&gt;:&lt;tag&gt;&lt;/code&gt;. Alternatively, you can save an image as a &lt;code&gt;.tar&lt;/code&gt; file locally with &lt;code&gt;docker image save -o image.tar &lt;image_name&gt;&lt;/code&gt; and share that file, which can then be loaded by others using &lt;code&gt;docker image load -i image.tar&lt;/code&gt;.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is the functional difference between RUN and CMD commands in a Dockerfile?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;&lt;code&gt;RUN&lt;/code&gt; commands execute at build time and are used to build the image itself (e.g., installing packages, compiling code). Each &lt;code&gt;RUN&lt;/code&gt; command creates a new layer in the image. &lt;code&gt;CMD&lt;/code&gt; specifies the default command that will be executed when a container is started from the image. Only one &lt;code&gt;CMD&lt;/code&gt; instruction is allowed per Dockerfile; if multiple are present, only the last one takes effect.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Where can I find a quick reference for common Docker commands?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The article includes a 'TL;DR Cheat Sheet' section that provides a concise list of essential Docker commands for actions like building and running images, managing containers, persisting data, and sharing images. This serves as a handy reference for quick lookups.&lt;/p&gt;
&lt;/details&gt;</p>
<h2>Final Words</h2>
<p>Docker might seem like a lot at first, but once you get it, it feels like magic. No more "it works on my machine" drama.</p>
<p>So go ahead — experiment, break things, fix them, and deploy like it's no big deal. Your future self will thank you for learning Docker today!</p>
]]></content>
        <author>
            <name>Gaurav Adhikari</name>
            <uri>https://gauravadhikari.com</uri>
        </author>
        <published>2025-06-03T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[How to customize Strapi Dashboard / Home Page]]></title>
        <id>https://gauravadhikari.com/how-to-customize-strapi-dashboard-home-page/</id>
        <link href="https://gauravadhikari.com/how-to-customize-strapi-dashboard-home-page/"/>
        <updated>2024-12-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Quick guide on how to customize Strapi's Admin Panel homepage the right way, and easy as well]]></summary>
        <content type="html"><![CDATA[<p><img src="https://gauravadhikari.com/images/articles/how-to-customize-strapi-dashboard-home-page/how-to-customize-strapi-dashboard-home-page.webp" alt="How to customize Strapi Dashboard / Home Page" /></p>
<h2>Customize Strapi Dashboard / Home Page</h2>
<p>Strapi is a powerful headless CMS that provides a robust admin panel. But sometimes, you want to make it your own for branding, but the Strapi official docs miss the how-tos of customizing the admin homepage. This quick guide shows you how to customize Strapi's Admin Panel the right way, and easy as well.</p>
<p>Rename src/admin/app.example.tsx to app.tsx
Change the contents to</p>
<pre><code>// src/admin/app.tsx

import type { StrapiApp } from '@strapi/strapi/admin'

export default {
  config: {
    locales: [],
  },
  bootstrap() {},
}
</code></pre>
<p>Just create a Homepage.tsx file with your custom Homepage</p>
<pre><code>// src/admin/Homepage.tsx

function Homepage() {
  return (
    &lt;div
      style={{
        textAlign: 'center',
        backgroundColor: '#f1f1f1',
        padding: '20px',
        borderRadius: '5px',
        fontFamily: 'Arial, sans-serif',
        fontSize: '24px',
        color: '#333',
        fontWeight: 'bold',
      }}
    &gt;
      Welcome to the CMS!
    &lt;/div&gt;
  )
}

export { Homepage }
</code></pre>
<p>This is how the final version of app.tsx looks like and you are done. 😉</p>
<pre><code>// src/admin/app.tsx

import type { StrapiApp } from '@strapi/strapi/admin'

export default {
  config: {
    tutorials: false,
    locales: [],
  },
  bootstrap() {},
  register(app: StrapiApp) {
    const indexRoute = app.router.routes.find(({ index }) =&gt; index)
    if (!indexRoute)
      throw new Error('unable to find index page')
    indexRoute.lazy = async () =&gt; {
      const { Homepage } = await import('./Homepage')
      return { Component: Homepage }
    }
  },
}
</code></pre>
<p>Kind credits to Andrew Bone for his solution in https://feedback.strapi.io/feature-requests/p/customize-the-admin-panel-welcome-page-strapi-5</p>
<p>Looking for your next project? Explore these <a href="/react-project-ideas-2026/">60 React Project Ideas for 2026</a>.</p>
<h2>Frequently Asked Questions</h2>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is the primary purpose of customizing the Strapi Dashboard homepage?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The main purpose is to personalize the Strapi Admin Panel for branding, to provide a custom welcome message, or to tailor the initial experience for users logging into the CMS. It replaces the default Strapi welcome screen.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What specific files need to be modified or created to implement this customization?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;You need to rename &lt;code&gt;src/admin/app.example.tsx&lt;/code&gt; to &lt;code&gt;app.tsx&lt;/code&gt; and then create a new file named &lt;code&gt;Homepage.tsx&lt;/code&gt; within the same &lt;code&gt;src/admin&lt;/code&gt; directory.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What kind of content can I include on my custom Strapi homepage?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Since the custom homepage is defined as a React component (&lt;code&gt;Homepage.tsx&lt;/code&gt;), you can include any valid JSX. This allows for custom text, images, links, or more complex interactive elements to be displayed.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Does this customization method require deep knowledge of Strapi's internal architecture?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;No, the guide provides exact code snippets and clear, step-by-step instructions. While a basic understanding of React and TypeScript is helpful for further customization, the provided solution is straightforward to implement.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What version of Strapi does this customization apply to?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Strapi v5.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I revert the changes and go back to the default Strapi homepage?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, you can easily revert the changes by undoing the modifications made to &lt;code&gt;app.tsx&lt;/code&gt; and deleting the &lt;code&gt;Homepage.tsx&lt;/code&gt; file. If you kept a backup of the original &lt;code&gt;app.example.tsx&lt;/code&gt; before renaming, that would also help in restoring the default.&lt;/p&gt;
&lt;/details&gt;</p>
<p>Thanks for reading! I hope you learned something useful.</p>
<p><a href="https://www.buymeacoffee.com/gauravadhikar">~ Buy Me A Coffee ☕</a></p>
]]></content>
        <author>
            <name>Gaurav Adhikari</name>
            <uri>https://gauravadhikari.com</uri>
        </author>
        <published>2024-12-07T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[How to Add Mentions and Hashtags in React using react-mentions [Full Tutorial]]]></title>
        <id>https://gauravadhikari.com/mentions-and-hashtags-in-reactjs/</id>
        <link href="https://gauravadhikari.com/mentions-and-hashtags-in-reactjs/"/>
        <updated>2025-07-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Want to build social-style inputs in ReactJS? Learn how to use the react-mentions package to easily add @mentions and #hashtags with full working code examples and UI integration.]]></summary>
        <content type="html"><![CDATA[<p><img src="https://gauravadhikari.com/images/articles/mentions-and-hashtags-in-reactjs/mentions-and-hashtags-in-reactjs.webp" alt="Creating Mentions And Hashtags In ReactJS" /></p>
<h2># And @ In React Apps</h2>
<p>There are many use cases in real-world applications where you need to implement triggers — like showing a list of users when typing the @ symbol or adding a hashtag with #. If you're wondering how to add mentions in React using react-mentions, this blog will walk you through the process step-by-step.</p>
<p>Want to give it a try ? Here is deployed version <a href="https://hashtags-n-mentions.netlify.app/">https://hashtags-n-mentions.netlify.app</a>.</p>
<p>Update (2025): If you're using TypeScript or looking for the latest best practices, check out my new post — <a href="https://gauravadhikari.com/react-mentions-implementation-guide-with-typescript-in-2025/">React Mentions Implementation Guide with TypeScript in 2025</a>. It covers the modern setup and improvements since this tutorial was first published.</p>
<hr />
<h2>Prerequisites</h2>
<ul>
<li>
<p><a href="https://nodejs.org/en/download/">Node.js</a> ≥v18 is installed on your machine</p>
</li>
<li>
<p><a href="https://www.npmjs.com/">npm</a>/<a href="https://yarnpkg.com/">yarn</a> is installed on your machine</p>
</li>
<li>
<p>You have a basic understanding of <a href="https://reactjs.org/">React.js</a></p>
</li>
</ul>
<h2>What We Will Be Using</h2>
<ul>
<li>
<p>Vite (instead of Create React App)</p>
</li>
<li>
<p>ReactJS</p>
</li>
<li>
<p>Functional components with hooks</p>
</li>
<li>
<p>Tailwind CSS for styling</p>
</li>
<li>
<p>NPM package called <a href="https://www.npmjs.com/package/react-mentions">react-mentions</a></p>
</li>
<li>
<p>Backend API to fetch posts, users, tags, and create posts. (No worries, I have already created the API)</p>
</li>
</ul>
<p>Now let's get our hands dirty!</p>
<h2>Setup React Project</h2>
<p>Create react app using vite:</p>
<pre><code>npm create vite@latest hashtags-and-mentions-in-react -- --template react
</code></pre>
<p>Move into the created project:</p>
<pre><code>cd hashtags-and-mentions-in-react
</code></pre>
<p>Install required dependencies:</p>
<pre><code>npm install react-router-dom axios react-mentions html-react-parser
</code></pre>
<p>Install TailwindCSS and configure it in our app:</p>
<p>You can refer to their doc - <a href="https://tailwindcss.com/docs/installation/using-vite">https://tailwindcss.com/docs/installation/using-vite</a></p>
<pre><code>npm install tailwindcss @tailwindcss/vite
</code></pre>
<p>vite.config.js
<img src="https://gauravadhikari.com/images/articles/mentions-and-hashtags-in-reactjs/using-tailwindcss-in-vite.webp" alt="Using TailwindCSS" /></p>
<p>Once it is done, lets start the show ?</p>
<pre><code>npm run dev
</code></pre>
<p>We will create the UI first then implement functionality ;-)</p>
<p>This is the folder structure of our final application</p>
<p><img src="https://gauravadhikari.com/images/articles/mentions-and-hashtags-in-reactjs/folder-structure.webp" alt="react app folder structure" /></p>
<p>App.jsx</p>
<pre><code>import { BrowserRouter, Route, Routes } from 'react-router-dom'

import { Filter, Header, NewPost, Posts } from '/components'

function App() {
  return (
    &lt;BrowserRouter&gt;
      &lt;Header /&gt;
      &lt;Routes&gt;
        &lt;Route
          path="/"
          element={(
            &lt;section className="px-4 pb-4 pt-4 space-y-4 lg:px-4 sm:px-6 xl:px-6 lg:pb-4 sm:pb-6 xl:pb-6"&gt;
              &lt;Filter /&gt;
              &lt;Posts /&gt;
            &lt;/section&gt;
          )}
        /&gt;
        &lt;Route path="/new" element={&lt;NewPost /&gt;} /&gt;
      &lt;/Routes&gt;

    &lt;/BrowserRouter&gt;
  )
}

export default App
</code></pre>
<p>components/index.js</p>
<pre><code>export { default as Card } from './Card'
export { default as Filter } from './Filter'
export { default as Header } from './Header'
export { default as NewPost } from './NewPost'
export { default as Posts } from './Posts'
</code></pre>
<p>Let start creating these components now.</p>
<p>components/Header.jsx</p>
<pre><code>import { Link } from 'react-router-dom'

function Header() {
  return (
    &lt;header className="flex items-center justify-between"&gt;
      &lt;Link to="/"&gt;
        &lt;h2 className="px-4 py-2 text-lg text-black font-medium leading-6"&gt;
          &lt;span className="text-green-400"&gt;#&lt;/span&gt;
          n
          &lt;span className="text-blue-400"&gt;@&lt;/span&gt;
        &lt;/h2&gt;
      &lt;/Link&gt;
      &lt;Link
        to="/new"
        className="group flex items-center rounded-md bg-light-blue-100 px-4 py-2 text-sm text-light-blue-600 font-medium hover:bg-light-blue-200 hover:text-light-blue-800"
      &gt;
        New
      &lt;/Link&gt;
    &lt;/header&gt;
  )
}

export default Header
</code></pre>
<p>components/Filter.jsx</p>
<pre><code>function Filter() {
  return (
    &lt;form className="relative"&gt;
      &lt;svg
        width="20"
        height="20"
        fill="currentColor"
        className="absolute left-3 top-1/2 transform text-gray-400 -translate-y-1/2"
      &gt;
        &lt;path
          fillRule="evenodd"
          clipRule="evenodd"
          d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
        /&gt;
      &lt;/svg&gt;
      &lt;input
        className="w-full border border-gray-200 rounded-md py-2 pl-10 text-sm text-black focus:outline-none focus:ring-1 focus:ring-light-blue-500 placeholder-gray-500"
        type="text"
        aria-label="Filter posts"
        placeholder="Filter posts"
      /&gt;
    &lt;/form&gt;
  )
}

export default Filter
</code></pre>
<p>services/service.js</p>
<pre><code>import axios from 'axios'

const instance = axios.create({
  baseURL:
    import.meta.env.VITE_SERVER_API
      || 'https://hashtags-and-mentions-server.onrender.com/api',
  headers: { 'Content-Type': 'application/json' },
  timeout: 1000 * 8, // Wait for request to complete in 8 seconds
})

export default instance
</code></pre>
<p>Here we have created an instance from axios so that next time we do not have to pass baseURL and headers in every request.</p>
<p>services/index.js</p>
<pre><code>export { default as APIservice } from './service'
</code></pre>
<p>components/Posts.jsx</p>
<pre><code>import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { APIservice } from '../services'

import Card from './Card'

function Posts() {
  const [posts, setPosts] = useState([])

  useEffect(() =&gt; {
    getPosts()
  }, [])

  async function getPosts() {
    try {
      const res = await APIservice.get('/posts')
      setPosts(res.data.posts)
    }
    catch (error) {
      console.error(error)
    }
  }

  return (
    &lt;ul className="grid grid-cols-1 gap-4 lg:grid-cols-3 sm:grid-cols-2 xl:grid-cols-2"&gt;
      {posts &amp;&amp; posts.length &gt; 0
        ? posts
            .sort((a, b) =&gt; b.createdAt - a.createdAt)
            .map(post =&gt; (
              &lt;Card key={post._id} title={post.title} content={post.content} /&gt;
            ))
        : null}
      &lt;li className="flex rounded-lg hover:shadow-lg"&gt;
        &lt;Link
          to="/new"
          className="hover:shadow-xs w-full flex items-center justify-center border-2 border-gray-200 rounded-lg border-dashed py-4 text-sm font-medium hover:border-gray-300"
        &gt;
          New Post
        &lt;/Link&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  )
}

export default Posts
</code></pre>
<p>Here we are getting the posts from the server in useEffect, and we are populating that data to our state posts using setPosts.</p>
<p>Later in the return statement we are checking if there are posts and then sorting posts based on created time.</p>
<p>Finally the posts are rendered in the Card component which takes title and content as props.</p>
<p>components/Card.jsx</p>
<pre><code>import parse from 'html-react-parser'
import { Link } from 'react-router-dom'

function Card({ title, content }) {
  return (
    &lt;li className="flex flex-col gap-2 border border-gray-100 rounded-xl bg-white p-5 shadow-sm transition-shadow hover:shadow-md"&gt;
      &lt;div className="mb-1"&gt;
        &lt;span className="line-clamp-2 text-lg text-gray-900 font-semibold"&gt;
          {title}
        &lt;/span&gt;
      &lt;/div&gt;
      &lt;div className="break-words text-sm text-gray-700 leading-relaxed"&gt;
        {parse(content, {
          replace: (domNode) =&gt; {
            if (domNode.name === 'a') {
              const node = domNode.children[0]
              return (
                &lt;Link
                  to={domNode.attribs.href}
                  className={
                    node.data &amp;&amp; node.data[0] === '#'
                      ? 'text-green-500 font-medium hover:underline'
                      : 'text-blue-500 font-medium hover:underline'
                  }
                &gt;
                  {node.data}
                &lt;/Link&gt;
              )
            }
          },
        })}
      &lt;/div&gt;
    &lt;/li&gt;
  )
}

export default Card
</code></pre>
<p>Important thing to note in this component is the <code>parse</code> which we have imported from <code>html-react-parser</code>. We are parsing our content so that if we get an anchor tag(a href), we replace it with <code>Link (from react-router-dom)</code> else the anchor tag will refresh the whole page on click.</p>
<p>By the way, these anchor tags (now <code>Link</code>) are the hashtags or mentions. Now you can create dynamic routes like <code>/tags/:tag_name</code> or <code>/user/:user_id</code> to show relevant data.</p>
<p>index.css</p>
<pre><code>/* ./src/index.css */
@import "tailwindcss";

.mentions--singleLine .mentions__control {
  display: inline-block;
}
.mentions--singleLine .mentions__higlighter {
  padding: 1px;
  border: 2px inset transparent;
}
.mentions--singleLine .mentions__input {
  padding: 5px;
  border: 2px inset;
}
.mentions--multiLine .mentions__control {
  font-family: monospace;
  font-size: 11pt;
  border: 1px solid silver;
}
.mentions--multiLine .mentions__highlighter {
  padding: 9px;
}
.mentions--multiLine .mentions__input {
  padding: 9px;
  min-height: 63px;
  outline: 0;
  border: 0;
}
.mentions__suggestions__list {
  background-color: white;
  border: 1px solid rgba(0, 0, 0, 0.15);
  font-size: 10pt;
}
.mentions__suggestions__item {
  padding: 5px 15px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.15);
}
.mentions__suggestions__item--focused {
  background-color: #cee4e5;
}
.mentions__mention {
  background-color: #cee4e5;
}
</code></pre>
<p>components/NewPost.jsx</p>
<pre><code>import { useEffect, useRef, useState } from 'react'
import { Mention, MentionsInput } from 'react-mentions'
import { Link, useNavigate } from 'react-router-dom'

import { APIservice } from '../services'

function NewPost() {
  const [title, setTitle] = useState('')
  const [content, setContent] = useState('')
  const [users, setUsers] = useState([])
  const [tagNames, setTagNames] = useState([])
  const myInput = useRef()
  const navigate = useNavigate()

  useEffect(() =&gt; {
    getActors()
  }, [])

  function addContent(input) {
    if (input.length &lt;= 350) {
      setContent(input)
    }
  }

  async function getActors() {
    const res = await APIservice.get(`/users`)
    // Transform the users to what react-mentions expects
    const usersArr = []
    res.data.users.map(item =&gt;
      usersArr.push({
        id: item._id,
        display: item.name,
      })
    )
    setUsers(usersArr)
  }

  async function asyncTags(query, callback) {
    if (!query)
      return

    APIservice.get(`/tag/search?name=${query}`)
      .then((res) =&gt; {
        if (res.data.tags.length) {
          const suggestion = { id: query, display: query }
          const tagsArray = res.data.tags.map(tag =&gt; ({
            id: tag._id,
            display: tag.name,
          }))
          return [...tagsArray, suggestion]
        }
        else {
          return [{ id: query, display: query }]
        }
      })
      .then(callback)
  }

  async function savePost(e) {
    e.preventDefault()

    let newContent = content

    newContent = newContent.split('@@@__').join('&lt;a href="/user/')
    newContent = newContent.split('^^^__').join(`"&gt;@`)
    newContent = newContent.split('@@@^^^').join('&lt;/a&gt;')

    newContent = newContent.split('$$$__').join('&lt;a href="/tag/')
    newContent = newContent.split('~~~__').join(`"&gt;#`)
    newContent = newContent.split('$$$~~~').join('&lt;/a&gt;')
    if (newContent !== '') {
      const body = newContent.trim()
      // Call to your DataBase like backendModule.savePost(body,  along_with_other_params);
      tagNames.map(async (tag) =&gt; {
        try {
          await APIservice.post('/tag', {
            name: tag,
          })
        }
        catch (error) {
          console.log(error)
        }
      })
      console.log(body)
      try {
        await APIservice.post('/post', {
          title,
          content: body,
          createdAt: new Date().getTime(),
        })
        navigate('/')
      }
      catch (error) {
        console.error(error)
      }
    }
  }

  return (
    &lt;div className="flex items-center justify-center py-8"&gt;
      &lt;form
        onSubmit={savePost}
        className="max-w-xl w-full flex flex-col gap-4 border border-gray-100 rounded-xl bg-white p-6 shadow-md"
      &gt;
        &lt;div className="mb-2 text-center"&gt;
          &lt;h2 className="mb-1 text-2xl text-gray-700 font-bold"&gt;New Post&lt;/h2&gt;
          &lt;p className="text-sm text-gray-400"&gt;
            Share your thoughts with hashtags and mentions
          &lt;/p&gt;
        &lt;/div&gt;
        &lt;input
          value={title}
          onChange={e =&gt; setTitle(e.target.value)}
          className="title mb-4 border border-gray-300 p-2 outline-none"
          spellCheck="false"
          placeholder="Title"
          type="text"
          required
        /&gt;
        &lt;&gt;
          &lt;MentionsInput
            singleLine={false}
            className="mentions"
            inputRef={myInput}
            spellCheck="false"
            placeholder="Describe everything about this post here"
            value={content}
            onChange={event =&gt; addContent(event.target.value)}
            required
          &gt;
            &lt;Mention
              trigger="@"
              data={users}
              markup="@@@____id__^^^____display__@@@^^^"
              displayTransform={(_, display) =&gt; `@${display}`}
              style={{ backgroundColor: '#daf4fa' }}
              appendSpaceOnAdd
            /&gt;
            &lt;Mention
              trigger="#"
              data={asyncTags}
              markup="$$$____id__~~~____display__$$$~~~"
              displayTransform={(_, display) =&gt; `#${display}`}
              style={{ backgroundColor: '#daf4fa' }}
              onAdd={display =&gt; setTagNames(tags =&gt; [...tags, display])}
              appendSpaceOnAdd
            /&gt;
          &lt;/MentionsInput&gt;
        &lt;/&gt;
        &lt;div className="flex items-center justify-between text-xs text-gray-500"&gt;
          &lt;div className="flex gap-2"&gt;
            &lt;button
              type="button"
              onClick={() =&gt; {
                myInput.current.focus()
                setContent(content =&gt; `${content}@`)
              }}
              className="border border-gray-300 rounded-full px-3 py-1 text-base font-semibold transition hover:bg-gray-100"
            &gt;
              @
            &lt;/button&gt;
            &lt;button
              type="button"
              onClick={() =&gt; {
                myInput.current.focus()
                setContent(content =&gt; `${content}#`)
              }}
              className="border border-gray-300 rounded-full px-3 py-1 text-base font-semibold transition hover:bg-gray-100"
            &gt;
              #
            &lt;/button&gt;
          &lt;/div&gt;
          &lt;div className="ml-auto text-xs text-gray-400 font-semibold"&gt;
            {350 - content.length}
            /350
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div className="mt-2 flex justify-end gap-2"&gt;
          &lt;Link
            to="/"
            className="border border-gray-300 rounded-md px-4 py-2 text-gray-500 font-semibold transition hover:bg-gray-100"
          &gt;
            Cancel
          &lt;/Link&gt;
          &lt;button
            type="submit"
            className="rounded-md bg-indigo-600 px-4 py-2 text-white font-semibold transition hover:bg-indigo-700"
          &gt;
            Post
          &lt;/button&gt;
        &lt;/div&gt;
      &lt;/form&gt;
    &lt;/div&gt;
  )
}

export default NewPost
</code></pre>
<p>Pretty big component ha?</p>
<p>Actually, this is the component that is the essence of this article, so bear with me some more time ;-)
Here we have states for <code>title</code> and <code>content</code> of post which are self explanatory.</p>
<p><code>users</code> and <code>tagNames</code> are the data which we will get from backend and render on @ and # trigger respectively.</p>
<p>There are two ways in which we can show data to user in React Mention input</p>
<ol>
<li>Load data initially (like we did for <code>users</code> i.e. in useEffect)</li>
<li>Load data asynchronously (<code>asyncTags</code> function which will get executed every time tag input changes)</li>
</ol>
<p>Now have a look at MentionsInput in return statement.</p>
<p><img src="https://gauravadhikari.com/images/articles/mentions-and-hashtags-in-reactjs/mentionsinput.webp" alt="React Mentions Component with react-mentions library" /></p>
<p>The first thing to note is that MentionsInput is a textarea, so we have given <code>value</code> and set <code>onChange</code> handler for content to it.</p>
<p>The second thing is there are two Mention components inside it which are nothing but the triggers for @ and # respectively.</p>
<p>For every Mention, there are two required things ie trigger(like @ # $..) and data(either static or async) and we are good to go.</p>
<h2>Saving to Database</h2>
<p><img src="https://gauravadhikari.com/images/articles/mentions-and-hashtags-in-reactjs/save_reactmentions_to_db.webp" alt="save react-mentions to db" /></p>
<p>Before saving the data to DB, we will have to handle it so that we can render it correctly later. After extracting the mentions and tags from the content, we save it to DB.</p>
<p>Also, we have called add/tag API so that new tags added by users are saved to DB too.</p>
<p>At the last of code, we have two buttons for adding @ or # by clicking the UI(like linkedin), we have just made a ref of content input, and call</p>
<p>— myInput.current.focus() to focus cursor to content input box</p>
<p>— setContent((content) =&gt; content + "@") to append @/# after whatever the state of content is.</p>
<p>Github repo link for the above app <a href="https://github.com/gauravadhikari1997/hashtags-and-mentions-in-react">https://github.com/gauravadhikari1997/hashtags-and-mentions-in-react</a>.</p>
<h2>Frequently Asked Questions</h2>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is this tutorial about?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;This tutorial provides a comprehensive, step-by-step guide on how to implement mentions (like @user) and hashtags (like #topic) functionality in a React application using the &lt;code&gt;react-mentions&lt;/code&gt; library.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is &lt;code&gt;react-mentions&lt;/code&gt; and why is it used in this tutorial?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;&lt;code&gt;react-mentions&lt;/code&gt; is an NPM package designed to add mention and hashtag capabilities to text input fields in React. It's used here because it simplifies the process of creating interactive triggers (e.g., showing a list of users when '@' is typed) and handling the input transformation.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What are the prerequisites for following this tutorial?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;To follow along, you need Node.js (v18 or higher) and npm/yarn installed on your machine, along with a basic understanding of React.js.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How does this tutorial handle saving mentions and hashtags to a database?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The tutorial demonstrates how to transform the &lt;code&gt;react-mentions&lt;/code&gt; output, which uses custom markup, into standard HTML anchor tags (&lt;code&gt;&lt;a&gt;&lt;/code&gt;) before saving the content to a database. It also shows how new tags added by users are saved to the backend.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How are mentions and hashtags displayed correctly after being saved?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Mentions and hashtags are displayed by parsing the saved HTML content using &lt;code&gt;html-react-parser&lt;/code&gt;. The tutorial specifically shows how to replace standard &lt;code&gt;&lt;a&gt;&lt;/code&gt; tags with &lt;code&gt;react-router-dom&lt;/code&gt;'s &lt;code&gt;&lt;Link&gt;&lt;/code&gt; component to enable dynamic client-side routing (e.g., &lt;code&gt;/user/:user_id&lt;/code&gt; or &lt;code&gt;/tag/:tag_name&lt;/code&gt;) without full page refreshes.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I see a live demo or the full source code for this implementation?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, the tutorial provides a link to a deployed version of the application at &lt;a href="https://hashtags-n-mentions.netlify.app" target="_blank" rel="noopener noreferrer"&gt;https://hashtags-n-mentions.netlify.app&lt;/a&gt; and a GitHub repository link for the full source code at &lt;a href="https://github.com/gauravadhikari1997/hashtags-and-mentions-in-react" target="_blank" rel="noopener noreferrer"&gt;https://github.com/gauravadhikari1997/hashtags-and-mentions-in-react&lt;/a&gt;.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Does this solution support both mentions (@) and hashtags (#)?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, the implementation covers both mentions, triggered by the '@' symbol (displaying users), and hashtags, triggered by the '#' symbol (displaying tags).&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What styling approach is used in this React mentions and hashtags tutorial?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The tutorial utilizes Tailwind CSS for application styling. It also includes specific custom CSS to style the &lt;code&gt;react-mentions&lt;/code&gt; components, such as the input fields, suggestion lists, and the appearance of the highlighted mentions/hashtags.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Is it possible to load mention/hashtag suggestions asynchronously?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, the tutorial demonstrates both ways to load data for suggestions: loading data initially (e.g., for users in &lt;code&gt;useEffect&lt;/code&gt;) and loading data asynchronously (e.g., for tags, where suggestions are fetched based on user input via an API call).&lt;/p&gt;
&lt;/details&gt;</p>
<p>Thanks for reading. Hope you like the article and find it useful.</p>
<p><a href="https://www.buymeacoffee.com/gauravadhikar">~ Buy Me A Coffee ☕</a></p>
]]></content>
        <author>
            <name>Gaurav Adhikari</name>
            <uri>https://gauravadhikari.com</uri>
        </author>
        <published>2024-08-10T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[How To Deploy Node React App On Web Hosting]]></title>
        <id>https://gauravadhikari.com/how-to-deploy-node-react-app-on-web-hosting/</id>
        <link href="https://gauravadhikari.com/how-to-deploy-node-react-app-on-web-hosting/"/>
        <updated>2024-04-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Easy guide for deploying Node JS/ReactJS App On Web Hosting cPanel – With Screenshots...]]></summary>
        <content type="html"><![CDATA[<p><img src="https://gauravadhikari.com/images/articles/how-to-deploy-node-react-app-on-web-hosting/how-to-deploy-node-react-app-on-web-hosting.webp" alt="How To Deploy Node React App On Web Hosting" /></p>
<h2>Deploy Node React App Using CPanel</h2>
<p>To demonstrate the whole procedure, I have created a subdomain nodereactapp.gauravadhikari.com where I will place all my node &amp; react app files.</p>
<p>I'll use one of my Node React projects from GitHub. Here is the <a href="https://github.com/gauravadhikari1997/MERN-product-app">repo link</a> if you want to check the code.</p>
<p><img src="https://gauravadhikari.com/images/articles/how-to-deploy-node-react-app-on-web-hosting/react-app-github-repo.webp" alt="react app github repo" /></p>
<p>Our React app resides in /client directory.</p>
<h2>Follow These Simple Steps To Host Node React App On The Webserver</h2>
<h4>1. Go to your cPanel and search for Terminal</h4>
<p><img src="https://gauravadhikari.com/images/articles/how-to-deploy-node-react-app-on-web-hosting/how-to-deploy-node-react-app-on-web-hosting.webp" alt="terminal in cpanel" /></p>
<h4>2. In Terminal, type cd your_project_directory, for me it is cd nodereactapp.gauravadhikari.com and then git clone https://github.com/gauravadhikari1997/MERN-product-app.git to clone the project</h4>
<blockquote>
<p>Note: Check in your File Manager, the project will be initialized into a separate folder,in my case MERN-product-app,open it and move all its content into root folder i.e nodereactapp.gauravadhikari.com/</p>
</blockquote>
<h4>3. Now let's create script to run our node and react app Open package.json and add this script in scripts object "myScript": "concurrently --kill-others-on-fail "npm run start" "cd client &amp;&amp; npm install &amp;&amp; npm run build"",</h4>
<p><img src="https://gauravadhikari.com/images/articles/how-to-deploy-node-react-app-on-web-hosting/react-app-package.json-file.webp" alt="react app package.json file" /></p>
<h4>4. Now open cPanel and search Node and click on Setup Node.js App</h4>
<h4>5. Now click on Create Application, this brings a form and we need to populate it with some obvious values like, where our project files are and Application URL, Startup file, etc</h4>
<p><img src="https://gauravadhikari.com/images/articles/how-to-deploy-node-react-app-on-web-hosting/creating-node-js-app-in-web-hosting.webp" alt="creating node js app in web hosting" /></p>
<blockquote>
<p>I have added MONGODB_URI in Environment Variable, as it is used by my application to connect to MongoDB</p>
</blockquote>
<h4>6. After that click on Run NPN Install</h4>
<p><img src="https://gauravadhikari.com/images/articles/how-to-deploy-node-react-app-on-web-hosting/running-NPM-install.webp" alt="running NPM install" /></p>
<h4>7. After that click Run JS Script, and click on myScript which you and I added before. On running this you will notice that react-scripts are not installed</h4>
<p><img src="https://gauravadhikari.com/images/articles/how-to-deploy-node-react-app-on-web-hosting/react-scripts-command-not-found.webp" alt="react scripts command not found" /></p>
<p>To fix this issue, we need to go to Terminal again, move into the client directory, and install scripts one by one.</p>
<p><img src="https://gauravadhikari.com/images/articles/how-to-deploy-node-react-app-on-web-hosting/installing-react-react-scripts.webp" alt="installing react react scripts" /></p>
<p><img src="https://gauravadhikari.com/images/articles/how-to-deploy-node-react-app-on-web-hosting/react-scripts-command-not-found-solved.webp" alt="react scripts command not found solved" /></p>
<blockquote>
<p>Note: I first ran source /home /wanhrkzk /nodevenv /nodeapp.gauravadhikari.com /10 /bin /activate &amp;&amp; cd /home /wanhrkzk /nodeapp.gauravadhikari.com to be able to run npm commands</p>
</blockquote>
<h4>8. Now Run myScript again and it will work fine.</h4>
<h4>9. Open your Application URL and Voila? Your app on the web, now pat yourself on the back</h4>
<p><img src="https://gauravadhikari.com/images/articles/how-to-deploy-node-react-app-on-web-hosting/how-to-deploy-node-react-app-on-web-server.gif" alt="running node react app on web server" /></p>
<h2>Frequently Asked Questions</h2>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is the primary method for deploying a Node.js and React application detailed in this guide?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;This guide provides a step-by-step tutorial on how to deploy a Node.js and React application to web hosting using cPanel's built-in features and terminal access.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How can I run both my Node.js backend and React frontend simultaneously on cPanel?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The guide recommends creating a custom script in your &lt;code&gt;package.json&lt;/code&gt; (e.g., "myScript") that utilizes the &lt;code&gt;concurrently&lt;/code&gt; package to execute both your Node.js start command and the React app's build and start commands (&lt;code&gt;cd client &amp;&amp; npm install &amp;&amp; npm run build&lt;/code&gt;).&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is the &lt;code&gt;concurrently&lt;/code&gt; package used for in this deployment process?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The &lt;code&gt;concurrently&lt;/code&gt; package enables you to run multiple commands or npm scripts in parallel. In this context, it ensures both your Node.js server and your React application (after building) are started and running at the same time from a single cPanel script execution.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How do I configure environment variables like &lt;code&gt;MONGODB_URI&lt;/code&gt; for my Node.js application in cPanel?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;When setting up your Node.js application in cPanel's "Setup Node.js App" interface, there is a dedicated section to add &lt;code&gt;Environment Variables&lt;/code&gt;, where you can define key-value pairs like &lt;code&gt;MONGODB_URI&lt;/code&gt; for your application to use.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;I'm getting a "react-scripts command not found" error during deployment. How do I resolve this issue?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;To fix this, you need to access the cPanel Terminal, navigate into your React application's &lt;code&gt;client&lt;/code&gt; directory, and manually run &lt;code&gt;npm install&lt;/code&gt; to ensure &lt;code&gt;react-scripts&lt;/code&gt; and other dependencies are properly installed and accessible within that environment.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Do I need to move my project files after cloning from GitHub on cPanel?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, the guide advises that after cloning your project from GitHub, it might create a new subfolder. You should then use cPanel's File Manager to move all the contents of this subfolder directly into your main application's root directory (e.g., &lt;code&gt;nodereactapp.example.com/&lt;/code&gt;).&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What are the initial steps to configure a Node.js application using cPanel's interface?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Begin by searching for "Node" in your cPanel dashboard and clicking "Setup Node.js App." From there, select "Create Application" and fill in essential details such as the application root directory, Application URL, and the startup file for your Node.js server.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Is this deployment method suitable for MERN stack applications?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, the guide explicitly uses a MERN stack example project, demonstrating how to deploy a Node.js backend and a React frontend (located in a &lt;code&gt;client&lt;/code&gt; directory) together on cPanel, making it highly suitable for MERN stack applications.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is the "Run JS Script" option in cPanel's Node.js application manager used for?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The "Run JS Script" button in cPanel allows you to execute custom scripts defined within the &lt;code&gt;scripts&lt;/code&gt; object of your &lt;code&gt;package.json&lt;/code&gt; file. This is crucial for running your combined Node.js and React startup script (e.g., "myScript") after initial setup.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What if my React application is not located in a 'client' directory?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The provided script assumes your React app is in a &lt;code&gt;client&lt;/code&gt; directory. If yours is located elsewhere, you would need to modify the &lt;code&gt;cd client&lt;/code&gt; part of the &lt;code&gt;myScript&lt;/code&gt; command in your &lt;code&gt;package.json&lt;/code&gt; to reflect the actual path to your React application's folder.&lt;/p&gt;
&lt;/details&gt;</p>
<p>Thanks for reading! I hope you learned something useful.</p>
<p><a href="https://www.buymeacoffee.com/gauravadhikar">~ Buy Me A Coffee ☕</a></p>
]]></content>
        <author>
            <name>Gaurav Adhikari</name>
            <uri>https://gauravadhikari.com</uri>
        </author>
        <published>2024-04-11T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Reduce Page Load Time (5 Techniques)]]></title>
        <id>https://gauravadhikari.com/reduce-page-load-time-5-techniques/</id>
        <link href="https://gauravadhikari.com/reduce-page-load-time-5-techniques/"/>
        <updated>2024-01-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Descriptive case study on how I reduced page load time using techniques like building our own font library, implementing lazy loading…]]></summary>
        <content type="html"><![CDATA[<p><img src="https://gauravadhikari.com/images/articles/reduce-page-load-time-5-techniques/reduce-page-load-time-5-techniques.webp" alt="Reduce Web Page Load Time" /></p>
<h2>How I Reduced Page Load Time From 20 Sec To 4.5 Sec</h2>
<p>Following are the five techniques that I used to achieve lesser page load time.</p>
<h3>1. Minimize Use Of JQuery And JS</h3>
<p>I am using the bootstrap framework to leverage the mobile-first front-end development of my website. The easiest &amp; recommended way to use bootstrap in your project is to use its CDN, following are the CDN links:</p>
<p><img src="https://gauravadhikari.com/images/articles/reduce-page-load-time-5-techniques/bootstrap-cdn.webp" alt="bootstrap cdn" /></p>
<p>Bootstrap uses jQuery and Popper.js for JavaScript components but if you just use the CSS part of Bootstrap, you don't need to import them. That's what I did to reduce a lot of load time.</p>
<blockquote>
<p>But the navbar stopped functioning, nothing happened on clicking it. This is because some components of bootstrap require JavaScript, like Buttons for toggling states, Alerts dismissing, Modals for displaying, positioning, and scroll behavior, Tooltips, and popovers, etc.</p>
</blockquote>
<p>&lt;iframe height="300" style="width: 100%;" scrolling="no" title="responsive nav bar in css only" src="https://codepen.io/gauravadhikari/embed/BajGPYd?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"&gt;
See the Pen &lt;a href="https://codepen.io/gauravadhikari/pen/BajGPYd"&gt;
responsive nav bar in css only&lt;/a&gt; by Gaurav Adhikari (&lt;a href="https://codepen.io/gauravadhikari"&gt;@gauravadhikari&lt;/a&gt;)
on &lt;a href="https://codepen.io"&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;</p>
<h3>2. Minify Resources</h3>
<p>Always minify your resources ie. HTML, CSS, &amp; JS before using them in the production version of your website. As recommended by https://developers.google.com/ following are good tools to minify your resources for free:</p>
<p>— To minify HTML,  try <a href="https://kangax.github.io/html-minifier">HTMLMinifier</a></p>
<p>— To minify CSS, try <a href="http://css.github.io/csso/csso.html">csso</a></p>
<p>— To minify JavaScript, try <a href="https://github.com/mishoo/UglifyJS2">UglifyJS</a></p>
<p>Check how I achieved 43.85% saving by using HTML minifier and 37.79% saving using CSS minifier.</p>
<p><img src="https://gauravadhikari.com/images/articles/reduce-page-load-time-5-techniques/html-minifier.webp" alt="html minifier" /></p>
<p><img src="https://gauravadhikari.com/images/articles/reduce-page-load-time-5-techniques/css-minifier.webp" alt="css minifier" /></p>
<h3>3. Compress Assets Like Images, Videos, GIFs</h3>
<p>Large images, videos, gifs take up a lot of space and decrease the page load time disastrously. You should always compress your assets without compromising with quality. I personally use <a href="https://kraken.io/web-interface">kraken.io</a> for image compression.
Check the screenshot before compression and after compression (savings 60.81 %, loss negligible)</p>
<p><img src="https://gauravadhikari.com/images/articles/reduce-page-load-time-5-techniques/image-compress-online.webp" alt="image compressor online" /></p>
<h3>4. Customize Your Font Icon Library</h3>
<p>If you're using just 5-6 font icons from font awesome library then why import full library of thousands of icons. Make your custom font library with just a handful of needed icons using IcoMoon.</p>
<p>— Head over to  <a href="https://icomoon.io/app/">icomoon.io</a></p>
<p>— Select icons you require</p>
<p>— Click Generate font and download
How to use:</p>
<p>— Extract the zipped folder</p>
<p>— Check demo.html file for your icon class</p>
<p>— Upload style.css and font folder to your hosting</p>
<h3>5. Use Lazy Loading</h3>
<p>Lazy loading is a technique commonly used in websites, to not load an object until the point at which it is needed. It contributes to the efficiency of the website.
I use Craig Buckler's progressive-image.js lazyloading as it gives a nice CSS blur effect when the image is loading (like Medium). Check documentation here:</p>
<p>&lt;iframe height="300" style="width: 100%;" scrolling="no" title="responsive-image" src="https://codepen.io/craigbuckler/embed/yPqLXW?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"&gt;
See the Pen &lt;a href="https://codepen.io/craigbuckler/pen/yPqLXW"&gt;
responsive-image&lt;/a&gt; by Craig Buckler (&lt;a href="https://codepen.io/craigbuckler"&gt;@craigbuckler&lt;/a&gt;)
on &lt;a href="https://codepen.io"&gt;CodePen&lt;/a&gt;.
&lt;/iframe&gt;</p>
<p>How to use:</p>
<p>— Add the CSS in &lt;head&gt; tag and JS just above ending &lt;body&gt; tag</p>
<p>— Add an 'img' tag for the small image with a class of preview, surround it with 'a' link to the large image and add progressive replace as classes</p>
<blockquote>
<p>Note: The preview and full-size images must have the same aspect ratio, e.g 40x30 and 800x600.</p>
</blockquote>
<h2>Frequently Asked Questions</h2>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What are the primary benefits of reducing page load time for my website?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Reducing page load time significantly improves user experience, decreases bounce rates, and enhances your website's search engine ranking. Faster loading pages are generally preferred by both users and search algorithms.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How much page load time improvement can I expect by applying these techniques?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The author managed to reduce page load time from 20 seconds to 4.5 seconds on their own website. While specific results vary, applying these techniques can lead to substantial performance gains.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What are the five key techniques discussed for optimizing website speed?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;The five core techniques are: minimizing the use of jQuery and JavaScript, minifying resources (HTML, CSS, JS), compressing assets like images and videos, customizing your font icon library, and implementing lazy loading for content.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Can I use Bootstrap without jQuery and JavaScript to improve speed, and what are the implications?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, you can import only the CSS part of Bootstrap to avoid unnecessary JavaScript. However, some Bootstrap components (like navbars, modals, tooltips) require JavaScript. You might need to implement custom CSS-only alternatives or selectively add minimal JS.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Which free tools are recommended for minifying HTML, CSS, and JavaScript files?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;For HTML: &lt;code&gt;HTMLMinifier&lt;/code&gt;. For CSS: &lt;code&gt;csso&lt;/code&gt;. For JavaScript: &lt;code&gt;UglifyJS&lt;/code&gt;. The author saw significant file size reductions (e.g., 43.85% for HTML, 37.79% for CSS) using these tools.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is the best way to compress images and other assets without losing quality?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Compress large assets like images and videos using tools like &lt;a href="https://kraken.io" target="_blank"&gt;Kraken.io&lt;/a&gt;. The author achieved up to 60.81% savings with minimal quality loss.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;How can I customize my font icon library to reduce page load time?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Instead of importing an entire font icon library (like Font Awesome), use &lt;a href="https://icomoon.io" target="_blank"&gt;IcoMoon.io&lt;/a&gt; to generate a custom font with only the icons you need. This reduces file size significantly.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;What is lazy loading, and how does it contribute to website efficiency?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Lazy loading defers loading of non-visible elements (like images or videos) until they appear in the user's viewport. This reduces initial page load time and improves overall performance.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Is there a recommended lazy loading solution that also offers visual effects?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, the author recommends &lt;code&gt;progressive-image.js&lt;/code&gt; by Craig Buckler. It adds a blur-up effect similar to Medium.com while images are loading.&lt;/p&gt;
&lt;/details&gt;</p>
<p>&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Are these techniques applicable to all types of websites and web technologies?&lt;/strong&gt;&lt;/summary&gt;
&lt;p&gt;Yes, while the examples use Bootstrap, the core principles (minifying, compressing, lazy loading, etc.) are universal best practices that apply to most websites and frameworks.&lt;/p&gt;
&lt;/details&gt;</p>
<p>Thanks for reading! I hope you learned something useful.</p>
<p><a href="https://www.buymeacoffee.com/gauravadhikar">~ Buy Me A Coffee ☕</a></p>
]]></content>
        <author>
            <name>Gaurav Adhikari</name>
            <uri>https://gauravadhikari.com</uri>
        </author>
        <published>2024-01-16T00:00:00.000Z</published>
    </entry>
</feed>