Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Навигация: Link и useRouter

Для ссылок между страницами в Next.js есть компонент Link. Он рисует обычный тег a, но переход происходит без полной перезагрузки: браузер загружает только новую страницу, а макет остаётся на месте. Для переходов из кода, например после нажатия кнопки, служит хук useRouter.

Добавим меню в корневой макет:

// app/layout.tsx
import Link from 'next/link';
import './globals.css';
 
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ru">
      <body>
        <nav>
          <Link href="/">Главная</Link> | <Link href="/posts">Статьи</Link> |{' '}
          <Link href="/about">О блоге</Link>
        </nav>
        {children}
      </body>
    </html>
  );
}

Свойство href — адрес страницы. Пройдите по ссылкам и посмотрите на вкладку Network в инструментах разработчика: страница целиком не перезагружается.

Ссылки на статьи

Сделаем заголовки в списке статей ссылками:

// app/posts/page.tsx
import Link from 'next/link';
 
const posts = [
  { slug: 'hello-nextjs', title: 'Привет, Next.js' },
  { slug: 'server-components', title: 'Серверные компоненты' },
];
 
export default function PostsPage() {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.slug}>
          <Link href={`/posts/${post.slug}`}>{post.title}</Link>
        </li>
      ))}
    </ul>
  );
}

Адрес собирается шаблонной строкой. Ссылки пока ведут на 404 — страницу статьи создадим в уроке о динамических маршрутах.

Предзагрузка

Когда Link появляется в видимой части экрана, Next.js заранее подгружает страницу, на которую она ведёт (в собранной версии сайта). Поэтому клик срабатывает почти мгновенно.

Переход из кода

Хук useRouter работает только в клиентском компоненте — файле с директивой 'use client' в первой строке. Подробно о таких компонентах — в отдельном уроке.

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

Используйте кнопку на любой странице: import BackButton from '@/components/BackButton' и затем <BackButton /> в разметке. Нажатие вернёт на предыдущую страницу.

Методы роутера

МетодЧто делает
router.push('/posts')Переходит на адрес
router.replace('/posts')Переходит, не добавляя запись в историю
router.back()Возвращает назад
router.refresh()Заново запрашивает данные текущей страницы с сервера

Активная ссылка

Хук usePathname из next/navigation возвращает текущий адрес, например /posts. Его сравнивают с href, чтобы выделить пункт меню, на странице которого находится посетитель.

Частая ошибка

Импортировать useRouter из next/router. Это хук старого Pages Router, в App Router он выдаёт ошибку «NextRouter was not mounted». Правильный импорт — next/navigation.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.