Next/link та навігація в Next.js
Next.js надає кілька способів навігації: компонент Link для декларативної навігації, хук useRouter для програмної навігації та функції redirect/permanentRedirect для серверної навігації.
Компонент Link
Link є основним способом навігації. Він рендерить тег <a>, але перехоплює клік і виконує навігацію на стороні клієнта без повного перезавантаження сторінки:
import Link from 'next/link'
export default function Navigation() {
return (
<nav>
<Link href="/docs">База знань</Link>
<Link href="/problems">Проблеми</Link>
<Link href="/roadmap">Дорожня карта</Link>
</nav>
)
}Попереднє завантаження
За замовчуванням Link попередньо завантажує сторінку, коли вона потрапляє у видиму область. Це робить переходи миттєвими:
// Попереднє завантаження увімкнено за замовчуванням
<Link href="/docs/next/ssg">SSG у Next.js</Link>
// Вимкнути попереднє завантаження для рідко відвідуваних сторінок
<Link href="/settings" prefetch={false}>Налаштування</Link>Для статичних маршрутів попереднє завантаження завантажує весь RSC Payload. Для динамічних маршрутів воно завантажує до найближчого loading.tsx.
Динамічний href
<Link href={`/docs/${doc.slug}`}>
{doc.title}
</Link>
// З об'єктом
<Link
href={{
pathname: '/problems',
query: { difficulty: 'hard' }
}}
>
Важкі проблеми
</Link>Активне посилання
Щоб підсвітити поточну сторінку, використовуйте usePathname:
'use client'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
export function NavLink({
href,
children
}: {
href: string
children: React.ReactNode
}) {
const pathname = usePathname()
const isActive = pathname === href
return (
<Link
href={href}
className={isActive ? 'text-blue-600 font-bold' : 'text-neutral-600'}
>
{children}
</Link>
)
}useRouter
Для програмної навігації в компонентах клієнта:
'use client'
import { useRouter } from 'next/navigation'
export function LoginButton() {
const router = useRouter()
const handleLogin = async () => {
const result = await login()
if (result.success) {
router.push('/dashboard')
}
}
return <button onClick={handleLogin}>Увійти</button>
}Методи useRouter
| Метод | Опис |
|---|---|
router.push(url) | Навігація до URL (додає до історії) |
router.replace(url) | Навігація без додавання до історії |
router.back() | Повернутися в історії |
router.forward() | Продовжити в історії |
router.refresh() | Оновити поточний маршрут (перезавантажує дані з сервера) |
router.prefetch(url) | Попереднє завантаження маршруту |
Важливо:
useRouter з next/navigation (App Router) та useRouter з next/router (Pages Router) — це різні хуки з різними API. У App Router немає router.query, використовуйте замість цього useSearchParams.
Серверна навігація
У серверних компонентах та серверних діях використовуйте redirect:
// У серверній дії
'use server'
import { redirect } from 'next/navigation'
export async function createProblem(formData: FormData) {
const problem = await db.problem.create({ ... })
redirect(`/problems/${problem.id}`)
}
// У серверному компоненті
import { redirect } from 'next/navigation'
export default async function Page() {
const user = await getUser()
if (!user) redirect('/auth/login')
return <Dashboard user={user} />
}useSearchParams
Для роботи з параметрами запиту:
'use client'
import { useSearchParams } from 'next/navigation'
export function FilterPanel() {
const searchParams = useSearchParams()
const difficulty = searchParams.get('difficulty')
return <p>Фільтр: {difficulty || 'всі'}</p>
}usePathname
Щоб отримати поточний шлях:
'use client'
import { usePathname } from 'next/navigation'
export function Breadcrumbs() {
const pathname = usePathname()
const segments = pathname.split('/').filter(Boolean)
return (
<nav>
{segments.map((segment, i) => (
<span key={i}>{segment}</span>
))}
</nav>
)
}Корисні ресурси
- nextjs.org/docs — Посилання та навігація
- API посилання
- API useRouter
Суміжні теми
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.