How To Use Next Link for Routing to Avoid Page Refresh

57 Views Asked by At

Below is the code for my navbar:

    'use client'
    
    import { useState } from 'react';
    import { GiHamburgerMenu } from 'react-icons/gi';
    import Link from 'next/link';
    import Image from 'next/image';
    
    const Header = () => {
      const [isOpen, setIsOpen] = useState(false);
    
      const toggleMenu = () => {
        setIsOpen(!isOpen);
      };
    
      return (
        <header className="bg-gray-800 p-4 fixed w-full top-0 z-10">
          <div className="container mx-auto flex justify-between items-center">
            <div className="flex items-center">
              <Link legacyBehavior href="/">
              <a>
              <Image
                    src="/logo.svg"
                    width={100}
                    height={100}
                    alt="logo"
                    />
                </a>
              </Link>
            </div>
            <div className="md:hidden">
              <GiHamburgerMenu className="text-white text-2xl cursor-pointer" onClick={toggleMenu} />
            </div>
            <nav className={`md:hidden absolute top-16 left-0 w-full bg-gray-800 p-8 transition-all ${isOpen ? 'block' : 'hidden'}`}>
            <NavLink href="/" text="Home" onClick={toggleMenu} />
              <NavLink href="/menu" text="Menu" onClick={toggleMenu} />
              <NavLink href="/about" text="About" onClick={toggleMenu} />
              <NavLink href="/contact" text="Contact" onClick={toggleMenu} />
            </nav>
            <div className="md:flex md:ml-auto md:items-center hidden">
            <NavLink href="/" text="Home" />
              <NavLink href="/menu" text="Menu" />
              <NavLink href="/about" text="About" />
              <NavLink href="/contact" text="Contact" />
            </div>
          </div>
        </header>
      );
    };
    
    const NavLink = ({ href, text, onClick }) => (
      <Link legacyBehavior href={href}>
        <a className="text-white hover:text-gray-300 px-4 py-2 rounded-md block" onClick={onClick}>{text}</a>
      </Link>
    );
    
    export default Header;

This is my page.js code:

    import Image from "next/image";
    import Header from "./components/Header";
    import HomeSection from "./components/HomeSection";
    import Menu from "./components/Menu";
    
       export default function Home() {
          return (
           <>
              <Header />
              <HomeSection />
              <Menu />
              </>
          );
        }

How can I write my code better and get better navigation without having a full page refresh? Also, when I click the menu on the navbar it's redirecting me to 404 This page could not be found. Here is a deployed version of the project. Here is my project folder structure. However, the project is not yet complete. I would love to collaborate with someone willing to help me with the issues I'm facing. Drop your GitHub username or email so that can add you.

1

There are 1 best solutions below

0
Beast80K On

Problems :

  1. navigation without having a full page refresh?
  2. when I click the menu on the navbar it's redirecting me to 404

Causes:

  • Use Link component from NextJS to navigate to a page without refresh,
  • Improper folder structure, NextJS uses folder names as page name & it(folder) contains a file page.js which is actually the page, hence when you try to navigate to /Menu it tries to find folder name as Menu which is not there according to your folder structure.

Solution :

Steps :

  • Create folder Menu, under app folder. Then add a file in it as page.js.

  • Do same, for other pages. Make folder with page names, & add a file in it as page.js.

Replace:

<NavLink href="/menu" text="Menu" />

by

<Link href="/menu">Menu</Link>

Here's a small example :

Folder Structure (excluded unnecessary):

projectname
├── src
│   └── app
│       ├── comp    // Components folder
│       │   ├── Menus
│       │   │   └── Menus.js
│       │   └── MyNavBar
│       │       └── MyNavBar.js   
│       ├── globals.css
│       ├── layout.js      // add Navbar here, so its visible in all pages
│       ├── menu           // menu page folder
│       │   └── page.js    // menu page file
│       └── page.js        // home page (http://localhost:3000/)
└── tailwind.config.js

layout.js :

import { Inter } from 'next/font/google'
import './globals.css'
import MyNavBar from './comp/MyNavBar/MyNavBar'


const inter = Inter({
  subsets: ['latin'],
  variable: '--inter',
  display: 'swap',
})


export default function RootLayout({ children }) {
  return (
    <html lang="en" className={`${inter.variable}`} >
      <body className={`bg-background font-Inter scroll-smooth`}>
        <MyNavBar />

        {children}

      </body>
    </html >
  )
}

Components :

Menus.js at src\app\comp\Menus\Menus.js :

'use client'
import React from 'react'

const Menus = () => {
    return (
        <div>
            <h3>Menus</h3>

            <ul>
                <li>A</li>
                <li>B</li>
                <li>C</li>
            </ul>
        </div>
    )
}

export default Menus

MyNavBar.js at src\app\comp\MyNavBar\MyNavBar.js :

'use client'

import Link from 'next/link'
import React from 'react'

const MyNavBar = () => {
    return (
        <div className='flex gap-4 items-center'>
            <Link href={"/"}>Home</Link>
            <Link href={"/menu"}>Menu</Link>
            <Link href={"/about"}>About</Link>
            <Link href={"/contact"}>Contact</Link>
        </div>
    )
}

export default MyNavBar

menu page at src\app\menu\page.js :

import Menus from "../comp/Menus/Menus";

export default function MenuPg() {
    return (
        <h1>
            Menu Page
            <Menus />
        </h1>
    );
}

Explaination :

  • Go to url http://localhost:3000/, you will see header. Click on menu link,
  • http://localhost:3000/menu you will see Menus component output.

Do the same for remaining links

Please Read :

If you still have any doubts, leave a comment.