Rutare pe partea client în Next.js
Publicat: 2022-03-10Hyperlink-urile au fost una dintre bijuteriile Web-ului încă de la începuturile sale. Potrivit MDN, hyperlinkurile sunt ceea ce face ca Webul să fie un web. Deși este utilizat în scopuri precum legarea între documente, utilizarea sa principală este de a face referire la diferite pagini web identificabile printr-o adresă web unică sau o adresă URL.
Rutarea este un aspect important al fiecărei aplicații web, așa cum sunt hyperlinkurile către Web. Este un mecanism prin care cererile sunt direcționate către codul care le gestionează. În ceea ce privește rutarea, paginile Next.js sunt referite și identificabile printr-o cale URL unică. Dacă Web-ul constă din pagini web de navigare interconectate prin hyperlinkuri , atunci fiecare aplicație Next.js constă din pagini care pot fi rutate (gestionare de rute sau rute) interconectate de un router.
Next.js are suport încorporat pentru rutare, care poate fi dificil de despachetat, mai ales când se ia în considerare randarea și preluarea datelor. Ca o condiție prealabilă pentru înțelegerea rutării pe partea client în Next.js, este necesar să aveți o privire de ansamblu asupra conceptelor precum rutarea, randarea și preluarea datelor în Next.js.
Acest articol va fi benefic pentru dezvoltatorii React care sunt familiarizați cu Next.js și doresc să învețe cum gestionează rutarea. Trebuie să aveți cunoștințe practice despre React și Next.js pentru a profita la maximum de articol, care se referă exclusiv la rutarea pe partea client și conceptele conexe în Next.js.
Rutare și randare
Rutarea și redarea sunt complementare una cu cealaltă și vor juca un rol important pe parcursul acestui articol. Îmi place cum le explică Gaurav:
Rutarea este procesul prin care utilizatorul este navigat la diferite pagini de pe un site web.
Redarea este procesul de punere a acestor pagini în interfața de utilizare. De fiecare dată când solicitați o rută către o anumită pagină, redați și pagina respectivă, dar nu fiecare randare este rezultatul unei rute.
Luați cinci minute să vă gândiți la asta.
Ceea ce trebuie să înțelegeți despre randarea în Next.js este că fiecare pagină este pre-redată în avans împreună cu codul JavaScript minim necesar pentru a deveni complet interactiv printr-un proces cunoscut sub numele de hidratare. Modul în care Next.js face acest lucru depinde în mare măsură de forma de pre-rendare: generare statică sau randare pe server , care sunt ambele puternic cuplate cu tehnica de preluare a datelor utilizată și separate de momentul în care HTML-ul pentru o pagină este generat.
În funcție de cerințele dvs. de preluare a datelor, este posibil să utilizați funcții de preluare a datelor încorporate, cum ar fi getStaticProps
, getStaticPaths
sau, getServerSideProps
, instrumente de preluare a datelor la nivel client, cum ar fi SWR, react-query sau abordări tradiționale de preluare a datelor, cum ar fi fetch-on- randare, adu-apoi-redare, redare-cum-aduceți (cu Suspans).
Pre-randarea (înainte de randare — către UI ) este complementară cu rutarea și foarte mult cuplată cu preluarea datelor - un întreg subiect propriu în Next.js. Deci, deși aceste concepte sunt fie complementare, fie strâns legate, acest articol se va concentra exclusiv pe simpla navigare între pagini (rutare), cu referiri la concepte înrudite acolo unde este necesar.
Cu asta din drum, să începem cu esența fundamentală: Next.js are un router bazat pe sistem de fișiere construit pe conceptul de pagini.
Pagini
Paginile din Next.js sunt componente React care sunt disponibile automat ca rute. Acestea sunt exportate ca exporturi implicite din directorul de pagini cu extensii de fișiere acceptate, cum ar fi .js
, .jsx
, .ts
sau .tsx
.
O aplicație tipică Next.js va avea o structură de foldere cu directoare de nivel superior, cum ar fi pagini , public și stiluri.
next-app ├── node_modules ├── pages │ ├── index.js // path: base-url (/) │ ├── books.jsx // path: /books │ └── book.ts // path: /book ├── public ├── styles ├── .gitignore ├── package.json └── README.md
Fiecare pagină este o componentă React:
// pages/books.js — `base-url/book` export default function Book() { return
Cărți
}
Notă : Rețineți că paginile pot fi denumite și „gestionare de rute”.
Pagini personalizate
Acestea sunt pagini speciale care se află în directorul de pagini , dar nu participă la rutare. Acestea sunt prefixate cu simbolul de subliniere, ca în _app.js
și _document.js
.
-
_app.js
Aceasta este o componentă personalizată care se află în folderul pagini. Next.js folosește această componentă pentru a inițializa pagini. -
_document.js
La fel ca_app.js
,_document.js
este o componentă personalizată pe care Next.js o folosește pentru a vă mări aplicațiile<html>
și etichetele<body>
. Acest lucru este necesar deoarece paginile Next.js omit definiția de marcare a documentului din jur.
next-app ├── node_modules ├── pages │ ├── _app.js // ️ Custom page (unavailable as a route) │ ├── _document.jsx // ️ Custom page (unavailable as a route) │ └── index.ts // path: base-url (/) ├── public ├── styles ├── .gitignore ├── package.json └── README.md
Legătura între pagini
Next.js expune o componentă Link
din API- next/link
care poate fi utilizată pentru a efectua tranziții de rută pe partea client între pagini.
// Import the <Link/> component import Link from "next/link"; // This could be a page component export default function TopNav() { return ( <nav> <Link href="/">Home</Link> <Link href="/">Publications</Link> <Link href="/">About</Link> </nav> ) } // This could be a non-page component export default function Publications() { return ( <section> <TopNav/> {/* ... */} </section> ) }
Componenta Link
poate fi folosită în interiorul oricărei componente, fie pagină sau nu. Când este folosită în forma sa cea mai de bază, ca în exemplul de mai sus, componenta Link
se traduce într-un hyperlink cu un atribut href
. (Mai multe despre Link
în secțiunea următoare/link de mai jos.)
Dirijare
Sistemul de rutare bazat pe fișiere Next.js poate fi utilizat pentru a defini cele mai comune modele de rută. Pentru a se adapta acestor modele, fiecare traseu este separat în funcție de definiția sa.
Index rute
În mod implicit, în aplicația dvs. Next.js, traseul inițial/implicit este pages/index.js
, care servește automat ca punct de plecare al aplicației dvs. ca /
. Cu o adresă URL de bază localhost:3000
, această rută de index poate fi accesată la nivelul URL de bază al aplicației în browser.
Rutele indexate acționează automat ca rută implicită pentru fiecare director și pot elimina redundanțele de denumire. Structura de directoare de mai jos expune două căi de rută: /
și /home
.
next-app └── pages ├── index.js // path: base-url (/) └── home.js // path: /home
Eliminarea este mai evidentă cu rutele imbricate .
Trasee imbricate
Un traseu precum pages/book
are un nivel adânc. A merge mai adânc înseamnă a crea rute imbricate, care necesită o structură de foldere imbricate. Cu o adresă URL de bază a https://www.smashingmagazine.com
, puteți accesa ruta https://www.smashingmagazine.com/printed-books/printed-books
prin crearea unei structuri de foldere similare celei de mai jos:
next-app └── pages ├── index.js // top index route └── printed-books // nested route └── printed-books.js // path: /printed-books/printed-books
Sau eliminați redundanța căilor cu rute index și accesați ruta pentru cărți tipărite la https://www.smashingmagazine.com/printed-books
.
next-app └── pages ├── index.js // top index route └── printed-books // nested route └── index.js // path: /printed-books
Rutele dinamice joacă, de asemenea, un rol important în eliminarea redundanțelor.
Trasee dinamice
Din exemplul anterior folosim ruta index pentru a accesa toate cărțile tipărite. Pentru a accesa cărți individuale necesită fie crearea unor rute diferite pentru fiecare carte, cum ar fi:
// ️ Don't do this. next-app └── pages ├── index.js // top index route └── printed-books // nested route ├── index.js // path: /printed-books ├── typesript-in-50-lessons.js // path: /printed-books/typesript-in-50-lessons ├── checklist-cards.js // path: /printed-books/checklist-cards ├── ethical-design-handbook.js // path: /printed-books/ethical-design-handbook ├── inclusive-components.js // path: /printed-books/inclusive-components └── click.js // path: /printed-books/click
care este extrem de redundantă, nescalabilă și poate fi remediată cu rute dinamice precum:
// Do this instead. next-app └── pages ├── index.js // top index route └── printed-books ├── index.js // path: /printed-books └── [book-id].js // path: /printed-books/:book-id
Sintaxa parantezei — [book-id]
— este segmentul dinamic și nu se limitează numai la fișiere. Poate fi folosit și cu foldere precum exemplul de mai jos, făcând autorul disponibil la ruta /printed-books/:book-id/author
.
next-app └── pages ├── index.js // top index route └── printed-books ├── index.js // path: /printed-books └── [book-id] └── author.js // path: /printed-books/:book-id/author
Segmentele dinamice ale unei rute sunt expuse ca un parametru de interogare care poate fi accesat în oricare dintre componentele de conectare implicate în rută cu obiectul de query
al useRouter()
- (Mai multe despre acest lucru în secțiunea API următoare/router) ).
// printed-books/:book-id import { useRouter } from 'next/router'; export default function Book() { const { query } = useRouter(); return ( <div> <h1> book-id <em>{query['book-id']}</em> </h1> </div> ); }
// /printed-books/:book-id/author import { useRouter } from 'next/router'; export default function Author() { const { query } = useRouter(); return ( <div> <h1> Fetch author with book-id <em>{query['book-id']}</em> </h1> </div> ); }
Extinderea segmentelor dinamice de rută cu Catch All Routes
Ați văzut sintaxa de paranteză dinamică a segmentului de rută ca în exemplul anterior cu [book-id].js
. Frumusețea acestei sintaxe este că duce lucrurile și mai departe cu Catch-All Routes . Puteți deduce ce face acest lucru din nume: prinde toate rutele.
Când ne-am uitat la exemplul dinamic, am învățat cum ajută la eliminarea redundanței creării fișierelor pentru o singură rută pentru a accesa mai multe cărți cu ID-ul lor. Dar am fi putut face altceva.
Mai exact, am avut calea /printed-books/:book-id
, cu o structură de director:
next-app └── pages ├── index.js └── printed-books ├── index.js └── [book-id].js
Dacă am actualizat calea pentru a avea mai multe segmente, cum ar fi categorii, s-ar putea să ajungem la ceva de genul: /printed-books/design/:book-id
, /printed-books/engineering/:book-id
, sau mai bine /printed-books/:category/:book-id
.
Să adăugăm anul lansării: /printed-books/:category/:release-year/:book-id
. Poți vedea un model? Structura directorului devine:
next-app └── pages ├── index.js └── printed-books └── [category] └── [release-year] └── [book-id].js
Am înlocuit utilizarea fișierelor denumite cu rutele dinamice, dar cumva tot am ajuns cu o altă formă de redundanță. Ei bine, există o soluție: Prinde toate rutele care elimină nevoia de rute imbricate profund:
next-app └── pages ├── index.js └── printed-books └── [...slug].js
Folosește aceeași sintaxă pentru paranteze, cu excepția faptului că este prefixată cu trei puncte. Gândiți-vă la puncte precum sintaxa de răspândire JavaScript. S-ar putea să vă întrebați: dacă folosesc rutele catch-all, cum accesez categoria ( [category]
) și anul lansării ( [release-year]
). Doua feluri:
- În cazul exemplului cărților tipărite, obiectivul final este cartea și fiecare informații despre carte va avea metadatele atașate la ea sau
- Segmentele „slug” sunt returnate ca o matrice de parametrii de interogare.
import { useRouter } from 'next/router'; export default function Book() { const { query } = useRouter(); // There's a brief moment where `slug` is undefined // so we use the Optional Chaining (?.) and Nullish coalescing operator (??) // to check if slug is undefined, then fall back to an empty array const [category, releaseYear, bookId] = query?.slug ?? []; return ( <table> <tbody> <tr> <th>Book Id</th> <td>{bookId}</td> </tr> <tr> <th>Category</th> <td>{category}</td> </tr> <tr> <th>Release Year</th> <td>{releaseYear}</td> </tr> </tbody> </table> ); }
Iată mai multe exemple pentru traseul /printed-books/[…slug]
:
cale | Parametru de interogare |
---|---|
/printed-books/click.js | { „slug”: [„clic”] } |
/printed-books/2020/click.js | { „slug”: [„2020”, „clic”] } |
/printed-books/design/2020/click.js | { „slug”: [„design”, „2020”, „clic”] } |
Așa cum este cu ruta catch-all, ruta /printed-books
va genera o eroare 404 dacă nu furnizați o rută index de rezervă.
next-app └── pages ├── index.js └── printed-books ├── index.js // path: /printed-books └── [...slug].js
Acest lucru se datorează faptului că traseul catch-all este „strict”. Fie se potrivește cu un melc, fie aruncă o eroare. Dacă doriți să evitați crearea de rute indexate alături de rutele catch-all, puteți utiliza în schimb rutele opționale catch-all .
Extinderea segmentelor de rută dinamice cu rute Catch-All opționale
Sintaxa este aceeași cu catch-all-routes, dar cu paranteze pătrate duble.
next-app └── pages ├── index.js └── printed-books └── [[...slug]].js
În acest caz, ruta catch-all (slug) este opțională și, dacă nu este disponibilă, se întoarce la calea /printed-books
, redată cu [[…slug]].js
route handler, fără parametri de interogare.
Utilizați catch-all împreună cu rutele index sau numai rutele opționale catch-all. Evitați să folosiți rute catch-all și opționale catch-all alături.
Precedenta traseelor
Capacitatea de a putea defini cele mai comune modele de rutare poate fi o „lebădă neagră”. Posibilitatea ca rutele să se ciocnească este o amenințare care se profilează, mai ales când începeți să puneți la punct rutele dinamice.
Când este logic să faceți acest lucru, Next.js vă informează despre ciocnirile de rute sub formă de erori. Când nu, aplică prioritate rutelor în funcție de specificul lor.
De exemplu, este o eroare să aveți mai multe rute dinamice la același nivel.
// This is an error // Failed to reload dynamic routes: Error: You cannot use different slug names for the // same dynamic path ('book-id' !== 'id'). next-app └── pages ├── index.js └── printed-books ├── [book-id].js └── [id].js
Dacă te uiți îndeaproape la rutele definite mai jos, vei observa potențialul de ciocniri.
// Directory structure flattened for simplicity next-app └── pages ├── index.js // index route (also a predefined route) └── printed-books ├── index.js ├── tags.js // predefined route ├── [book-id].js // handles dynamic route └── [...slug].js // handles catch all route
De exemplu, încercați să răspundeți la asta: ce rută se ocupă de calea /printed-books/inclusive-components
?
-
/printed-books/[book-id].js
sau -
/printed-books/[…slug].js
.
Răspunsul constă în „specificitatea” gestionatorilor de rute. Rutele predefinite vin pe primul loc, urmate de rutele dinamice, apoi rutele catch-all. Vă puteți gândi la modelul de solicitare/tratare a rutei ca un pseudo-cod cu următorii pași:
- Există un handler de rută predefinit care poate gestiona ruta?
-
true
— gestionează solicitarea rutei. -
false
- treceți la 2.
-
- Există un handler dinamic de rută care poate gestiona ruta?
-
true
— gestionează solicitarea rutei. -
false
- treceți la 3.
-
- Există un catch-all route handler care poate gestiona ruta?
-
true
— gestionează solicitarea rutei. -
false
— aruncați o pagină 404 negăsită.
-
Prin urmare, /printed-books/[book-id].js
câștigă.
Iată mai multe exemple:
Traseu | Manipulator de rută | Tipul de traseu |
---|---|---|
/printed-books | /printed-books | Ruta index |
/printed-books/tags | /printed-books/tags.js | Traseu predefinit |
/printed-books/inclusive-components | /printed-books/[book-id].js | Traseu dinamic |
/printed-books/design/inclusive-components | /printed-books/[...slug].js | Traseul general |
API- next/link
API- next/link
expune componenta Link
ca o modalitate declarativă de a efectua tranziții de rută pe partea clientului.
import Link from 'next/link' function TopNav() { return ( <nav> <Link href="/">Smashing Magazine</Link> <Link href="/articles">Articles</Link> <Link href="/guides">Guides</Link> <Link href="/printed-books">Books</Link> </nav> ) }
Componenta Link
se va rezolva într-un hyperlink HTML obișnuit. Adică, <Link href="/">Smashing Magazine</Link>
se va rezolva la <a href="/">Smashing Magazine</a>
.
Elementul href
este singurul element necesar pentru componenta Link
. Consultați documentele pentru o listă completă de elemente de recuzită disponibile pe componenta Link
.
Există și alte mecanisme ale componentei Link
de care trebuie să fii conștient.
Trasee cu segmente dinamice
Înainte de Next.js 9.5.3, Link
la rute dinamice însemna că trebuia să furnizați atât href
, cât și as
prop pentru Link
, ca în:
import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href="/printed-books/[printed-book-id]" as={`/printed-books/${printedBook.id}`} > {printedBook.name} </Link> )); }
Deși acest lucru a permis Next.js să interpoleze href pentru parametrii dinamici, a fost plictisitor, predispus la erori și oarecum imperativ, iar acum a fost remediat pentru majoritatea cazurilor de utilizare odată cu lansarea Next.js 10.
Această remediere este, de asemenea, compatibilă cu versiunea inversă. Dacă ați folosit atât as
cât și href
, nimic nu se întrerupe. Pentru a adopta noua sintaxă, eliminați href
și valoarea acesteia și redenumiți as
prop în href
ca în exemplul de mai jos:
import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={`/printed-books/${printedBook.id}`}>{printedBook.name}</Link> )); }
Consultați Rezolvarea automată a href.
Cazuri de utilizare pentru prop. passHref
Aruncă o privire atentă la fragmentul de mai jos:
import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; // Say this has some sort of base styling attached function CustomLink({ href, name }) { return <a href={href}>{name}</a>; } export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={`/printed-books/${printedBook.id}`} passHref> <CustomLink name={printedBook.name} /> </Link> )); }
Elementele de recuzită passHref
forțează componenta Link
să transmită prop-ul href
către componenta copil CustomLink
. Acest lucru este obligatoriu dacă componenta Link
se încadrează peste o componentă care returnează o etichetă de hyperlink <a>
. Cazul dvs. de utilizare ar putea fi pentru că utilizați o bibliotecă precum componentele cu stil sau dacă trebuie să treceți mai mulți copii la componenta Link
, deoarece se așteaptă doar un singur copil.
Consultați documentele pentru a afla mai multe.
Obiecte URL
href
al componentei Link
poate fi, de asemenea, un obiect URL cu proprietăți precum query
, care este formatată automat într-un șir URL.
Cu obiectul printedBooks
, exemplul de mai jos va trimite la:
-
/printed-books/ethical-design?name=Ethical+Design
and -
/printed-books/design-systems?name=Design+Systems
.
import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={{ pathname: `/printed-books/${printedBook.id}`, query: { name: `${printedBook.name}` }, }} > {printedBook.name} </Link> )); }
Dacă includeți un segment dinamic în pathname
, atunci trebuie să îl includeți și ca proprietate în obiectul de interogare pentru a vă asigura că interogarea este interpolată în pathname
:
import Link from 'next/link'; const printedBooks = [ { name: 'Ethical Design', id: 'ethical-design' }, { name: 'Design Systems', id: 'design-systems' }, ]; // In this case the dynamic segment `[book-id]` in pathname // maps directly to the query param `book-id` export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={{ pathname: `/printed-books/[book-id]`, query: { 'book-id': `${printedBook.id}` }, }} > {printedBook.name} </Link> )); }
Exemplul de mai sus are căi:
-
/printed-books/ethical-design
, și -
/printed-books/design-systems
.
Dacă inspectați atributul href
în VSCode, veți găsi tipul LinkProps
, cu proprietatea href
un tip Url
, care este fie un string
, fie UrlObject
, așa cum sa menționat anterior.
Inspectarea UrlObject
duce în continuare la interfața cu proprietățile:
Puteți afla mai multe despre aceste proprietăți în documentația modulului URL Node.js.
Un caz de utilizare al hash-ului este acela de a lega anumite secțiuni dintr-o pagină.
import Link from 'next/link'; const printedBooks = [{ name: 'Ethical Design', id: 'ethical-design' }]; export default function PrintedBooks() { return printedBooks.map((printedBook) => ( <Link href={{ pathname: `/printed-books/${printedBook.id}`, hash: 'faq', }} > {printedBook.name} </Link> )); }
Hyperlinkul se va rezolva la /printed-books/ethical-design#faq
.
Aflați mai multe în documente.
next/router
API
Dacă next/link
este declarativ, atunci next/router
este imperativ. Acesta expune un cârlig useRouter
care permite accesul la obiectul router
din interiorul oricărei componente de funcție. Puteți folosi acest cârlig pentru a efectua manual rutarea, mai ales în anumite scenarii în care next/link
nu este suficient sau în care trebuie să vă „conectați” la rutare.
import { useRouter } from 'next/router'; export default function Home() { const router = useRouter(); function handleClick(e) { e.preventDefault(); router.push(href); } return ( <button type="button" onClick={handleClick}>Click me</button> ) }
useRouter
este un hook React și nu poate fi folosit cu clase. Aveți nevoie de obiectul router
în componente de clasă? Utilizați withRouter
.
import { withRouter } from 'next/router'; function Home({router}) { function handleClick(e) { e.preventDefault(); router.push(href); } return ( <button type="button" onClick={handleClick}>Click me</button> ) } export default withRouter(Home);
Obiectul router
Atât componenta useRouter
, cât și componenta de ordin superior withRouter
, returnează un obiect router cu proprietăți precum pathname
, query
, asPath
și basePath
care vă oferă informații despre starea URL a paginii curente, locale
, locales
și defaultLocale
care oferă informații despre local implicit activ, acceptat sau curent.
Obiectul router are, de asemenea, metode precum push
pentru navigarea la o nouă adresă URL prin adăugarea unei noi intrări URL în stiva de istoric, replace
, similar cu push, dar înlocuiește adresa URL curentă în loc să adauge o nouă intrare URL în stiva de istoric.
Aflați mai multe despre obiectul router.
Configurare personalizată a rutei Cu next.config.js
Acesta este un modul Node.js obișnuit care poate fi utilizat pentru a configura anumite comportamente Next.js.
module.exports = { // configuration options }
Nu uitați să reporniți serverul oricând actualizați
next.config.js
. Află mai multe.
Calea de bază
S-a menționat că traseul inițial/implicit în Next.js este pages/index.js
cu calea /
. Acesta este configurabil și puteți face ca ruta implicită să fie o cale secundară a domeniului.
module.exports = { // old default path: / // new default path: /dashboard basePath: '/dashboard', };
Aceste modificări vor avea efect automat în aplicația dvs. cu toate /
căile direcționate către /dashboard
.
Această funcție poate fi utilizată numai cu Next.js 9.5 și versiuni ulterioare. Află mai multe.
Bara oblica de la urma
În mod implicit, o bară oblică finală nu va fi disponibilă la sfârșitul fiecărei adrese URL. Cu toate acestea, puteți comuta cu:
module.exports = { trailingSlash: true };
# trailingSlash: false /printed-books/ethical-design#faq # trailingSlash: true /printed-books/ethical-design/#faq
Atât funcțiile de cale de bază, cât și de slash final pot fi utilizate numai cu Next.js 9.5 și versiuni ulterioare.
Concluzie
Rutarea este una dintre cele mai importante părți ale aplicației dvs. Next.js și se reflectă în routerul bazat pe sistemul de fișiere, construit pe conceptul de pagini. Paginile pot fi folosite pentru a defini cele mai comune modele de rută. Conceptele de rutare și randare sunt strâns legate. Luați cu dvs. lecțiile din acest articol în timp ce vă creați propria aplicație Next.js sau lucrați la o bază de cod Next.js. Și verificați resursele de mai jos pentru a afla mai multe.
Resurse conexe
- Documentația oficială Next.js pentru Pages
- Documentația oficială Next.js pentru preluarea datelor
- Documentația oficială Next.js pentru next.config.js
- Next.js 10: Rezolvarea automată a
href
- Documentația oficială Next.js pentru next/link
- Documentația oficială Next.js pentru next/router