Ota Next.js App Routerin teho haltuun perusteellisella oppaallamme tiedostopohjaiseen reititykseen. Opi rakentamaan sovelluksesi, luomaan dynaamisia reittejä ja käsittelemään asetteluja.
Next.js App Router: Kattava opas tiedostopohjaiseen reititykseen
Next.js App Router, joka esiteltiin Next.js 13:ssa ja josta on tullut standardi myöhemmissä versioissa, mullistaa tavan, jolla rakennamme ja navigoimme sovelluksissa. Se esittelee tehokkaan ja intuitiivisen tiedostopohjaisen reititysjärjestelmän, joka yksinkertaistaa kehitystä, parantaa suorituskykyä ja kohentaa yleistä kehittäjäkokemusta. Tämä kattava opas syventyy App Routerin tiedostopohjaiseen reititykseen ja antaa sinulle tiedot ja taidot vankkojen ja skaalautuvien Next.js-sovellusten rakentamiseen.
Mitä on tiedostopohjainen reititys?
Tiedostopohjainen reititys on reititysjärjestelmä, jossa sovelluksesi reittien rakenne määräytyy suoraan tiedostojesi ja hakemistojesi organisoinnin perusteella. Next.js App Routerissa reitit määritellään luomalla tiedostoja `app`-hakemistoon. Jokainen kansio edustaa reitin osaa, ja kansioiden sisällä olevat erikoistiedostot määrittävät, miten kyseinen reitin osa käsitellään. Tällä lähestymistavalla on useita etuja:
- Intuitiivinen rakenne: Tiedostojärjestelmä heijastaa sovelluksen reittirakennetta, mikä tekee siitä helposti ymmärrettävän ja navigoitavan.
- Automaattinen reititys: Next.js generoi reitit automaattisesti tiedostorakenteesi perusteella, poistaen tarpeen manuaaliselle konfiguroinnille.
- Koodin sijoittelu: Reitinkäsittelijät ja käyttöliittymäkomponentit sijaitsevat yhdessä, mikä parantaa koodin organisointia ja ylläpidettävyyttä.
- Sisäänrakennetut ominaisuudet: App Router tarjoaa sisäänrakennetun tuen asetteluille, dynaamisille reiteille, datan noudolle ja muulle, mikä yksinkertaistaa monimutkaisia reititystilanteita.
App Routerin käyttöönotto
Jotta voit käyttää App Routeria, sinun on luotava uusi Next.js-projekti tai siirrettävä olemassa oleva projekti. Varmista, että käytät Next.js-versiota 13 tai uudempaa.
Uuden projektin luominen:
Voit luoda uuden Next.js-projektin App Routerilla käyttämällä seuraavaa komentoa:
npx create-next-app@latest my-app --example with-app
Olemassa olevan projektin siirtäminen:
Siirtääksesi olemassa olevan projektin sinun on siirrettävä sivusi `pages`-hakemistosta `app`-hakemistoon. Saatat joutua mukauttamaan reitityslogiikkaasi vastaavasti. Next.js tarjoaa siirto-oppaan auttamaan sinua tässä prosessissa.
Tiedostopohjaisen reitityksen peruskäsitteet
App Router esittelee useita erikoistiedostoja ja käytäntöjä, jotka määrittelevät, miten reittejäsi käsitellään:
1. `app`-hakemisto
`app`-hakemisto on sovelluksesi reittien juuri. Kaikkia tämän hakemiston sisällä olevia tiedostoja ja kansioita käytetään reittien generointiin. App Router jättää huomiotta kaiken `app`-hakemiston ulkopuolella olevan (kuten `pages`-hakemiston, jos olet siirtymässä).
2. `page.js`-tiedosto
`page.js`- (tai `page.jsx`, `page.ts`, `page.tsx`) tiedosto on App Routerin perustavanlaatuisin osa. Se määrittelee käyttöliittymäkomponentin, joka renderöidään tietylle reitin osalle. Se on pakollinen tiedosto kaikille reitin osille, joiden haluat olevan suoraan saavutettavissa.
Esimerkki:
Jos sinulla on tällainen tiedostorakenne:
app/
about/
page.js
Komponentti, joka exportataan tiedostosta `app/about/page.js`, renderöidään, kun käyttäjä siirtyy osoitteeseen `/about`.
// app/about/page.js
import React from 'react';
export default function AboutPage() {
return (
<div>
<h1>Meistä</h1>
<p>Lue lisää yrityksestämme.</p>
</div>
);
}
3. `layout.js`-tiedosto
`layout.js`- (tai `layout.jsx`, `layout.ts`, `layout.tsx`) tiedosto määrittelee käyttöliittymän, joka jaetaan useiden sivujen kesken reitin osassa. Asettelut ovat hyödyllisiä yhtenäisten ylä- ja alatunnisteiden, sivupalkkien ja muiden elementtien luomiseen, joiden tulisi olla läsnä useilla sivuilla.
Esimerkki:
Oletetaan, että haluat lisätä ylätunnisteen sekä `/about`-sivulle että hypoteettiselle `/about/team`-sivulle. Voit luoda `layout.js`-tiedoston `app/about`-hakemistoon:
// app/about/layout.js
import React from 'react';
export default function AboutLayout({ children }) {
return (
<div>
<header>
<h1>Tietoja yrityksestämme</h1>
</header>
<main>{children}</main>
</div>
);
}
`children`-props korvataan käyttöliittymällä, jonka renderöi samassa hakemistossa tai missä tahansa sisäkkäisessä hakemistossa oleva `page.js`-tiedosto.
4. `template.js`-tiedosto
`template.js`-tiedosto on samankaltainen kuin `layout.js`, mutta se luo uuden instanssin komponentista jokaiselle lapsireitille. Tämä on hyödyllistä tilanteissa, joissa haluat ylläpitää komponentin tilaa tai estää uudelleenrenderöintejä navigoidessasi lapsireittien välillä. Toisin kuin asettelut, templatet renderöityvät uudelleen navigoinnin yhteydessä. Templatejen käyttö on erinomaista elementtien animointiin navigoinnin aikana.
Esimerkki:
// app/template.js
'use client'
import { useState } from 'react'
export default function Template({ children }) {
const [count, setCount] = useState(0)
return (
<main>
<p>Template: {count}</p>
<button onClick={() => setCount(count + 1)}>Päivitä template</button>
{children}
</main>
)
}
5. `loading.js`-tiedosto
`loading.js`- (tai `loading.jsx`, `loading.ts`, `loading.tsx`) tiedoston avulla voit luoda latausnäkymän, joka näytetään reitin osan latautuessa. Tämä on hyödyllistä paremman käyttäjäkokemuksen tarjoamiseksi datan noudon tai muiden asynkronisten operaatioiden aikana.
Esimerkki:
// app/about/loading.js
import React from 'react';
export default function Loading() {
return <p>Ladataan tietoja...</p>;
}
Kun käyttäjä siirtyy osoitteeseen `/about`, `Loading`-komponentti näytetään, kunnes `page.js`-komponentti on täysin renderöity.
6. `error.js`-tiedosto
`error.js`- (tai `error.jsx`, `error.ts`, `error.tsx`) tiedoston avulla voit luoda mukautetun virhenäkymän, joka näytetään, kun reitin osassa tapahtuu virhe. Tämä on hyödyllistä käyttäjäystävällisemmän virheilmoituksen tarjoamiseksi ja koko sovelluksen kaatumisen estämiseksi.
Esimerkki:
// app/about/error.js
'use client'
import React from 'react';
export default function Error({ error, reset }) {
return (
<div>
<h2>Tapahtui virhe!</h2>
<p>{error.message}</p>
<button onClick={() => reset()}>Yritä uudelleen</button>
</div>
);
}
Jos `/about`-sivun renderöinnin aikana tapahtuu virhe, `Error`-komponentti näytetään. `error`-props sisältää tietoa virheestä, ja `reset`-funktio antaa käyttäjälle mahdollisuuden yrittää ladata sivu uudelleen.
7. Reittiryhmät
Reittiryhmät `(groupName)` mahdollistavat reittien organisoinnin ilman, että se vaikuttaa URL-rakenteeseen. Ne luodaan ympäröimällä kansion nimi sulkeilla. Tämä on erityisen hyödyllistä asettelujen ja jaettujen komponenttien järjestämisessä.
Esimerkki:
app/
(marketing)/
about/
page.js
contact/
page.js
(shop)/
products/
page.js
Tässä esimerkissä `about`- ja `contact`-sivut on ryhmitelty `marketing`-ryhmän alle, ja `products`-sivu on `shop`-ryhmän alla. URL-osoitteet pysyvät vastaavasti `/about`, `/contact` ja `/products`.
8. Dynaamiset reitit
Dynaamiset reitit mahdollistavat reittien luomisen muuttuvilla osilla. Tämä on hyödyllistä sisällön näyttämiseen, joka perustuu tietokannasta tai API:sta noudettuun dataan. Dynaamiset reitin osat määritellään ympäröimällä osan nimi hakasulkeilla (esim. `[id]`).
Esimerkki:
Oletetaan, että haluat luoda reitin yksittäisten blogikirjoitusten näyttämiseen niiden tunnisteen perusteella. Voit luoda tiedostorakenteen näin:
app/
blog/
[id]/
page.js
`[id]`-osa on dynaaminen osa. Komponentti, joka exportataan tiedostosta `app/blog/[id]/page.js`, renderöidään, kun käyttäjä siirtyy URL-osoitteeseen kuten `/blog/123` tai `/blog/456`. `id`-parametrin arvo on saatavilla komponentin `params`-propsissa.
// app/blog/[id]/page.js
import React from 'react';
export default async function BlogPost({ params }) {
const { id } = params;
// Nouda blogikirjoituksen data annetulla ID:llä
const post = await fetchBlogPost(id);
if (!post) {
return <p>Blogikirjoitusta ei löytynyt.</p>;
}
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
}
async function fetchBlogPost(id) {
// Simuloi datan noutoa tietokannasta tai API:sta
return new Promise((resolve) => {
setTimeout(() => {
const posts = {
'123': { title: 'Ensimmäinen blogikirjoitukseni', content: 'Tämä on ensimmäisen blogikirjoitukseni sisältö.' },
'456': { title: 'Toinen blogikirjoitus', content: 'Tässä on lisää jännittävää sisältöä.' },
};
resolve(posts[id] || null);
}, 500);
});
}
Voit myös käyttää useita dynaamisia osia reitissä. Esimerkiksi sinulla voisi olla reitti kuten `/blog/[category]/[id]`.
9. Kaiken kattavat segmentit (Catch-all)
Kaiken kattavat segmentit (catch-all) mahdollistavat reittien luomisen, jotka vastaavat mitä tahansa määrää segmenttejä. Tämä on hyödyllistä esimerkiksi CMS:n luomisessa, jossa URL-rakenne määräytyy käyttäjän mukaan. Kaiken kattavat segmentit määritellään lisäämällä kolme pistettä ennen segmentin nimeä (esim. `[...slug]`).
Esimerkki:
app/
docs/
[...slug]/
page.js
`[...slug]`-segmentti vastaa mitä tahansa määrää segmenttejä `/docs`-polun jälkeen. Se vastaa esimerkiksi polkuja `/docs/getting-started`, `/docs/api/users` ja `/docs/advanced/configuration`. `slug`-parametrin arvo on taulukko, joka sisältää vastaavat segmentit.
// app/docs/[...slug]/page.js
import React from 'react';
export default function DocsPage({ params }) {
const { slug } = params;
return (
<div>
<h1>Docs</h1>
<p>Slug: {slug ? slug.join('/') : 'Ei slugia'}</p>
</div>
);
}
Valinnaiset kaiken kattavat segmentit voidaan luoda lisäämällä segmentin nimi kaksinkertaisiin hakasulkeisiin `[[...slug]]`. Tämä tekee reitin segmentistä valinnaisen. Esimerkki:
app/
blog/
[[...slug]]/
page.js
Tämä asetus renderöi page.js-komponentin sekä osoitteessa `/blog` että `/blog/any/number/of/segments`.
10. Rinnakkaiset reitit
Rinnakkaiset reitit (Parallel Routes) mahdollistavat yhden tai useamman sivun samanaikaisen renderöinnin samassa asettelussa. Tämä on erityisen hyödyllistä monimutkaisissa asetteluissa, kuten hallintapaneeleissa, joissa sivun eri osiot voidaan ladata itsenäisesti. Rinnakkaiset reitit määritellään käyttämällä `@`-symbolia, jota seuraa slotin nimi (esim. `@sidebar`, `@main`).
Esimerkki:
app/
@sidebar/
page.js // Sivupalkin sisältö
@main/
page.js // Pääosion sisältö
default.js // Pakollinen: Määrittelee oletusasettelun rinnakkaisille reiteille
`default.js`-tiedosto on pakollinen, kun käytetään rinnakkaisia reittejä. Se määrittelee, miten eri slotit yhdistetään lopullisen asettelun luomiseksi.
// app/default.js
export default function RootLayout({ children: { sidebar, main } }) {
return (
<div style={{ display: 'flex' }}>
<aside style={{ width: '200px', backgroundColor: '#f0f0f0' }}>
{sidebar}
</aside>
<main style={{ flex: 1, padding: '20px' }}>
{main}
</main>
</div>
);
}
11. Sieppaavat reitit
Sieppaavat reitit (Intercepting Routes) mahdollistavat reitin lataamisen sovelluksen toisesta osasta nykyisen asettelun sisällä. Tämä on hyödyllistä modaalien, kuvagallerioiden ja muiden käyttöliittymäelementtien luomiseen, joiden tulisi ilmestyä olemassa olevan sivun sisällön päälle. Sieppaavat reitit määritellään käyttämällä `(..)`-syntaksia, joka osoittaa, kuinka monta tasoa hakemistopuussa ylöspäin mennään löytääkseen siepattavan reitin.
Esimerkki:
app/
(.)photos/
[id]/
page.js // Siepattu reitti
feed/
page.js // Sivu, jolla valokuvamodaali näytetään
Tässä esimerkissä, kun käyttäjä napsauttaa kuvaa `/feed`-sivulla, `app/(.)photos/[id]/page.js`-reitti siepataan ja näytetään modaalina `/feed`-sivun päällä. `(.)`-syntaksi kertoo Next.js:lle, että sen tulee etsiä `photos/[id]`-reittiä yhden tason ylempää (eli `app`-hakemistosta).
Datan nouto App Routerilla
App Router tarjoaa sisäänrakennetun tuen datan noudolle käyttämällä palvelinkomponentteja (Server Components) ja asiakaskomponentteja (Client Components). Palvelinkomponentit renderöidään palvelimella, kun taas asiakaskomponentit renderöidään selaimessa. Tämä antaa sinulle mahdollisuuden valita paras lähestymistapa kullekin komponentille sen vaatimusten perusteella.
Palvelinkomponentit
Palvelinkomponentit ovat oletusarvo App Routerissa. Niiden avulla voit noutaa dataa suoraan komponenteissasi ilman erillisiä API-reittejä. Tämä voi parantaa suorituskykyä ja yksinkertaistaa koodiasi.
Esimerkki:
// app/products/page.js
import React from 'react';
export default async function ProductsPage() {
const products = await fetchProducts();
return (
<div>
<h1>Tuotteet</h1>
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
</div>
);
}
async function fetchProducts() {
// Simuloi datan noutoa tietokannasta tai API:sta
return new Promise((resolve) => {
setTimeout(() => {
const products = [
{ id: 1, name: 'Tuote A' },
{ id: 2, name: 'Tuote B' },
{ id: 3, name: 'Tuote C' },
];
resolve(products);
}, 500);
});
}
Tässä esimerkissä `fetchProducts`-funktiota kutsutaan suoraan `ProductsPage`-komponentin sisällä. Komponentti renderöidään palvelimella, ja data noudetaan ennen kuin HTML lähetetään selaimelle.
Asiakaskomponentit
Asiakaskomponentit renderöidään selaimessa ja mahdollistavat selainpuolen ominaisuuksien, kuten tapahtumankuuntelijoiden, tilan ja selain-API:en käytön. Jotta voit käyttää asiakaskomponenttia, sinun on lisättävä `'use client'` -direktiivi tiedoston alkuun.
Esimerkki:
// app/counter/page.js
'use client'
import React, { useState } from 'react';
export default function CounterPage() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Laskuri</h1>
<p>Määrä: {count}</p>
<button onClick={() => setCount(count + 1)}>Kasvata</button>
</div>
);
}
Tässä esimerkissä `CounterPage`-komponentti on asiakaskomponentti, koska se käyttää `useState`-hookia. `'use client'` -direktiivi kertoo Next.js:lle, että tämä komponentti tulee renderöidä selaimessa.
Edistyneet reititystekniikat
App Router tarjoaa useita edistyneitä reititystekniikoita, joita voidaan käyttää monimutkaisten ja hienostuneiden sovellusten luomiseen.
1. Reitinkäsittelijät (Route Handlers)
Reitinkäsittelijät (Route Handlers) mahdollistavat API-päätepisteiden luomisen `app`-hakemiston sisällä. Tämä poistaa tarpeen erilliselle `pages/api`-hakemistolle. Reitinkäsittelijät määritellään tiedostoissa nimeltä `route.js` (tai `route.ts`), ja ne vievät funktioita, jotka käsittelevät eri HTTP-metodeja (esim. `GET`, `POST`, `PUT`, `DELETE`).
Esimerkki:
// app/api/users/route.js
import { NextResponse } from 'next/server'
export async function GET(request) {
// Simuloi käyttäjien noutoa tietokannasta
const users = [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' },
];
return NextResponse.json(users);
}
export async function POST(request) {
const body = await request.json()
console.log('Vastaanotettu data:', body)
return NextResponse.json({ message: 'Käyttäjä luotu' }, { status: 201 })
}
Tämä esimerkki määrittelee reitinkäsittelijän osoitteessa `/api/users`, joka käsittelee sekä `GET`- että `POST`-pyyntöjä. `GET`-funktio palauttaa listan käyttäjistä, ja `POST`-funktio luo uuden käyttäjän.
2. Reittiryhmät useilla asetteluilla
Voit yhdistää reittiryhmiä ja asetteluja luodaksesi erilaisia asetteluja sovelluksesi eri osioille. Tämä on hyödyllistä tilanteissa, joissa haluat erilaisen ylätunnisteen tai sivupalkin sivustosi eri osiin.
Esimerkki:
app/
(marketing)/
layout.js // Markkinointiasettelu
about/
page.js
contact/
page.js
(admin)/
layout.js // Ylläpitoasettelu
dashboard/
page.js
Tässä esimerkissä `about`- ja `contact`-sivut käyttävät `marketing`-asettelua, kun taas `dashboard`-sivu käyttää `admin`-asettelua.
3. Middleware
Middlewaren avulla voit suorittaa koodia ennen kuin sovelluksesi käsittelee pyynnön. Tämä on hyödyllistä tehtävissä kuten todennus, valtuutus, lokitus ja käyttäjien uudelleenohjaus heidän sijaintinsa tai laitteensa perusteella.
Middleware määritellään tiedostossa nimeltä `middleware.js` (tai `middleware.ts`) projektisi juuressa.
Esimerkki:
// middleware.js
import { NextResponse } from 'next/server'
export function middleware(request) {
// Tarkista, onko käyttäjä todennettu
const isAuthenticated = false; // Korvaa omalla todennuslogiikallasi
if (!isAuthenticated && request.nextUrl.pathname.startsWith('/admin')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
// Katso "Matching Paths" alempaa lisätietoja varten
export const config = {
matcher: '/admin/:path*',
}
Tämä esimerkki määrittelee middlewaren, joka tarkistaa, onko käyttäjä todennettu, ennen kuin sallii pääsyn mihin tahansa `/admin`-polun alla olevaan reittiin. Jos käyttäjä ei ole todennettu, hänet ohjataan `/login`-sivulle.
Tiedostopohjaisen reitityksen parhaat käytännöt
Saadaksesi kaiken irti App Routerin tiedostopohjaisesta reititysjärjestelmästä, harkitse seuraavia parhaita käytäntöjä:
- Pidä tiedostorakenne järjestettynä: Käytä merkityksellisiä kansionimiä ja ryhmittele toisiinsa liittyvät tiedostot yhteen.
- Käytä asetteluja jaetulle käyttöliittymälle: Luo asetteluja ylä- ja alatunnisteille, sivupalkeille ja muille elementeille, jotka jaetaan useiden sivujen kesken.
- Käytä latausnäkymiä: Tarjoa latausnäkymiä reiteille, jotka noutavat dataa tai suorittavat muita asynkronisia operaatioita.
- Käsittele virheet siististi: Luo mukautettuja virhenäkymiä tarjotaksesi paremman käyttäjäkokemuksen virhetilanteissa.
- Käytä reittiryhmiä organisointiin: Käytä reittiryhmiä reittien järjestämiseen vaikuttamatta URL-rakenteeseen.
- Hyödynnä palvelinkomponentteja suorituskyvyn parantamiseksi: Käytä palvelinkomponentteja datan noutoon ja käyttöliittymän renderöintiin palvelimella, mikä parantaa suorituskykyä ja SEO:ta.
- Käytä asiakaskomponentteja tarvittaessa: Käytä asiakaskomponentteja, kun tarvitset selainpuolen ominaisuuksia, kuten tapahtumankuuntelijoita, tilaa ja selain-API:eja.
Esimerkkejä kansainvälistämisestä Next.js App Routerilla
Next.js App Router yksinkertaistaa kansainvälistämistä (i18n) tiedostopohjaisen reitityksen avulla. Näin voit toteuttaa i18n:n tehokkaasti:
1. Alipolkureititys
Järjestä reitit kieliversion (locale) mukaan käyttämällä alipolkuja. Esimerkiksi:
app/
[locale]/
page.tsx // Kotisivu kieliversiolle
about/
page.tsx // Tietoja-sivu kieliversiolle
// app/[locale]/page.tsx
import { getTranslations } from './dictionaries';
export default async function HomePage({ params: { locale } }) {
const t = await getTranslations(locale);
return (<h1>{t.home.title}</h1>);
}
// dictionaries.js
const dictionaries = {
en: () => import('./dictionaries/en.json').then((module) => module.default),
es: () => import('./dictionaries/es.json').then((module) => module.default),
};
export const getTranslations = async (locale) => {
try {
return dictionaries[locale]() ?? dictionaries.en();
} catch (error) {
console.error(`Kieliversion ${locale} käännösten lataaminen epäonnistui`, error);
return dictionaries.en();
}
};
Tässä asetelmassa `[locale]` dynaaminen reitin osa käsittelee eri kieliversioita (esim. `/en`, `/es`). Käännökset ladataan dynaamisesti kieliversion perusteella.
2. Verkkotunnusreititys
Edistyneempää lähestymistapaa varten voit käyttää eri verkkotunnuksia tai aliverkkotunnuksia kullekin kieliversiolle. Tämä vaatii usein lisäkonfiguraatiota hosting-palveluntarjoajasi kanssa.
3. Middleware kieliversion tunnistamiseen
Käytä middlewarea tunnistaaksesi automaattisesti käyttäjän suosiman kieliversion ja ohjataksesi hänet sen mukaisesti.
// middleware.js
import { NextResponse } from 'next/server';
import { match } from '@formatjs/intl-localematcher';
import Negotiator from 'negotiator';
let locales = ['en', 'es', 'fr'];
function getLocale(request) {
const negotiatorHeaders = {};
request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));
let languages = new Negotiator({ headers: negotiatorHeaders }).languages();
try {
return match(languages, locales, 'en'); // Käytä "en" oletuskieliversiona
} catch (error) {
console.error("Virhe kieliversion yhdistämisessä:", error);
return 'en'; // Palataan englantiin, jos yhdistäminen epäonnistuu
}
}
export function middleware(request) {
const pathname = request.nextUrl.pathname;
const pathnameIsMissingLocale = locales.every(
(locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
);
if (pathnameIsMissingLocale) {
const locale = getLocale(request);
return NextResponse.redirect(
new URL(
`/${locale}${pathname.startsWith('/') ? '' : '/'}${pathname}`,
request.url
)
);
}
}
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
Tämä middleware tarkistaa, onko pyydetyssä polussa kieliversion etuliitettä. Jos ei ole, se tunnistaa käyttäjän suosiman kieliversion `Accept-Language`-otsakkeesta ja ohjaa hänet sopivaan kieliversiokohtaiseen polkuun. Kirjastoja, kuten `@formatjs/intl-localematcher` ja `negotiator`, käytetään kieliversioneuvottelun hoitamiseen.
Next.js App Router ja globaali saavutettavuus
Globaalisti saavutettavien verkkosovellusten luominen vaatii saavutettavuuden (a11y) periaatteiden huolellista harkintaa. Next.js App Router tarjoaa vankan perustan saavutettavien kokemusten rakentamiselle, mutta on olennaista toteuttaa parhaita käytäntöjä varmistaakseen, että sovellus on kaikkien käytettävissä heidän kyvyistään riippumatta.
Keskeiset saavutettavuusnäkökohdat
- Semanttinen HTML: Käytä semanttisia HTML-elementtejä (esim. `<article>`, `<nav>`, `<aside>`, `<main>`) sisällön jäsentämiseen. Tämä antaa merkityksen avustaville teknologioille ja auttaa käyttäjiä navigoimaan sivustollasi helpommin.
- ARIA-attribuutit: Käytä ARIA (Accessible Rich Internet Applications) -attribuutteja parantamaan mukautettujen komponenttien ja widgettien saavutettavuutta. ARIA-attribuutit tarjoavat lisätietoa elementtien roolista, tilasta ja ominaisuuksista avustaville teknologioille.
- Näppäimistöllä navigointi: Varmista, että kaikki interaktiiviset elementit ovat saavutettavissa näppäimistöllä. Käyttäjien tulee pystyä navigoimaan sovelluksessasi `Tab`-näppäimellä ja olemaan vuorovaikutuksessa elementtien kanssa `Enter`- tai `Välilyönti`-näppäimellä.
- Värikontrasti: Käytä riittävää värikontrastia tekstin ja taustan välillä varmistaaksesi luettavuuden näkövammaisille käyttäjille. Verkkosisällön saavutettavuusohjeet (WCAG) suosittelevat vähintään 4.5:1 kontrastisuhdetta normaalille tekstille ja 3:1 suurelle tekstille.
- Kuvan alt-teksti: Tarjoa kuvaileva alt-teksti kaikille kuville. Alt-teksti tarjoaa tekstivaihtoehdon kuville, jonka ruudunlukijat voivat lukea.
- Lomakkeen selitteet: Yhdistä lomakkeen selitteet vastaaviin syöttökenttiin käyttämällä `<label>`-elementtiä. Tämä tekee käyttäjille selväksi, mitä tietoja kussakin kentässä odotetaan.
- Ruudunlukijatestaus: Testaa sovellustasi ruudunlukijalla varmistaaksesi, että se on saavutettavissa näkövammaisille käyttäjille. Suosittuja ruudunlukijoita ovat NVDA, JAWS ja VoiceOver.
Saavutettavuuden toteuttaminen Next.js App Routerissa
- Käytä Next.js Link-komponenttia: Käytä `<Link>`-komponenttia navigointiin. Se tarjoaa sisäänrakennettuja saavutettavuusominaisuuksia, kuten esilatauksen ja fokuksen hallinnan.
- Fokuksen hallinta: Kun navigoit sivujen välillä tai avaat modaaleja, varmista, että fokus hallitaan oikein. Fokus tulisi asettaa uuden sivun tai modaalin loogisimpaan elementtiin.
- Saavutettavat mukautetut komponentit: Kun luot mukautettuja komponentteja, varmista, että ne ovat saavutettavia noudattamalla yllä hahmoteltuja periaatteita. Käytä semanttista HTML:ää, ARIA-attribuutteja ja näppäimistöllä navigointia tehd_äksesi komponenteistasi kaikkien käytettävissä olevia.
- Linttaus ja testaus: Käytä linttaustyökaluja, kuten ESLintia saavutettavuuslisäosien kanssa, tunnistaaksesi mahdolliset saavutettavuusongelmat koodissasi. Käytä myös automaattisia testaustyökaluja testataksesi sovelluksesi saavutettavuusrikkomusten varalta.
Yhteenveto
Next.js App Routerin tiedostopohjainen reititysjärjestelmä tarjoaa tehokkaan ja intuitiivisen tavan jäsentää ja navigoida sovelluksissasi. Ymmärtämällä tässä oppaassa esitetyt peruskäsitteet ja parhaat käytännöt voit rakentaa vakaita, skaalautuvia ja ylläpidettäviä Next.js-sovelluksia. Kokeile App Routerin eri ominaisuuksia ja löydä, miten se voi yksinkertaistaa kehitystyönkulkuasi ja parantaa käyttäjäkokemusta.