<?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: Haris Ahmad</title>
    <description>The latest articles on DEV Community by Haris Ahmad (@harisahmadev).</description>
    <link>https://dev.to/harisahmadev</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%2F624113%2F3f6f23c2-6988-4223-8299-254276d630fe.jpeg</url>
      <title>DEV Community: Haris Ahmad</title>
      <link>https://dev.to/harisahmadev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/harisahmadev"/>
    <language>en</language>
    <item>
      <title>How to broadcast live data on your application?</title>
      <dc:creator>Haris Ahmad</dc:creator>
      <pubDate>Sun, 16 Apr 2023 22:14:41 +0000</pubDate>
      <link>https://dev.to/harisahmadev/how-to-broadcast-live-data-on-your-application-172i</link>
      <guid>https://dev.to/harisahmadev/how-to-broadcast-live-data-on-your-application-172i</guid>
      <description>&lt;p&gt;You just bought a new home and you go in the basement. You are shocked to see that it is filled up to the ceiling with a lot of things. Guess what, the previous home owner was a hoarder. He left without cleaning and now you have to deal with his unwanted toasters, buckets, mattresses and his old nasty smelling shoes.&lt;/p&gt;

&lt;p&gt;But you have an advantage. You are a Software Developer. You can make an Auction website and auction all of this stuff to earn money. May be not those smelly shoes. They need to go to garbage or personally get thrown through the window of the previous home owner's current home 😮‍💨.&lt;/p&gt;

&lt;p&gt;Now, you get to the drawing board and you figured that an Auction would require the following things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Frontend Client, to display the data (Bids)&lt;/li&gt;
&lt;li&gt;A Backend Server, to store the data&lt;/li&gt;
&lt;li&gt;A flow of data from Server to Client when the data changes (Auction Bids change)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  First Attempt
&lt;/h3&gt;

&lt;p&gt;Coming from a background where you have a day job of creating NodeJS, React apps, for this application you also create a NodeJS REST API and a React Frontend application. This setting is a Client/Server architecture in which Client (ReactJS app) will always request for data to the Server (NodeJS API) but never the otherwise.&lt;/p&gt;

&lt;p&gt;The first two items in the above list are marked done. Now you start to work on the 3rd item: How the data flow will happen?&lt;/p&gt;

&lt;p&gt;Since it is a Client/Server architecture to update the data on clients, clients have to request the data every time they want to update the data (Show next bids). &lt;/p&gt;

&lt;p&gt;The solution you adopt is, having an infinite loop on the client, constantly checking server for the data change every 1 second. If there is a change the clients will pull the new data. (Client oriented broadcast).&lt;/p&gt;

&lt;p&gt;On launch date 10,000 bidders show up on your website. You are happy to see the $$$ amount going up and imagining yourself driving your brand new Lamborghini when the reality hits. The server went down. Wait...What happened?? &lt;/p&gt;

&lt;p&gt;Your website went down because the server was overloaded with the amount of requests it has to serve for 10,000 clients. Every client is requesting new data every second, which means your server is getting 10,000 HTTP requests in one second, 60,000 in one minute. Poor server.&lt;/p&gt;

&lt;p&gt;You pray to God that somehow he gives you a solution and God sends this Article to you. (Or let you find it of the internet).&lt;/p&gt;

&lt;h3&gt;
  
  
  Second Attempt
&lt;/h3&gt;

&lt;p&gt;In this attempt, we do things a little differently. We figure out what are the bottlenecks.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Too many requests to the server&lt;/li&gt;
&lt;li&gt;Too frequent requests to the server&lt;/li&gt;
&lt;/ol&gt;

&lt;h5&gt;
  
  
  In-Person vs Online Auction
&lt;/h5&gt;

&lt;p&gt;If we take an example of a real life, in-person auction, we can find some similarities. Host of the auction act as a server where the people sitting there bidding, act as clients. But notice an important thing about the broadcast. In in-person auction, the information is flowing from the host of the auction to the bidders via voice. It makes more sense for the host to shout out the bids, rather than each bidder whispering the host to ask what is the current bid on this product. &lt;strong&gt;Host shouting saves a lot of time and a lot of effort while the bidders keeps synced with the auction.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will use the same pattern here. &lt;strong&gt;If we shift the responsibility of broadcast to the Server, Clients do not have to request the information every second.&lt;/strong&gt; Server should know when the data is changed and on this data change, it should send the new data to all the clients. Clients should just receive this data and display it.&lt;/p&gt;

