Routing berbasis berkas
Tidak ada berkas rute untuk dipelihara. Yang ada aturan prioritas, dan satu keputusan trailing slash yang kalau salah akan menggandakan seluruh URL portalmu di mata Google.
Intisari
src/pages/berita/[slug].astroโ/berita/apa-saja. Nama berkas adalah rutenya.- Rute statis selalu menang atas rute dinamis.
/berita/arsipmengalahkan/berita/[slug]โ tanpa kamu mengatur apa pun. [...jalur].astromenangkap sisa jalur berapa pun dalamnya. Ini kunci untuk memetakan URL warisan CI3.trailingSlashharus diputuskan sekali dan konsisten. Salah setel = dua URL untuk satu halaman = konten terduplikasi di indeks Google.Astro.rewrite()mengganti isi tanpa mengubah URL;Astro.redirect()mengubah URL-nya.
Pemetaan dasar
| Berkas | URL |
|---|---|
src/pages/index.astro | / |
src/pages/berita/index.astro | /berita |
src/pages/berita/arsip.astro | /berita/arsip |
src/pages/berita/[slug].astro | /berita/apa-pun |
src/pages/perusahaan/[kode]/[tab].astro | /perusahaan/BBCA/keuangan |
src/pages/[...jalur].astro | /apa/saja/sedalam/apa/pun |
src/pages/api/webhook.ts | /api/webhook (endpoint, bukan halaman) |
Aturan prioritas โ hafalkan urutannya
Saat lebih dari satu rute cocok dengan satu URL, Astro memilih berdasarkan spesifisitas, bukan urutan berkas:
- Rute statis โ
/berita/arsip - Rute dinamis satu segmen โ
/berita/[slug] - Rute rest โ
/berita/[...jalur] - Rute rest paling luar โ
/[...jalur]
/berita/arsip โ berita/arsip.astro (menang: statis)
/berita/halo โ berita/[slug].astro (statis tidak ada)
/xyz/abc/def โ [...jalur].astro (tidak ada yang lebih spesifik)
Ini yang menyelamatkanmu saat migrasi. Kamu bisa memasang [...jalur].astro
sebagai penangkap terakhir yang mencari URL lama di tabel pemetaan dan mengembalikan 301 โ sementara
rute baru yang sudah kamu tulis tetap menang. Tidak perlu satu pun aturan urutan manual. Polanya ada di
Fase 9.
Trailing slash โ keputusan yang harus benar sejak awal
export default defineConfig({
site: "https://portal.contoh.id",
trailingSlash: "never", // "always" | "never" | "ignore"
});
| Nilai | Artinya | Untuk portal berita |
|---|---|---|
"ignore" | Dua-duanya diterima (default) | Jangan. Dua URL untuk satu halaman. |
"never" | /berita/halo saja | Pilihan yang bersih kalau URL CI3-mu juga tanpa slash |
"always" | /berita/halo/ saja | Pilih ini kalau URL lamamu memang berakhiran slash |
Cocokkan dengan URL yang sudah terindeks, bukan dengan selera. Portal beritamu punya ribuan URL
di indeks Google dan ratusan backlink dari situs lain. Kalau URL lamamu /news/detail/123/slug
tanpa slash, pilih "never". Mengubah bentuk URL dan memindahkan platform sekaligus
berarti dua sumber kerusakan SEO yang tidak bisa kamu pisahkan saat trafiknya turun.
Perlu diingat juga: Cloudflare punya pengaturannya sendiri, dan nginx maupun ALB bisa menambahkan redirect.
Kalau ketiganya tidak sepakat, kamu bisa mendapat rantai redirect atau โ lebih buruk โ loop. Verifikasi
dengan curl -I setelah semuanya terpasang, bukan hanya di lokal.
Rewrite vs redirect
---
const artikel = await ambilArtikelPublik(Astro.params.slug!);
// Artikel tidak ada: tampilkan halaman 404, URL tetap seperti yang diminta
if (!artikel) {
return Astro.rewrite("/404");
}
// Slug berubah karena judul disunting: kirim pembaca ke URL kanoniknya
if (artikel.slug !== Astro.params.slug) {
return Astro.redirect(`/berita/${artikel.slug}`, 301);
}
---
Astro.rewrite() | Astro.redirect() | |
|---|---|---|
| URL di address bar | Tidak berubah | Berubah |
| Jumlah request | Satu | Dua |
| Status HTTP | Ditentukan halaman tujuan | 301, 302, 307, 308 |
| Untuk | 404, A/B test, multi-tenant | URL kanonik, URL lama, pasca-login |
Blok kedua di contoh itu penting untuk portal berita. Editor menyunting judul, slug ikut berubah, dan URL lama yang sudah tersebar di media sosial jadi mati. Dengan mencari artikel berdasarkan ID di dalam slug โ atau lewat tabel slug lama โ kamu bisa mengembalikan 301 ke slug baru, dan tautan lama tetap hidup. Ini akan diperluas di Fase 9.
Redirect statis di konfigurasi
export default defineConfig({
redirects: {
"/news": "/berita",
"/news/[...jalur]": "/berita/[...jalur]",
"/kategori/ekonomi": { status: 301, destination: "/berita/ekonomi" },
},
});
Cocok untuk redirect yang jumlahnya puluhan dan diketahui saat build. Tidak cocok untuk peta 40.000 URL warisan โ itu masuk ke database dan dilayani rute rest, karena memasukkan 40.000 entri ke konfigurasi akan memperlambat build dan membuat berkasnya tidak bisa direview siapa pun.
Endpoint: berkas .ts di dalam pages/
// src/pages/api/artikel.json.ts โ /api/artikel.json
import type { APIRoute } from "astro";
import { ambilArtikelTerbaru } from "@/lib/artikel";
export const prerender = false;
export const GET: APIRoute = async ({ url }) => {
const kategori = url.searchParams.get("kategori") ?? "semua";
const artikel = await ambilArtikelTerbaru(kategori, 20);
return new Response(JSON.stringify(artikel), {
headers: {
"Content-Type": "application/json",
"Cache-Control": "public, max-age=60, s-maxage=300",
},
});
};
Nama fungsi yang di-export adalah metode HTTP-nya. Request POST ke berkas yang
hanya meng-export GET mendapat 405 Method Not Allowed otomatis โ tanpa kamu
menuliskan satu pun pengecekan. Bandingkan dengan CI3, di mana satu method controller menerima semua
metode dan pemeriksaan $this->input->method() mudah terlupa.
Latihan: buat tiga rute โ berita/index.astro, berita/arsip.astro,
dan berita/[slug].astro. Buktikan aturan prioritasnya: buka /berita/arsip dan
pastikan yang muncul halaman arsip, bukan halaman slug dengan slug === "arsip". Lalu setel
trailingSlash: "never", jalankan pnpm build && pnpm preview, dan
jalankan curl -I ke versi ber-slash โ pastikan ia mengembalikan redirect, bukan 200.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.