<Link>

Примеры

<Link> — это React-компонент, расширяющий HTML-элемент <a> для предоставления предварительной загрузки (prefetching) и клиентской навигации между маршрутами. Это основной способ навигации между маршрутами в Next.js.

Рассмотрим пример с директорией pages, содержащей следующие файлы:

  • pages/index.js
  • pages/about.js
  • pages/blog/[slug].js

Мы можем создать ссылки на эти страницы следующим образом:

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link href="/">Главная</Link>
      </li>
      <li>
        <Link href="/about">О нас</Link>
      </li>
      <li>
        <Link href="/blog/hello-world">Пост в блоге</Link>
      </li>
    </ul>
  )
}

export default Home

Свойства (Props)

Вот сводка доступных свойств для компонента Link:

СвойствоПримерТипОбязательно
hrefhref="/dashboard"String или ObjectДа
replacereplace={false}Boolean-
scrollscroll={false}Boolean-
prefetchprefetch={false}Boolean-

Полезно знать: Атрибуты тега <a>, такие как className или target="_blank", можно добавлять к <Link> как свойства, и они будут переданы базовому элементу <a>.

href (обязательное)

Путь или URL для навигации.

<Link href="/dashboard">Dashboard</Link>

href также может принимать объект, например:

// Навигация на /about?name=test
<Link
  href={{
    pathname: '/about',
    query: { name: 'test' },
  }}
>
  О нас
</Link>

replace

По умолчанию false. Когда true, next/link заменит текущее состояние истории вместо добавления нового URL в стек истории браузера.

import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" replace>
      Dashboard
    </Link>
  )
}
import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" replace>
      Dashboard
    </Link>
  )
}

scroll

По умолчанию true. По умолчанию <Link> прокручивает страницу к началу нового маршрута или сохраняет позицию прокрутки при навигации назад/вперед. Когда false, next/link не будет прокручивать страницу к началу после навигации.

import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" scroll={false}>
      Dashboard
    </Link>
  )
}
import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" scroll={false}>
      Dashboard
    </Link>
  )
}

Полезно знать:

  • Next.js будет прокручивать страницу к Page, если она не видна в области просмотра при навигации.

prefetch

Предварительная загрузка (prefetching) происходит, когда компонент <Link /> попадает в область просмотра пользователя (изначально или при прокрутке). Next.js предварительно загружает связанный маршрут (указанный в href) и данные в фоновом режиме для улучшения производительности клиентской навигации. Предварительная загрузка работает только в production.

  • true (по умолчанию): Весь маршрут и его данные будут загружены.
  • false: Предварительная загрузка не будет происходить при попадании в область просмотра, но будет работать при наведении. Если вы хотите полностью отключить загрузку при наведении, рассмотрите использование тега <a> или постепенный переход на App Router, который позволяет отключать предварительную загрузку при наведении.
import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" prefetch={false}>
      Dashboard
    </Link>
  )
}
import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" prefetch={false}>
      Dashboard
    </Link>
  )
}

Другие свойства

legacyBehavior

Элемент <a> больше не требуется как дочерний для <Link>. Добавьте свойство legacyBehavior для использования старого поведения или удалите <a> для обновления. Доступен codemod для автоматического обновления вашего кода.

Полезно знать: когда legacyBehavior не установлен в true, все свойства anchor тега можно передать в next/link, такие как className, onClick и т.д.

passHref

Принудительно передает свойство href дочернему элементу. По умолчанию false.

scroll

Прокручивает страницу к началу после навигации. По умолчанию true.

shallow

Обновляет путь текущей страницы без повторного выполнения getStaticProps, getServerSideProps или getInitialProps. По умолчанию false.

locale

Активная локаль автоматически добавляется. locale позволяет указать другую локаль. Когда false, href должен включать локаль, так как поведение по умолчанию отключено.

Примеры

Ссылки на динамические маршруты

Для динамических маршрутов удобно использовать шаблонные строки для создания пути ссылки.

Например, можно сгенерировать список ссылок на динамический маршрут pages/blog/[slug].js:

pages/blog/index.js
import Link from 'next/link'

function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          <Link href={`/blog/${post.slug}`}>{post.title}</Link>
        </li>
      ))}
    </ul>
  )
}

export default Posts

Если дочерний элемент — это пользовательский компонент, оборачивающий тег <a>

Если дочерний элемент Link — это пользовательский компонент, оборачивающий тег <a>, необходимо добавить passHref в Link. Это необходимо при использовании библиотек, таких как styled-components. Без этого тег <a> не будет иметь атрибута href, что ухудшает доступность вашего сайта и может повлиять на SEO. Если вы используете ESLint, есть встроенное правило next/link-passhref для обеспечения правильного использования passHref.

