<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>
  )
}

prefetch

По умолчанию true. При значении true next/link предварительно загрузит страницу (указанную в href) в фоновом режиме. Это полезно для повышения производительности клиентской навигации. Любой <Link /> в области видимости (изначально или при прокрутке) будет предзагружен.

Предзагрузку можно отключить, передав prefetch={false}. Предзагрузка работает только в production-режиме.

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
  • Если вы используете функцию JSX pragma в emotion (@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

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

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

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

По умолчанию компонент Link добавляет новый URL в стек истории. Можно использовать свойство 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' : '/dashboard'
  return (
    <Link as="/dashboard" href={path}>
      Dashboard
    </Link>
  )
}

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

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

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