Routing po stronie klienta w Next.js

Opublikowany: 2022-03-10
Szybkie podsumowanie ↬ Next.js ma system routingu oparty na plikach, w którym każda strona automatycznie staje się trasą na podstawie nazwy pliku. Każda strona jest domyślnym wyeksportowanym komponentem React z katalogu stron, którego można użyć do zdefiniowania najpopularniejszych wzorców tras. Ten artykuł poprowadzi Cię przez prawie wszystko, co musisz wiedzieć o routingu w Next.js i wskaże Ci powiązane tematy i koncepcje.

Hiperłącza były jednym z klejnotów sieci od samego początku. Według MDN, hiperłącza są tym, co sprawia, że ​​sieć jest siecią. Chociaż jest używany do celów takich jak tworzenie łączy między dokumentami, jego głównym zastosowaniem jest odwoływanie się do różnych stron internetowych, które można zidentyfikować za pomocą unikalnego adresu internetowego lub adresu URL.

Routing jest ważnym aspektem każdej aplikacji internetowej, podobnie jak hiperłącza do sieci. Jest to mechanizm, przez który żądania są kierowane do kodu, który je obsługuje. W odniesieniu do routingu strony Next.js są przywoływane i można je zidentyfikować za pomocą unikalnej ścieżki URL. Jeśli sieć składa się z nawigacyjnych stron internetowych połączonych hiperłączami , wówczas każda aplikacja Next.js składa się ze stron z możliwością wyznaczania tras (obsługi tras lub tras) połączonych routerem.

Next.js ma wbudowaną obsługę routingu, który może być niewygodny do rozpakowania, zwłaszcza gdy rozważa się renderowanie i pobieranie danych. Warunkiem wstępnym zrozumienia routingu po stronie klienta w Next.js jest przegląd pojęć, takich jak routing, renderowanie i pobieranie danych w Next.js.

Ten artykuł przyda się programistom React, którzy znają Next.js i chcą dowiedzieć się, jak radzi sobie z routingiem. Musisz mieć praktyczną wiedzę o React i Next.js, aby jak najlepiej wykorzystać artykuł, który dotyczy wyłącznie routingu po stronie klienta i powiązanych koncepcji w Next.js.

Routing i renderowanie

Routing i renderowanie uzupełniają się nawzajem i będą odgrywać ogromną rolę w trakcie tego artykułu. Podoba mi się, jak Gaurav je wyjaśnia:

Routing to proces, w którym użytkownik jest przekierowywany do różnych stron w witrynie.

Renderowanie to proces umieszczania tych stron w interfejsie użytkownika. Za każdym razem, gdy żądasz trasy do określonej strony, renderujesz również tę stronę, ale nie każde renderowanie jest wynikiem trasy.

Poświęć pięć minut na przemyślenie tego.

To, co musisz zrozumieć o renderowaniu w Next.js, to fakt, że każda strona jest wstępnie renderowana z wyprzedzeniem wraz z minimalnym kodem JavaScript niezbędnym do tego, aby stała się w pełni interaktywna w procesie znanym jako hydratacja. Sposób, w jaki Next.js to robi, w dużym stopniu zależy od formy wstępnego renderowania: generowania statycznego lub renderowania po stronie serwera , które są ściśle powiązane z stosowaną techniką pobierania danych i oddzielone momentem generowania kodu HTML strony.

W zależności od wymagań dotyczących pobierania danych możesz korzystać z wbudowanych funkcji pobierania danych, takich jak getStaticProps , getStaticPaths lub getServerSideProps , narzędzi do pobierania danych po stronie klienta, takich jak SWR, respond-query lub tradycyjnych metod pobierania danych, takich jak pobieranie po- renderuj, pobieraj, a następnie renderuj, renderuj w miarę pobierania (z trybem Suspense).

Wstępne renderowanie (przed renderowaniem — do interfejsu użytkownika ) jest uzupełnieniem routingu i w dużym stopniu łączy się z pobieraniem danych — to samodzielny temat w Next.js. Tak więc, chociaż te pojęcia są albo komplementarne, albo ściśle powiązane, ten artykuł będzie koncentrował się wyłącznie na samej nawigacji między stronami (routing), z odniesieniami do pokrewnych pojęć tam, gdzie jest to konieczne.

Odkładając to na bok, zacznijmy od podstawowego sedna: Next.js ma router oparty na systemie plików oparty na koncepcji stron.

Więcej po skoku! Kontynuuj czytanie poniżej ↓

Strony

