<Link>
<Link> 是一個擴展 HTML <a> 元素的 React 元件,提供 預取 (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>
}屬性
以下是 Link 元件可用的屬性摘要:
| 屬性 | 範例 | 類型 | 必填 |
|---|---|---|---|
href | href="/dashboard" | 字串或物件 | 是 |
replace | replace={false} | 布林值 | - |
scroll | scroll={false} | 布林值 | - |
prefetch | prefetch={false} | 布林值或 null | - |
須知:
<a>標籤的屬性如className或target="_blank"可以作為屬性添加到<Link>中,並會傳遞給底層的<a>元素。
href (必填)
要導航至的路徑或 URL。
<Link href="/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>
儀表板
</Link>
)
}import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" replace>
儀表板
</Link>
)
}scroll
預設為 true。 <Link> 的預設行為是 滾動到新路由的頂部或維持後退和前進導航的滾動位置。 當設為 false 時,next/link 在導航後 不會 滾動到頁面頂部。
import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" scroll={false}>
儀表板
</Link>
)
}import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" scroll={false}>
儀表板
</Link>
)
}須知:
- 如果導航時 頁面 不在視窗的可見範圍內,Next.js 會滾動到該頁面。
prefetch
當 <Link /> 元件進入使用者的視窗(初始或通過滾動)時,預取就會發生。Next.js 會在背景預取並載入連結的路由(由 href 表示)及其資料,以提高客戶端導航的性能。預取僅在生產環境中啟用。
null(預設):預取行為取決於路由是靜態還是動態。對於靜態路由,將預取完整路由(包括所有資料)。對於動態路由,將預取到最近的loading.js邊界的分段路由。true:對於靜態和動態路由,都會預取完整路由。false:無論是進入視窗還是懸停,都不會進行預取。
import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" prefetch={false}>
儀表板
</Link>
)
}import Link from 'next/link'
export default function Page() {
return (
<Link href="/dashboard" prefetch={false}>
儀表板
</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> 標籤的自訂元件,您必須向 Link 添加 passHref。如果您使用像 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),即使直接使用<a>標籤,也必須使用passHref。 - 元件應支援
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 模組文件 中定義的所有屬性。
替換 URL 而不是推送
Link 元件的預設行為是將新 URL push 到 history 堆疊中。您可以使用 replace 屬性來防止新增條目,如下例所示:
<Link href="/about" replace>
關於我們
</Link>禁用滾動到頁面頂部
Link 的預設行為是滾動到頁面頂部。當定義了 hash 時,它會滾動到特定的 id,就像普通的 <a> 標籤一樣。要防止滾動到頂部 / hash,可以將 scroll={false} 添加到 Link:
<Link href="/#hashid" scroll={false}>
禁用滾動到頂部
</Link>中介軟體 (Middleware)
通常會使用 中介軟體 (Middleware) 進行身份驗證或其他涉及將使用者重寫到不同頁面的用途。為了讓 <Link /> 元件能正確預取通過中介軟體重寫的連結,您需要告訴 Next.js 要顯示的 URL 和要預取的 URL。這是為了避免不必要的向中介軟體發送請求以了解要預取的正確路由。
例如,如果您想提供一個具有已驗證和訪客視圖的 /dashboard 路由,您可以在中介軟體中添加類似以下的內容,以將使用者重定向到正確的頁面:
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}>
儀表板
</Link>
)
}版本歷史
| 版本 | 變更內容 |
|---|---|
v13.0.0 | 不再需要子 <a> 標籤。提供了一個 codemod 來自動更新您的程式碼庫。 |
v10.0.0 | 指向動態路由的 href 屬性現在會自動解析,不再需要 as 屬性。 |
v8.0.0 | 改進了預取 (prefetching) 效能。 |
v1.0.0 | 引入 next/link。 |