Nextjs Metadata SEO Route Groups Layouts Loading Error UI
Selesai membaca dokumentasi ini?
Kembali ke rujukan utama Next.js untuk melanjutkan topik lainnya.
Kembali ke rujukan utama Next.js untuk melanjutkan topik lainnya.
Di App Router, beberapa file khusus mengatur cara Next.js merender halaman, membangun <head>, dan menangani transisi antar-route. Topik yang paling sering dipakai adalah:
(...) untuk mengelompokkan struktur tanpa mengubah URLKalau dipahami bersama, keenam hal ini membentuk cara Next.js mengatur pengalaman baca halaman dari request awal sampai navigasi antar-route.
Pola ini relevan saat aplikasi mulai punya:
Kalau aplikasi masih sangat kecil, semua konsep ini tetap bisa dipakai, tetapi manfaatnya paling terasa ketika struktur route mulai bertambah.
Next.js App Router tidak menunggu developer menulis tag <meta> secara manual di setiap halaman. Sebagai gantinya, Next.js membaca ekspor metadata dari layout.tsx atau page.tsx, lalu membangkitkan tag HTML yang diperlukan.
Ada dua pendekatan utama:
metadata statisPakai ini kalau nilainya sudah jelas di saat build atau tidak bergantung pada data runtime.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Blog Hadie',
description: 'Catatan teknis tentang Next.js, React, dan web development.',
}Pendekatan ini cocok untuk:
generateMetadata dinamisPakai ini kalau metadata bergantung pada param route, data fetch, atau context segment di atasnya.
import type { Metadata } from 'next'
type Props = {
params: Promise<{ slug: string }>
}
export async function generateMetadata({ params }: Props
Poin pentingnya:
generateMetadata hanya tersedia di Server ComponentparamsUrutannya berjalan dari root ke leaf segment. Artinya:
Jika beberapa segment mengisi key yang sama, nilai paling bawah menang. Karena itu, root layout biasanya dipakai untuk default global seperti title.template, metadataBase, dan description generik.
Metadata punya pengaruh langsung ke SEO dan share preview:
title membantu identifikasi halaman di hasil pencarian dan tab browserdescription sering dipakai untuk cuplikan hasil pencarianopenGraph dan twitter memengaruhi kartu saat link dibagikanrobots mengatur apakah halaman boleh diindeksalternates membantu canonical dan bahasa alternatifNamun SEO di App Router bukan cuma soal metadata. Struktur render juga ikut menentukan kualitas halaman:
Selain ekspor metadata dan generateMetadata, Next.js juga mendukung file khusus seperti:
favicon.icoicon.pngapple-icon.pngopengraph-image.tsxrobots.txtsitemap.xmlIni berguna kalau aset metadata lebih enak dikelola sebagai file daripada konfigurasi kode.
Layout dipakai ketika ada UI yang harus dibagikan oleh beberapa page dan tidak perlu diganti total setiap navigasi.
Contoh penggunaan layout:
Layout adalah kerangka, bukan isi final halaman. Ia menerima children dan membungkus page atau nested layout di bawahnya.
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div className="dashboard-shell">
<aside>Sidebar</aside>
<main
Pakai layout jika:
Pakai page jika:
Di App Router, layout membantu:
Catatan penting: root layout wajib memuat <html> dan <body>.
Route group ditulis dengan folder berkurung, misalnya:
app/
(marketing)/
about/
page.tsx
(dashboard)/
settings/
page.tsxFolder (marketing) dan (dashboard) dipakai untuk organisasi kode, tetapi tidak muncul di URL.
Hasil route-nya tetap:
app/(marketing)/about/page.tsx → /aboutapp/(dashboard)/settings/page.tsx → /settingsRoute groups berguna untuk:
Ada dua hal yang perlu diingat:
Artinya, route groups memang membantu organisasi, tetapi tetap harus dirancang bersama struktur layout dan URL yang konsisten.
File loading.tsx atau loading.js dipakai untuk memberi fallback UI saat sebuah route segment sedang diproses.
export default function Loading() {
return <p>Memuat halaman…</p>
}Di App Router, loading.tsx otomatis membungkus page segment dengan Suspense boundary. Begitu segment belum siap, Next.js bisa menampilkan fallback lebih cepat tanpa menunggu seluruh page selesai.
Ini penting untuk:
Loading UI sebaiknya ringan:
Jangan gunakan loading screen yang berat kalau tujuan utamanya hanya memberi jeda singkat. Idealnya loading UI membantu user tetap yakin bahwa aplikasi masih bekerja.
File error.tsx atau error.js dipakai untuk menangkap error pada segment tertentu dan menampilkan fallback yang lebih ramah.
'use client'
export default function Error(
{ error,
reset }: { error: Error & { digest?: string },
reset: () => void }
) {
Error UI menjaga agar kegagalan tidak langsung menjatuhkan seluruh aplikasi. Dengan boundary di level route segment:
Gunakan error boundary saat:
Secara sederhana, alurnya seperti ini:
Diagram ini menunjukkan tiga hal penting:
app/
layout.tsx
page.tsx
(marketing)/
layout.tsx
about/
page.tsx
loading.tsx
error.tsx
(dashboard)/
layout.tsx
settings/
page.tsxCara membacanya:
app/layout.tsx = root shell global(marketing)/layout.tsx = shell khusus area marketing(dashboard)/layout.tsx = shell khusus area dashboardloading.tsx = fallback saat page segment sedang diproseserror.tsx = fallback saat segment gagal rendermetadata statis untuk default global dan halaman yang tidak bergantung data runtime.generateMetadata untuk route dinamis yang title/description-nya datang dari data.loading.tsx untuk fallback ringan, bukan untuk mengganti seluruh page dengan layar yang berat.error.tsx untuk mengisolasi kegagalan per segment agar user tetap bisa recovery.metadata dan generateMetadataopengraph-image dan sitemap.xmllayout.tsx untuk shell yang dibagikan(folder) untuk organisasi tanpa perubahan URLloading.tsx untuk Suspense fallbackerror.tsx untuk error boundary segmentKalau harus dipadatkan:
Itu kombinasi dasar yang biasanya paling berguna saat membangun App Router yang rapi dan enak dipakai harian.