Hydration mismatch SSR muncul ketika status autentikasi yang disuntikkan dari OAuth self-managed Cloudflare berbeda antara render server dan klien. Di artikel ini, kita langsung membahas bagaimana memastikan status user konsisten, dari verifikasi state hingga fallback loading, agar UI tetap stabil.
Memahami penyebab Hydration Mismatch SSR dengan OAuth Self-Managed Cloudflare
Pada arsitektur SSR/SSG yang memanfaatkan Cloudflare OAuth untuk semua, server biasanya menyuntikkan data user saat render awal. Namun, jika klien menerima cookie atau token autentikasi setelah hydration atau dalam kondisi berbeda (misalnya pending prompt OAuth), React/Framework akan mendeteksi DOM statis berbeda dari virtual DOM baru. Ini menghasilkan warning hydration mismatch dan UI yang terlihat berkedip atau terpatah-patah.
Faktor utama: token, cookie, atau flag status user yang tidak sinkron antara permintaan awal dan state yang diteruskan ke klien. Kasus umum terjadi ketika response OAuth self-managed menyimpan cookie `cf_oauth_state` berbeda di sisi klien sebelum hydration selesai.
Verifikasi state OAuth sebelum render
Langkah pertama adalah verifikasi state yang masuk pada endpoint OAuth dan meneruskannya ke SSR context. Gunakan middleware atau server handler untuk memetakan state yang diterima ke session internal, lalu hanya render halaman jika state valid.
Contoh pendekatan Next.js dengan getServerSideProps:
export async function getServerSideProps({ req, res }) {
const state = req.cookies['cf_oauth_state'];
const storedState = await fetchStoredState(req);
if (!state || state !== storedState) {
return {
redirect: {
destination: '/auth/trigger',
permanent: false,
},
};
}
const user = await buildUserFromToken(req);
return { props: { user } };
}
Verifikasi seperti ini memastikan tidak ada data user yang dipakai di server dengan kondisi state yang berbeda. Bila validasi gagal, arahkan ulang agar user menjalani ulang flow OAuth.
Mengkonsolidasikan cookie/token sebelum hydrating
Setelah state valid, konsolidasikan data autentikasi agar server dan klien membaca sumber yang sama. Gunakan cookie HttpOnly atau header `Authorization` yang hanya diakses server, lalu expose representasi minimal (seperti ID user) dalam props. Hindari membiarkan klien membaca token mentah, tapi pastikan props tidak berubah antara render pertama dan hydration.
Contoh pola respons di API internal yang dijadikan source of truth:
export async function buildUserFromToken(req) {
const token = req.cookies['cf_oauth_token'];
if (!token) return null;
const cached = await redis.get(`user:${token}`);
if (cached) return JSON.parse(cached);
const user = await fetchFromAuthServer(token);
await redis.set(`user:${token}`, JSON.stringify(user), 'EX', 300);
return user;
}
Selalu simpan hasil dalam cache menyeluruh untuk menghindari perbedaan state akibat perhitungan ulang di sisi server. Klien hanya menerima atribut seperti user.id dan user.roles yang tidak berubah secara tiba-tiba.
Penerapan fallback skeleton untuk mencegah UI membingungkan
Jika status autentikasi belum tentu siap saat server merender (misalnya dalam proses redirect OAuth), sediakan fallback skeleton atau placeholder state. Selama hydration, pastikan placeholder sama antara server dan klien supaya React tidak mendeteksi mismatch.
Contoh pendekatan sederhana:
function Page({ user }) {
if (!user) {
return (
<main role="status" aria-live="polite">
Menyiapkan autentikasi...
</main>
);
}
return <Dashboard user={user} />;
}
Skeleton ini harus deterministic dan tidak mengandalkan efek samping (misalnya fetching tambahan di client). Jika user spontan tersedia setelah hydration, gunakan client-side effect untuk memperbarui UI tanpa mengganti markup awal.
Debugging mismatch dan best practice tambahan
- Bandingkan markup server vs klien: Gunakan browser devtools untuk melihat DOM sebelum dan sesudah hydration. Fokus pada elemen yang menyertakan data user.
- Cek konsistensi cookie/token: Pastikan cookie yang diset dalam response OAuth self-managed memiliki path, domain, dan flag yang sama untuk request server berikutnya.
- Logging state: Catat nilai state, cookie, dan prop user selama rendering server. Jika berbeda, trace dari middleware OAuth ke SSR handler.
- Fallback timeouts: Jika server menunggu validasi state yang bisa terlambat, gunakan timeout pendek untuk menghindari blocking render yang berkepanjangan, lalu render skeleton dengan pesan loading.
Ketika mengintegrasikan Cloudflare OAuth self-managed, selalu buat aliran yang deterministik: state validasi, token konsisten, dan markup fallback yang tidak berubah saat hydration. Ini akan membuat peralihan antara server render dan klien lebih halus dan menghindari UI membingungkan.
Kesimpulan
Mencegah hydration mismatch SSR saat menggunakan OAuth self-managed Cloudflare membutuhkan sinkronisasi state yang ketat serta handling fallback. Verifikasi state, konsolidasikan cookie/token, dan pastikan skeleton fallback sama pada server dan klien. Dengan pendekatan ini, integrasi OAuth dapat berjalan mulus tanpa peringatan React atau kebingungan pengguna.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!