Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Navigation: Link and useRouter

Next.js has the Link component for links between pages. It renders an ordinary a tag, but navigation happens without a full reload: the browser loads only the new page, and the layout stays in place. For navigating from code, for example after a button click, there is the useRouter hook.

Let us add a menu to the root layout:

// app/layout.tsx
import Link from 'next/link';
import './globals.css';
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <nav>
          <Link href="/">Home</Link> | <Link href="/posts">Posts</Link> |{' '}
          <Link href="/about">About</Link>
        </nav>
        {children}
      </body>
    </html>
  );
}

The href prop is the page address. Click the links and watch the Network tab in the developer tools: the page is not reloaded as a whole.

Let us turn the titles in the posts list into links:

// app/posts/page.tsx
import Link from 'next/link';
 
const posts = [
  { slug: 'hello-nextjs', title: 'Hello, Next.js' },
  { slug: 'server-components', title: 'Server components' },
];
 
export default function PostsPage() {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.slug}>
          <Link href={`/posts/${post.slug}`}>{post.title}</Link>
        </li>
      ))}
    </ul>
  );
}

The address is built with a template string. For now the links lead to a 404 — the post page comes in the dynamic routes lesson.

Prefetching

When a Link appears in the visible part of the screen, Next.js loads the target page in advance (in the built version of the site). That is why a click responds almost instantly.

The useRouter hook only works in a client component — a file with the 'use client' directive on its first line. Such components get their own lesson.

// components/BackButton.tsx
'use client';
 
import { useRouter } from 'next/navigation';
 
export default function BackButton() {
  const router = useRouter();
  return <button onClick={() => router.back()}>Back</button>;
}

Use the button on any page: import BackButton from '@/components/BackButton' and then <BackButton /> in the markup. A click returns to the previous page.

Router methods

MethodWhat it does
router.push('/posts')Goes to the address
router.replace('/posts')Goes there without adding a history entry
router.back()Goes back
router.refresh()Requests the current page data from the server again

The usePathname hook from next/navigation returns the current address, such as /posts. Compare it with href to highlight the menu item of the page the visitor is on.

Common mistake

Importing useRouter from next/router. That is the old Pages Router hook; in the App Router it throws "NextRouter was not mounted". The correct import is next/navigation.

Thanks for reading!

Donate to the site — we work hard for you.