<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Luqman Shaban</title>
    <description>The latest articles on DEV Community by Luqman Shaban (@luqmanshaban).</description>
    <link>https://dev.to/luqmanshaban</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F898886%2F44b18afa-314a-4119-b819-062faa12f779.jpeg</url>
      <title>DEV Community: Luqman Shaban</title>
      <link>https://dev.to/luqmanshaban</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/luqmanshaban"/>
    <language>en</language>
    <item>
      <title>Building a Smarter Way to Explore Next.js Docs: My Weekend with Semantic Search + RAG</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Mon, 28 Apr 2025 08:57:21 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/building-a-smarter-way-to-explore-nextjs-docs-my-weekend-with-semantic-search-rag-5hl4</link>
      <guid>https://dev.to/luqmanshaban/building-a-smarter-way-to-explore-nextjs-docs-my-weekend-with-semantic-search-rag-5hl4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This past weekend, fueled by curiosity and the "learn by doing" mantra, I embarked on a mission: to build a more intelligent way to navigate the vast landscape of the &lt;strong&gt;Next.js&lt;/strong&gt; documentation. The result? An AI-powered semantic search and Retrieval-Augmented Generation &lt;a href="https://js.langchain.com/docs/tutorials/rag/" rel="noopener noreferrer"&gt;(RAG)&lt;/a&gt; tool specifically designed for the official &lt;strong&gt;Next.js&lt;/strong&gt; docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Simple Keyword Search
&lt;/h2&gt;

&lt;p&gt;We've all experienced the frustration of sifting through numerous search results, many only tangentially related to our actual query. Traditional keyword-based search often struggles with understanding the nuances of language and the context of our questions. This is particularly true for complex documentation like that of a powerful framework like Next.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Solution: Semantic Search + RAG
&lt;/h2&gt;

&lt;p&gt;To tackle this, I decided to leverage the power of semantic search and Retrieval-Augmented Generation (RAG). Here's the core idea:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semantic Search&lt;/strong&gt;: Instead of just matching keywords, the system understands the meaning behind your question. This allows for more relevant results, even if your query doesn't use the exact terminology present in the documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retrieval-Augmented Generation (RAG)&lt;/strong&gt;: Once relevant documentation snippets are found, a language model uses this context to generate a more informed and accurate answer to your question, complete with citations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diving into the Implementation
&lt;/h2&gt;

&lt;p&gt;Here's a peek under the hood at the technologies and processes involved:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Populating the Knowledge Base&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;The first crucial step was to ingest and process the Next.js documentation. This involved:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fetching Navigation Links&lt;/strong&gt;: I started by scraping the main Next.js &lt;a href="https://nextjs.org/docs" rel="noopener noreferrer"&gt;documentation page&lt;/a&gt; to extract all the links to individual documentation pages.&lt;br&gt;
&lt;strong&gt;Crawling and Extracting Content&lt;/strong&gt;: For each of these links, I used &lt;code&gt;CheerioWebBaseLoader&lt;/code&gt; to fetch the content of the page.&lt;br&gt;
&lt;strong&gt;Chunking the Text&lt;/strong&gt;: Large documents were split into smaller, manageable chunks using &lt;code&gt;RecursiveCharacterTextSplitter&lt;/code&gt;. This is important for efficient embedding and retrieval.&lt;br&gt;
&lt;strong&gt;Generating Embeddings&lt;/strong&gt;: The heart of semantic search! I used &lt;code&gt;GoogleGenerativeAIEmbeddings&lt;/code&gt; to create vector &lt;code&gt;embeddings&lt;/code&gt; for each chunk of the documentation. These &lt;code&gt;embeddings&lt;/code&gt; capture the semantic meaning of the text.&lt;br&gt;
&lt;strong&gt;Storing in a Vector Database&lt;/strong&gt;: The generated &lt;code&gt;embeddings&lt;/code&gt; were stored in &lt;code&gt;Chroma&lt;/code&gt;, an efficient vector store that allows for fast similarity searches.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Chroma } from "@langchain/community/vectorstores/chroma";
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
import { GoogleGenerativeAIEmbeddings } from "@langchain/google-genai";
import { load } from "cheerio";
import "dotenv/config";
import { CheerioWebBaseLoader } from "@langchain/community/document_loaders/web/cheerio";
import { Document } from "@langchain/core/documents";

const embeddings = new GoogleGenerativeAIEmbeddings({
  model: "models/text-embedding-004",
  apiKey: process.env.GOOGLE_API_KEY,
});

const textSplitter = new RecursiveCharacterTextSplitter({
  chunkSize: 1000,
  chunkOverlap: 200,
});

const vectorStore = new Chroma(embeddings, {
  collectionName: "next-js-docs",
});

export async function PopulateDatabase() {
  const navs = await GetNavLinks();
  if (!Array.isArray(navs) || navs.length &amp;lt; 0) {
    throw new Error("Failed to populate database");
  }

  // const testNavs = navs.slice(0, 3);
  const testNavs = navs.slice(1, 375)


  for (let index = 0; index &amp;lt; testNavs.length; index++) {
    const i = testNavs[index];
    try {
      console.info(
        `🌐 Processing link ${index + 1} of ${
          testNavs.length
        }: https://nextjs.org/${i}`
      );

      const loader = new CheerioWebBaseLoader(`https://nextjs.org/${i}`);
      const docs = await loader.load();
      const splitDocs = await textSplitter.splitDocuments(docs);

      await InsertIntoDB(splitDocs);
    } catch (error) {
      console.error(`Error processing page ${i}:`, error);
      throw new Error("Failed to populate database \n " + error);
    }
  }

  console.log("✅ Successfully Completed inserting into db");
}

async function InsertIntoDB(validDocs: Document&amp;lt;Record&amp;lt;string, any&amp;gt;&amp;gt;[]) {
  const batchSize = 1000;
  const totalBatches = Math.ceil(validDocs.length / batchSize);

  console.info(
    `📄 Inserting ${validDocs.length} documents in ${totalBatches} batch(es)...`
  );

  for (let i = 0; i &amp;lt; validDocs.length; i += batchSize) {
    const batch = validDocs.slice(i, i + batchSize);

    try {
      await vectorStore.addDocuments(batch);
      console.log(
        `✅ Successfully added batch ${
          Math.floor(i / batchSize) + 1
        } of ${totalBatches}`
      );
    } catch (error) {
      console.error(
        `❌ Error adding batch ${
          Math.floor(i / batchSize) + 1
        } of ${totalBatches}:`,
        error
      );
      console.error(
        "🔍 First few items in failing batch:",
        batch
          .slice(0, 2)
          .map((doc) =&amp;gt; doc.pageContent.substring(0, 150) + "...")
      );
    }
  }
}

