Компонент <Link>

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

import Link from 'next/link'

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

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

Свойства (Props)

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

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

Полезно знать: Атрибуты тега <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.

  • null (по умолчанию): Поведение предварительной загрузки зависит от типа маршрута. Для статических маршрутов загружается весь маршрут (включая все данные). Для динамических маршрутов загружается часть маршрута до ближайшего сегмента с границей loading.js.
  • true: Весь маршрут будет загружен для статических и динамических маршрутов.
  • false: Предварительная загрузка не будет происходить ни при попадании в область просмотра, ни при наведении.
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>
  )
}

Примеры

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

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

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

app/blog/page.js
import Link from 'next/link'

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

Если дочерний элемент — это пользовательский компонент, оборачивающий тег <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>
  )
}

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

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