import Link from 'next/link'
import styled from 'styled-components'

// Создаем пользовательский компонент, оборачивающий тег <a>
const RedLink = styled.a`
  color: red;
`

function NavLink({ href, name }) {
  return (
    <Link href={href} passHref legacyBehavior>
      <RedLink>{name}</RedLink>
    </Link>
  )
}

export default NavLink
  • Если вы используете emotion с JSX pragma (@jsx jsx), необходимо использовать passHref, даже если вы используете тег <a> напрямую.
  • Компонент должен поддерживать свойство onClick для корректного выполнения навигации.

Если дочерний элемент — функциональный компонент

Если дочерний элемент Link — функциональный компонент, помимо использования passHref и legacyBehavior, необходимо обернуть компонент в React.forwardRef:

import Link from 'next/link'

// `onClick`, `href` и `ref` должны быть переданы DOM-элементу
// для корректной обработки
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
  return (
    <a href={href} onClick={onClick} ref={ref}>
      Нажми меня
    </a>
  )
})

function Home() {
  return (
    <Link href="/about" passHref legacyBehavior>
      <MyButton />
    </Link>
  )
}

export default Home

С объектом URL

Link также может принимать объект URL, который автоматически форматируется в строку URL. Вот как это сделать:

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link
          href={{
            pathname: '/about',
            query: { name: 'test' },
          }}
        >
          О нас
        </Link>
      </li>
      <li>
        <Link
          href={{
            pathname: '/blog/[slug]',
            query: { slug: 'my-post' },
          }}
        >
          Пост в блоге
        </Link>
      </li>
    </ul>
  )
}

export default Home

В приведенном выше примере ссылки ведут на:

Можно использовать все свойства, определенные в документации Node.js URL module.

Замена URL вместо добавления

По умолчанию компонент Link добавляет новый URL в стек history. Можно использовать свойство replace, чтобы предотвратить добавление новой записи, как в следующем примере:

<Link href="/about" replace>
  О нас
</Link>

Отключение прокрутки к началу страницы

По умолчанию Link прокручивает страницу к началу. При наличии хэша прокрутка выполняется к конкретному id, как в обычном теге <a>. Чтобы отключить прокрутку к началу/хэшу, можно добавить scroll={false}:

<Link href="/#hashid" scroll={false}>
  Отключает прокрутку к началу
</Link>

Middleware

Часто Middleware используется для аутентификации или других целей, связанных с перенаправлением пользователя на другую страницу. Чтобы компонент <Link /> правильно предварительно загружал ссылки с перенаправлениями через Middleware, необходимо указать Next.js как URL для отображения, так и URL для предварительной загрузки. Это нужно, чтобы избежать лишних запросов к middleware для определения правильного маршрута.

Например, если вы хотите обслуживать маршрут /dashboard с аутентифицированным и гостевым представлением, можно добавить что-то подобное в Middleware для перенаправления пользователя на нужную страницу:

middleware.js
export function middleware(req) {
  const nextUrl = req.nextUrl
  if (nextUrl.pathname === '/dashboard') {
    if (req.cookies.authToken) {
      return NextResponse.rewrite(new URL('/auth/dashboard', req.url))
    } else {
      return NextResponse.rewrite(new URL('/public/dashboard', req.url))
    }
  }
}

В этом случае следует использовать следующий код в компоненте <Link />:

import Link from 'next/link'
import useIsAuthed from './hooks/useIsAuthed'

export default function Page() {
  const isAuthed = useIsAuthed()
  const path = isAuthed ? '/auth/dashboard' : '/public/dashboard'
  return (
    <Link as="/dashboard" href={path}>
      Dashboard
    </Link>
  )
}

Полезно знать: Если вы используете Динамические маршруты, необходимо адаптировать свойства as и href. Например, если у вас есть динамический маршрут /dashboard/authed/[user], который вы хотите представить через middleware, напишите: <Link href={{ pathname: '/dashboard/authed/[user]', query: { user: username } }} as="/dashboard/[user]">Профиль</Link>.

История версий

ВерсияИзменения
v13.0.0Больше не требует дочернего тега <a>. Предоставлен кодмод для автоматического обновления кодовой базы.
v10.0.0Свойства href, указывающие на динамический маршрут, автоматически разрешаются и больше не требуют свойства as.
v8.0.0Улучшена производительность предварительной загрузки (prefetching).
v1.0.0Введён next/link.