async function GetNavLinks(): Promise&amp;lt;string[] | Error&amp;gt; {
  try {
    const response = await fetch("https://nextjs.org/docs");
    const html = await response.text();

    const $ = load(html);

    const routes: string[] = [];

    $("main nav ul li a").map((_, el) =&amp;gt; {
      const href = $(el).attr("href");
      if (href) {
        routes.push(href);
      }
    });

    return routes;
  } catch (error) {
    console.error(error);
    return new Error("Failed to populate database");
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. The Search and Answer Generation Pipeline&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;When a user asks a question, the following steps occur:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Keyword Generation (Optimization)&lt;/strong&gt;: To potentially refine the search, the &lt;code&gt;ChatGoogleGenerativeAI&lt;/code&gt; model is used with a specific prompt to generate a concise list of relevant Next.js keywords from the user's question. This helps focus the subsequent semantic search.&lt;br&gt;
&lt;strong&gt;- Semantic Retrieval&lt;/strong&gt;: The generated keywords (or the original question) are used to perform a similarity search in the &lt;code&gt;Chroma&lt;/code&gt; vector store using the &lt;code&gt;similaritySearch&lt;/code&gt; function. This retrieves the most semantically similar documentation snippets.&lt;br&gt;
&lt;strong&gt;- Answer Generation with Context&lt;/strong&gt;: The retrieved documentation snippets are then passed to the &lt;code&gt;ChatGoogleGenerativeAI&lt;/code&gt; model (specifically gemini-2.0-flash) along with the original question and a carefully crafted prompt. This prompt instructs the model to act as a knowledgeable Next.js assistant, using the provided context to answer the question accurately and cite the source.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Chroma } from "@langchain/community/vectorstores/chroma";
import { ChatGoogleGenerativeAI, GoogleGenerativeAIEmbeddings } from "@langchain/google-genai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { Annotation, StateGraph } from "@langchain/langgraph";
import { Document } from "@langchain/core/documents";
import 'dotenv/config'

const llm = new ChatGoogleGenerativeAI({
  model: "gemini-2.0-flash",
  apiKey: process.env.GOOGLE_API_KEY,
});

const embeddings = new GoogleGenerativeAIEmbeddings({
  model: "models/text-embedding-004",
  apiKey: process.env.GOOGLE_API_KEY,
});

const vectorStore = new Chroma(embeddings, {
  collectionName: "next-js-docs",
});

const promptTemplate = ChatPromptTemplate.fromMessages([
  ["system", `You are a knowledgeable and confident Next.js assistant.

Important behavior rules:
- Your top priority is to answer the user's question as accurately and helpfully as possible.
- Use the provided context to support your answer **only if it is relevant**.
- NEVER reference, mention, or comment on the existence, quality, or amount of the context.
- If helpful information is found in the context, cite it properly in markdown format (e.g., [link](url)).
- If context is not helpful, answer based on your own knowledge.
- Always respond in professional, clear Markdown format.
`],

  ["user", `
User Question:
{question}

Additional Context (if useful):
{context}
`],
]);



const keywordGenerationPrompt = ChatPromptTemplate.fromTemplate(
  `You are a semantic search assistant.

Given a user question, generate a concise list of 5-10 keywords that are highly relevant for searching within NEXT.JS official documentation only.

Important rules:
- Focus ONLY on Next.js concepts, features, methods, APIs, and relevant terminology.
- Do NOT include general cloud providers, hosting platforms, or unrelated services (e.g., AWS, Azure, Netlify, Vercel).
- Prefer specific technical terms over generic words.
- If the question is very general, generate keywords that stay within the context of building or deploying a Next.js app.

Return the keywords as a comma-separated list. No extra explanations.

User Question:
{question}

Keywords:
`
);


// Define state for application
const InputStateAnnotation = Annotation.Root({
  question: Annotation&amp;lt;string&amp;gt;,
});

const StateAnnotation = Annotation.Root({
  question: Annotation&amp;lt;string&amp;gt;,
  context: Annotation&amp;lt;Document[]&amp;gt;,
  answer: Annotation&amp;lt;string&amp;gt;,
  keywords: Annotation&amp;lt;string[]&amp;gt;,
});

// Define application steps
const generateKeywords = async (state: typeof InputStateAnnotation.State) =&amp;gt; {
  const keywordsResponse = await llm.invoke(await keywordGenerationPrompt.invoke(state));
  const keywords = keywordsResponse.content?.toString().split(',').map((k: string) =&amp;gt; k.trim()) || [state.question];
  console.log("Generated Keywords:", keywords);
  return { keywords };
};

const retrieve = async (state: typeof StateAnnotation.State) =&amp;gt; {
  const searchQuery = (state.keywords || [state.question]).join(" ");
  const retrievedDocs = await vectorStore.similaritySearch(searchQuery, 20);
  return { context: retrievedDocs };
};


const generateAnswer = async (state: typeof StateAnnotation.State) =&amp;gt; {
  const docsContent = state.context
    .map((doc: Document) =&amp;gt; `Content: ${doc.pageContent}\nSource: ${doc.metadata.source}`)
    .join("\n\n---\n\n");
  const messages = await promptTemplate.invoke({
    question: state.question,
    context: docsContent,
  });
  const response = await llm.invoke(messages);
  return { answer: response.content };
};

// Compile application and test
const graph = new StateGraph(StateAnnotation)
  .addNode("generate_keywords", generateKeywords)
  .addNode("retrieve", retrieve)
  .addNode("generate_answer", generateAnswer)
  .addEdge("__start__", "generate_keywords")
  .addEdge("generate_keywords", "retrieve")
  .addEdge("retrieve", "generate_answer")
  .addEdge("generate_answer", "__end__")
  .compile();

export default async function Generate(question: string) {
  console.info("🔍 Performing a sample search...");
  let inputs = {
    question: question,
  };

  const result = await graph.invoke(inputs);
  console.log("🤖 Gemini's Response:");
  console.log(result.answer);
  return result.answer
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Orchestration with Langgraph&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;To manage the flow of information through these steps, I utilized &lt;code&gt;Langgraph&lt;/code&gt;. This powerful tool allows you to define a graph of interconnected steps, making it easier to build complex AI workflows. In this case, the graph includes nodes for keyword generation, document retrieval, and answer generation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Impressions and Learnings
&lt;/h2&gt;

&lt;p&gt;Building this tool over the weekend has been an incredibly rewarding learning experience. Here are some key takeaways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Semantic search significantly improves relevance&lt;/strong&gt;: The ability to understand the meaning behind a query leads to far more accurate and helpful results compared to simple keyword matching.&lt;br&gt;
&lt;strong&gt;- RAG provides grounded and trustworthy answers&lt;/strong&gt;: By grounding the language model's responses in the official documentation, the answers are more reliable and can be easily verified through the provided citations.&lt;br&gt;
&lt;strong&gt;- Langchain simplifies complex AI pipelines&lt;/strong&gt;: It provides a fantastic set of abstractions and integrations that make building these kinds of tools much more manageable.&lt;br&gt;
&lt;strong&gt;- Vector databases are crucial for efficient semantic search&lt;/strong&gt;: &lt;code&gt;Chroma's&lt;/code&gt; performance in storing and querying &lt;code&gt;embeddings&lt;/code&gt; is essential for a responsive search experience.&lt;/p&gt;

&lt;p&gt;The Journey Continues...&lt;br&gt;
This weekend project is just the beginning. I'm excited to continue exploring Semantic Search in details and solve actual problems.&lt;/p&gt;

&lt;p&gt;👉 Checkout the prototype &lt;a href="https://nextai.tanelt.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Stay tuned for future updates as this project evolves!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>web</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Building a Blazing-Fast URL Shortener in Go 🚀</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Mon, 28 Oct 2024 06:04:46 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/building-a-blazing-fast-url-shortener-in-go-4bj5</link>
      <guid>https://dev.to/luqmanshaban/building-a-blazing-fast-url-shortener-in-go-4bj5</guid>
      <description>&lt;p&gt;Hey, Dev Community!&lt;/p&gt;

&lt;p&gt;After spending some time honing my skills with Go, I decided to tackle a fun and practical project: creating a URL shortener! Inspired by Chapter 8 of a system design book, I wanted to build something that’s fast, efficient, and minimalistic. So, here it is: &lt;a href="https://url.tanelt.com" rel="noopener noreferrer"&gt;https://url.tanelt.com&lt;/a&gt; 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea 💡
&lt;/h2&gt;

&lt;p&gt;I’ve always been fascinated by systems that handle high traffic with minimal latency, so I wanted to apply that principle to a small-scale project. URL shorteners are a perfect use case: they need to be fast, lightweight, and designed to handle lots of quick database lookups. I set out with two main goals:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Minimalist design&lt;/strong&gt; — Keep it simple, clean, and functional.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimized for speed&lt;/strong&gt; — Implement a Go backend that minimizes response times.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Stack 🛠️
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Go&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: I went with a simple data store to keep things light. For this project, MongoDB worked well for fast lookups and ease of use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Just HTML/CSS for a simple, distraction-free design. Go templates kept things neat and quick.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Challenges Faced 🧗‍♂️
&lt;/h2&gt;

&lt;p&gt;Building this involved a few interesting challenges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Slug Generation&lt;/strong&gt;: Creating unique, short slugs that look clean but also avoid collisions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redirect Speed&lt;/strong&gt;: I wanted to optimize server response time, so I spent time refining database queries and ensuring the server responds in milliseconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimalist UI&lt;/strong&gt;: It’s easy to over-design, but keeping things minimal was a fun challenge.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Key Learnings 📘
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;API Dev with Gin&lt;/strong&gt;: This project deepened my experience with Gin, a popular HTTP web framework for Go. Gin's speed and simplicity made it a perfect choice for building a responsive API. I learned a lot about routing and error handling, which were crucial for making the app’s performance snappy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficient Database Access&lt;/strong&gt;:  Integrating MongoDB taught me the importance of optimizing database connections and queries for high-performance applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Balancing Design and Functionality&lt;/strong&gt;: With a minimalist UI, every element on the page has to serve a purpose. This taught me to focus on usability above all.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It Out! 🎉
&lt;/h2&gt;

&lt;p&gt;If you’re interested, check it out here: &lt;a href="https://url.tanelt.com" rel="noopener noreferrer"&gt;https://url.tanelt.com&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/luqmanshaban/go-url-shortner.git" rel="noopener noreferrer"&gt;Source code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re curious about the code, optimization tricks, or design decisions, let’s chat in the comments! I’d love to hear your thoughts or suggestions for further improvements.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>go</category>
      <category>projects</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Devchat: Building my first social app</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Tue, 24 Sep 2024 13:10:23 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/devchat-building-my-first-social-app-2pgd</link>
      <guid>https://dev.to/luqmanshaban/devchat-building-my-first-social-app-2pgd</guid>
      <description>&lt;p&gt;Over the past two weeks, I went on a an exciting journey to build &lt;a href="https://devchat.tanelt.com" rel="noopener noreferrer"&gt;Devchat&lt;/a&gt;, a real-time messaging app specifically for developers. The goal was simple: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Learn websockets&lt;/li&gt;
&lt;li&gt;Create a messaging app&lt;/li&gt;
&lt;li&gt;Make it open-source&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But, as with any project, devchat brought its fair share of challenges, hurdles and triumphs. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Starting with the Basics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I decided to build the front-end with &lt;strong&gt;React&lt;/strong&gt; and &lt;strong&gt;Vite&lt;/strong&gt;. I had to think twice whether to use &lt;strong&gt;Nextjs&lt;/strong&gt; but it figured it word a level of complexity to the project. For styling, &lt;strong&gt;Tailwind CSS&lt;/strong&gt; and &lt;strong&gt;Daisy UI&lt;/strong&gt; came to the rescue, making it easy to create responsive layouts without writing to much CSS.&lt;/p&gt;

&lt;p&gt;The front-end's focus was all about simplicity and user experience. With React Router, I set up smooth transitions between routes, including user authentication, messaging components, and user profiles. When it came to handling state between components, I used &lt;strong&gt;zustand&lt;/strong&gt; for the first time and setting it up was as simple is it could get. Real-time messaging was next on my list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend Architecture: Node.js &amp;amp; MongoDB&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The backend was powered by &lt;strong&gt;Node.js&lt;/strong&gt; and Express, with &lt;strong&gt;Mongoose&lt;/strong&gt; as the ORM for the &lt;strong&gt;Mongo&lt;/strong&gt; database. Structuring the API to handle user authentication, chat room creation, and message storage required a bit of planning. I used JWT for secure authentication and MongoDB's flexibility to store messages and user data efficiently. &lt;em&gt;I knew that this could be simply implemented using firebase but that meant I would miss out out on learning the core concepts of websockets&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One challenge I faced here was designing a schema that could handle a large number of real-time messages without impacting performance and user experience. It was crucial to effectively save every conversation between users to the database and sync them with broadcast them to the client without conflict. After some thorough digging I found a &lt;a href="https://github.com/luqmanshaban/devchat-app/blob/main/server/socket/socket.js" rel="noopener noreferrer"&gt;solution&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment &amp;amp; Scaling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the core functionality was in place, it was time to deploy. I chose Vercel for the client and &lt;a href="https://render.com/register" rel="noopener noreferrer"&gt;Render&lt;/a&gt; to host the server. Both platforms have seamless integration with GitHub making it easy to set up continuous deployment. Every push to the repository automatically triggered a new deployment, which kept the entire development cycle smooth and efficient.&lt;br&gt;
I also bought a domain from &lt;a href="https://hostinger.com?REFERRALCODE=1LUQMAN31" rel="noopener noreferrer"&gt;Hostinger&lt;/a&gt; and configured it on vercel pretty easily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;br&gt;
Building &lt;strong&gt;&lt;a href="https://devchat.tanelt.com/" rel="noopener noreferrer"&gt;DevChat&lt;/a&gt;&lt;/strong&gt; taught me so much in a short time. Here are a few key lessons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Real-time systems are fascinating but complex. Managing live data streams requires planning and careful resource management.&lt;/li&gt;
&lt;li&gt;Socket.io is a powerful tool for WebSocket communication, but it’s important to keep scalability in mind from the start.&lt;/li&gt;
&lt;li&gt;Tailwind CSS and Daisy UI save a ton of time. Styling that would normally take hours (or days!) was simplified thanks to these tools.&lt;/li&gt;
&lt;li&gt;Deployment is as important as development. Setting up automated deployments and managing environment variables across different environments (development and production) was key to ensuring a smooth experience.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The Open-Source Journey&lt;/strong&gt;&lt;br&gt;
What excites me most about &lt;strong&gt;&lt;a href="//devchat.tanelt.com"&gt;DevChat&lt;/a&gt;&lt;/strong&gt; is that it’s open source. Developers are welcome to contribute, add features, or adapt it to their own needs. The journey of building this project is ongoing, and I’m eager to see how it evolves with community input.&lt;/p&gt;

&lt;p&gt;This project was a fantastic learning experience, and I’m proud of what I’ve built in such a short time. Right now, it boasts a simple connecting and messaging features, but I look forward to improving &lt;a href="//devchat.tanelt.com"&gt;DevChat&lt;/a&gt; further and hope it becomes a valuable tool for developer communities around the world!&lt;/p&gt;

&lt;p&gt;If you're interested, you can check out the site &lt;a href="//devchat.tanelt.com"&gt;here&lt;/a&gt; and contribute &lt;a href="https://github.com/luqmanshaban/devchat-app" rel="noopener noreferrer"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Adios&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>sideprojects</category>
      <category>developer</category>
    </item>
    <item>
      <title>How to conditionally render components in React</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Sat, 21 Sep 2024 20:55:17 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/how-to-conditionally-render-components-in-react-24kk</link>
      <guid>https://dev.to/luqmanshaban/how-to-conditionally-render-components-in-react-24kk</guid>
      <description>&lt;p&gt;I've been working on a messaging web app this week and one of the features I wanted to implement was conditionally rendering multiple components when a particular condition is met. Let me explain.&lt;/p&gt;

&lt;p&gt;Imagine a restaurant menu page that has a variety of food items in different categories, ranging from regular meals to drinks and desserts. You might want to add filters to render a specific category like desserts. There are several ways to achieve this, here are a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using a bunch of &lt;code&gt;if/else&lt;/code&gt; statements;&lt;/li&gt;
&lt;li&gt;Using a &lt;code&gt;ternary&lt;/code&gt; operator&lt;/li&gt;
&lt;li&gt;Exclusive component rendering &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll implement the third option while sing our restaurant menu page example, lets create three components returning the menu items:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

const AllFoodItems = () =&amp;gt; &amp;lt;div&amp;gt;All Menus&amp;lt;/div&amp;gt;
const MealsComponent = () =&amp;gt; &amp;lt;div&amp;gt;Meals&amp;lt;/div&amp;gt;
const DessertComponent = () =&amp;gt; &amp;lt;div&amp;gt;Dessert&amp;lt;/div&amp;gt;
const DrinksComponent = () =&amp;gt; &amp;lt;div&amp;gt;Drinks&amp;lt;/div&amp;gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is just a simple use case, but it will do the job. Suppose we wanted to exclusively render the desserts when the user clicks on the desserts button. We can do this by creating an array of boolean values, with each value representing a component, e.g., element 1 of the array, will represent &lt;code&gt;AllFoodItems&lt;/code&gt; and element 2 represents &lt;code&gt;MealsComponent&lt;/code&gt; and so on. &lt;/p&gt;

&lt;p&gt;Initially, we set all the values to false except for the first one, which will be the default component rendered.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

const [renderedComponents, setRenederedComponent] = useState([true, false, false, false])


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The next step would be to create a function that will update the indexes by setting all their values to false except for one.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

const toggleComponent = (index: number) =&amp;gt; setRenederedComponent(prev =&amp;gt; prev.map((_, i) =&amp;gt; i === index))


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the function above, we're passing an argument &lt;code&gt;index&lt;/code&gt;, and then mapping over the &lt;code&gt;renderedComponents&lt;/code&gt; array. When we reach the element whose index matches the number passed in the argument, we update its value to true, while setting the other elements to false.&lt;/p&gt;

&lt;p&gt;In the following step, we call this function inside button elements and pass the corresponding index for the component. You could imagine this as your filter component that renders a specific component on a click event:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

    &amp;lt;ul&amp;gt;
        &amp;lt;li&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; toggleComponent(0)}&amp;gt;All&amp;lt;/button&amp;gt;
        &amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; toggleComponent(1)}&amp;gt;Meals&amp;lt;/button&amp;gt;
        &amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; toggleComponent(2)}&amp;gt;Dessert&amp;lt;/button&amp;gt;
        &amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; toggleComponent(3)}&amp;gt;Drinks&amp;lt;/button&amp;gt;
        &amp;lt;/li&amp;gt;
      &amp;lt;/ul&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, we conditionally render the components when they're truthy:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

      &amp;lt;div&amp;gt;
        {renderedComponents[0] &amp;amp;&amp;amp; &amp;lt;AllFoodItems /&amp;gt;}
        {renderedComponents[1] &amp;amp;&amp;amp; &amp;lt;MealsComponent /&amp;gt;}
        {renderedComponents[2] &amp;amp;&amp;amp; &amp;lt;DessertComponent /&amp;gt;}
        {renderedComponents[3] &amp;amp;&amp;amp; &amp;lt;DrinksComponent /&amp;gt;}
      &amp;lt;/div&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here's the full code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { useState } from 'react'