Strony w Next.js to React Components, które są automatycznie dostępne jako trasy. Są one eksportowane jako domyślne eksporty z katalogu stron z obsługiwanymi rozszerzeniami plików, takimi jak .js , .jsx , .ts lub .tsx .

Typowa aplikacja Next.js będzie miała strukturę folderów z katalogami najwyższego poziomu, takimi jak pages , public i styles.

 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

Każda strona to komponent React:

 // pages/books.js — `base-url/book` export default function Book() { return

Książki

}

Uwaga : pamiętaj, że strony mogą być również określane jako „obsługi tras”.

Strony niestandardowe

Są to specjalne strony, które znajdują się w katalogu stron , ale nie uczestniczą w routingu. Są one poprzedzone symbolem podkreślenia, jak w _app.js i _document.js .

  • _app.js
    Jest to niestandardowy komponent, który znajduje się w folderze stron. Next.js używa tego komponentu do inicjowania stron.
  • _document.js
    Podobnie jak _app.js , _document.js jest niestandardowym komponentem, którego Next.js używa do rozszerzania tagów <html> i <body> aplikacji. Jest to konieczne, ponieważ strony Next.js pomijają definicję znaczników otaczającego dokumentu.
 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

Łączenie między stronami

Next.js udostępnia składnik Link z interfejsu API next/link , który może być używany do wykonywania przejść tras po stronie klienta między stronami.

 // 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> ) }

Komponent Link może być używany wewnątrz dowolnego komponentu, strony lub nie. W najbardziej podstawowej formie, jak w powyższym przykładzie, składnik Link przekłada się na hiperłącze z atrybutem href . (Więcej o Link w sekcji następny/link poniżej.)

Rozgromienie

Oparty na plikach system routingu Next.js może służyć do definiowania najpopularniejszych wzorców tras. Aby dostosować się do tych wzorców, każda trasa jest rozdzielana na podstawie jej definicji.

Indeksuj trasy

Domyślnie w aplikacji Next.js trasa początkowa/domyślna to pages/index.js , która automatycznie służy jako punkt początkowy aplikacji jako / . Za pomocą podstawowego adresu URL localhost:3000 ta trasa indeksu jest dostępna na poziomie podstawowego adresu URL aplikacji w przeglądarce.

Trasy indeksujące automatycznie działają jako trasy domyślne dla każdego katalogu i mogą wyeliminować nadmiarowość nazw. Poniższa struktura katalogów udostępnia dwie ścieżki tras: / i /home .

 next-app └── pages ├── index.js // path: base-url (/) └── home.js // path: /home

Eliminacja jest bardziej widoczna w przypadku tras zagnieżdżonych .

Trasy zagnieżdżone

Trasa, taka jak pages/book , ma jeden poziom głębokości. Aby wejść głębiej, należy utworzyć zagnieżdżone trasy, co wymaga zagnieżdżonej struktury folderów. Za pomocą podstawowego adresu URL https://www.smashingmagazine.com możesz uzyskać dostęp do trasy https://www.smashingmagazine.com/printed-books/printed-books , tworząc strukturę folderów podobną do poniższej:

 next-app └── pages ├── index.js // top index route └── printed-books // nested route └── printed-books.js // path: /printed-books/printed-books

Lub wyeliminuj nadmiarowość ścieżek za pomocą tras indeksowych i uzyskaj dostęp do trasy dla książek drukowanych pod https://www.smashingmagazine.com/printed-books .

 next-app └── pages ├── index.js // top index route └── printed-books // nested route └── index.js // path: /printed-books

Ważną rolę w eliminacji zwolnień odgrywają również trasy dynamiczne .

Dynamiczne trasy

Z poprzedniego przykładu używamy ścieżki indeksu, aby uzyskać dostęp do wszystkich drukowanych książek. Aby uzyskać dostęp do poszczególnych książek, należy utworzyć różne trasy dla każdej książki, takie jak:

 // ️ 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

który jest wysoce nadmiarowy, nieskalowalny i można go naprawić za pomocą tras dynamicznych, takich jak:

 // 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

Składnia nawiasów — [book-id] — jest segmentem dynamicznym i nie ogranicza się do samych plików. Można go również używać z folderami, jak w poniższym przykładzie, udostępniając autora pod adresem /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

Dynamiczne segmenty trasy są udostępniane jako parametr zapytania, do którego można uzyskać dostęp z dowolnego komponentu łączącego zaangażowanego w trasę z obiektem query haka useRouter() — (więcej na ten temat w sekcji API next/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> ); }