&lt;h5&gt;
  
  
  Is HTTP good for the Broadcast?
&lt;/h5&gt;

&lt;p&gt;Using HTTP (as we do in REST API), it is not possible because HTTP communication starts from client by placing an HTTP request on the server. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZOC637XH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrjxgtcatqfjk43at3l0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZOC637XH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrjxgtcatqfjk43at3l0.png" alt="Image description" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have to use a different protocol for this problem, which allows communication to be originated from the server. 'Web Sockets' come to our rescue&lt;/p&gt;

&lt;p&gt;Since I am a developer, it is my utmost duty to use ChatGPT for it's definition. According to ChatGPT:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WebSockets are a protocol for bi-directional, real-time communication between web browsers and servers over a single, long-lived connection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We setup a Web Socket server. Like ExpressJS on NodeJS we have a very amazing package for it called &lt;strong&gt;Socket.IO.&lt;/strong&gt; &lt;/p&gt;

&lt;h5&gt;
  
  
  Implementing Web Sockets in our App
&lt;/h5&gt;

&lt;p&gt;Every time a client is connected to the Socket server it assigns the connection an ID using which we can interact with the connection for sending and receiving the data.&lt;/p&gt;

&lt;p&gt;Each time the server detects a change in the data, server should engage all the client connections and send the new data to these client (Broadcasting).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UWbSZbkm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6j2vxjoo84cfs5s18ab2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UWbSZbkm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6j2vxjoo84cfs5s18ab2.png" alt="Image description" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One design pattern we can use for this application could be Publish/Subscribe pattern. In this pattern the clients gets subscribed to a stream of data and whenever there is a new data, server pushes the data to the subscribed clients.&lt;/p&gt;

&lt;p&gt;A simple implementation of this approach would be to create an array to keep track of active connections. Whenever a new client appears we add the connection to the client to this array. If the client closes the connection, we remove that connection from the array.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PwSQDiDK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qyls1368899vme6685io.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PwSQDiDK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qyls1368899vme6685io.png" alt="Image description" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whenever there is a new data available, we can iterate through this array and one-by-one push the data on the iterated connection. A pseudo code implementation would be something like this:&lt;br&gt;
&lt;/p&gt;

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

Function onNewConnection(connection){
    connections.push(connection)
}

Function onConnectionRemoved(connection){
    connections.delete(connection)
}

