Nextjs SEO Sitemap Robots Open Graph Canonical Structured Data
Definisi
Di Next.js App Router, SEO production essentials adalah kumpulan sinyal yang membantu crawler memahami halaman, membantu mesin pencari memilih URL yang tepat, dan membantu link preview tampil rapi saat dibagikan.
Komponen utamanya biasanya mencakup:
- sitemap.xml: daftar URL penting yang ingin dikenali crawler
- robots.txt: aturan dasar untuk crawler tentang area yang boleh atau tidak boleh diakses
- metadata: title, description, robots, alternates, dan metadata dasar lain yang dibangkitkan Next.js
- Open Graph: data preview untuk platform sosial dan messaging
- canonical URL: penanda URL utama untuk menghindari duplikasi sinyal indeks
- structured data: data terstruktur, biasanya JSON-LD, untuk memberi konteks tambahan ke mesin pencari
Kalau dibaca sebagai sistem, keenam komponen ini tidak berdiri sendiri. Sitemap membantu discovery, robots mengatur akses, metadata memberi konteks, canonical mengurangi ambiguitas URL, dan structured data memperkaya pemahaman konten.
Kapan dipakai
Paket SEO ini relevan hampir selalu untuk halaman publik, tetapi urgensinya naik ketika aplikasi mulai punya:
- banyak halaman konten atau listing
- route dinamis seperti post, produk, kategori, atau dokumentasi
- variasi URL yang bisa duplikat, misalnya parameter query, sort, filter, atau pagination
- kebutuhan share preview di WhatsApp, X, LinkedIn, atau Slack
- domain marketing yang harus siap di-crawl sejak deploy pertama
- beberapa bahasa atau regional variant
Untuk halaman internal seperti dashboard, panel admin, atau area login, biasanya fokusnya berbeda. Halaman itu sering justru tidak perlu diindeks, jadi robots dan metadata noindex lebih penting daripada sitemap.
Cara kerja SEO di App Router
App Router mengubah cara kita mengelola metadata. Alih-alih menulis <head> manual di setiap page, Next.js merakit metadata dari layout.tsx dan page.tsx, lalu mengubahnya menjadi tag HTML yang sesuai.
Ada dua jalur utama:
1. metadata statis
Pakai ini kalau nilai metadata sudah jelas sejak build atau sangat jarang berubah.
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Dokumentasi Pemrograman',
description: 'Referensi teknis tentang web, backend, dan Next.js.',
}2. generateMetadata dinamis
Pakai ini kalau metadata bergantung pada params, hasil fetch, atau konteks route.
import type { Metadata } from 'next'
type Props = {
params: Promise<{ slug: string }>
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params
const post = await fetch(`https://example.com/api/posts/${slug}`).then((res) => res.json())
return {
title: post.title,
description: post.excerpt,
}
}Urutan resolusi metadata
Next.js merakit metadata dari root ke leaf segment. Artinya:
app/layout.tsxbiasanya jadi tempat default global- nested layout menambah atau menimpa sebagian nilai
page.tsxmemberi metadata paling spesifik untuk route itu
Kalau beberapa level mengisi key yang sama, nilai yang lebih bawah menang. Karena itu, root layout biasanya dipakai untuk default seperti:
metadataBasetitle.templatedescriptiongenerik- default Open Graph image
- default robots rule
sitemap.xml
Sitemap dipakai untuk memberi daftar URL penting secara eksplisit ke mesin pencari.
Kapan dipakai
Gunakan sitemap kalau:
- situs punya banyak halaman publik
- URL baru tidak selalu mudah ditemukan lewat internal linking
- ada konten dinamis yang ingin diindeks lebih konsisten
- kamu ingin memberi hint prioritas discovery ke crawler
Kapan tidak cukup
Sitemap bukan jaminan indexing. Kalau halaman:
- diblokir oleh
robots.txt - diberi
noindex - punya canonical ke URL lain
- kualitas kontennya rendah atau duplikatif
maka URL tersebut tetap bisa gagal diindeks walau ada di sitemap.
Implementasi di Next.js
Untuk App Router, sitemap biasanya dibuat sebagai file route, misalnya app/sitemap.ts.
import type { MetadataRoute } from 'next'
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: 'https://example.com/',
lastModified: new Date(),
},
{
url: 'https://example.com/blog/nextjs-seo',
lastModified: new Date(),
},
]
}Pola ini cocok untuk:
- homepage
- halaman statis penting
- daftar artikel atau produk
- URL dinamis yang bisa dihitung saat build atau runtime
Catatan penting
Kalau situs besar, sitemap biasanya perlu dibagi per segmen atau per batch agar lebih mudah dikelola. Untuk konten yang sering berubah, pastikan lastModified realistis, bukan sekadar diset ke tanggal yang sama terus.
robots.txt
robots.txt dipakai untuk memberi aturan crawling di level domain.
Kapan dipakai
Gunakan robots.txt untuk:
- melarang area private atau tidak relevan
- mencegah crawler membuang budget ke route teknis
- mengarahkan crawler ke sitemap
- membatasi halaman hasil filter yang tidak perlu diindeks
Apa yang perlu diingat
robots.txt mengatur crawling, bukan indexing sepenuhnya. URL yang sudah diketahui mesin pencari masih bisa muncul di indeks jika ada sinyal lain, meski kontennya tidak di-crawl ulang seperti yang kamu harapkan.
Karena itu, untuk halaman yang benar-benar tidak boleh tampil di hasil pencarian, jangan hanya mengandalkan robots.txt. Tambahkan juga noindex lewat metadata.
Implementasi di Next.js
Di App Router, robots biasanya dibuat sebagai file route app/robots.ts.
import type { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: [
{
userAgent: '*',
allow: '/',
disallow: ['/api/', '/admin/', '/dashboard/'],
},
],
sitemap: 'https://example.com/sitemap.xml',
}
}Pola umum
- allow untuk halaman publik
- disallow untuk area internal, endpoint teknis, atau halaman noisy
- selalu cek apakah disallow itu benar-benar perlu; terlalu agresif bisa menghalangi crawl halaman yang justru penting
Open Graph
Open Graph dipakai untuk mengontrol bagaimana halaman tampil saat dibagikan ke platform sosial.
Kapan dipakai
Gunakan Open Graph untuk hampir semua halaman publik yang berpotensi dibagikan, terutama:
- artikel
- landing page
- produk
- halaman kampanye
- dokumentasi publik
Komponen penting
Biasanya yang paling penting adalah:
og:titleog:descriptionog:urlog:imageog:type
Twitter/X preview sering mengikuti pola yang mirip, jadi di Next.js biasanya sekalian disiapkan lewat metadata yang sama.
Implementasi di App Router
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Next.js SEO Production Essentials',
description: 'Panduan praktis untuk sitemap, robots.txt, metadata, dan structured data.',
openGraph: {
title: 'Next.js SEO Production Essentials',
description: 'Panduan praktis untuk sitemap, robots.txt, metadata, dan structured data.',
url: 'https://example.com/blog/nextjs-seo-essentials',
siteName: 'Dokumentasi Pemrograman',
images: [
{
url: 'https://example.com/og/nextjs-seo.png',
width: 1200,
height: 630,
alt: 'Next.js SEO Production Essentials',
},
],
type: 'article',
},
}Jebakan umum Open Graph
- gambar terlalu kecil atau rasio tidak cocok
- URL gambar 404 atau diblokir auth
og:urltidak sama dengan canonical- title terlalu panjang sehingga preview terpotong
- cache preview sosial belum di-refresh setelah update
Canonical URL
Canonical URL dipakai untuk menandai satu versi utama dari sebuah konten.
Kapan dipakai
Canonical penting ketika ada kemungkinan duplikasi atau variasi URL, misalnya:
- pagination
- parameter
?utm=... - filter dan sort query string
- versi trailing slash vs non-trailing slash
- halaman yang kontennya sangat mirip
- konten yang diakses lewat beberapa path alias
Kenapa penting
Tanpa canonical, crawler bisa bingung memilih versi mana yang dianggap utama. Akibatnya, sinyal ranking bisa terpecah ke beberapa URL yang isinya sama atau hampir sama.
Praktik yang sehat
- gunakan canonical absolut kalau bisa
- pastikan canonical menunjuk ke URL yang benar-benar publik dan final
- jangan canonical-kan semua halaman ke homepage
- jangan membuat canonical yang bertentangan dengan redirect atau internal linking
Di App Router
Canonical bisa ditulis lewat metadata alternates.
import type { Metadata } from 'next'
export const metadata: Metadata = {
alternates: {
canonical: 'https://example.com/blog/nextjs-seo-essentials',
},
}Kalau site punya locale, alternates.languages juga sering dipakai untuk membantu relasi antarversi bahasa.
Structured data basics
Structured data memberi konteks tambahan dalam format yang bisa dibaca mesin, paling sering JSON-LD.
Kapan dipakai
Pakai structured data kalau halaman kamu punya entitas yang jelas, misalnya:
- artikel atau posting
- produk
- breadcrumb
- event
- FAQ
- organisasi
- profil penulis
Apa manfaatnya
Structured data membantu mesin pencari memahami tipe konten, bukan cuma teks mentahnya. Hasil akhirnya bisa berupa rich result atau pemahaman yang lebih akurat tentang halaman.
Batasan penting
Structured data bukan trik instan untuk ranking. Data harus cocok dengan isi halaman. Kalau markup menyebut FAQ, isi halaman juga harus benar-benar FAQ.
Contoh JSON-LD
const structuredData = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: 'Next.js SEO Production Essentials',
description: 'Panduan sitemap, robots.txt, metadata, Open Graph, canonical, dan structured data.',
author: {
'@type': 'Person',
name: 'Hadie',
},
mainEntityOfPage: 'https://example.com/blog/nextjs-seo-essentials',
}
export default function Page() {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData) }}
/>
<article>...</article>
</>
)
}Catatan implementasi
- taruh structured data hanya pada halaman yang relevan
- pastikan nilai
headline,description, dan URL sesuai konten nyata - untuk komponen reusable, jangan sampai satu data schema dipasang di banyak route tanpa penyesuaian
Alur crawl → metadata → index → preview
Jebakan umum yang memengaruhi indexing
1. Mengira sitemap pasti membuat halaman terindeks
Sitemap hanya memberi petunjuk discovery. Halaman tetap bisa tidak terindeks kalau sinyal lain lemah.
2. Memblokir halaman penting lewat robots.txt
Kalau halaman penting ada di disallow, crawler mungkin tidak bisa melihat metadata atau kontennya dengan baik.
3. Melupakan noindex untuk halaman yang seharusnya private
robots saja tidak selalu cukup. Halaman internal sebaiknya juga diberi robots: { index: false, follow: false } lewat metadata bila memang tidak boleh tampil di pencarian.
4. Canonical yang salah arah
Canonical ke homepage, ke URL lama, atau ke halaman yang parameter-nya beda bisa membuat sinyal indexing kacau.
5. Metadata dinamis yang tidak konsisten
Jika generateMetadata fetch data yang berbeda dari isi page, crawler bisa melihat satu judul di head dan konten lain di body. Ini bikin kualitas sinyal turun.
6. Open Graph image gagal diakses
Preview sosial bisa kosong kalau image tidak publik, lambat, atau dimensinya tidak sesuai.
7. Structured data tidak cocok dengan isi halaman
Markup yang terlalu generik atau tidak sesuai isi halaman bisa diabaikan, atau minimal tidak memberi manfaat.
8. Mengandalkan client-side rendering untuk konten utama
Kalau HTML awal nyaris kosong lalu semua isi baru muncul di client, crawler masih bisa membaca sebagian halaman, tetapi proses indexing jadi lebih rapuh dibanding server-rendered HTML yang lengkap.
9. Lupa metadata di segment yang benar
Di App Router, metadata default di root layout bisa ditimpa oleh nested layout atau page. Kalau letaknya salah, hasil akhirnya sering bukan yang kamu kira.
10. metadataBase tidak diset
Tanpa metadataBase, URL absolut untuk canonical atau Open Graph bisa jadi ambigu, terutama saat deploy ke environment berbeda.
Contoh struktur yang sehat
app/
layout.tsx
page.tsx
sitemap.ts
robots.ts
blog/
[slug]/
page.tsxPola ini membuat:
- sitemap dan robots dikelola sebagai route file
- metadata global tetap di root layout
- page dinamis punya metadata spesifik
- canonical dan Open Graph bisa disusun per konten
Ringkasan praktik produksi
- Pakai sitemap untuk discovery URL penting.
- Pakai robots.txt untuk mengatur crawl, tapi jangan jadikan itu satu-satunya pengaman indexing.
- Pakai metadata App Router untuk title, description, robots, alternates, dan default global.
- Pakai Open Graph untuk preview sosial yang konsisten.
- Pakai canonical untuk menegaskan URL utama.
- Pakai structured data hanya jika markup benar-benar sesuai isi halaman.
- Pastikan HTML awal sudah cukup informatif; jangan menggantungkan SEO pada client-only rendering.
Referensi terkait
- Next.js App Router metadata API
- file-based metadata:
sitemap.tsdanrobots.ts - SEO handling untuk route dinamis dan shared layout
- praktik canonical dan duplicate content di situs konten besar