Search code examples
javascriptreactjsreact-router-domtailwind-cssnav

React navbar renders components separately with react-router-dom


I am using react router dom to render a website with react and tailwindcss. The navbar when clicked refreshes and renders the component on it's own without the other components. This is not what I want.

I want the components rendered in a single page in the way it is structured in my App.js file

I have tried using normal hrefs and now Link from react-router-dom, But I still get the same result

App.js

const App = () => {
  return (
    <div className="max-w-[1440px] mx-auto bg-page overflow-hidden relative">
      <Header />
      <Routes>
        <Route path="/" element={<Banner />} />
        <Route path="/home" element={<Banner />} />
        <Route path="/about" element={<About />} />
        <Route path="/hero" element={<Hero />} />
        <Route path="/featured" element={<Featured />} />
        <Route path="/gallery" element={<GallerySection />} />
        <Route path="/testimonies" element={<Testimony />} />
        <Route path="/join" element={<Join />} />
        <Route path="/footer" element={<Footer />} />
        <Route path="/copy" element={<Copyright />} />
      </Routes>
    </div>
  );
};

export default App;

Index.js

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <Router>
      <App />
    </Router>
  </React.StrictMode>
);

Navbar.js

const Nav = () => {
  return (
    <nav className="hidden lg:flex">
      <ul className="flex gap-x-8 text-white">
        {["home", "about", "featured", "gallery", "testimonies", "join"].map(
          (item) => {
            return (
              <li key={`link-${item}`}>
                <Link to={`/${item}`} className="capitalize">
                  {item}
                </Link>
              </li>
            );
          }
        )}
      </ul>
    </nav>
  );
};

export default Nav;

I would appreciate any help please


Solution

  • You need to use hashtags instead different routes.

    So you have to use only one index route

    <Route path="/" element={<IndexPage />} />
    

    and render section components in IndexPage component one by one

    const IndexPage = () => (
      <>
        <Banner />
        ...
      </>
    )
    

    then add into each section component wrapper id attribute

    const Banner = () => (
      <div id="banner">
        ...content...
      </div>
    )
    

    and use hashtag links in you Nav component:

    <Link to={`#${item}`} className="capitalize">
      {item}
    </Link>
    

    links will be looks like domain.com/#banner and if use open it then browser will scroll down to specific element with id

    also I suggest to add some css to make scrolling smooth:

    html {
      scroll-behavior: smooth;
    }