Rozszerzanie dynamicznych segmentów tras z funkcją Catch All Routes

Widziałeś składnię dynamicznego nawiasu segmentu trasy, jak w poprzednim przykładzie z [book-id].js . Piękno tej składni polega na tym, że dzięki Catch-All Routes posuwa się ona jeszcze dalej. Możesz wywnioskować, co to robi z nazwy: przechwytuje wszystkie trasy.

Kiedy przyjrzeliśmy się dynamicznemu przykładowi, dowiedzieliśmy się, jak pomaga wyeliminować nadmiarowość tworzenia plików dla pojedynczej trasy dostępu do wielu książek za pomocą ich identyfikatora. Ale możemy zrobić coś jeszcze.

W szczególności mieliśmy ścieżkę /printed-books/:book-id , ze strukturą katalogów:

 next-app └── pages ├── index.js └── printed-books ├── index.js └── [book-id].js

Jeśli zaktualizujemy ścieżkę, aby zawierała więcej segmentów, takich jak kategorie, możemy otrzymać coś takiego: /printed-books/design/:book-id , /printed-books/engineering/:book-id , a jeszcze lepiej /printed-books/:category/:book-id .

Dodajmy rok wydania: /printed-books/:category/:release-year/:book-id . Czy widzisz wzór? Struktura katalogów staje się:

 next-app └── pages ├── index.js └── printed-books └── [category] └── [release-year] └── [book-id].js

Zamieniliśmy użycie nazwanych plików na trasy dynamiczne, ale w jakiś sposób udało nam się uzyskać inną formę redundancji. Cóż, jest poprawka: Catch All Routes, która eliminuje potrzebę głęboko zagnieżdżonych tras:

 next-app └── pages ├── index.js └── printed-books └── [...slug].js

Używa tej samej składni nawiasów, z wyjątkiem tego, że jest poprzedzony trzema kropkami. Pomyśl o kropkach jak o składni rozłożonej JavaScript. Być może zastanawiasz się: jeśli korzystam z tras typu catch-all, w jaki sposób mogę uzyskać dostęp do kategorii ( [category] ) i roku wydania ( [release-year] ). Dwie drogi:

  1. W przypadku książek drukowanych, ostatecznym celem jest książka, a każda informacja o książce będzie miała dołączone metadane, lub
  2. Segmenty „slug” są zwracane jako tablica parametrów zapytania.
 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> ); }

Oto więcej przykładów dla trasy /printed-books/[…slug] :

Ścieżka Parametr zapytania
/printed-books/click.js { „ślimak”: [„klik”] }
/printed-books/2020/click.js { „ślimak”: [„2020”, „klik”] }
/printed-books/design/2020/click.js { „ślimak”: [„projekt”, „2020”, „klik”] }

Podobnie jak w przypadku trasy catch-all, trasa /printed-books zgłosi błąd 404, chyba że podasz trasę indeksu rezerwowego.

 next-app └── pages ├── index.js └── printed-books ├── index.js // path: /printed-books └── [...slug].js

Dzieje się tak, ponieważ trasa typu catch-all jest „ścisła”. Albo pasuje do ślimaka, albo zgłasza błąd. Jeśli chcesz uniknąć tworzenia tras indeksowych obok tras typu catch-all, możesz zamiast tego użyć opcjonalnych tras typu catch-all .

Rozszerzanie dynamicznych segmentów tras za pomocą opcjonalnych tras typu „catch-all”

Składnia jest taka sama jak w przypadku tras typu catch-all, ale zamiast tego zastosowano podwójne nawiasy kwadratowe.

 next-app └── pages ├── index.js └── printed-books └── [[...slug]].js

W takim przypadku trasa catch-all (slug) jest opcjonalna, a jeśli nie jest dostępna, powraca do ścieżki /printed-books , renderowanej za pomocą procedury obsługi trasy [[…slug]].js bez żadnych parametrów zapytania.

Używaj tylko tras typu catch-all obok tras indeksowych lub opcjonalnych tras typu catch-all. Unikaj korzystania z tras typu „catch-all” i opcjonalnych tras typu „catch-all”.

Pierwszeństwo tras

Możliwość zdefiniowania najczęstszych wzorców tras może być „czarnym łabędziem”. Możliwość kolizji tras jest groźnym zagrożeniem, zwłaszcza gdy zaczniesz pracować nad dynamicznymi trasami.

Kiedy ma to sens, Next.js informuje o kolizjach tras w postaci błędów. Jeśli tak nie jest, nadaje pierwszeństwo trasom zgodnie z ich specyfiką.

