08 — Link komponenta (navigace)
Výuka
Proč to existuje?
V tradičních webových stránkách se používá pro odkazy. Problém je, že každý klik reloaduje celou stránku — prohlížeč stáhne nové HTML, CSS, JavaScript, znovu spustí skripty... To je pomalé a působí "old-school".
Moderní webové aplikace (SPA - Single Page Applications) chtějí rychlé přechody bez reloadu. Next.js poskytuje komponentu , která umožňuje client-side navigation — přechod mezi stránkami je okamžitý, bez reloadu.
Jak to funguje?
Komponenta Link z next/link:
- Vypadá jako odkaz, ale chová se jako moderní navigace
- Při kliknutí neloaduje celou stránku — jen mění obsah
- Automaticky přednačítá cílovou stránku (když je odkaz viditelný)
- Zachovává stav aplikace (např. otevřené menu zůstane otevřené)
Důležité:
K čemu to slouží?
- Rychlejší UX — přechody mezi stránkami jsou okamžité
- Lepší výkon — přednačítání (prefetch) stránek na pozadí
- Zachování stavu — aplikace nerestartuje při navigaci
- Progresivní enhancement — funguje i bez JavaScriptu (fallback na
)
JavaScript
// components/Nav.js
import Link from 'next/link'
export default function Nav(){
return (
<nav>
<Link href="/">Domů</Link>
<Link href="/about">O nás</Link>
<Link href="/blog">Blog</Link>
<Link href="/contact">Kontakt</Link>
</nav>
)
}
// Pro externí odkazy použij <a>
export default function ExternalLinks(){
return (
<div>
<Link href="/internal">Interní odkaz (používá Link)</Link>
<a href="https://google.com" target="_blank" rel="noopener noreferrer">
Google (externí, používá a)
</a>
</div>
)
}
Link s dynamickou URL
import Link from 'next/link'
export default function ProductList({ products }){
return (
<ul>
{products.map(product => (
<li key={product.id}>
<Link href={`/products/${product.id}`}>
{product.name}
</Link>
</li>
))}
</ul>
)
}
Programová navigace (imperativní)
"use client"
import { useRouter } from 'next/navigation'
export default function SearchForm(){
const router = useRouter()
function handleSubmit(e){
e.preventDefault()
const query = new FormData(e.target).get('q')
// Přesměruj na stránku s výsledky
router.push(`/search?q=${encodeURIComponent(query)}`)
}
return (
<form onSubmit={handleSubmit}>
<input name="q" placeholder="Hledat..." />
<button type="submit">Hledat</button>
</form>
)
}
TypeScript
import Link from 'next/link'
export default function Nav(): JSX.Element{
return (
<nav>
<Link href="/">Domů</Link>
<Link href="/about">O nás</Link>
<Link href="/blog">Blog</Link>
</nav>
)
}
// Programová navigace s typy
"use client"
import { useRouter } from 'next/navigation'
import type { FormEvent } from 'react'
export default function SearchForm(): JSX.Element{
const router = useRouter()
function handleSubmit(e: FormEvent<HTMLFormElement>){
e.preventDefault()
const formData = new FormData(e.currentTarget)
const query = String(formData.get('q') || '')
router.push(`/search?q=${encodeURIComponent(query)}`)
}
return (
<form onSubmit={handleSubmit}>
<input name="q" placeholder="Hledat..." />
<button type="submit">Hledat</button>
</form>
)
}
Rozdíl JS vs TS
TypeScript přidává typy pro:
- Event handlery (
FormEvent) - Router metody (
useRouter()má typované metodypush,replace, atd.) - Props pro vlastní Link komponenty
Programová navigace - useRouter API
"use client"
import { useRouter } from 'next/navigation'
export default function NavigationExample(){
const router = useRouter()
return (
<div>
{/* Push - přidá nový záznam do historie */}
<button onClick={() => router.push('/dashboard')}>
Jdi na Dashboard
</button>
{/* Replace - nahradí aktuální záznam (nelze se vrátit zpět) */}
<button onClick={() => router.replace('/login')}>
Jdi na Login (nahraď historii)
</button>
{/* Back - zpět v historii */}
<button onClick={() => router.back()}>
Zpět
</button>
{/* Forward - vpřed v historii */}
<button onClick={() => router.forward()}>
Vpřed
</button>
{/* Refresh - znovu načte aktuální route */}
<button onClick={() => router.refresh()}>
Refresh
</button>
</div>
)
}
Kdy použít co:
router.push()— normální navigace (např. po kliknutí na tlačítko)router.replace()— po úspěšném odeslání formuláře (zabráníš duplicitnímu odeslání)router.back()— tlačítko "Zpět"router.refresh()— znovu načti data (např. po změně v databázi)
Prefetch (přednačítání)
import Link from 'next/link'
// Výchozí - prefetch zapnutý
<Link href="/about">O nás</Link>
// Vypnout prefetch (pro velké stránky nebo citlivá data)
<Link href="/dashboard" prefetch={false}>
Dashboard
</Link>
Jak funguje prefetch:
- Link který je viditelný na stránce = Next.js přednačte cílovou stránku na pozadí
- Když uživatel klikne = stránka se zobrazí okamžitě (už je v cache)
- Pro produkční build = automaticky zapnuté
- Pro development = vypnuté (aby se nereloadovaly změny)
Bezpečnost externích odkazů
// ❌ NEBEZPEČNÉ - umožňuje window.opener útok
<a href="https://example.com" target="_blank">
Externí odkaz
</a>
// ✅ BEZPEČNÉ - rel="noopener noreferrer"
<a href="https://example.com" target="_blank" rel="noopener noreferrer">
Externí odkaz
</a>
Proč je to důležité:
target="_blank"otevře nové okno- Bez
rel="noopener"může cílová stránka manipulovat s původní stránkou noreferrerskryje, odkud uživatel přišel (privacy)
Tip
- Vždy používej
Linkpro interní navigaci — rychlejší a lepší UX - Externí odkazy =
+target="_blank" rel="noopener noreferrer" - Programová navigace —
router.push()pro akce s logikou (např. po odeslání formuláře) - Prefetch vypni — pro admin sekce nebo velké stránky (
prefetch={false}) - Style odkazy pomocí className —
Text
Styling odkazů
import Link from 'next/link'
// S CSS třídou
<Link href="/about" className="text-blue-500 hover:underline">
O nás
</Link>
// S inline styly
<Link href="/about" style={{ color: 'blue', textDecoration: 'none' }}>
O nás
</Link>
// S aktivním stavem (pomocí usePathname)
"use client"
import { usePathname } from 'next/navigation'
import Link from 'next/link'
export default function NavLink({ href, children }){
const pathname = usePathname()
const isActive = pathname === href
return (
<Link
href={href}
className={isActive ? 'active' : ''}
style={{ fontWeight: isActive ? 'bold' : 'normal' }}
>
{children}
</Link>
)
}
Kvíz
Komponenta z Next.js provádí client-side navigation — při kliknutí se stránka nemění kompletně (bez reloadu), ale jen se aktualizuje obsah. To je mnohem rychlejší než tradiční odkaz, který reloaduje celou stránku. Navíc automaticky přednačítá (prefetch) cílové stránky, takže přechod je okamžitý. Pro interní navigaci vždy používej , pro externí odkazy používej .
🎯 Závěrečný projekt
Po dokončení všech 8 dílů vytvoříte jednoduchou Todо aplikaci v čistém JavaScriptu. Naučíte se, jak aplikovat vše, co jste se naučili, na reálný projekt.
Zobrazit podrobnosti projektu →Informace o seriálu
Obtížnost
Délka
Cca 480 minut
Počet videí
8 videí + projekty
Certifikát
Po dokončení obdržíte certifikát
Lekce v této sekci
- 01 — Co je Next.js
- 02 — Vytvoření projektu
- 03 — Struktura projektu (app/)
- 04 — Page komponenty (page.js / page.tsx)
- 05 — Layout komponenty (layout.js / layout.tsx)
- 06 — File-based routing
- 07 — Dynamické routy ([id]/page.js)
- 08 — Link komponenta (navigace)
- 09 — Image komponenta (next/image)
- 10 — Metadata (title, description, Open Graph)
- 11 — Loading UI (loading.js / loading.tsx)
- 12 — Error handling (error.js / error.tsx)
- 13 — Not Found (not-found.js / not-found.tsx)
Struktura lekcí (souborový strom)
- 1.1 Úvod do JavaScriptu a TypeScriptu
- 1.2 Nastavení prostředí
- 1.3 První program
- 1.4 Proměnné: var, let, const
- 1.5 Datové typy - přehled
- 1.6 String (řetězce)
- 1.7 Number (čísla)
- 1.8 Boolean (pravda/nepravda)
- 1.9 Null a Undefined
- 1.10 Type Inference vs Annotations
- 1.11 Aritmetické operátory
- 1.12 Porovnávací operátory
- 1.13 Logické operátory
- 1.14 Komentáře
- 1.15 Console metody
- 03.01 Deklarace funkce
- 03.02 Function Expression
- 03.03 Arrow Functions
- 03.04 Parametry a argumenty
- 03.05 Return hodnoty
- 03.06 Výchozí parametry
- 03.07 Rest parametry
- 03.08 Co je Scope
- 03.09 Lexikální Scope
- 03.10 Řetězec Scope
- 03.11 Globální Scope
- 03.12 Životní Cyklus Proměnných
- 03.13 Omezení Scope
- 03.14 Použití Closures
- 03.15 Callback funkce
- 03.16 Higher-order Functions
- 03.17 IIFE
- 03.18 Void funkce
- 03.19 Rekurze
- v přípravě
- v přípravě
- v přípravě
- v přípravě
- 01 — Co je Next.js
- 02 — Vytvoření projektu
- 03 — Struktura projektu (app/)
- 04 — Page komponenty (page.js / page.tsx)
- 05 — Layout komponenty (layout.js / layout.tsx)
- 06 — File-based routing
- 07 — Dynamické routy ([id]/page.js)
- 08 — Link komponenta (navigace)
- 09 — Image komponenta (next/image)
- 10 — Metadata (title, description, Open Graph)
- 11 — Loading UI (loading.js / loading.tsx)
- 12 — Error handling (error.js / error.tsx)
- 13 — Not Found (not-found.js / not-found.tsx)
- v přípravě
- v přípravě
- v přípravě