Persetujuan Kuki untuk Next.js, Gatsby dan Laman Statik: Panduan Integrasi untuk Pembangun
Masalah Persetujuan untuk Laman Statik
Rangka kerja JavaScript moden seperti Next.js, Gatsby dan Nuxt.js memperkenalkan perubahan paradigma dalam cara halaman web dibina dan dihantar. Halaman dipra-render pada masa binaan atau di pelayan, kemudian dihidratkan pada klien. Ini mewujudkan cabaran unik untuk persetujuan kuki: sepanduk persetujuan mesti sedia sebelum sebarang skrip penjejakan dijalankan, tetapi halaman itu sendiri mungkin sudah dirender dan di-cache di edge.
CMP tradisional direka untuk halaman PHP yang dirender di pelayan atau halaman HTML ringkas di mana dokumen dimuat secara linear dari atas ke bawah. Dalam dunia rangka kerja dengan pemisahan kod, pemuatan malas dan rendering pelayan berstrim, andaian ini tidak lagi terpakai. Mendapatkan persetujuan yang betul dalam persekitaran ini memerlukan pemahaman tentang rantaian rendering.
Mengapa Masa Lebih Penting Daripada Yang Anda Sangka
Dalam halaman HTML biasa, meletakkan skrip CMP dalam <head> sebelum skrip lain adalah mudah. Dalam Next.js App Router atau Gatsby, keadaannya lebih kompleks:
- HTML pra-render tiba dahulu: Pelayar menerima HTML lengkap daripada CDN atau pelayan. Jika sebarang skrip sebaris atau tag pihak ketiga dibenamkan dalam HTML itu, ia mungkin dijalankan sebelum logik persetujuan anda dimuat.
- Jurang hidrasi: Hidrasi React berlaku selepas HTML dilukis. Jika komponen persetujuan anda ialah komponen React, ia tidak wujud dalam keadaan berfungsi sehingga hidrasi selesai. Dalam jurang ini, tag Google atau skrip analitik boleh dicetuskan tanpa persetujuan.
- Komplikasi cache di edge: Jika anda menggunakan ISR (Incremental Static Regeneration) atau fungsi edge, HTML akan di-cache. Anda tidak boleh menyuntik logik bergantung persetujuan secara dinamik ke dalam HTML yang di-cache tanpa mekanisme di sisi klien.
Prinsip terasnya ialah: persetujuan mesti ditetapkan pada peringkat skrip, bukan peringkat komponen. Komponen React yang merender sepanduk persetujuan sudah terlambat jika ia hanya menjadi interaktif selepas hidrasi.
Integrasi Next.js App Router
Next.js 13+ dengan App Router memperkenalkan cara baharu untuk mengendalikan skrip. Berikut ialah pendekatan yang disyorkan untuk integrasi persetujuan:
Langkah 1: Muatkan Skrip CMP dalam Root Layout
Gunakan komponen Script Next.js dengan strategi beforeInteractive dalam layout.tsx root anda. Ini memberitahu Next.js untuk menyuntik skrip ke dalam dokumen HTML awal, sebelum hidrasi bermula:
Strategi beforeInteractive adalah kritikal. Strategi lalai afterInteractive memuatkan skrip selepas hidrasi, yang terlalu lewat untuk persetujuan. Dengan beforeInteractive, skrip CMP dimasukkan dalam HTML yang dirender di pelayan dan dijalankan ketika halaman dimuat.
Langkah 2: Tetapkan Persetujuan Lalai Sebelum Tag Google
Sebelum snippet Google Tag Manager atau gtag.js anda, sertakan skrip sebaris yang menetapkan keadaan persetujuan lalai. Ini memastikan walaupun GTM dimuat sebelum sepanduk CMP muncul, ia mematuhi tetapan lalai yang ditolak:
Skrip sebaris ini perlu diletakkan dalam <head> layout root anda, sebelum skrip CMP dan GTM. Dalam Next.js, anda boleh menggunakan tag <script> biasa di dalam elemen <head> layout anda untuk tujuan ini.
Langkah 3: Tangani Pertukaran Laluan
Dalam navigasi aplikasi halaman tunggal, skrip CMP dimuat sekali tetapi pertukaran laluan tidak mencetuskan muat semula halaman penuh. CMP anda mesti kekal merentasi navigasi di sisi klien. FlexyConsent mengendalikan perkara ini secara automatik — sebaik sahaja dimuat, ia kekal aktif merentasi semua pertukaran laluan tanpa perlu diinisialisasi semula.
Integrasi Next.js Pages Router
Bagi projek yang masih menggunakan Pages Router, pendekatannya serupa tetapi menggunakan _document.tsx dan bukannya root layout. Letakkan skrip CMP dalam komponen <Head> kelas Document tersuai anda. Strategi beforeInteractive berfungsi dengan cara yang sama dalam Pages Router.
Perbezaan utama ialah _document.tsx hanya dirender di pelayan, jadi sebarang logik persetujuan di sini dijamin berada dalam payload HTML awal.
Integrasi Laman Statik Gatsby
Gatsby menjana HTML statik sepenuhnya pada masa binaan. Tiada rendering di pelayan pada masa permintaan, yang memudahkan beberapa aspek tetapi menyukarkan yang lain:
- Gunakan
gatsby-ssr.tsxuntuk menyuntik skrip CMP ke dalam<head>setiap halaman. APIonRenderBodymembolehkan anda menambah skrip ke head yang akan wujud dalam setiap fail HTML statik. - Elakkan plugin Gatsby yang memuatkan persetujuan secara malas: Sesetengah plugin komuniti membalut persetujuan dalam komponen React yang hanya mount selepas hidrasi. Ini mewujudkan jurang masa yang dibincangkan tadi.
- Letakkan tetapan lalai persetujuan secara sebaris: Gunakan
setHeadComponentsdalamgatsby-ssr.tsxuntuk menambah skrip sebaris yang menetapkan keadaan persetujuan lalai. Skrip ini akan berada dalam HTML statik dan dijalankan serta-merta.
Pendekatan masa binaan Gatsby bermakna setiap fail HTML pada CDN anda akan menyertakan skrip persetujuan. Ini sebenarnya ideal — tiada logik pelayan yang boleh gagal atau di-cache dengan tidak betul.
Pertimbangan Nuxt.js
Nuxt.js (berasaskan Vue) mempunyai corak tersendiri. Dalam Nuxt 3, gunakan composable useHead atau konfigurasi app head dalam nuxt.config.ts untuk menambah skrip CMP secara global. Nuxt menyokong pilihan body: false (yang meletakkan skrip dalam head) dan atribut async untuk pemuatan tidak menyekat.
Untuk mod rendering di pelayan Nuxt, prinsip yang sama terpakai: skrip CMP mesti berada dalam respons HTML awal, bukan disuntik secara dinamik oleh komponen Vue selepas mount.
Mengelakkan Peralihan Susun Atur
Sepanduk persetujuan terkenal kerana menyebabkan Cumulative Layout Shift (CLS), satu Core Web Vital yang menjejaskan kedudukan SEO. Apabila sepanduk muncul selepas halaman dirender, ia menolak kandungan ke bawah atau menindihnya secara tidak dijangka.
Strategi untuk meminimumkan CLS daripada sepanduk persetujuan:
- Gunakan sepanduk di bahagian bawah: Sepanduk di bahagian bawah viewport tidak mengalihkan kandungan halaman. Ini ialah pendekatan yang paling mesra CLS.
- Tempah ruang: Jika anda mesti menggunakan sepanduk di bahagian atas, tempah ruang menegak dalam CSS anda supaya susun atur halaman mengambil kira sepanduk sebelum ia dirender.
- Elakkan lapisan modals ketika muat: Dinding persetujuan skrin penuh yang muncul selepas halaman dirender menyebabkan ketidakstabilan susun atur yang dirasai. Jika anda memerlukan dinding, renderkannya sebagai sebahagian daripada keadaan awal halaman.
- Muatkan CMP secara segerak dalam head: Apabila CMP dimuat sebagai skrip yang menyekat rendering dalam head, sepanduk boleh muncul sebagai sebahagian daripada lukisan awal dan bukannya muncul kemudian.
Pendekatan Neutral Rangka Kerja FlexyConsent
FlexyConsent direka untuk berfungsi dengan mana-mana rangka kerja — atau tanpa rangka kerja langsung — dengan beroperasi pada peringkat skrip dan bukannya peringkat komponen. Inilah sebabnya ia penting:
- Satu tag skrip async tunggal: Satu tag
<script>dalam<head>sudah memadai. Tiada pakej npm untuk dipasang, tiada pembalut khusus rangka kerja, tiada konfigurasi binaan. - Tetapan lalai persetujuan dicetuskan serta-merta: Skrip menetapkan tetapan lalai Consent Mode V2 sebagai tindakan pertama, sebelum sebarang callback atau manipulasi DOM. Ini bermakna tag Google mematuhi persetujuan dari milisaat pertama.
- Tiada kebergantungan pada DOM: Logik persetujuan tidak menunggu React, Vue atau Svelte dihidratkan. Ia beroperasi secara bebas daripada kitar hayat rangka kerja.
- Berfungsi dengan SSG, SSR, ISR dan CSR: Oleh kerana ia hanyalah skrip biasa, ia berfungsi sama ada halaman dijana secara statik, dirender di pelayan, dijana semula secara berperingkat atau dirender di sisi klien.
Tip pembangun: Ujian paling ringkas untuk integrasi CMP yang betul ialah membuka tab Network pelayar anda, tapis mengikut domain Google dan muat semula halaman. Tiada permintaan Google sepatutnya dicetuskan sebelum arahan tetapan lalai persetujuan muncul dalam konsol. Jika ada, CMP anda dimuat terlalu lewat.
Pelan percuma FlexyConsent menyokong paparan halaman tanpa had dan berfungsi dengan Next.js, Gatsby, Nuxt, Astro, SvelteKit, Remix dan HTML biasa. Integrasinya sama untuk semuanya: satu tag skrip, diletakkan dengan betul.