Function onDataChange(newData){
    for(connection in connections){
        connection.send(newData)
    }    
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next day you implement this fix and you run the auction and following things happen&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now the number of requests are significantly reduced because the new data is not requested every second. It will be requested only when the data changes (New bids appear). &lt;/li&gt;
&lt;li&gt;The auction is also perfectly synced because there is no delay between the point where auction updates and the point where auction data is broadcasted. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The auction ends and at the end of the day, you have One Million Dollars in the bank. You can now have a Lamborghini and you should thank me for that.&lt;/p&gt;

&lt;p&gt;So overall, it is a good idea for a broadcasting service to make the data keeper be the responsible for data broadcasting, rather than the consumer of the broadcast should have to request the data. One way to do it is Socket based communication. &lt;/p&gt;

&lt;h3&gt;
  
  
  Connect
&lt;/h3&gt;

&lt;p&gt;Blog👉 &lt;a href="https://hariscodes.com/"&gt;https://hariscodes.com/&lt;/a&gt;&lt;br&gt;
Twitter👉 &lt;a href="https://twitter.com/tweetharisahmad"&gt;https://twitter.com/tweetharisahmad&lt;/a&gt;&lt;br&gt;
Instagram👉 &lt;a href="https://www.instagram.com/hariscodes/"&gt;https://www.instagram.com/hariscodes/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sockets</category>
      <category>node</category>
      <category>react</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Simplest way to monitor visits on your website (No Purchase, No Sign Up)</title>
      <dc:creator>Haris Ahmad</dc:creator>
      <pubDate>Sun, 07 Aug 2022 21:03:54 +0000</pubDate>
      <link>https://dev.to/harisahmadev/simplest-way-to-monitor-visits-on-your-website-no-purchase-no-sign-up-18ml</link>
      <guid>https://dev.to/harisahmadev/simplest-way-to-monitor-visits-on-your-website-no-purchase-no-sign-up-18ml</guid>
      <description>&lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;, you don't have to purchase an Analytics Service or sign up to some sketchy application just to know simple thing like how many visits did your site has. Just with a few lines of code you can easily find out the overall visit count of your website.&lt;/p&gt;

&lt;h2&gt;
  
  
  2 Steps to install this service
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Add the following JavaScript to your Website ⚙️
&lt;/h3&gt;

&lt;p&gt;Add the following code to your website where it is called every time a user visits (Could be your homepage). Replace [YOUR WEBSITE NAME] to your Website name or any other uniquely identifiable string&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;window.onload = function (){
    fetch('https://api.countapi.xyz/hit/[YOUR WEBSITE NAME]/visits')
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: View the Page Visits 🕵
&lt;/h3&gt;

&lt;p&gt;To get the page view you can visit the following endpoint&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.countapi.xyz/get/[YOUR WEBSITE NAME]/visits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wait✋! but it might not be end for you
&lt;/h3&gt;

&lt;p&gt;The example that I have provided is the bare minimum setup you need to do to monitor the visits. You might want to monitor the visits on each page of your site separately or want to have rather complex analytics. Thanks to &lt;a href="https://countapi.xyz/"&gt;CountAPI&lt;/a&gt; which gives us this tooling for free. For more complex 'Visit Analytics', please go ahead and read the docs from &lt;a href="https://countapi.xyz/"&gt;CountAPI&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Liked the solution?
&lt;/h3&gt;

&lt;p&gt;If you liked the post you can read more from me. For more please follow me on my social media handles provided below&lt;/p&gt;

&lt;p&gt;Blog👉 &lt;a href="https://hariscodes.com/"&gt;https://hariscodes.com/&lt;/a&gt;&lt;br&gt;
Twitter👉 &lt;a href="https://twitter.com/tweetharisahmad"&gt;https://twitter.com/tweetharisahmad&lt;/a&gt;&lt;br&gt;
Instagram👉 &lt;a href="https://www.instagram.com/hariscodes/"&gt;https://www.instagram.com/hariscodes/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>analytics</category>
      <category>webdev</category>
      <category>html</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to create Nested Tabs Layout with Routing in NextJS?</title>
      <dc:creator>Haris Ahmad</dc:creator>
      <pubDate>Tue, 04 May 2021 23:03:04 +0000</pubDate>
      <link>https://dev.to/harisahmadev/how-to-create-nested-tabs-layout-with-routing-in-nextjs-3d4a</link>
      <guid>https://dev.to/harisahmadev/how-to-create-nested-tabs-layout-with-routing-in-nextjs-3d4a</guid>
      <description>&lt;h1&gt;
  
  
  The pain 😳
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;"I will not repeat myself"&lt;/strong&gt;. This is what I vowed to me this morning and every morning and here I am copying and pasting the same code for the dashboard tabs to all my pages. What a shame. It might be because &lt;strong&gt;I could not find if NextJS allows you to have layout in dynamic routing without touching _app.js and the ways I found to do it were a little hacky.&lt;/strong&gt; From time to time, we developers have to remind ourselves that God has created us for a purpose higher than Ctrl+C &amp;amp; Ctrl+V and still ending up getting an error and cursing the stack-overflow AnonymusUser034 because pasting his code in my code-base has caused an error at line 983 of file i_have_no_idea.jpg. At that point we need to realize that we have to turn to our original job, which is to be creative. Well, enough pain inflicted, let us dive right into the solution. Although you might still Ctrl+C from here.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Antidote 💉
&lt;/h1&gt;

&lt;h3&gt;
  
  
  The solution in one line
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;We are going to use dynamic routes query and useRouter hook to map the route paths with the ReactJS components&lt;/strong&gt;. Didn't make sense? I thought so. It is because you can't put an elephant in a cookie-jar without killing it. So lets not kill our work-ethic and do some hard work.&lt;/p&gt;

&lt;h3&gt;
  
  
  The solution in more lines
&lt;/h3&gt;

&lt;p&gt;In the following the steps we are going to follow are listed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a Dynamic Route&lt;/li&gt;
&lt;li&gt;Create the routes for the components (Tabs definition)&lt;/li&gt;
&lt;li&gt;Find the component that is matching the route&lt;/li&gt;
&lt;li&gt;Render the component&lt;/li&gt;
&lt;li&gt;Create Navigation UI Elements&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1.Create a Dynamic Route
&lt;/h3&gt;

&lt;p&gt;Creating a dynamic route is fairly simple. You just have to create a &lt;code&gt;.js&lt;/code&gt; file in pages directory with the filename inside &lt;code&gt;[]&lt;/code&gt;. An example would be &lt;code&gt;[route].js&lt;/code&gt;. If this does not make sense to you, either you are at the wrong article or NextJS is as much alien to you as aliens are to us. You can visit &lt;a href="https://nextjs.org/"&gt;Next JS Docs&lt;/a&gt; if you want to learn more about NextJS. Our file-tree should look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src
 |_pages
  |_[route].js

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.Create the routes for the components
&lt;/h3&gt;

&lt;p&gt;To represent the routes, we are going to use simple Javascript objects. We will put all the objects inside an array so we can map them later. So our &lt;code&gt;[route].js&lt;/code&gt; would look something like this (which is wrapped inside at React component "NavBar").&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const NavBar = ()=&amp;gt;{
  const routes = [
    {
      slug: 'members',  
      label:'Organization Members', 
      component: &amp;lt;MemberTable /&amp;gt;
    },
    {
      slug: 'drivers-search', 
      label:'Driver Pre-Screen', 
      component: &amp;lt;DriversSearch /&amp;gt;
    }
  ]

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;slug&lt;/strong&gt;: The part of URL at which you want to display your component. Like &lt;code&gt;users&lt;/code&gt; in &lt;code&gt;myamazingsite.com/users&lt;/code&gt; is a slug.&lt;br&gt;
&lt;strong&gt;label&lt;/strong&gt;: The Label you want to display on a menu item which will represent this component.&lt;br&gt;
&lt;strong&gt;component&lt;/strong&gt;: The React Component that will be rendered for this path.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Find the component that is matching the route
&lt;/h3&gt;

&lt;p&gt;Now we will find one of the components inside the &lt;code&gt;routes&lt;/code&gt; array which matches the requested path. For example if someone enters &lt;code&gt;localhost:3000/members&lt;/code&gt; we will find in the &lt;code&gt;routes&lt;/code&gt; array an item that has &lt;code&gt;slug: 'members'&lt;/code&gt;. For this purpose, we have to know what user has requested in the URL&lt;/p&gt;
&lt;h4&gt;
  
  
  useRouter
&lt;/h4&gt;

&lt;p&gt;We will use &lt;code&gt;useRouter&lt;/code&gt; hook from &lt;code&gt;next/router&lt;/code&gt; module which will allow us to see what URL is there in the address bar. To get the URL we will:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {useRouter} from 'next/router'

const NavBar = ()=&amp;gt;{
  const components = [
    {
      slug: 'members',  
      label:'Organization Members', 
      component: &amp;lt;MemberTable /&amp;gt;
    },
    {
      slug: 'drivers-search', 
      label:'Driver Pre-Screen', 
      component: &amp;lt;DriversSearch /&amp;gt;
    }
  ]

  // --&amp;gt;
  const router = useRouter()
  currentPath = router.query.route
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;router.query.route&lt;/strong&gt;: &lt;code&gt;router.query&lt;/code&gt; will give us an object that contains all the route's paths requested. The end part &lt;code&gt;.route&lt;/code&gt; corresponds to the file name &lt;code&gt;[route].js&lt;/code&gt;.It would store in itself the requested path. if the path is &lt;code&gt;localhost:3000/members&lt;/code&gt;, &lt;code&gt;router.query.route&lt;/code&gt; will return string &lt;code&gt;'members'&lt;/code&gt;. The filename kind of acts like a variable. If you had filename as &lt;code&gt;[dummy].js&lt;/code&gt; Then you would request &lt;code&gt;router.query.dummy&lt;/code&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  Finding the component
&lt;/h4&gt;

&lt;p&gt;To find the object in &lt;code&gt;routes&lt;/code&gt; array which have a slug matching the &lt;code&gt;currentPath&lt;/code&gt;, I spare you with your fancy algorithms to iterate over the array, but I am going to use a simple approach. I am going to use &lt;code&gt;Array.find()&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {useRouter} from 'next/router'

const NavBar = ()=&amp;gt;{
  const routes = [
    {
      slug: 'members',  
      label:'Organization Members', 
      component: &amp;lt;MemberTable /&amp;gt;
    },
    {
      slug: 'drivers-search', 
      label:'Driver Pre-Screen', 
      component: &amp;lt;DriversSearch /&amp;gt;
    }
  ]

  const router = useRouter()
  currentPath = router.query.route

  // --&amp;gt;
  const findSlugMatchingCmp = ()=&amp;gt;components.find((cmp =&amp;gt;{
        return cmp.slug === currentPath
    } 
  )

  useEffect(()=&amp;gt;{
    const foundComponent = findSlugMatchingCmp()
  }, [router])
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am using &lt;code&gt;useEffect&lt;/code&gt; hook because getting a route using &lt;code&gt;useRouter&lt;/code&gt; hook is asynchronous operation. As you can see in the dependency array of &lt;code&gt;useEffect&lt;/code&gt; we depend on the change in &lt;code&gt;useRouter&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  What if user is naughty and he enters &lt;code&gt;localhost:3000/hehe&lt;/code&gt; path which doesn't exist?
&lt;/h4&gt;

&lt;p&gt;We will redirect him&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {useRouter} from 'next/router'

const NavBar = ()=&amp;gt;{
  const routes = [
    {
      slug: 'members',  
      label:'Organization Members', 
      component: &amp;lt;MemberTable /&amp;gt;
    },
    {
      slug: 'drivers-search', 
      label:'Driver Pre-Screen', 
      component: &amp;lt;DriversSearch /&amp;gt;
    }
  ]

  const router = useRouter()
  currentPath = router.query.route

  const findSlugMatchingCmp = ()=&amp;gt;components.find((cmp =&amp;gt;{
        return cmp.slug === currentPath
    } 
  )

  useEffect(()=&amp;gt;{
    const foundComponent = findSlugMatchingCmp()

    // --&amp;gt;
    if(currentPath &amp;amp;&amp;amp; !foundComponent)
        router.push('/404')
  }, [router])
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Render the component
&lt;/h3&gt;

&lt;p&gt;Now that we know what component matches with the slug, we will go ahead and return it for rendering&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {useRouter} from 'next/router'

const NavBar = ()=&amp;gt;{
  const routes = [
    {
      slug: 'members',  
      label:'Organization Members', 
      component: &amp;lt;MemberTable /&amp;gt;
    },
    {
      slug: 'drivers-search', 
      label:'Driver Pre-Screen', 
      component: &amp;lt;DriversSearch /&amp;gt;
    }
  ]

  const router = useRouter()
  currentPath = router.query.route

  const findSlugMatchingCmp = ()=&amp;gt;components.find((cmp =&amp;gt;{
        return cmp.slug === router.query.route
    } 
  )

  useEffect(()=&amp;gt;{
    const foundComponent = findSlugMatchingCmp()

    if(currentPath &amp;amp;&amp;amp; !foundComponent)
        router.push('/404')
  }, [router])

  // --&amp;gt;
  const cmp = findSlugMatchingCmp().component

  return (
    &amp;lt;div&amp;gt;
      {cmp}
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Create Navigation UI Elements
&lt;/h3&gt;

&lt;p&gt;I will leave it upto you if you either want Tabs, SideMenu, Navigation bar, or whatever navigation component you want to implement. For the demo I am going to use NextJS &lt;code&gt;Link&lt;/code&gt; component because it is relatively simple. We just have to redirect user to the correct path when user click on an element from our UI navigation. e.g&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {useRouter} from 'next/router'

const NavBar = ()=&amp;gt;{
  const routes = [
    {
      slug: 'members',  
      label:'Organization Members', 
      component: &amp;lt;MemberTable /&amp;gt;
    },
    {
      slug: 'drivers-search', 
      label:'Driver Pre-Screen', 
      component: &amp;lt;DriversSearch /&amp;gt;
    }
  ]

  const router = useRouter()
  currentPath = router.query.route

  const findSlugMatchingCmp = ()=&amp;gt;components.find((cmp =&amp;gt;{
        return cmp.slug === router.query.route
    } 
  )

  useEffect(()=&amp;gt;{
    const foundComponent = findSlugMatchingCmp()

    if(currentPath &amp;amp;&amp;amp; !foundComponent)
        router.push('/404')
  }, [router])

  const cmp = findSlugMatchingCmp().component

  return (
    &amp;lt;div&amp;gt;
      // --&amp;gt;
      &amp;lt;div&amp;gt;
        {routes.map(route=&amp;gt;(
          &amp;lt;Link href={route.slug}&amp;gt;{route.label}&amp;lt;/Link&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
      {cmp}
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;We have created a nested next route with layout by using dynamic routes query and useRouter hook to map the route paths with the ReactJS components. &lt;/p&gt;

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