Na przykład błędem jest posiadanie więcej niż jednej trasy dynamicznej na tym samym poziomie.

 // 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

Jeśli przyjrzysz się bliżej zdefiniowanym poniżej trasom, zauważysz potencjał do starć.

 // 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

Na przykład spróbuj odpowiedzieć na to: jaka trasa obsługuje ścieżkę /printed-books/inclusive-components ?

  • /printed-books/[book-id].js , lub
  • /printed-books/[…slug].js .

Odpowiedź tkwi w „specyfice” obsługi tras. Najpierw są trasy predefiniowane, następnie trasy dynamiczne, a następnie trasy typu catch-all. Możesz myśleć o modelu żądania/obsługi trasy jak o pseudokodzie, wykonując następujące kroki:

  1. Czy istnieje predefiniowany program obsługi tras , który może obsługiwać trasę?
    • true — obsłuż żądanie trasy.
    • false — przejdź do 2.
  2. Czy istnieje program obsługi tras dynamicznych , który może obsługiwać trasę?
    • true — obsłuż żądanie trasy.
    • false — przejdź do 3.
  3. Czy istnieje program obsługi tras typu catch-all , który może obsłużyć trasę?
    • true — obsłuż żądanie trasy.
    • false — wyrzuć stronę 404, której nie znaleziono.

Dlatego /printed-books/[book-id].js wygrywa.

Oto więcej przykładów:

Trasa Obsługa tras Rodzaj trasy
/printed-books /printed-books Trasa indeksu
/printed-books/tags /printed-books/tags.js Predefiniowana trasa
/printed-books/inclusive-components /printed-books/[book-id].js Trasa dynamiczna
/printed-books/design/inclusive-components /printed-books/[...slug].js Trasa typu „catch-all”

next/link API

Interfejs API next/link udostępnia składnik Link jako deklaratywny sposób wykonywania przejść tras po stronie klienta.

 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> ) }

Komponent Link zmieni się w zwykłe hiperłącze HTML. Oznacza to, że <Link href="/">Smashing Magazine</Link> zmieni się w <a href="/">Smashing Magazine</a> .

Właściwość href jest jedyną wymaganą właściwością komponentu Link . Zapoznaj się z dokumentacją, aby uzyskać pełną listę właściwości dostępnych w komponencie Link .

Należy pamiętać o innych mechanizmach komponentu Link .

Trasy z dynamicznymi segmentami

Przed Link 9.5.3 łączenie z trasami dynamicznymi oznaczało, że trzeba było podać zarówno atrybut href , as i atrybut Link , jak w:

 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> )); }

Chociaż umożliwiło to Next.js interpolację href dla parametrów dynamicznych, było to żmudne, podatne na błędy i nieco konieczne, a teraz zostało naprawione w większości przypadków użycia wraz z wydaniem Next.js 10.

Ta poprawka jest również zgodna z poprzednimi wersjami. Jeśli używasz zarówno as , jak i href , nic się nie zepsuje. Aby przyjąć nową składnię, odrzuć właściwość href i jej wartość oraz zmień nazwę as prop na href , jak w poniższym przykładzie:

 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> )); }

Zobacz Automatyczne rozwiązywanie href.

Przypadki użycia dla passHref Prop

Przyjrzyj się uważnie poniższemu fragmentowi:

 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> )); }

Właściwości passHref wymuszają na komponencie Link przekazanie właściwości href do komponentu potomnego CustomLink . Jest to obowiązkowe, jeśli składnik Link zawija się w składnik, który zwraca znacznik <a> hiperłącza. Przykładem użycia może być to, że używasz biblioteki, takiej jak styled-components, lub jeśli potrzebujesz przekazać wiele elementów potomnych do składnika Link , ponieważ oczekuje on tylko jednego elementu potomnego.

Zobacz dokumentację, aby dowiedzieć się więcej.

Obiekty URL

Właściwość href komponentu Link może być również obiektem URL z właściwościami takimi jak query , które jest automatycznie formatowane do ciągu URL.

W przypadku obiektu printedBooks poniższy przykład będzie zawierał link do:

  1. /printed-books/ethical-design?name=Ethical+Design and
  2. /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> )); }

Jeśli dołączysz dynamiczny segment do pathname , musisz również dołączyć go jako właściwość w obiekcie zapytania , aby upewnić się , że zapytanie jest interpolowane w 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> )); }

Powyższy przykład ma ścieżki:

  1. /printed-books/ethical-design , oraz
  2. /printed-books/design-systems .

