Lompat ke konten
dokumentasi.id
Commit 9a47d33
v2
Star3,4 rb

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

12

SEO, Sitemap, dan Deploy

Starter ini menyiapkan publikasi lewat beberapa bagian kecil yang saling bergantung: objek siteConfig, objek metadata di RootLayout, konfigurasi next-sitemap yang berjalan sebagai postbuild, dan satu header cache yang hanya berlaku di Vercel. Halaman ini menelusuri nilai dari sumbernya sampai ke berkas yang benar-benar dibaca mesin pencari dan peramban. Struktur layout serta metadata per route dibahas di App Router, Layout, dan Metadata.

Satu sumber, tiga jalur publikasi

graph TD
  siteConfig["siteConfig (src/constant/config.ts)"] --> metadata["metadata di RootLayout"]
  siteConfig --> ogImages["openGraph.images dan twitter.images"]
  siteConfig --> robotsMeta["robots: index, follow"]
  build["next build"] --> postbuild["postbuild: next-sitemap --config"]
  sitemapCfg["siteUrl di next-sitemap.config.js"] --> postbuild
  postbuild --> robotsTxt["robots.txt hasil generate"]
  postbuild --> sitemapXml["sitemap.xml dan sitemap-*.xml"]
  fontFace["@font-face di globals.css"] --> vercelJson["source di vercel.json"]
  vercelJson --> fontCache["Cache-Control: immutable"]
  style siteConfig fill:#f59e0b,color:#000
  style sitemapCfg fill:#f59e0b,color:#000
  style vercelJson fill:#f59e0b,color:#000
  style build fill:#2d7d46,color:#fff
  style postbuild fill:#2d7d46,color:#fff
  style fontCache fill:#2d7d46,color:#fff
  style metadata fill:#8b5cf6,color:#fff
  style ogImages fill:#8b5cf6,color:#fff
  style robotsMeta fill:#8b5cf6,color:#fff
  style robotsTxt fill:#8b5cf6,color:#fff
  style sitemapXml fill:#8b5cf6,color:#fff
  style fontFace fill:#8b5cf6,color:#fff
%% fig: Jalur nilai dari siteConfig ke berkas publikasi
%% desc: siteConfig memasok metadata dan gambar OG, postbuild menurunkan sitemap serta robots.txt, dan vercel.json menambahkan header cache untuk berkas font.
Fig. 1: Jalur nilai dari siteConfig ke berkas publikasisiteConfig memasok metadata dan gambar OG, postbuild menurunkan sitemap serta robots.txt, dan vercel.json menambahkan header cache untuk berkas font.

Tiga berkas menjadi sumber nilai: src/constant/config.ts, src/app/layout.tsx, dan next-sitemap.config.js. Ketiganya harus diubah bersamaan ketika domain atau judul situs berganti, karena tidak ada satu pun yang membaca nilai dari yang lain kecuali layout.tsx.

siteConfig sebagai sumber nilai

RootLayout mengimpor siteConfig lalu memakai ketiga field-nya secara langsung. Tidak ada pembacaan environment variable di jalur ini.

FieldNilai di repositoryDikonsumsi oleh
titleNext.js + Tailwind CSS + TypeScript Startermetadata.title.default, metadata.title.template, openGraph.title, openGraph.siteName, twitter.title
descriptionA starter for Next.js, Tailwind CSS, and TypeScript with Absolute Import, Seo, Link component, pre-configured with Huskymetadata.description, openGraph.description, twitter.description
urlhttps://tsnext-tw.thcl.devmetadataBase, openGraph.url, openGraph.images, twitter.images

src/constant/config.ts:1-7

⚠️ Komentar di berkas meminta url ditulis tanpa / di akhir. Alasannya terlihat di layout.tsx: images dibentuk dengan konkatenasi string ${siteConfig.url}/images/og.jpg, jadi garis miring tambahan menghasilkan //images/og.jpg. src/constant/config.ts:1-7 src/app/layout.tsx:28-36

Metadata di RootLayout

Seluruh metadata situs didefinisikan sebagai satu objek Metadata yang diekspor dari RootLayout. Berikut pemetaan kunci ke nilainya.

KunciNilaiEfek
metadataBasenew URL(siteConfig.url)Dasar untuk URL relatif di metadata
title.defaultsiteConfig.titleJudul halaman tanpa judul sendiri
title.template%s | ${siteConfig.title}Judul halaman anak menjadi <judul> | <judul situs>
descriptionsiteConfig.descriptionDeskripsi default
robots{ index: true, follow: true }Instruksi crawl di dalam HTML
icons.icon/favicon/favicon.icoFavicon utama
icons.shortcut/favicon/favicon-16x16.pngShortcut icon
icons.apple/favicon/apple-touch-icon.pngIkon iOS
manifest/favicon/site.webmanifestWeb app manifest
openGraphurl, title, description, siteName, images, type: 'website', locale: 'en_US'Kartu pratinjau Open Graph
twittercard: 'summary_large_image', title, description, imagesKartu pratinjau Twitter

src/app/layout.tsx:8-19 src/app/layout.tsx:22-27 src/app/layout.tsx:28-36 src/app/layout.tsx:37-43

Dua hal mudah tertukar di sini. robots: { index: true, follow: true } adalah tag di HTML, bukan berkas robots.txt; berkas itu datang dari next-sitemap. Kedua, images di openGraph dan twitter menunjuk berkas statis public/images/og.jpg, bukan hasil helper openGraph di src/lib/og.ts.

Template judul bekerja pada halaman yang punya metadata sendiri. Layout komponen hanya menetapkan title: 'Components', sehingga judul akhirnya menjadi Components | Next.js + Tailwind CSS + TypeScript Starter. src/app/components/layout.tsx:6-9

