I'm using NextJS version 13.4.4, and I've been trying to implement active navlinks. The issue is that for this solution, I want to access the current URL, but every attempt to do so ends up failing. My folder structure is like this:
my navbar code looks like this:
'use client'
import React from 'react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useRouter } from 'next/router';
export const Navbar = (props:any):JSX.Element =>{
const links = [
{
path: "/",
name: "Home"
},
{
path: "/about",
name: "Resume"
},
{
path: "/projects",
name: "Projects"
},
{
path: "/contact",
name: "Contact Me"
}
];
const router = useRouter();
const url = usePathname();
//const url = router.pathname;
return(
<nav className="navbar navbar-dark navbar-expand-lg border-bottom topNav">
<div className="container-fluid">
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse justify-content-center w-100 mt-3 mt-lg-auto" id="navbarNav">
<ul className="navbar-nav justify-content-center">
{links.map((link, index):JSX.Element =>{
return(
<li className="nav-item px-5" key={index}>
<Link className={
url === link.path ? "nav-link text-white navLink activeLink"
: "nav-link text-white navLink"
} aria-current="page" href={link.path}>{link.name}</Link>
</li>
)
})}
</ul>
</div>
</div>
</nav>
);
}
All suggestions welcome.
I've tried
import { useRouter } from 'next/router
export default Navbar = () =>{
const router = useRouter();
const url = router.pathname;
...
}
which results in my app crashing and the 'NextRouter not mounted' error.
I've tried
import { usePathname } from 'next/navigation'
export default Navbar = () =>{
const url = usePathname();
...
}
which results in 'url' being null.
And I've also tried this just to see what options I have for getting the URL from this
import { useRouter } from 'next/navigation
export default Navbar = () =>{
const router = useRouter();
console.log(router)
...
}
which resulted in "Error: invariant expected app router to be mounted"
EDIT: After further reading, I discovered that my setup was quite janky. I was using Next 13+ features designed to play well with the app router, but my project was using the pages router. Of course, I could have made it work, but I felt that continuing with the pages router would involve lots of wasted effort doing simple things like this, so I decided to restructure my app to take advantage of the app router instead. Now everything works like clockwork.
Major changes
import { useRouter } from 'next/router';
❌ Not supported in Nextjs 13.4import { useRouter } from 'next/navigation';
✅ supported in Nextjs 13.4For pathName
not to be null
you need to pass path using useRouter
i.e
import { useRouter } from 'next/navigation'; // important
router = useRouter();
router.push(pages/<your_page_here>);