Jeśli sprawdzisz atrybut href w VSCode, znajdziesz typ LinkProps , z właściwością href typu Url , który jest string lub UrlObject , jak wspomniano wcześniej.

Zrzut ekranu sprawdzanego typu LinkProps w VSCode
Sprawdzanie LinkProps w VSCode. (duży podgląd)

Inspekcja UrlObject prowadzi dalej do interfejsu z właściwościami:

Zrzut ekranu sprawdzanego <code>UrlObject</code> w VSCode
Inspekcja UrlObject w programie VSCode. (duży podgląd)

Więcej informacji o tych właściwościach można znaleźć w dokumentacji modułu URL Node.js.

Jednym z przypadków użycia skrótu jest linkowanie do określonych sekcji na stronie.

 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> )); }

Hiperłącze zmieni się na /printed-books/ethical-design#faq .

Dowiedz się więcej w dokumentacji.

next/router API

Jeśli next/link jest deklaratywne, to next/router jest konieczny. Odsłania zaczep useRouter , który umożliwia dostęp do obiektu router wewnątrz dowolnego składnika funkcji. Możesz użyć tego zaczepu do ręcznego wykonania routingu, zwłaszcza w niektórych scenariuszach, w których next/link nie wystarczy lub musisz „zahaczyć się” o routing.

 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 jest hakiem React i nie może być używany z klasami. Potrzebujesz obiektu router w komponentach klasy? Użyj 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);

Obiekt router

Zarówno useRouter hook, jak i składnik wyższego rzędu withRouter zwracają obiekt routera z właściwościami, takimi jak pathname , query , asPath i basePath , który dostarcza informacji o stanie adresu URL bieżącej strony , locale , locales i defaultLocale , który zawiera informacje o aktywne, obsługiwane lub aktualne domyślne ustawienia regionalne.

Obiekt routera ma również metody, takie jak push do nawigowania do nowego adresu URL przez dodanie nowego wpisu adresu URL do stosu historii, replace , podobny do push, ale zastępuje bieżący adres URL zamiast dodawać nowy wpis adresu URL do stosu historii.

Dowiedz się więcej o obiekcie routera.

Konfiguracja niestandardowej trasy za pomocą next.config.js

Jest to zwykły moduł Node.js, którego można użyć do skonfigurowania określonego zachowania Next.js.

 module.exports = { // configuration options }

Pamiętaj o ponownym uruchomieniu serwera za każdym razem, gdy aktualizujesz next.config.js . Ucz się więcej.

Ścieżka podstawowa

Wspomniano, że początkowa/domyślna trasa w Next.js to pages/index.js ze ścieżką / . Jest to konfigurowalne i możesz ustawić trasę domyślną jako podścieżkę domeny.

 module.exports = { // old default path: / // new default path: /dashboard basePath: '/dashboard', };

Te zmiany automatycznie zaczną obowiązywać w Twojej aplikacji ze wszystkimi ścieżkami / ścieżkami skierowanymi do /dashboard .

Ta funkcja może być używana tylko z Next.js 9.5 i nowszymi. Ucz się więcej.

Końcowy ukośnik

Domyślnie końcowy ukośnik nie będzie dostępny na końcu każdego adresu URL. Możesz to jednak zmienić za pomocą:

 module.exports = { trailingSlash: true };
 # trailingSlash: false /printed-books/ethical-design#faq # trailingSlash: true /printed-books/ethical-design/#faq

Zarówno ścieżka podstawowa, jak i funkcje końcowego ukośnika mogą być używane tylko z Next.js 9.5 i nowszymi.

Wniosek

Routing jest jedną z najważniejszych części Twojej aplikacji Next.js i odzwierciedla się w routerze opartym na systemie plików zbudowanym na koncepcji stron. Strony mogą służyć do definiowania najpopularniejszych wzorców tras. Koncepcje routingu i renderowania są ze sobą ściśle powiązane. Weź ze sobą lekcje zawarte w tym artykule, tworząc własną aplikację Next.js lub pracując nad bazą kodu Next.js. Sprawdź poniższe zasoby, aby dowiedzieć się więcej.

Powiązane zasoby

  • Oficjalna dokumentacja Next.js dla stron
  • Oficjalna dokumentacja Next.js do pobierania danych
  • Oficjalna dokumentacja Next.js dla next.config.js
  • Next.js 10: Automatyczne rozwiązywanie href
  • Oficjalna dokumentacja Next.js dla next/link
  • Oficjalna dokumentacja Next.js dla next/router