Queue · 0 items

Redirect locale berbasis cookie ter-cache di Firebase CDN tanpa Vary: Cookie, bikin Googlebot kena 307 terus. Begini cara diagnosis dan perbaikannya.
noindex yang tidak sengaja masuk, atau robots.txt yang rusak. Ternyata bukan. Penyebabnya jauh lebih halus — dan jujur, saya tidak menyangka sebuah cookie bahasa bisa bikin separah ini.
/id/curl ke homepage live untuk cek response header:
curl -sI https://snipgeek.com/ | grep -iE 'HTTP|location|cache|cdn'HTTP/2 307
location: /id/
cache-control: public, s-maxage=3600, stale-while-revalidate=86400
cdn-cache-status: hit
age: 2326
/id/ — versi Bahasa Indonesia — untuk semua pengunjung, termasuk Googlebot. Dan CDN sudah meng-cache-nya selama lebih dari 38 menit.
Saya cek halaman lain seperti /blog dan /about — semuanya normal, return 200. Tapi homepage, halaman paling penting untuk crawling, justru yang rusak.
proxy.ts (pengganti middleware di Next.js 16).
Ini kode yang menyebabkan masalah:
// proxy.ts (SEBELUM — versi yang bermasalah)
const preferredLocale = request.cookies.get("NEXT_LOCALE")?.value;
if (pathnameIsMissingLocale) {
if (preferredLocale && preferredLocale !== i18n.defaultLocale) {
// Redirect ini di-cache CDN!
return NextResponse.redirect(
new URL(`/${preferredLocale}${pathname}`, request.url),
);
}
return NextResponse.rewrite(
new URL(`/${i18n.defaultLocale}${pathname}`, request.url),
);
}NEXT_LOCALE=id, redirect ke versi Indonesia. Kalau tidak, rewrite ke locale default (English).
Masalahnya ada di apa yang terjadi setelah response redirect itu keluar dari server.
next.config.ts saya menerapkan cache header ini untuk semua route halaman:
{
key: "Cache-Control",
value: "public, s-maxage=3600, stale-while-revalidate=86400",
}Vary: Cookie.
Jadi ketika saya (atau pengunjung manapun yang prefer bahasa Indonesia) mengakses homepage dengan cookie NEXT_LOCALE=id, CDN langsung meng-cache redirect 307 itu. Setiap pengunjung berikutnya — termasuk Googlebot — mendapat redirect yang ter-cache, bukan halaman HTML yang sebenarnya.
Googlebot tidak mengirim cookie. Dia mengharapkan konten HTML di snipgeek.com/. Yang didapat malah dipantulkan ke /id/ terus-menerus, tergantung timing cache CDN. Hasilnya: Google berhenti mempercayai homepage sebagai entry point yang stabil, dan impressions ambruk.
Vary: Cookie = cache poisoning. Cookie pengunjung pertama menentukan apa yang dilihat semua orang sampai cache expired.robots.txt mengizinkan / untuk semua user agent, dan sitemap.xml berisi semua 216 URL yang published termasuk setiap blog post. Tapi setelah audit, saya sadar ada satu celah hardening SEO: robots.txt juga memblokir /_next/, padahal untuk Next.js itu terlalu ketat karena Google bisa butuh aset tersebut agar halaman dirender dengan benar. Itu sudah saya perbaiki setelahnya.curl -sS https://snipgeek.com/robots.txt | head -20
curl -sS https://snipgeek.com/sitemap.xml | grep -c '<url>'noindex:curl -sS https://snipgeek.com/blog/disable-windows-defender-windows-11 \
| grep -i 'robots'<meta name="robots" content="index, follow"/> — benar. Tidak ada X-Robots-Tag header juga.curl -sI -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
https://snipgeek.com/blog/disable-windows-defender-windows-11age: 2326 dan cdn-cache-status: hit mengonfirmasi ini bukan response segar dari server. CDN yang menyajikan redirect basi. Saya telusuri kembali ke proxy.ts dan menemukan branch redirect berbasis cookie.proxy.ts:
// proxy.ts (SESUDAH — versi yang sudah diperbaiki)
if (pathnameIsMissingLocale) {
return NextResponse.rewrite(
new URL(
`/${i18n.defaultLocale}${pathname.startsWith("/") ? "" : "/"}${pathname}`,
request.url,
),
);
}LanguageSwitcher dan LocaleSuggestionBanner menggunakan router.push() untuk navigasi ke URL /id/ saat pengguna mengganti bahasa. Cookie tetap di-set untuk logika "jangan tampilkan lagi" di banner, tapi proxy tidak pernah membacanya lagi.
Vary: Cookie (yang efektifnya mematikan CDN caching) atau pindahkan logikanya ke client-side./en duplikat dari next.config.ts — proxy sudah meng-handle kanonisasi /en/* → /* dengan redirect 308. Punya keduanya itu redundan.robots.txt untuk aset Next.js — saya berhenti men-disallow /_next/ supaya crawler bisa mengambil CSS/JS yang dibutuhkan untuk render halaman dengan benar.robots eksplisit ke generateMetadata blog dan notes — sebelumnya mengandalkan inheritance dari layout, yang rapuh kalau metadata layout berubah./id/ — persis seperti yang didesain). Tidak ada error log, tidak ada 500, tidak ada build failure.
Satu-satunya sinyal adalah grafik Search Console yang turun ke nol. Kalau saya tidak cek GSC minggu itu, bug ini bisa tidak terdeteksi jauh lebih lama.
Tiga poin yang saya pin untuk ke depan:
public. Kalau response bervariasi berdasarkan cookie, tandai private atau gunakan Vary: Cookie.curl, bukan browser. Browser membawa cookie dan cache state yang menyembunyikan masalah level CDN.curl -sI homepage-kamu.com sekarang juga. Bisa saja hasilnya mengejutkan.
Pilih topik untuk menemukan artikel lain dengan bahasan yang serupa.
Menyiapkan area komentar...