Next.js ist als Web-Development-Framework weit verbreitet und mit Version 13 wurde der neue App Router als Standard-Routing-System eingeführt.
Wenn man an beiden Projekten – Pages Router und App Router – arbeitet, kann es vorkommen, dass man sich fragt: "Welche Schreibweise war nochmal die richtige?" Genau das ist mir passiert!!
Es gibt erhebliche Unterschiede zwischen Pages Router und App Router, die man nicht außer Acht lassen sollte – angefangen bei der Routing-Definition basierend auf Dateistruktur, über die Behandlung dynamischer URL-Teile, bis hin zu Rendering-Mechanismen und Datenbeschaffung von APIs, also Kernaspekte der Anwendungsentwicklung.
Mit Fokus auf "oft verwechselte" Punkte dokumentiere ich hier die wichtigsten Unterschiede zwischen Pages Router und App Router – zwar nicht erschöpfend, aber als praktische Gedächtnisstütze!
Unterschiede in der Datei-Strukturierung
Pages Router: Die Einfachheit, dass Dateinamen direkt zum Pfad werden
Im Pages Router ist es ganz einfach: .js, .jsx, .ts und .tsx Dateien, die im pages-Verzeichnis platziert sind, werden direkt zu URL-Pfaden – der Dateiname ist der Pfad.
Beispiel: src/page/about.tsx ⇒ Das Routing wird zu /about.
App Router: Strukturiert nach Ordnern und spezifischen Dateinamen
Mit dem App Router können Sie das Routing konfigurieren, indem Sie Ordner und Dateien unter src/app platzieren.
Dateien mit dem spezifischen Namen "page" werden jedoch als Inhalte der Seite behandelt, die dem entsprechenden Pfad entspricht.
Beispiel: src/app/about/page.tsx ⇒ Das Routing wird zu /about.
Die „speziellen Dateien", die den App Router auszeichnen
Darüber hinaus gibt es im App Router weitere Dateien mit besonderen Funktionen neben page.tsx.
app/
├── page.tsx --> ページの中身。これが一番よく使うファイル
├── route.tsx --> APIの定義(page.jsと共存不可)
├── layout.tsx --> 共通の見た目
├── loading.tsx --> 読み込み中の画面
├── error.tsx --> エラー時の画面
├── global-error.tsx --> グローバルエラー画面
├── templete.tsx --> 共通の見た目(リセットされるレイアウト)
├── default.tsx --> デフォルトの画面
└── not-found.tsx --> notFound関数がスローされたときの画面
Persönlich war ich überrascht von not-found.tsx. Allein durch die Bereitstellung dieser Seite wird sie automatisch angezeigt, wenn auf nicht vorhandene URLs zugegriffen wird. Ich war begeistert, dass sich so etwas so einfach implementieren lässt.
Unterschiede beim Rendering
Komponenten im Pages Router basieren grundsätzlich darauf, auf der Client-Seite interaktiv zu sein. Das Rendering auf der Server-Seite wird hauptsächlich für schnelleres initiales Laden und SEO durchgeführt. React-Hooks wie useState und useEffect können frei innerhalb von Seitenkomponenten und ihren untergeordneten Komponenten verwendet werden.
Andererseits werden Komponenten in app/ des App Routers standardmäßig als Server-Komponenten behandelt, sofern nicht explizit anders angegeben. Daher können React-Hooks wie useState und useEffect nicht verwendet werden. Auch clientseitige Aktionen und Event-Handler wie onClick können nicht verwendet werden.
Um CSR mit dem App Router zu verwenden, schreiben Sie use client.
use client
Dies ist eine Deklaration der Grenze zwischen Server Component und Client Component. Wenn Sie use client deklarieren, werden nicht nur diese Komponente, sondern alle importierten Module als Client Components behandelt.
Dynamisches Routing [○○]
Das dynamische Routing von Next.js ist ein Mechanismus, um "dynamische URLs" zu unterstützen, bei denen sich Teile der URL je nach Benutzer oder Inhalt ändern, wie z. B. auf Seiten mit Artikel- oder Newsdetails.
Angenommen, es gibt Links, die zu Artikel A und Artikel B führen.
import Link from "next/link";
const linkStyle=`ext-lg font-bold border-b border-primary px-1`
export default function page() {
return (
<div>
<div className="flex gap-6">
<Link href="/post/A" className={linkStyle}>記事Aへのリンク</Link>
<Link href="/post/B" className={linkStyle}>記事Bへのリンク</Link>
</div>
</div>
);
}Ziele der einzelnen Links
Wenn Sie dynamisches Routing verwenden möchten, erstellen Sie einfach eine Datei namens [slug], und Sie können sowohl für post/A als auch für post/B dieselbe Vorlage verwenden.
*Die Benennung in [ ] ist beliebig, es muss nicht slug sein
Im Fall des App Routers
/app/post/[slug]/page.tsx
export default aysinc function PostPage({ params }: { params: Promise<{ slug: string }>) {
const {slug}= await params;
return (
<div>
<h1>記事: {slug}</h1>
</div>
);
}
Verwenden Sie params. params.slug enthält den [slug]-Teil der URL.
* params bei der Parametererfassung musste bisher nicht asynchron sein, aber ab Next.js 15 wurde dies geändert, um asynchron zu erfolgen. Daher scheint es notwendig zu sein, props als Promise-Typ zu definieren.
Im Falle von Pages Router
/pages/post/[slug].tsx
import { useRouter } from 'next/router';
export default function PostPage() {
const router = useRouter();
const { slug } = router.query;
return (
<div>
<h1>記事: {slug}</h1>
</div>
);
}
useRouter wird verwendet. In router.query.slug wird der Wert des [slug]-Teils der URL gespeichert.
API-Datenbeschaffungsmethode
microCMS, das auch in dieser Liberogic-Kolumne sehr aktiv ist, funktioniert gut mit Frameworks wie Next.js.
Im Fall des App Routers
Es ist ausreichend, einfach fetch oder async await zu verwenden.
Allerdings werden Dateien, in denen use client deklariert ist, zu CSR, daher können async await nicht verwendet werden!
async function getPost() {
const res = await fetch(`https://.../api/data/`);
// エラーハンドリング例
if (!res.ok) {
throw new Error(`Failed to fetch post: ${res.status}`);
}
return res.json();
}
Aufrufort
export default function Example() {
const data = await getPost()
// ... data を使って表示 ...
}
Im Falle von Pages Router
Verwenden Sie getStaticProps, um die abgerufenen Daten als props an die Seitenkomponente zu übergeben.
export async function getServerSideProps(context) {
// context.req, context.res などにアクセス可能
const res = await fetch(`https://.../api/data/`, {
headers: { Cookie: context.req.headers.cookie } // 例: Cookieを渡す
});
const data = await res.json();
return {
props: {
data,
},
};
}
Aufrufort
export default function Example({ data }) {
// ... data を使って表示 ...
}
Verstehen Sie die beiden Router und beherrschen Sie Next.js!
In meinem Fall war mein erstes Projekt mit Next.js mit dem App Router.
Später arbeitete ich in einem anderen Projekt mit dem Pages Router und fragte mich: "Sollte ich die Datei index.tsx oder page.tsx nennen??"
Der heutige Inhalt ist nur ein kleiner Teil von Next.js, aber durch die erneute Untersuchung der Unterschiede zwischen App Router und Pages Router konnte ich mein Verständnis selbst klären.
Persönlich mag ich die App-Router-Syntax, weil sie verständlicher ist, aber ich möchte auch bei Pages-Router-Projekten gut zurechtkommen.
Das Ideal ist, Next.js tiefer zu verstehen und beide Router je nach Projekt und Anforderungen flexibel einsetzen zu können!
Ich konzentriere mich auf Markup und entwickle Frontends mit JavaScript, React und Next.js. Es freut mich immer, wenn die Websites, an denen ich mitgearbeitet habe, erfolgreich veröffentlicht werden! Mein Hobby ist Gitarrespielen. Ich mag Katzen und gebackene Süßkartoffeln 🐱🍠
Hiraicchi
Frontend-Engineer / Eintritt 2022