<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>
)
}
Полезно знать:
- 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
:
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
В приведенном выше примере ссылки ведут на:
- Предопределенный маршрут:
/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>
)
}
Полезно знать: Если вы используете Динамические маршруты, необходимо адаптировать свойства
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 . |