موافقة ملفات تعريف الارتباط لـ Next.js وGatsby والمواقع الثابتة: دليل المطور للتكامل
مشكلة الموافقة في المواقع الثابتة
أحدثت أُطر JavaScript الحديثة مثل Next.js وGatsby وNuxt.js تحولاً جذرياً في كيفية بناء صفحات الويب وتقديمها. يتم تصيير الصفحات مسبقاً في وقت البناء أو على الخادم، ثم يتم ترطيبها على جانب العميل. وهذا يخلق تحدياً فريداً لموافقة ملفات تعريف الارتباط: يجب أن يكون شعار الموافقة جاهزاً قبل تنفيذ أي نصوص تتبع برمجية، لكن الصفحة نفسها قد تكون قد تم تصييرها وتخزينها مؤقتاً على الحافة بالفعل.
صُممت منصات إدارة الموافقة التقليدية للصفحات المصيَّرة من الخادم بلغة PHP أو صفحات HTML البسيطة حيث يتم تحميل المستند بشكل خطي من الأعلى إلى الأسفل. في عالم الأُطر مع تقسيم الكود والتحميل الكسول والتصيير من جانب الخادم المتدفق، تنهار هذه الافتراضات. يتطلب التعامل الصحيح مع الموافقة في هذه البيئات فهم خط أنابيب التصيير.
لماذا التوقيت أهم مما تعتقد
في صفحة HTML عادية، يعد وضع نص CMP البرمجي في <head> قبل النصوص البرمجية الأخرى أمراً بسيطاً. في Next.js App Router أو Gatsby، الوضع أكثر تعقيداً:
- يصل HTML المصيَّر مسبقاً أولاً: يتلقى المتصفح HTML كاملاً من شبكة CDN أو الخادم. إذا كانت أي نصوص برمجية مضمنة أو علامات طرف ثالث مدمجة في ذلك HTML، فقد تُنفَّذ قبل تحميل منطق الموافقة الخاص بك.
- فجوة الترطيب: يحدث ترطيب React بعد رسم HTML. إذا كان مكون الموافقة الخاص بك هو مكون React، فإنه لا يوجد في حالة وظيفية حتى يكتمل الترطيب. خلال هذه الفجوة، قد تُطلَق علامات Google أو نصوص التحليلات البرمجية بدون موافقة.
- تعقيدات التخزين المؤقت على الحافة: إذا كنت تستخدم ISR (التجديد الثابت التزايدي) أو وظائف الحافة، يتم تخزين HTML مؤقتاً. لا يمكنك حقن منطق يعتمد على الموافقة ديناميكياً في HTML المخزن مؤقتاً بدون آلية من جانب العميل.
المبدأ الأساسي هو: يجب إنشاء الموافقة على مستوى النص البرمجي، وليس على مستوى المكون. مكون React الذي يعرض شعار موافقة يكون متأخراً جداً إذا أصبح تفاعلياً فقط بعد الترطيب.
تكامل Next.js App Router
قدم Next.js 13+ مع App Router طريقة جديدة للتعامل مع النصوص البرمجية. إليك النهج الموصى به لتكامل الموافقة:
الخطوة 1: تحميل نص CMP البرمجي في التخطيط الجذري
استخدم مكون Script في Next.js مع استراتيجية beforeInteractive في layout.tsx الجذري. هذا يخبر Next.js بحقن النص البرمجي في مستند HTML الأولي، قبل بدء الترطيب:
استراتيجية beforeInteractive حاسمة. تقوم استراتيجية afterInteractive الافتراضية بتحميل النصوص البرمجية بعد الترطيب، وهو متأخر جداً للموافقة. مع beforeInteractive، يتم تضمين نص CMP البرمجي في HTML المصيَّر من الخادم ويُنفَّذ أثناء تحميل الصفحة.
الخطوة 2: تعيين الموافقة الافتراضية قبل علامات Google
قبل مقتطف Google Tag Manager أو gtag.js، قم بتضمين نص برمجي مضمن يعيّن حالات الموافقة الافتراضية. هذا يضمن أنه حتى لو تم تحميل GTM قبل ظهور شعار CMP، فإنه يحترم الإعدادات الافتراضية المرفوضة:
يجب وضع هذا النص البرمجي المضمن في <head> لتخطيطك الجذري، قبل نصوص CMP وGTM البرمجية. في Next.js، يمكنك استخدام علامة <script> عادية داخل عنصر <head> في تخطيطك لهذا الغرض.
الخطوة 3: التعامل مع تغييرات المسار
في التنقل داخل تطبيق الصفحة الواحدة، يتم تحميل نص CMP البرمجي مرة واحدة لكن تغييرات المسار لا تؤدي إلى إعادة تحميل كاملة للصفحة. يجب أن يستمر CMP الخاص بك عبر عمليات التنقل من جانب العميل. يتعامل FlexyConsent مع هذا تلقائياً — بمجرد تحميله، يظل نشطاً عبر جميع تغييرات المسار بدون إعادة تهيئة.
تكامل Next.js Pages Router
للمشاريع التي لا تزال تستخدم Pages Router، النهج مشابه لكن يستخدم _document.tsx بدلاً من التخطيط الجذري. ضع نص CMP البرمجي في مكون <Head> لفئة Document المخصصة. تعمل استراتيجية beforeInteractive بنفس الطريقة في Pages Router.
الفرق الرئيسي هو أن _document.tsx يُصيَّر فقط على الخادم، لذا فإن أي منطق موافقة هنا مضمون أن يكون في حمولة HTML الأولية.
تكامل موقع Gatsby الثابت
يولّد Gatsby صفحات HTML ثابتة بالكامل في وقت البناء. لا يوجد تصيير من جانب الخادم في وقت الطلب، مما يبسط بعض الجوانب لكن يعقد أخرى:
- استخدم
gatsby-ssr.tsxلحقن نص CMP البرمجي في<head>لكل صفحة. تتيح لك واجهةonRenderBodyإضافة نصوص برمجية إلى الرأس ستكون موجودة في كل ملف HTML ثابت. - تجنب إضافات Gatsby التي تحمّل الموافقة بشكل كسول: بعض إضافات المجتمع تغلف الموافقة في مكونات React التي لا تُركَّب إلا بعد الترطيب. هذا يخلق فجوة التوقيت التي ناقشناها سابقاً.
- ضع إعدادات الموافقة الافتراضية مضمنة: استخدم
setHeadComponentsفيgatsby-ssr.tsxلإضافة نص برمجي مضمن يعيّن حالات الموافقة الافتراضية. سيكون هذا النص البرمجي في HTML الثابت ويُنفَّذ فوراً.
نهج Gatsby القائم على وقت البناء يعني أن كل ملف HTML على شبكة CDN الخاصة بك سيتضمن نص الموافقة البرمجي. هذا في الواقع مثالي — لا يوجد منطق خادم يمكن أن يفشل أو يُخزَّن مؤقتاً بشكل غير صحيح.
اعتبارات Nuxt.js
لدى Nuxt.js (المبني على Vue) أنماطه الخاصة. في Nuxt 3، استخدم الدالة التركيبية useHead أو تكوين رأس التطبيق في nuxt.config.ts لإضافة نص CMP البرمجي بشكل عام. يدعم Nuxt خيار body: false (الذي يضع النصوص البرمجية في الرأس) وخاصية async للتحميل غير المعيق.
بالنسبة لوضع التصيير من جانب الخادم في Nuxt، ينطبق نفس المبدأ: يجب أن يكون نص CMP البرمجي في استجابة HTML الأولية، وليس محقوناً ديناميكياً بواسطة مكون Vue بعد التركيب.
تجنب إزاحة التخطيط
تشتهر شعارات الموافقة بالتسبب في إزاحة التخطيط التراكمية (CLS)، وهي مقياس من مقاييس Core Web Vitals يؤثر على تصنيفات محركات البحث. عندما يظهر شعار فجأة بعد تصيير الصفحة، فإنه يدفع المحتوى للأسفل أو يتراكب عليه بشكل غير متوقع.
استراتيجيات لتقليل CLS من شعارات الموافقة:
- استخدم شعاراً في أسفل الصفحة: الشعارات في أسفل نافذة العرض لا تزيح محتوى الصفحة. هذا هو النهج الأكثر ملاءمة لـ CLS.
- احجز المساحة: إذا كان يجب عليك استخدام شعار علوي، احجز المساحة العمودية في CSS الخاص بك حتى يأخذ تخطيط الصفحة الشعار في الاعتبار قبل تصييره.
- تجنب التراكبات المشروطة عند التحميل: جدران الموافقة بملء الشاشة التي تظهر بعد تصيير الصفحة تسبب عدم استقرار ملحوظ في التخطيط. إذا كنت بحاجة إلى جدار، اعرضه كجزء من حالة الصفحة الأولية.
- حمّل CMP بشكل متزامن في الرأس: عندما يتم تحميل CMP كنص برمجي يحظر التصيير في الرأس، يمكن أن يظهر الشعار كجزء من الرسم الأولي بدلاً من الظهور لاحقاً.
نهج FlexyConsent المستقل عن الأُطر
صُمم FlexyConsent للعمل مع أي إطار عمل — أو بدون إطار على الإطلاق — من خلال العمل على مستوى النص البرمجي بدلاً من مستوى المكون. إليك لماذا هذا مهم:
- علامة نص برمجي غير متزامنة واحدة: علامة
<script>واحدة في<head>هي كل ما تحتاجه. لا حزم npm لتثبيتها، لا أغلفة خاصة بالإطار، لا تكوين بناء. - تُطلَق إعدادات الموافقة الافتراضية فوراً: يعيّن النص البرمجي إعدادات Consent Mode V2 الافتراضية كأول إجراء له، قبل أي استدعاء أو معالجة DOM. هذا يعني أن علامات Google تحترم الموافقة من أول ميلي ثانية.
- لا اعتماد على DOM: لا ينتظر منطق الموافقة ترطيب React أو Vue أو Svelte. يعمل بشكل مستقل عن دورة حياة الإطار.
- يعمل مع SSG وSSR وISR وCSR: لأنه نص برمجي عادي، يعمل بشكل متطابق سواء كانت الصفحة مولَّدة ثابتياً أو مصيَّرة من الخادم أو مُجدَّدة تزايدياً أو مصيَّرة من جانب العميل.
نصيحة للمطورين: أبسط اختبار لتكامل CMP الصحيح هو فتح علامة تبويب الشبكة في متصفحك، والتصفية حسب نطاقات Google، وإعادة تحميل الصفحة. يجب ألا تُطلَق أي طلبات Google قبل ظهور أمر الموافقة الافتراضي في وحدة التحكم. إذا حدث ذلك، فإن CMP الخاص بك يتحمّل متأخراً.
يدعم الخطة المجانية لـ FlexyConsent عدداً غير محدود من مشاهدات الصفحات ويعمل مع Next.js وGatsby وNuxt وAstro وSvelteKit وRemix وHTML العادي. التكامل هو نفسه عبر جميعها: علامة نص برمجي واحدة، موضوعة بشكل صحيح.