const AllFoodItems = () =&amp;gt; &amp;lt;div&amp;gt;All Menus&amp;lt;/div&amp;gt;
const MealsComponent = () =&amp;gt; &amp;lt;div&amp;gt;Meals&amp;lt;/div&amp;gt;
const DessertComponent = () =&amp;gt; &amp;lt;div&amp;gt;Dessert&amp;lt;/div&amp;gt;
const DrinksComponent = () =&amp;gt; &amp;lt;div&amp;gt;Drinks&amp;lt;/div&amp;gt;


const App = () =&amp;gt; {
  const [renderedComponents, setRenederedComponent] = useState([true, false, false, false])

  const toggleComponent = (index: number) =&amp;gt; setRenederedComponent(prev =&amp;gt; prev.map((_, i) =&amp;gt; i === index))
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;ul&amp;gt;
        &amp;lt;li&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; toggleComponent(0)}&amp;gt;All&amp;lt;/button&amp;gt;
        &amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; toggleComponent(1)}&amp;gt;Meals&amp;lt;/button&amp;gt;
        &amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; toggleComponent(2)}&amp;gt;Dessert&amp;lt;/button&amp;gt;
        &amp;lt;/li&amp;gt;
        &amp;lt;li&amp;gt;
          &amp;lt;button onClick={() =&amp;gt; toggleComponent(3)}&amp;gt;Drinks&amp;lt;/button&amp;gt;
        &amp;lt;/li&amp;gt;
      &amp;lt;/ul&amp;gt;

      &amp;lt;div&amp;gt;
        {renderedComponents[0] &amp;amp;&amp;amp; &amp;lt;AllFoodItems /&amp;gt;}
        {renderedComponents[1] &amp;amp;&amp;amp; &amp;lt;MealsComponent /&amp;gt;}
        {renderedComponents[2] &amp;amp;&amp;amp; &amp;lt;DessertComponent /&amp;gt;}
        {renderedComponents[3] &amp;amp;&amp;amp; &amp;lt;DrinksComponent /&amp;gt;}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

export default App


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Live demo:&lt;/p&gt;

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

&lt;p&gt;This is a simple demonstration of how you can conditionally render components in React. It's a better approach when dealing with scenarios like food menus, product categories, etc.&lt;/p&gt;

&lt;p&gt;I hope this was helpful, Lol!&lt;/p&gt;

&lt;p&gt;Do you know a better way to do this?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://linkedin.com/in/luqman-shaban" rel="noopener noreferrer"&gt;Let's connect&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Integrate AI into Your Node.js Application: A Step-by-Step Guide</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Wed, 17 Jul 2024 13:54:39 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/how-to-integrate-ai-into-your-nodejs-application-a-step-by-step-guide-3b82</link>
      <guid>https://dev.to/luqmanshaban/how-to-integrate-ai-into-your-nodejs-application-a-step-by-step-guide-3b82</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From being a fantasy to becoming a reality, Generative AI has proven to be a beneficial tool for many of us. It has boosted our overall productivity, automated repetitive tasks, and, in my case, created informative and educational content. That said, GenAI (Generative AI) still has a long way to go and shouldn't be fully relied upon for any given task.&lt;/p&gt;

&lt;p&gt;As a developer, you don't need to be an expert in AI or ML to build cool stuff. There are plenty of tools you can use to leverage the power of AI and integrate it into your projects. In this article, I will walk you through &lt;a href="https://js.langchain.com/v0.2/docs/introduction/" rel="noopener noreferrer"&gt;langchainjs&lt;/a&gt;, a framework for developing applications powered by Large Language Models (LLMs). I will guide you on how to build a simple Node.js API that takes user input and interacts with the Gemini model to generate a response.&lt;/p&gt;

&lt;p&gt;This is not a Node.js API tutorial but rather an introduction to incorporating GenAI into the API. If you're new to Node.js, you can check out this &lt;a href="https://dev.to/luqmanshaban/building-a-nodejs-server-side-application-with-sequelize-and-express-beginners-guide-5758"&gt;article&lt;/a&gt; I've written on the topic.&lt;/p&gt;

