ref https://github.com/ashok-khanna/react-snippets/blob/main/Router.js

    1. /*
    2. Implements React Routing in Plain React, without reliance on React-Router or any other libraries.
    3. To use:
    4. In your top-level React Component (e.g. App or Index.js):
    5. - Import Router (e.g.: import Router from './Router')
    6. - Create a const with your routes and their associated component
    7. - Create a const with the component to show on urls not routed (i.e. 404 page)
    8. - Return a Router component as the top-level component of your App
    9. Example:
    10. ```function App() {
    11. ...
    12. const routes = [{path:"/", component:<Home/>}, {path:"/register", component:<Register/>}]
    13. ...
    14. const defaultComponent = <NoPageExists/>
    15. return (
    16. <Router routes={routes} defaultComponent={defaultComponent}/>
    17. )
    18. }

    Then to use routes:

    And that’s it!

    */

    / Code Starts Here /

    import React from ‘react’; import { useEffect, useState } from ‘react’;

    // Global Event Listener on “click” // Credit Chris Morgan: https://news.ycombinator.com/item?id=31373486 window.addEventListener(“click”, function (event) { // Only run this code when an link is clicked const link = event.target.closest(“a”); // Correctly handle clicks to external sites and // modifier keys if ( !event.button && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey && link && link.href.startsWith(window.location.origin + “/“) && link.target !== “_blank” ) { // prevent full page reload event.preventDefault(); // Main routing function navigate(link.href); } });

    / Main Component /

    export default function Router ({routes, defaultComponent}) {

    1. // state to track URL and force component to re-render on change
    2. const [currentPath, setCurrentPath] = useState(window.location.pathname);
    3. useEffect(() => {
    4. // define callback as separate function so it can be removed later with cleanup function
    5. const onLocationChange = () => {
    6. // update path state to current window URL
    7. setCurrentPath(window.location.pathname);
    8. }
    9. // listen for popstate event
    10. window.addEventListener('popstate', onLocationChange);
    11. // clean up event listener
    12. return () => {
    13. window.removeEventListener('popstate', onLocationChange)
    14. };
    15. }, [])
    16. return routes.find(({path, component}) => path === currentPath)?.component || defaultComponent

    }

    / Use the below in buttons and programmatically to navigate to pages /

    export function navigate (href) {

    1. // update url
    2. window.history.pushState({}, "", href);
    3. // communicate to Routes that URL has changed
    4. const navEvent = new PopStateEvent('popstate');
    5. window.dispatchEvent(navEvent);

    } ```