<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:
Свойство | Пример | Тип | Обязательно |
---|---|---|---|
href | href="/dashboard" | String или Object | Да |
replace | replace={false} | Boolean | - |
scroll | scroll={false} | Boolean | - |
prefetch | prefetch={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
:
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
В примере выше ссылки ведут на:
- Предопределённый маршрут:
/about?name=test
- Динамический маршрут:
/blog/my-post
Можно использовать любые свойства, определённые в документации модуля 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 для перенаправления пользователя на правильную страницу:
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 . |