&lt;p&gt;To get started,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;initialize a node project and run the following command:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm i @langchain/google-genai dotenv express


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;.env&lt;/code&gt; file at the root of your project and add the following code: &lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

GOOGLE_API_KEY= _paste your gemini api key here_


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;_You can get your own API Key for free &lt;a href="https://aistudio.google.com/app/apikey" rel="noopener noreferrer"&gt;here_&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have a simple nodejs API that receives a user's prompt and returns a response:&lt;/p&gt;

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

&lt;p&gt;This code sets up an Express server that uses the Google Generative AI model to handle POST requests at the &lt;code&gt;/api/prompts&lt;/code&gt; endpoint. It receives a prompt from the request body, generates a response using the AI model, and sends the response back to the client. If an error occurs, it sends a 500 status with the error message. The API key and model are configured via environment variables.&lt;/p&gt;

&lt;p&gt;Now let's implement the &lt;code&gt;generateResponse&lt;/code&gt; method.&lt;/p&gt;

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

&lt;p&gt;The &lt;code&gt;generateResponse&lt;/code&gt; function asynchronously invokes the AI model with a given prompt. It logs and returns the generated response content. If an error occurs, it logs the error and returns the error message.&lt;/p&gt;

&lt;p&gt;Here's the entire code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
import 'dotenv/config'
import express from "express";

const model = new ChatGoogleGenerativeAI({
  model: "gemini-pro",
  maxOutputTokens: 2048
})

const app = express()
app.use(express.json())

app.post('/api/prompts', async(req, res) =&amp;gt; {
  const { prompt } = req.body
  try {
    const response = await generateResponse(prompt)
    res.status(200).json({response: response})
  } catch (error) {
    res.status(500).json({ error: error.message})
    console.error(error)
  }
})


async function generateResponse(prompt) {
  try {
    const response = await model.invoke(prompt)
    console.log(response.content)
    return response.content
  } catch (error) {
    console.error(error);
    return error.message
  }
}


app.listen(4000, () =&amp;gt; {
  console.log('SERVER RUNNING ON PORT:4000')
})



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's test it out on Postman, my server is running on port 4000 so if i send a post request with the prompt, i should get back an answer from the Gemini Model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1zf6ulqfrq9rwoevofa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1zf6ulqfrq9rwoevofa.png" alt="testing API on postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the response:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffc5fwoq47a25knalnbze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffc5fwoq47a25knalnbze.png" alt="Response from Gemini&amp;lt;br&amp;gt;
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5puqmdzjndq8ula3zc91.jpeg)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generative AI has transitioned from fantasy to a valuable tool, enhancing productivity, automating repetitive tasks, and generating informative content. However, while GenAI is powerful, it shouldn't be solely relied upon for any task. As developers, we can leverage frameworks like &lt;a href="https://js.langchain.com/v0.2/docs/introduction/" rel="noopener noreferrer"&gt;langchainjs&lt;/a&gt; to integrate AI into our projects without being AI or ML experts. This tutorial demonstrated how to build a Node.js API that interacts with the Gemini model to generate responses based on user input.&lt;/p&gt;

&lt;p&gt;Now that you have seen how to integrate Generative AI into a Node.js application, why not try it yourself? Start by setting up your project, and experiment with different prompts to see the varied responses the AI can generate. Don’t forget to share your experiences and projects with the community!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mailchi.mp/9275d6947c46/luqmandev" rel="noopener noreferrer"&gt;Subscribe to my newsletter&lt;/a&gt; to receive detailed tutorials every week and stay updated.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>gemini</category>
      <category>api</category>
      <category>node</category>
    </item>
    <item>
      <title>Extracting Text from Uploaded Files in Node.js: A Continuation</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Mon, 03 Jun 2024 15:30:21 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/extracting-text-from-uploaded-files-in-nodejs-a-continuation-416j</link>
      <guid>https://dev.to/luqmanshaban/extracting-text-from-uploaded-files-in-nodejs-a-continuation-416j</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In our previous &lt;a href="https://dev.to/luqmanshaban/how-to-upload-a-file-in-nodejs-a-step-by-step-guide-5cf6"&gt;article&lt;/a&gt;, we covered the basics of uploading files in a Node.js application. Now, let’s take it a step further by extracting text from uploaded files. This tutorial will guide you through using the &lt;code&gt;officeparser&lt;/code&gt; library to parse and extract text from office documents, such as PDFs, in a Node.js environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: Install the &lt;code&gt;officeparser&lt;/code&gt; Library&lt;/p&gt;

&lt;p&gt;First, install the &lt;code&gt;officeparser&lt;/code&gt; library if you haven’t already:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install officeparser&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;: Create the Extraction Function&lt;/p&gt;

&lt;p&gt;Next, create a function to extract text from the uploaded file. Here’s the code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import { parseOfficeAsync } from "officeparser";
async function extractTextFromFile(path) {
 try {
 const data = await parseOfficeAsync(path);
 return data.toString();
 } catch (error) {
 return error;
 }
}
const fileText = await extractTextFromFile('files/Luqman-resume.pdf');
console.log(fileText);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function utilizes &lt;code&gt;parseOfficeAsync&lt;/code&gt; to asynchronously read and extract text from the specified file path. If successful, it converts the data to a string and returns it; otherwise, it catches and returns any errors encountered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: Integrate with Node.js endpoints&lt;br&gt;
You can follow the tutorial in this &lt;a href="https://dev.to/luqmanshaban/how-to-upload-a-file-in-nodejs-a-step-by-step-guide-5cf6"&gt;Article&lt;/a&gt; to create an endpoint that supports file upload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
By following this tutorial, you’ve extended your Node.js application to extract text from these files. This can be particularly useful for applications requiring document processing or data extraction from user-uploaded files.&lt;/p&gt;

&lt;p&gt;Stay tuned for more advanced features and enhancements in our next article!&lt;/p&gt;

&lt;p&gt;— -&lt;/p&gt;

&lt;p&gt;Stay Updated!&lt;/p&gt;

&lt;p&gt;If you enjoyed this tutorial and want to stay updated with more tips and guides, &lt;a href="https://mailchi.mp/9275d6947c46/luqmandev" rel="noopener noreferrer"&gt;subscribe to our newsletter&lt;/a&gt; for the latest content straight to your inbox.&lt;/p&gt;

</description>
      <category>node</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>filehandling</category>
    </item>
    <item>
      <title>How to Upload a File in nodejs: A step by step guide</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Mon, 27 May 2024 16:52:36 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/how-to-upload-a-file-in-nodejs-a-step-by-step-guide-5cf6</link>
      <guid>https://dev.to/luqmanshaban/how-to-upload-a-file-in-nodejs-a-step-by-step-guide-5cf6</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hi there! In this article we will delve into file handling in a nodejs server. We’ll briefly discuss a simple way to upload file or images in using &lt;code&gt;multer&lt;/code&gt;. A package that streamlines the file uploading process in nodejs application. To get started, initialize a nodejs app and install the following packages:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm i express nodemon cors multer


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once the installation is complete, make sure to modify your package.json file by adding: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

“type”: “module”, and “start” : “nodemon index.js”


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Your &lt;code&gt;package.json&lt;/code&gt; file should like something like this&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{
  "name": "file-upload",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1",
    "start": "nodemon index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.19.2",
    "multer": "^1.4.5-lts.1",
    "nodemon": "^3.1.0"
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Create a folder named upload in the root folder.&lt;/p&gt;

&lt;p&gt;The next step will be creating index.js file (&lt;em&gt;in the root folder&lt;/em&gt;) and importing the libraries we just installed.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import express from 'express'
import cors from 'cors'
import multer from 'multer'
We’ll then create instances:

const upload = multer({ storage: storage })
const app = express()
app.use(express.json())
app.use(cors())



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This code sets up file uploads and a basic Express app:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.File Storage:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Defines storage for &lt;code&gt;multer&lt;/code&gt; to save files on disk in the uploads directory.&lt;br&gt;
Generates unique filenames combining a timestamp and random number with the original filename.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.Express App:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates an Express app (app).&lt;/li&gt;
&lt;li&gt;Uses middleware:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;express.json()&lt;/code&gt;: parses JSON data from requests.&lt;br&gt;
&lt;code&gt;cors()&lt;/code&gt;: potentially allows requests from other websites (CORS).&lt;/p&gt;

&lt;p&gt;Now let’s create an endpoint that will accept file uploads and pass the multer middleware to it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

app.post('/api/file-upload', upload.single('file'), (req, res) =&amp;gt; {
    try {
        res.status(200).json({ success: "file upload successful" })
    } catch (error) {
        res.status(500).json({ error: error })
    }
})


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This code defines a route for uploading files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/api/file-upload&lt;/code&gt;: This is the URL for the upload route.
upload.single(‘file’): This middleware from multer handles single file uploads named “file” in the request. To upload multiple files, refer to the &lt;a href="https://www.npmjs.com/package/multer" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(req, res) =&amp;gt;&lt;/code&gt; …: This is the route handler function that executes when a POST request is made to the &lt;code&gt;/api/file-upload&lt;/code&gt; URL.try…catch: It attempts to upload the file and sends a success response (status 200) with a message if successful.catch (error): If an error occurs during upload, it sends an error response (status 500) with the error details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To starts the Express.js application and make it listen for incoming requests, add the following line of code:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

app.listen(4000, () =&amp;gt; console.log('RUNNING ON PORT 4000'))


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Your index.js file should now be similar to this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

import express from 'express'
import cors from 'cors'
import multer from 'multer'

const storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, 'uploads/')
    },
    filename: function(req, file, cb) {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
        cb(null, uniqueSuffix+file.originalname)
    }
})
const upload = multer({ storage: storage })
const app = express()
app.use(express.json())
app.use(cors())

app.post('/api/file-upload', upload.single('file'), (req, res) =&amp;gt; {
    try {
        res.status(200).json({ success: "file upload successful" })
    } catch (error) {
        res.status(500).json({ error: error })
    }
})
app.listen(4000, () =&amp;gt; console.log('RUNNING ON PORT 4000'))


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Open your terminal and run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm start&lt;/code&gt;&lt;br&gt;
If everything went right, it should log: RUNNING ON PORT 4000.&lt;/p&gt;

