Next.js erfreut sich als Web-Entwicklungsframework großer Beliebtheit. Mit Version 13 wurde der neue App Router als Standard-Routing-System eingeführt.
Wer an Projekten mit sowohl Pages Router als auch App Router arbeitet, fragt sich vielleicht schnell: "Wie war das noch mal?" Genau so ging es mir selbst!
Besonders in den Grundlagen der Anwendungsentwicklung gibt es zwischen Pages Router und App Router wichtige Unterschiede. Dazu gehören die dateibasierte Definition von Routen, der Umgang mit dynamischen URL-Segmenten, das Rendering sowie das Abrufen von Daten über APIs.
Im Folgenden fasse ich die wichtigsten Unterschiede zwischen Pages Router und App Router zusammen, mit Fokus auf die Punkte, die leicht durcheinandergeraten. Die Übersicht ist bewusst kurz gehalten und dient als Gedächtnisstütze!
Unterschiede beim Dateirouting
Pages Router: Einfach, denn der Dateiname wird direkt zum Pfad
Dateien mit den Endungen .js, .jsx, .ts oder .tsx, die im Verzeichnis pages liegen, werden direkt als URL-Pfad verwendet. Das macht das System besonders einfach.
Beispiel: src/page/about.tsx ⇒ Die Route lautet /about.
App Router: Strukturierung über Ordner und bestimmte Dateinamen
Mit dem App Router können Routen definiert werden, indem Ordner und Dateien unterhalb von src/app abgelegt werden.
Eine Datei mit dem speziellen Namen page wird dabei als Seiteninhalt für den entsprechenden Pfad behandelt.
Beispiel: src/app/about/page.tsx ⇒ Die Route lautet /about.
Die "speziellen Dateien" des App Routers
Neben page.tsx gibt es im App Router noch weitere Dateien mit besonderer Bedeutung.
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関数がスローされたときの画面
Besonders überrascht hat mich not-found.tsx. Allein durch das Anlegen dieser Seite wird bei Aufruf einer nicht existierenden URL automatisch diese Seite angezeigt. Dass sich das so einfach umsetzen lässt, hat mich beeindruckt.
Unterschiede beim Rendering
Komponenten im Pages Router sind grundsätzlich für die clientseitige Interaktion ausgelegt, während das serverseitige Rendering vor allem zur Beschleunigung der Erstanzeige und für SEO eingesetzt wird. React-Hooks wie useState und useEffect können innerhalb von Seitenkomponenten und deren untergeordneten Komponenten frei verwendet werden.
Komponenten innerhalb von app/ werden im App Router dagegen standardmäßig als Server-Komponenten behandelt, sofern nichts anderes explizit angegeben ist. Daher können useState und useEffect sowie React-Hooks insgesamt nicht verwendet werden. Clientseitige Aktionen wie onClick sowie Event-Handler sind ebenfalls nicht verfügbar.
Um im App Router CSR zu nutzen, muss use client angegeben werden.
use client
Das ist die Abgrenzung zwischen Server Components und Client Components. Wenn Sie use client deklarieren, werden nicht nur diese Komponente, sondern auch alle importierten Module als Client Components behandelt.
Dynamisches Routing [○○]
Das dynamische Routing in Next.js ermöglicht es, dynamische URLs zu verarbeiten, bei denen sich ein Teil der URL je nach Nutzer oder Inhalt ändert, etwa auf den Detailseiten von Blogs oder Nachrichtenartikeln.
Angenommen, es gibt einen Link, der zu Artikel A und einen weiteren, der zu Artikel B führt.
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>
);
}Zielseite des jeweiligen Links
Für dynamisches Routing legen Sie eine Datei [slug] an. Dann können post/A und post/B dieselbe Vorlage verwenden.
※ Die Benennung in [ ] ist frei wählbar, daher muss es nicht slug sein.
Bei App Router
/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 Teil [slug] der URL.
※ Das Abrufen von params musste bisher nicht asynchron erfolgen. Ab Next.js 15 wird es jedoch asynchron ausgeführt. Daher scheint es erforderlich zu sein, props als Promise-Typ zu definieren.
Bei 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>
);
}
Verwende useRouter. router.query.slug enthält den Wert des Teils [slug] aus der URL.
Methoden zum Abrufen von API-Daten
microCMS, das auch in dieser Liberogic-Kolumne eine wichtige Rolle spielt, lässt sich gut mit Frameworks wie Next.js kombinieren.
Bei App Router
Einfach fetch oder async await verwenden genügt.
Allerdings wird eine Datei, in der use client deklariert ist, zu CSR, weshalb async await dort nicht mehr verwendet werden kann!
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();
}
Aufrufer
export default function Example() {
const data = await getPost()
// ... data を使って表示 ...
}
Bei Pages Router
Verwende getStaticProps und übergib die abgerufenen Daten als props an die Seitenkomponente.
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,
},
};
}
Aufrufer
export default function Example({ data }) {
// ... data を使って表示 ...
}
Verstehe beide Router und nutze Next.js souverän!
Das erste Projekt, bei dem ich mit Next.js gearbeitet habe, nutzte den App Router.
Später habe ich in einem anderen Projekt mit dem Pages Router gearbeitet und musste kurz überlegen: "Heißt die Datei für eine neue Seite index.tsx oder page.tsx?"
Dieser Beitrag behandelt nur einen kleinen Teil von Next.js, aber durch die erneute Recherche zu den Unterschieden zwischen App Router und Pages Router habe ich das Thema für mich selbst besser strukturieren können.
Persönlich finde ich die Schreibweise des App Routers übersichtlicher und mag sie sehr. Ich möchte aber auch in Projekten mit dem Pages Router sicher arbeiten können.
Ideal wäre es, Next.js noch besser zu verstehen und je nach Projekt oder Vorhaben den passenden Router gezielt einsetzen zu können!
Ich entwickle Frontend-Lösungen mit Schwerpunkt auf Markup sowie mit JavaScript, React und Next.js. Es freut mich besonders, wenn Websites, an denen ich mitgearbeitet habe, erfolgreich online gehen! In meiner Freizeit spiele ich gern Gitarre. Katzen und Süßkartoffeln mag ich sehr 🐱🍠
Hirattchi
Frontend-Entwickler / Eintritt 2022