Nextjs SEO Sitemap Robots Open Graph Canonical Structured Data
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 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:
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.
Paket SEO ini relevan hampir selalu untuk halaman publik, tetapi urgensinya naik ketika aplikasi mulai punya:
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.
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:
metadata statisPakai 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.',
}generateMetadata dinamisPakai 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
Next.js merakit metadata dari root ke leaf segment. Artinya:
app/layout.tsx biasanya jadi tempat default globalpage.tsx memberi metadata paling spesifik untuk route ituKalau beberapa level mengisi key yang sama, nilai yang lebih bawah menang. Karena itu, root layout biasanya dipakai untuk default seperti:
metadataBasetitle.templatedescription generikSitemap dipakai untuk memberi daftar URL penting secara eksplisit ke mesin pencari.
Gunakan sitemap kalau:
Sitemap bukan jaminan indexing. Kalau halaman:
robots.txtnoindexmaka URL tersebut tetap bisa gagal diindeks walau ada di sitemap.
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(),
},
{
Pola ini cocok untuk:
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 dipakai untuk memberi aturan crawling di level domain.
Gunakan robots.txt untuk:
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.
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/'
Open Graph dipakai untuk mengontrol bagaimana halaman tampil saat dibagikan ke platform sosial.
Gunakan Open Graph untuk hampir semua halaman publik yang berpotensi dibagikan, terutama:
Biasanya yang paling penting adalah:
og:titleog:descriptionog:urlog:imageog:typeTwitter/X preview sering mengikuti pola yang mirip, jadi di Next.js biasanya sekalian disiapkan lewat metadata yang sama.
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'
og:url tidak sama dengan canonicalCanonical URL dipakai untuk menandai satu versi utama dari sebuah konten.
Canonical penting ketika ada kemungkinan duplikasi atau variasi URL, misalnya:
?utm=...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.
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 memberi konteks tambahan dalam format yang bisa dibaca mesin, paling sering JSON-LD.
Pakai structured data kalau halaman kamu punya entitas yang jelas, misalnya:
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.
Structured data bukan trik instan untuk ranking. Data harus cocok dengan isi halaman. Kalau markup menyebut FAQ, isi halaman juga harus benar-benar FAQ.
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'
headline, description, dan URL sesuai konten nyataSitemap hanya memberi petunjuk discovery. Halaman tetap bisa tidak terindeks kalau sinyal lain lemah.
Kalau halaman penting ada di disallow, crawler mungkin tidak bisa melihat metadata atau kontennya dengan baik.
noindex untuk halaman yang seharusnya privaterobots saja tidak selalu cukup. Halaman internal sebaiknya juga diberi robots: { index: false, follow: false } lewat metadata bila memang tidak boleh tampil di pencarian.
Canonical ke homepage, ke URL lama, atau ke halaman yang parameter-nya beda bisa membuat sinyal indexing kacau.
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.
Preview sosial bisa kosong kalau image tidak publik, lambat, atau dimensinya tidak sesuai.
Markup yang terlalu generik atau tidak sesuai isi halaman bisa diabaikan, atau minimal tidak memberi manfaat.
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.
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.
metadataBase tidak disetTanpa metadataBase, URL absolut untuk canonical atau Open Graph bisa jadi ambigu, terutama saat deploy ke environment berbeda.
app/
layout.tsx
page.tsx
sitemap.ts
robots.ts
blog/
[slug]/
page.tsxPola ini membuat:
sitemap.ts dan robots.ts