Helper openGraph

openGraph adalah fungsi pembentuk URL untuk layanan gambar OG eksternal. Ia menerima siteName, description, templateTitle opsional, dan logo, lalu mengembalikan satu string. Setiap bagian di-encodeURIComponent, dan &templateTitle= hanya ditambahkan jika templateTitle diberikan. Nilai logo default masih placeholder: https://og.<your-domain>/images/logo.jpg. src/lib/og.ts:1-27

⚠️ Helper ini belum dipanggil dari halaman mana pun. Satu-satunya pemakai adalah test, yang memeriksa ada atau tidaknya &templateTitle= pada hasil. Ganti og.<your-domain> sebelum memakainya. src/lib/tests/og.test.ts:3-19 — test itu sendiri dibahas di Pengujian dengan Jest.

Sitemap dan robots.txt setelah build

package.json mendaftarkan postbuild yang menjalankan next-sitemap --config next-sitemap.config.js. Skrip postX dijalankan otomatis oleh npm dan pnpm setelah build, jadi pnpm build menghasilkan sitemap tanpa langkah tambahan. package.json:17

Konfigurasi next-sitemap hanya memuat siteUrl, generateRobotsTxt: true, dan satu policy yang mengizinkan seluruh path. next-sitemap.config.js:5-13

BerkasSumberIsiDilacak git
sitemap.xmlpostbuildDaftar URL dari siteUrlTidak
robots.txtpostbuildgenerateRobotsTxt: true dengan policy userAgent: '*', allow: '/'Tidak
sitemap-*.xmlpostbuildPecahan sitemap bila daftar URL dipecahTidak

.gitignore:39-42

⚠️ siteUrl ditulis dua kali: sebagai url di siteConfig dan sebagai siteUrl di next-sitemap.config.js. Keduanya bernilai sama sekarang, tetapi mengganti domain hanya di satu tempat membuat metadata dan sitemap menunjuk host berbeda. next-sitemap.config.js:5-13

Aset ikon dan manifest

Metadata ikon menunjuk berkas yang tersedia di public/favicon. Semua berkas itu sudah ada di repository.

Kunci metadataBerkas
icons.iconpublic/favicon/favicon.ico
icons.shortcutpublic/favicon/favicon-16x16.png
icons.applepublic/favicon/apple-touch-icon.png
manifestpublic/favicon/site.webmanifest
icons di manifestandroid-chrome-192x192.png, android-chrome-512x512.png

src/app/layout.tsx:22-27 public/favicon/site.webmanifest:1-19

⚠️ Di manifest, "name" dan "short_name" masih string kosong. Keduanya dipakai sebagai nama aplikasi saat pengguna memasang situs ke home screen, jadi isi dulu sebelum publikasi. theme_color dan background_color sudah bernilai #ffffff. public/favicon/site.webmanifest:1-19

Header cache font di vercel.json

vercel.json menyimpan satu aturan headers: untuk source /fonts/inter-var-latin.woff2, response diberi Cache-Control: public, max-age=31536000, immutable. Path itu sama dengan src di blok @font-face pada globals.css, jadi yang di-cache adalah berkas yang benar-benar dimuat halaman. vercel.json:1-13 src/styles/globals.css:66-71

sequenceDiagram
  participant B as Browser
  participant V as Vercel edge
  participant A as Berkas statis
  B->>V: GET /fonts/inter-var-latin.woff2
  V->>A: read asset
  A-->>V: woff2 bytes
  V-->>B: 200 plus Cache-Control: public, max-age=31536000, immutable
  Note over B: permintaan berikutnya dilayani cache lokal
%% fig: Siklus satu request font dengan header dari vercel.json
%% desc: Aturan headers di vercel.json menempelkan Cache-Control berumur satu tahun pada berkas font, sehingga peramban tidak meminta ulang.
Fig. 2: Siklus satu request font dengan header dari vercel.jsonAturan headers di vercel.json menempelkan Cache-Control berumur satu tahun pada berkas font, sehingga peramban tidak meminta ulang.

@font-face juga memakai font-display: block dan font-weight: 100 900, sehingga satu berkas variabel melayani seluruh rentang bobot. Header cache ini hanya berlaku jika aplikasi di-deploy ke Vercel; platform lain mengabaikan vercel.json.

Deploy

README menempatkan deploy ke Vercel sebagai langkah keempat setelah inisialisasi proyek, lengkap dengan tombol Deploy with Vercel. README.md:73-75

Tombol yang sama muncul di halaman beranda. UnstyledLink mengarah ke https://vercel.com/new/git/external?repository-url=... dan memuat gambar https://vercel.com/button dengan alt='Deploy with Vercel'. src/app/page.tsx:45-56

LangkahPerintah atau berkasCatatan
Buildpnpm buildMenjalankan next build lalu postbuild
Sitemapnext-sitemap.config.jssiteUrl wajib sama dengan siteConfig.url
Header cachevercel.jsonHanya berpengaruh di Vercel
Direktori lokal.vercelDiabaikan git

.gitignore:32-33

⚠️ Berkas sitemap.xml dan robots.txt tidak masuk repository. Deploy yang dijalankan tanpa build penuh, misalnya hanya mengunggah hasil yang sudah ada, akan tampil tanpa sitemap. Otomasi test, lint, dan typecheck sebelum commit ada di Otomasi Repository: Husky, Commitlint, dan CI.

Di atas ketiga lapisan ini, tidak ada konfigurasi deploy lain di repository: tidak ada file platform selain vercel.json, dan tidak ada workflow yang melakukan deploy otomatis. Publikasi sepenuhnya bergantung pada build, postbuild, dan setelan proyek di Vercel.