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