&lt;p&gt;To confirm that the code works as intended, we’ll test the API on postman. Open the app or it’s VsCode extension.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;select Body, check form-data and make sure the key’s name is set to file of type file. Upload your file or image then click send.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should see:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{
    "success": "file upload successful"
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Indicating that the file has been uploaded. If you navigate to the upload folder we created earlier, you should see the file or image in there. And that’s it, you have successfully implemented the uploading feature in Node.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
This article has successfully guided you through setting up file uploads in a Node.js application using the multer package. You learned how to:&lt;/p&gt;

&lt;p&gt;1.Install required dependencies (express, cors, multer, and nodemon).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configure file storage with unique filenames.&lt;/li&gt;
&lt;li&gt;Create an Express.js app and use middleware for JSON parsing and CORS.&lt;/li&gt;
&lt;li&gt;Define a route (/api/file-upload) to handle file uploads with multer.&lt;/li&gt;
&lt;li&gt;Implement error handling for successful uploads and potential errors.&lt;/li&gt;
&lt;li&gt;Start the server and test the functionality using Postman.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By following these steps, you’ve gained the ability to accept file uploads in your Node.js applications, enhancing their functionality and user experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never miss an article&lt;/strong&gt;: &lt;a href="https://mailchi.mp/9275d6947c46/luqmandev" rel="noopener noreferrer"&gt;Sign up for our programming newsletter today!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>webdev</category>
      <category>multer</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Uploading Files with React (POST Request)</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Wed, 01 May 2024 13:57:26 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/uploading-files-with-react-post-request-48gj</link>
      <guid>https://dev.to/luqmanshaban/uploading-files-with-react-post-request-48gj</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React applications are known for their interactivity and user-friendliness. But what if you want users to upload files, like images or document? Don't worry! In this article I'll guide you through the process of creating a React component that will handle file uploads. We'll break down the process, explore using libraries like &lt;strong&gt;axios&lt;/strong&gt;, and even touch upon handling upload progress and displaying success/error messages. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Set Up&lt;/strong&gt;&lt;br&gt;
To get started, I've used vite to create the react app and picked typescript. Follow the guide on how to set up react using vite. After you're done setting up the project, open it in a code editor of your choice. (I'll be using VsCode). For styling, we'll be using tailwind css, here's a guide on how to set it up. Once done, Open App.tsx and replace it's content with the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function App() {
  return (
    &amp;lt;h1 className="text-3xl font-bold underline"&amp;gt;
      Hello world!
    &amp;lt;/h1&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;open your terminal and run:&lt;br&gt;
&lt;code&gt;npm run dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;you should see something similar to this&lt;/p&gt;

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

&lt;p&gt;Open the port on your browser and you should see&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Creating the HTML Form&lt;/strong&gt;&lt;br&gt;
*&lt;em&gt;Step 1 *&lt;/em&gt;- Delete the h1 element and replace it with a form. To make things easier, I have already styled the form for you.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function App() {
  return (
    &amp;lt;div className="flex justify-center items-center pt-44"&amp;gt;
      &amp;lt;form&amp;gt;
        &amp;lt;div className='flex flex-col gap-y-4'&amp;gt;
          &amp;lt;div className="flex items-center justify-center w-full mt-5"&amp;gt;
            &amp;lt;label htmlFor="dropzone-file" className="flex flex-col items-center justify-center p-3 w-full h-36 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-[#ffffff] hover:bg-[#f9f9f9]"&amp;gt;
              &amp;lt;div className="flex flex-col items-center justify-center pt-5 pb-6"&amp;gt;
                &amp;lt;svg className="w-8 h-8 mb-4 text-[#7b7b7b] dark:text-[#9b9b9b]" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 16"&amp;gt;
                  &amp;lt;path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2" /&amp;gt;
                &amp;lt;/svg&amp;gt;
                &amp;lt;p className="mb-2 text-sm text-[#7b7b7b] dark:text-[#9b9b9b]"&amp;gt;&amp;lt;span className="font-semibold"&amp;gt;Click to upload&amp;lt;/span&amp;gt; or drag and drop&amp;lt;/p&amp;gt;
                &amp;lt;p className="text-xs text-[#7b7b7b] dark:text-[#9b9b9b]"&amp;gt;pdf, docx, doc (MAX.14MB)&amp;lt;/p&amp;gt;
              &amp;lt;/div&amp;gt;
              &amp;lt;input id="dropzone-file" type="file" className="hidden" accept='.pdf, .docx, .doc, .odt' required /&amp;gt;
            &amp;lt;/label&amp;gt;
          &amp;lt;/div&amp;gt;

          &amp;lt;button className="py-3 w-full bg-[blue] text-white rounded-lg text-center"&amp;gt;Submit&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The style is very minimal but it serves the purpose for now. &lt;em&gt;However, you may modify the style to match your own preferences.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding Functionality&lt;/strong&gt;&lt;br&gt;
Up to this point you might have noticed that no message is shown after the file has uploaded. To address this challenge, we'l use React's useState hook to dynamically display a message letting the user know that the file has being successfully uploaded. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt; - import useState from React. &lt;br&gt;
&lt;code&gt;import { useState } from "react"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Step 2 *&lt;/em&gt;- Create a state variable&lt;br&gt;
&lt;code&gt;const [isFileUploaded, setIsFileUploaded] = useState(false)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt; - conditionally render the message after file u&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pload
 {/* Notify the user after successful file upload */}
          {isFileUploaded &amp;amp;&amp;amp; &amp;lt;div className="flex flex-col gap-y-1 w-full"&amp;gt;
            &amp;lt;p className="text-center text-blue-800 text-sm"&amp;gt;File uploaded&amp;lt;/p&amp;gt;
            &amp;lt;div className="h-1.5 w-full bg-green-500 rounded-full"&amp;gt;&amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Storing the file in a state variable&lt;/strong&gt;&lt;br&gt;
To save the upload file, we'll create a state variable and method to listen for file uploads. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create the state variable
&lt;code&gt;const [file, setFile] = useState&amp;lt;File | null&amp;gt;(null)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the above code we declaring a state variable and assigning File or null type. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create HTML event method that listens for file uploads&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleFileInput = (e: React.ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
    const files = e.currentTarget.files
    if(files)
    setFile(files[0])
    // show success message on file upload
    setIsFileUploaded(true)
  } 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This code snippet handles what happens when a user selects a file for upload.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;handleFileInput&lt;/code&gt; is the function triggered when the user interacts with the file input element.
It receives an event object (e) containing details about the change.&lt;/li&gt;
&lt;li&gt;Inside the function, it accesses the files property from the event target (&lt;code&gt;e.currentTarget.files&lt;/code&gt;). This holds an array of uploaded files.&lt;/li&gt;
&lt;li&gt;Since we typically only want to handle a single file at a time, the code grabs the first element from the files array (&lt;code&gt;files[0]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;It then updates the React state variable &lt;code&gt;setFile&lt;/code&gt; with the chosen file.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Additionally, it sets another state variable, &lt;code&gt;setIsFileUploaded&lt;/code&gt; to true, likely to trigger a success message for the user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pass the function to &lt;code&gt;onChange&lt;/code&gt; event in the HTML input:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input id="dropzone-file" type="file" className="hidden" accept='.pdf, .docx, .doc, .odt' required onChange={handleFileInput}/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This code defines a hidden file input element that utilizes the &lt;code&gt;handleFileInput&lt;/code&gt; function.&lt;br&gt;
&lt;code&gt;&amp;lt;input ... /&amp;gt;&lt;/code&gt; defines an HTML input element specifically for file uploads.&lt;br&gt;
-&lt;code&gt;id="dropzone-file"&lt;/code&gt;: This assigns a unique identifier to the element, potentially for styling or referencing it later.&lt;br&gt;
-&lt;code&gt;type="file"&lt;/code&gt;: This specifies the input type as a file upload field.&lt;br&gt;
-&lt;code&gt;className="hidden"&lt;/code&gt;: This class likely hides the element from the user interface. You might use a separate dropzone component for user interaction and link this hidden input to it.&lt;br&gt;
-&lt;code&gt;accept='.pdf, .docx, .doc, .odt'&lt;/code&gt;: This restricts file selection to specific formats: PDF, DOCX, DOC, and ODT.&lt;br&gt;
required: This attribute enforces the user to select a file before submitting the form.&lt;br&gt;
-&lt;code&gt;onChange={handleFileInput}&lt;/code&gt;: This crucial part connects the input element to the handleFileInput function. Whenever the user selects a file, this function will be triggered to handle the chosen file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Send the file to the server&lt;/strong&gt;&lt;br&gt;
For this, we'll use axios. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install Axios - run the following command in your terminal&lt;br&gt;
&lt;code&gt;npm i axios&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;import axios - at the top of the file&lt;br&gt;
&lt;code&gt;import axios from 'axios';&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create a method that will handle the file submit&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleFileSubmit = async (e: React.FormEvent&amp;lt;HTMLFormElement&amp;gt;) =&amp;gt; {
    e.preventDefault()

    const formData = new FormData()
    if (file) {
      formData.append('file', file)
    }

    try {
      const response = await axios.post(`your_api_endpoint`, formData, { headers: { "Content-Type": "multipart/form-data" } })
      console.log(response);

    } catch (error: unknown) {
      console.error(error);
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This code snippet handles submitting the form with the uploaded file.&lt;br&gt;
-&lt;code&gt;handleFileSubmit&lt;/code&gt; is an asynchronous function triggered when the form is submitted (&lt;/p&gt;).&lt;br&gt;
-&lt;code&gt;e.preventDefault()&lt;/code&gt; prevents the default form submission behavior, allowing us to control the file upload process.&lt;br&gt;
-&lt;code&gt;const formData = new FormData()&lt;/code&gt; creates a new FormData object, specifically designed for handling file uploads.&lt;br&gt;
-&lt;code&gt;if (file) { formData.append('file', file) }&lt;/code&gt; checks if a file has been selected (file state variable) and if so, it adds the file to the formData object using the append method. The first argument ('file') specifies the key used on the server-side to access the file, and the second argument (file) is the actual file object.&lt;br&gt;
-&lt;code&gt;try...catch&lt;/code&gt; block handles the asynchronous nature of the file upload: try block attempts to send a POST request using &lt;code&gt;axios.post&lt;/code&gt;. The first argument ('your_api_endpoint') is a placeholder for your actual server-side endpoint that will receive the uploaded file. The second argument (formData) is the FormData object containing the file. The third argument &lt;code&gt;({ headers: { "Content-Type": "multipart/form-data" } })&lt;/code&gt; sets the Content-Type header in the request to multipart/form-data, which is essential for file uploads. &lt;code&gt;catch (error)&lt;/code&gt; block catches any errors that might occur during the upload process and logs them to the console for debugging.&lt;br&gt;
&lt;code&gt;console.log(response);&lt;/code&gt; (within the try block) logs the server's response to the console, allowing you to inspect the outcome (potentially success message or any additional data).&lt;br&gt;
In essence, this code snippet takes the uploaded file, prepares it for sending with FormData, and uses axios.post to submit it to your server-side API.

&lt;ol&gt;
&lt;li&gt; Pass the &lt;code&gt;handleFileSubmit&lt;/code&gt; method to the form
&lt;code&gt;&amp;lt;form onSubmit={handleFileSubmit}&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By now, you've equipped yourself with the skills to confidently integrate file uploads into your React applications. Remember, this is just the beginning! You can further enhance the user experience by adding features like drag-and-drop upload zones, progress bars, and informative error messages.&lt;br&gt;
Stay Connected, Keep Learning!&lt;br&gt;
If you have any questions or want to delve deeper into React development, feel free to join our WhatsApp group! We have a thriving community of developers eager to share knowledge and collaborate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chat.whatsapp.com/Iyv3qoHzM3P0I3M0wds9dF" rel="noopener noreferrer"&gt;Join the WhatsApp Group&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep up-to-date with the latest React trends and techniques. Happy coding!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>reactjsdevelopment</category>
      <category>forms</category>
    </item>
    <item>
      <title>Getting Started with Go Programming Language</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Fri, 29 Mar 2024 15:17:06 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/getting-started-with-go-programming-language-4ha</link>
      <guid>https://dev.to/luqmanshaban/getting-started-with-go-programming-language-4ha</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Go&lt;/code&gt;, a statically typed, high-level programming language developed by Google in 2009, is considered one of the best choices for building back-end applications. This includes web development (APIs), cloud services (like Docker), and many other use cases. &lt;code&gt;Go’s&lt;/code&gt; speed also makes it well-suited for complex applications.&lt;/p&gt;

&lt;p&gt;In this blog, I will walk you through the process of initializing a &lt;code&gt;Go&lt;/code&gt; project and printing out a simple Hello, World statement. To follow along, make sure you have &lt;code&gt;Go&lt;/code&gt; installed in your machine. Let’s start of by creating a simple hello world project.&lt;/p&gt;

&lt;p&gt;Open your terminal, create a new folder named helloWorld and initialize Go inside the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir helloWorld
cd helloWorld
go mod init helloWorld

#output
#go: creating new go.mod: module helloWorld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Let’s create a simple program that prints hello world.
— Open the project in your preferred code editor
— create a main.go file
— Paste the following code inside the file
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
        "fmt"
)

func main() {
        fmt.Println("Hello, World!")
        //prints Hello, World
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. package main:&lt;/strong&gt;&lt;br&gt;
This line declares the package name for this code file. In Go, code is organized into packages, which act like folders to group related functionality.&lt;br&gt;
The name main is special and signifies that this package contains the entry point for the program. This means the code within this package will be executed when you run the program.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. import (“fmt”)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This line imports a package called &lt;code&gt;fmt&lt;/code&gt;. Go has a standard library with various pre-written functionalities. The &lt;code&gt;fmt&lt;/code&gt; package provides functions for formatted printing and input/output operations.&lt;br&gt;
By importing &lt;code&gt;fmt&lt;/code&gt;, you gain access to the functions defined within that package. In this case, we'll be using a function from &lt;code&gt;fmt&lt;/code&gt; later in the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. func main() {}&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This line defines a function named main. Functions are reusable blocks of code that perform specific tasks.&lt;br&gt;
The main function has a special role in Go programs. It's the starting point where the program's execution begins.&lt;br&gt;
The curly braces {} mark the beginning and end of the function body, where you place the code that the function will execute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. fmt.Println(“Hello, World!”)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This line is where the actual action happens. It calls a function named &lt;code&gt;Println&lt;/code&gt; from the imported &lt;code&gt;fmt&lt;/code&gt; package.&lt;br&gt;
&lt;code&gt;Println&lt;/code&gt; takes one argument, which in this case is a string literal "Hello, World!". A string literal is text enclosed in double quotes.&lt;br&gt;
The &lt;code&gt;Println&lt;/code&gt; function prints the provided string &lt;code&gt;("Hello, World!")&lt;/code&gt; to the console, followed by a newline character.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You’ve successfully created your first Go program and printed “Hello, World!” to the console. This provides a solid foundation for exploring Go’s functionalities further. In the next section, we’ll delve deeper into Go’s basic building blocks, like variables, data types, and control flow statements. By understanding these fundamentals, you’ll be well-equipped to write more complex Go programs.&lt;/p&gt;

</description>
      <category>go</category>
      <category>backend</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Fetching and rendering data from an API in React.js</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Fri, 27 Oct 2023 19:14:46 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/fetching-and-rendering-data-from-an-api-in-reactjs-4oik</link>
      <guid>https://dev.to/luqmanshaban/fetching-and-rendering-data-from-an-api-in-reactjs-4oik</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Working with data has become a vital aspect of modern web apps, and knowing how to work with data can make you stand out from other developers. In this article, we’ll be covering the topic by creating a quote generator web application. You can view the live app here , and for those interested in the code, the GitHub repo is available here&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set-up&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;create a new React app&lt;/li&gt;
&lt;li&gt;Install the dependencies:
&lt;code&gt;npm i axios react-icons&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;set up tailwind CSS &lt;strong&gt;(Optional&lt;/strong&gt;)
&lt;em&gt;I’ll be using it for styling follow this guide to set it up&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;App.js&lt;/code&gt; file, import the following dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useState } from 'react';
import axios from 'axios';
import { ImQuotesLeft, ImQuotesRight } from 'react-icons/im'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create two states inside the App component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [quotes, setQuotes] = useState([])
const [randomQuote, setRandomQuote] = useState()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The quotes state will store the quotes retrieved from the dummy API while the &lt;code&gt;randomQuote&lt;/code&gt; will store the quote to be rendered.&lt;/p&gt;

&lt;p&gt;To send a request to the API, let’s create an asynchronous function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const getQuotes = async () =&amp;gt; {
    try {
      const response = await axios.get('https://dummyjson.com/quotes')
      setQuotes(response.data.quotes)
    } catch (error) {
      console.error(error);
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a function that will pick a random quote from the array of quotes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const generateRandomQuote = () =&amp;gt; {
    const randomIndex = Math.floor(Math.random() * quotes.length)
    setRandomQuote(quotes[randomIndex])
    console.log(quotes[randomIndex]);
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The variable &lt;code&gt;randomIndex&lt;/code&gt; generates a random index to select a quote from the quotes array&lt;br&gt;
&lt;code&gt;setRandomQuote(quotes[randomIndex]&lt;/code&gt;) sets the &lt;code&gt;randomQuote&lt;/code&gt; state to the quote at the randomly chosen index from the code before it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Call the getQuotes method
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;useEffect(() =&amp;gt; {
    getQuotes()
  },[])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Create the button&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Inside the div container, create a button that will generate a random and add a click event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
    &amp;lt;div className="md:p-32 px-10 flex items-center justify-center flex-col gap-y-20 bg-black w-full h-[100vh] font-sans"&amp;gt;
      &amp;lt;button onClick={generateRandomQuote} className='text-white border border-white  p-2 rounded-lg hover:text-black hover:bg-white transition ease-in-out duration-75'&amp;gt;Generate Quote&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Rendering the random quote
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
    &amp;lt;div className="md:p-32 px-10 flex items-center justify-center flex-col gap-y-20 bg-black w-full h-[100vh] font-sans"&amp;gt;
      {randomQuote &amp;amp;&amp;amp;
        &amp;lt;article className='bg-slate-200 shadow-md shadow-slate-50 md:w-auto w-full-10 h-auto rounded-xl p-10 text-black'&amp;gt;
          &amp;lt;p className='flex items-start md:flex-row flex-col gap-x-2 bg-slate-400 p-2 rounded-md shadow-md font-medium mb-3'&amp;gt;
            &amp;lt;ImQuotesLeft /&amp;gt; 
            {randomQuote.quote} 
            &amp;lt;ImQuotesRight /&amp;gt;
          &amp;lt;/p&amp;gt;
          &amp;lt;p className='text-gray-500 font-bold'&amp;gt;{randomQuote.author}&amp;lt;/p&amp;gt;
        &amp;lt;/article&amp;gt;
      }
      &amp;lt;button onClick={generateRandomQuote} className='text-white border border-white  p-2 rounded-lg hover:text-black hover:bg-white transition ease-in-out duration-75'&amp;gt;Generate Quote&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In the above code, we conditionally rendered random &lt;code&gt;{ randomQuote &amp;amp;&amp;amp; &amp;lt;article&amp;gt;&amp;lt;/article&amp;gt;}&lt;/code&gt; this part ensures that the quote only renders when the &lt;code&gt;randomQuote&lt;/code&gt; state has a value assigned to it to prevent errors and optimize performance.&lt;br&gt;
Inside the article, the first &lt;/p&gt;
&lt;p&gt; element renders the random quote. &lt;code&gt;&amp;lt;ImQuotesLeft /&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;ImQuotesRight /&amp;gt;&lt;/code&gt; are the quote icons from the react-icon library.&lt;br&gt;
&lt;code&gt;{randomQuote.quote}&lt;/code&gt; renders the actual quote itself. If you run the app and the browser's console, you'll see the following data from the API:&lt;br&gt;
&lt;code&gt;{id: 4, quote: 'Two roads diverged in a wood, and I—I took the one…raveled by, And that has made all the difference.', author: 'Robert Frost'&lt;/code&gt;}&lt;br&gt;
It's an Object with the keys id, quote, and author. Hence the &lt;code&gt;randomQuote.quote&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The second &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tags, renders the Author's name, in the same manner, the elements before it did by accessing the value of the the author from the Object:&lt;code&gt;{randomQuote.author}&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Final Code:&lt;br&gt;
This is how the file looks:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useEffect, useState } from 'react';
import axios from 'axios';
import { ImQuotesLeft, ImQuotesRight } from 'react-icons/im'

function App() {
  const [quotes, setQuotes] = useState([])
  const [randomQuote, setRandomQuote] = useState()

  const getQuotes = async () =&amp;gt; {
    try {
      const response = await axios.get('https://dummyjson.com/quotes')
      setQuotes(response.data.quotes)
    } catch (error) {
      console.error(error);
    }
  }

  const generateRandomQuote = () =&amp;gt; {
    const randomIndex = Math.floor(Math.random() * quotes.length)
    setRandomQuote(quotes[randomIndex])
    console.log(quotes[randomIndex]);
  }

  useEffect(() =&amp;gt; {
    getQuotes()
  },[])
  return (
    &amp;lt;div className="md:p-32 px-10 flex items-center justify-center flex-col gap-y-20 bg-black w-full h-[100vh] font-sans"&amp;gt;
      {randomQuote &amp;amp;&amp;amp;
        &amp;lt;article className='bg-slate-200 shadow-md shadow-slate-50 md:w-auto w-full-10 h-auto rounded-xl p-10 text-black'&amp;gt;
          &amp;lt;p className='flex items-start md:flex-row flex-col gap-x-2 bg-slate-400 p-2 rounded-md shadow-md font-medium mb-3'&amp;gt;
            &amp;lt;ImQuotesLeft /&amp;gt; 
            {randomQuote.quote} 
            &amp;lt;ImQuotesRight /&amp;gt;
          &amp;lt;/p&amp;gt;
          &amp;lt;p className='text-gray-500 font-bold'&amp;gt;{randomQuote.author}&amp;lt;/p&amp;gt;
        &amp;lt;/article&amp;gt;
      }
      &amp;lt;button onClick={generateRandomQuote} className='text-white border border-white  p-2 rounded-lg hover:text-black hover:bg-white transition ease-in-out duration-75'&amp;gt;Generate Quote&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
In this article, we’ve explored the fascinating world of web development and data manipulation by creating a quote generator web application. We began by emphasizing the increasing importance of working with data in modern web applications, highlighting the significance of this skill for developers. I hope the article helped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/luqmanshaban/ReactTutorials/tree/main/fetching-data" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Join our community by subscribing to the newsletter to receive regular updates, fresh insights, and exclusive content.&lt;/p&gt;

&lt;p&gt;Let’s Connect:&lt;br&gt;
&lt;a href="https://linkedin.com/in/luqman-shaban" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
&lt;a href="https://luqmanshaban.com" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>reactjsdevelopment</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>React Router: A step-by-step guide</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Sat, 21 Oct 2023 17:35:22 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/react-router-a-step-by-step-guide-307a</link>
      <guid>https://dev.to/luqmanshaban/react-router-a-step-by-step-guide-307a</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React Router is a crucial tool for building dynamic, single-page applications in React. It provides a seamless way to manage navigation, routing, and user interactions within your web application. In this article, we will explore the fundamentals of React Router, its core features, and how to implement routing in your React applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is React Router?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React Router is a popular library for managing client-side routing in React applications. It allows you to create complex, multi-page web applications that feel like traditional websites while still being single-page applications (SPAs) under the hood. With React Router, you can define and manage routes, enabling users to navigate through different views of your application without having to request a new HTML page from the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Concepts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before diving into the implementation, let’s understand some essential concepts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Route:&lt;/strong&gt; A route is a mapping between a URL and a component. When a user visits a specific URL, React Router renders the corresponding component.&lt;br&gt;
&lt;strong&gt;2. Router:&lt;/strong&gt; The router is the top-level component that provides the routing infrastructure. In React Router, you typically use BrowserRouter for web applications and HashRouter for static sites.&lt;br&gt;
Nested Routes: React Router allows you to nest routes, creating a hierarchy of components. This is especially useful for layout structures.&lt;br&gt;
&lt;strong&gt;3. Link:&lt;/strong&gt; The Link component enables navigation by creating anchor-like elements that maintain the application's state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;br&gt;
To use React Router in your project, you need to follow these steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.Installation:&lt;/strong&gt; Begin by installing React Router using npm or yarn:&lt;br&gt;
&lt;code&gt;npm install react-router-dom&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;**2. Set-Up: **Open &lt;code&gt;index.js&lt;/code&gt; and wrap the App component with it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
 import ReactDOM from 'react-dom/client';
 import './index.css';
 import App from './App';
 import reportWebVitals from './reportWebVitals';
 import { BrowserRouter } from 'react-router-dom';

 const root = ReactDOM.createRoot(document.getElementById('root'));
 root.render(
   &amp;lt;React.StrictMode&amp;gt;
     &amp;lt;BrowserRouter&amp;gt;
     &amp;lt;App /&amp;gt;
     &amp;lt;/BrowserRouter&amp;gt;
   &amp;lt;/React.StrictMode&amp;gt;
 );

 // If you want to start measuring performance in your app, pass a function
 // to log results (for example: reportWebVitals(console.log))
 // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
 reportWebVitals();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Creating the Navbar:&lt;/strong&gt; create a &lt;code&gt;Navbar.js&lt;/code&gt; file in your src folder and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import { Link } from "react-router-dom";

 const Navbar = () =&amp;gt; {
   return (
     &amp;lt;nav&amp;gt;
       &amp;lt;ul&amp;gt;
         &amp;lt;li&amp;gt;
           &amp;lt;Link to="/"&amp;gt;Home&amp;lt;/Link&amp;gt;
         &amp;lt;/li&amp;gt;
         &amp;lt;li&amp;gt;
           &amp;lt;Link to="/about"&amp;gt;About&amp;lt;/Link&amp;gt;
         &amp;lt;/li&amp;gt;
         &amp;lt;li&amp;gt;
           &amp;lt;Link to="/contact"&amp;gt;Contact&amp;lt;/Link&amp;gt;
         &amp;lt;/li&amp;gt;
       &amp;lt;/ul&amp;gt;
     &amp;lt;/nav&amp;gt;
   );
 }

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

&lt;/div&gt;



&lt;p&gt;In the above code, we’ve imported Link from react-router-dom, to enable navigation to different sections of the web app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Create the Pages:&lt;/strong&gt; Go ahead and create the files: Home, About and Contact. Inside the files, create the react components and import the Navbar component in each file.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;i. Home.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; //Home.js
 import React from 'react'
 import Navbar from './Navbar'

 const Home = () =&amp;gt; {
   return (
     &amp;lt;div&amp;gt;
         &amp;lt;Navbar /&amp;gt;
         &amp;lt;h1&amp;gt;Home&amp;lt;/h1&amp;gt;
     &amp;lt;/div&amp;gt;
   )
 }

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;ii. About.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; //About.js
 import React from 'react'
 import Navbar from './Navbar'

 const About = () =&amp;gt; {
   return (
     &amp;lt;div&amp;gt;
         &amp;lt;Navbar /&amp;gt;
         &amp;lt;h1&amp;gt;About&amp;lt;/h1&amp;gt;
     &amp;lt;/div&amp;gt;
   )
 }

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;iii. Contact.js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; //Contact.js
 import React from 'react'
 import Navbar from './Navbar'

 const Contact = () =&amp;gt; {
   return (
     &amp;lt;div&amp;gt;
         &amp;lt;Navbar /&amp;gt;
         &amp;lt;h1&amp;gt;Contact&amp;lt;/h1&amp;gt;
     &amp;lt;/div&amp;gt;
   )
 }

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Create the routes in App.js:&lt;/strong&gt; Open &lt;code&gt;App.js&lt;/code&gt; and import &lt;code&gt;Routes&lt;/code&gt;, &lt;code&gt;Route&lt;/code&gt;, from &lt;code&gt;react-router-dom&lt;/code&gt;.&lt;br&gt;
Import &lt;code&gt;Home&lt;/code&gt;, &lt;code&gt;About&lt;/code&gt;, and &lt;code&gt;Contact&lt;/code&gt; components as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//App.js
 import { Route, Routes } from 'react-router-dom';
 import './App.css';
 import Home from './Home';
 import About from './About';
 import Contact from './Contact';

 function App() {
   return (
     &amp;lt;div className="App"&amp;gt;

     &amp;lt;/div&amp;gt;
   );
 }

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

&lt;/div&gt;



&lt;p&gt;Inside the div element, add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div className="App"&amp;gt;
       &amp;lt;Routes&amp;gt;
         &amp;lt;Route path='/' element={&amp;lt;Home/&amp;gt;} /&amp;gt;
         &amp;lt;Route path='/about' element={&amp;lt;About/&amp;gt;} /&amp;gt;
         &amp;lt;Route path='/contact' element={&amp;lt;Contact/&amp;gt;} /&amp;gt;
       &amp;lt;/Routes&amp;gt;
     &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Route elements are wrapped inside Routes.&lt;br&gt;
path represents the URL path to the component it represents.&lt;br&gt;
element describes the component that the path points to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Run the Application:&lt;/strong&gt; When the app runs, the navbar links will dynamically navigate you to its corresponding page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React Router is a powerful tool for managing client-side routing in your React applications. It allows you to create seamless, dynamic user experiences by handling navigation, route parameters, nested routes, and more. By following the steps outlined in this article, you can get started with React Router and build highly interactive and user-friendly single-page applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/luqmanshaban/ReactTutorials/tree/main/router" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://luqmanshaban.blog/series/react-tutorials" rel="noopener noreferrer"&gt;Join our community&lt;/a&gt;&lt;/strong&gt; by subscribing to the newsletter to receive regular updates, fresh insights, and exclusive content.&lt;/p&gt;

&lt;p&gt;Let’s Connect:&lt;br&gt;
&lt;strong&gt;&lt;a href="https://www.linkedin.com/in/luqman-shaban/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://twitter.com/luqmanshaban01" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://www.facebook.com/luqman.dv/" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://luqmanshaban.com/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>React Context API: A step-by-step guide</title>
      <dc:creator>Luqman Shaban</dc:creator>
      <pubDate>Sun, 15 Oct 2023 14:26:52 +0000</pubDate>
      <link>https://dev.to/luqmanshaban/react-context-api-a-step-by-step-guide-i1i</link>
      <guid>https://dev.to/luqmanshaban/react-context-api-a-step-by-step-guide-i1i</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is Context?&lt;/strong&gt;&lt;br&gt;
At its core, Context is a way to share data between components without explicitly drilling through components props. It's a global state management system within your React application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use Context?&lt;/strong&gt;&lt;br&gt;
You should consider using Context API when you have data or Settings that need to be accessed by multiple components at different levels of your Application's component hierarchy. This may be applied to features like User Authentication, theme preference, language settings etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;br&gt;
To understand clearly how the Context API works, We'll create a simple Theme functionality that is commonly used in many React Applications.&lt;br&gt;
Let's go through the steps of implementing the Context API:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create A context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a folder store in your src directory and inside create a file called: ThemeContext.js and import the necessary dependencies:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import React, { createContext, useState } from 'react'&lt;/code&gt;&lt;br&gt;
We'll create and export a theme Context that we'll use to share data across our Application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { createContext, useState } from 'react'

 export const ThemeContext = createContext()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Provide the Context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After creating the context, we now have to create a Provider. This is a typical component that wraps the portion of your application where you want to make certain data available to other components. In our case, we'll wrap our Provider in index.js as we want the Theme context to be accessed globally.&lt;/p&gt;

&lt;p&gt;To create a Provider, we'll simply create a react component and name it ThemeProvider. We then pass props to the component named children.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  export const ThemeProvider = ({ children }) =&amp;gt; {
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the provider, we initialize a state variable and set it to false:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   export const ThemeProvider = ({ children }) =&amp;gt; {
        const [isDarkTheme, setIsDarkTheme] = useState(false)
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a function toggleTheme that will update the state every time its called.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    export const ThemeProvider = ({ children }) =&amp;gt; {
        const [isDarkTheme, setIsDarkTheme] = useState(false)

        const toggleTheme = () =&amp;gt; setIsDarkTheme(prevTheme =&amp;gt; !prevTheme)
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Consume the Context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To consume the Context, return the provider with the data you want to share with other components and wrap the children props inside.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; export const ThemeProvider = ({ children }) =&amp;gt; {
     const [isDarkTheme, setIsDarkTheme] = useState(false)

     const toggleTheme = () =&amp;gt; setIsDarkTheme(prevTheme =&amp;gt; !prevTheme)

     return (
         &amp;lt;ThemeContext.Provider value={{ isDarkTheme, toggleTheme }}&amp;gt;
             {children}
         &amp;lt;/ThemeContext.Provider&amp;gt;
     )
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you go! You've created a context API in React.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Using the Context In the App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To be able to access the data in the Context API, we will have to wrap the portion of our Application with the &lt;strong&gt;ThemeProvider&lt;/strong&gt; for the components to consume the data. So we'll wrap the App component with the Provider.&lt;/p&gt;

&lt;p&gt;Open your &lt;code&gt;index.js&lt;/code&gt; file, import the &lt;code&gt;ThemeProvider&lt;/code&gt; and Wrap the App component with it.&lt;br&gt;
Here's how the &lt;code&gt;index.js&lt;/code&gt; file should look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import React from 'react';
 import ReactDOM from 'react-dom/client';
 import App from './App';
 import { ThemeProvider } from './store/ThemeContext';

 const root = ReactDOM.createRoot(document.getElementById('root'));
 root.render(
   &amp;lt;React.StrictMode&amp;gt;
     &amp;lt;ThemeProvider&amp;gt;
      &amp;lt;App /&amp;gt;
     &amp;lt;/ThemeProvider&amp;gt;
   &amp;lt;/React.StrictMode&amp;gt;
 );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this setup, we can access the data throughout the entire application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Use Case 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the src directory, create a&lt;code&gt;Button.js&lt;/code&gt;file and inside import the following dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import React, { useContext } from 'react'
 import { ThemeContext } from './store/ThemeContext'
 import './App.css'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure you have &lt;code&gt;App.css&lt;/code&gt;in the same folder for styling the button.&lt;/p&gt;

&lt;p&gt;Create a React component called Button and add a button element to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import React, { useContext } from 'react'
    import { ThemeContext } from './store/ThemeContext'
    import './App.css'

    const Button = () =&amp;gt; {

      return (
        &amp;lt;button&amp;gt;
          change Theme
        &amp;lt;/button&amp;gt;
      )
    }

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

&lt;/div&gt;



&lt;p&gt;Import the data from &lt;code&gt;isDarkTheme&lt;/code&gt; and &lt;code&gt;toggleTheme&lt;/code&gt; from &lt;code&gt;ThemeContext&lt;/code&gt; API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  import React, { useContext } from 'react'
    import { ThemeContext } from './store/ThemeContext'
    import './App.css'

    const Button = () =&amp;gt; {
      //Consuming the Data from The context API
      const { isDarkTheme, toggleTheme } = useContext(ThemeContext) 
      return (
        &amp;lt;button&amp;gt;
          change Theme
        &amp;lt;/button&amp;gt;
      )
    }

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

&lt;/div&gt;



&lt;p&gt;Now that we have accessed the data, we can apply it to our button element. We'll add the &lt;code&gt;onClick&lt;/code&gt; event to the button and some styling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import React, { useContext } from 'react'
    import { ThemeContext } from './store/ThemeContext'
    import './App.css'

    const Button = () =&amp;gt; {
      const { isDarkTheme, toggleTheme } = useContext(ThemeContext)
      return (
        //adding onClick Event and the theme custom styles to the button
        &amp;lt;button onClick={toggleTheme} className={`${isDarkTheme ? 'lightBtn' : 'darkBtn'}`}&amp;gt;
          change Theme
        &amp;lt;/button&amp;gt;
      )
    }

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6. Use Case 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;App.js&lt;/code&gt; and add the following dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import { useContext } from 'react';
 import './App.css';
 import Button from './Button';
 import { ThemeContext } from './store/ThemeContext';

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the App component, import isDarkTheme from the ThemeContext API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; function App() {
   const { isDarkTheme } = useContext(ThemeContext)
 }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;return a div component with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; return (
       //Added the styles based on isDarkTheme Boolean value
       &amp;lt;div className={`App ${isDarkTheme ? 'darkTheme' : 'lightTheme'}`}&amp;gt;
         &amp;lt;h1&amp;gt;Theme Context Api&amp;lt;/h1&amp;gt;
         &amp;lt;p&amp;gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem quam quisquam enim minus, consectetur dignissimos vero beatae possimus reprehenderit sed officia eveniet obcaecati neque architecto ut, magnam odit optio veniam.&amp;lt;/p&amp;gt;
         &amp;lt;Button /&amp;gt;
       &amp;lt;/div&amp;gt;
   );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's how the entire file looks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import { useContext } from 'react';
 import './App.css';
 import Button from './Button';
 import { ThemeContext } from './store/ThemeContext';

 function App() {
   const { isDarkTheme } = useContext(ThemeContext)

   return (
       &amp;lt;div className={`App ${isDarkTheme ? 'darkTheme' : 'lightTheme'}`}&amp;gt;
         &amp;lt;h1&amp;gt;Theme Context Api&amp;lt;/h1&amp;gt;
         &amp;lt;p&amp;gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorem quam quisquam enim minus, consectetur dignissimos vero beatae possimus reprehenderit sed officia eveniet obcaecati neque architecto ut, magnam odit optio veniam.&amp;lt;/p&amp;gt;
         &amp;lt;Button /&amp;gt;
       &amp;lt;/div&amp;gt;
   );
 }

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Finally&lt;/strong&gt;, open &lt;code&gt;App.css&lt;/code&gt; and paste the following styles. You can modify them to suit your specific needs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    .App {
      padding: 50px;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      gap: 20px;
      height: 100vh;
    }

    .darkTheme {
      background-color: black;
      color: aliceblue;
    }

    .lightTheme {
      background-color: aliceblue;
      color: black;
    }

    button {
      padding: 10px;
      border-radius: 10px;
      border: 1px solid;
      cursor: pointer;
      font-size: 16px;
    }

    .darkBtn {
      background-color: black;
      color: aliceblue;
    }
    .lightBtn {
      background-color: aliceblue;
      color: black;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the App&lt;/p&gt;

&lt;p&gt;When you run the App in the browser, the theme will change on each button click demonstrating that the data is being shared between the Button component as well as in the App component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
In this article, we explored the concept of using Context API to efficiently share data between components while avoiding prop drilling. To help you understand how the Context API works, we implemented a simple functionality that is commonly used in many React Applications and verified that we were able to share global state across your application.&lt;br&gt;
&lt;a href="https://github.com/luqmanshaban/ReactTutorials/tree/main/context-api" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Never miss an article, &lt;a href="https://mailchi.mp/9275d6947c46/luqmandev" rel="noopener noreferrer"&gt;subscribe to our newsletter&lt;/a&gt; to receive regular updates, fresh insights, and exclusive content.&lt;/p&gt;

&lt;p&gt;Let's Connect:&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/luqman-shaban/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
&lt;a href="https://twitter.com/luqmanshaban01" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.instagram.com/luqman_shaban/" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.facebook.com/luqman.dv/" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;&lt;br&gt;
&lt;a href="https://luqmanshaban.com/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>statemanagement</category>
      <category>reactjsdevelopment</category>
    </item>
  </channel>
</rss>
