إضافة تحليلات تركز على الخصوصية إلى تطبيق SvelteKit
يعترض SvelteKit 2 التنقل من جانب العميل بشكل مختلف عن أطر العمل الأخرى. إليك النمط الصحيح لتتبع تغييرات المسار دون كوكيز أو لافتة موافقة.
كسر SvelteKit 2 معظم تكاملات التحليلات الموجودة بصمت. وسم <script> بسيط كان يعمل بشكل جيد في SvelteKit 1 سيُطلق فقط عند إعادة التحميل الكاملة في SvelteKit 2، متجاوزاً كل تنقل من جانب العميل. الإصلاح القياسي، وهو ربط history.pushState، لا يعمل أيضاً، لأن SvelteKit يعترض التنقل على مستوى الموجِّه قبل استدعاء pushState. يتعامل متعقب Monoid مع هذا بشكل صحيح من تلقاء نفسه.
لماذا يفشل النهج المعتاد
تكتشف نصوص التحليلات التقليدية تغييرات المسار من خلال تصحيح history.pushState وhistory.replaceState بطريقة مونكي-باتش. يستدعي موجِّه SvelteKit بدائيات التنقل الداخلية الخاصة به ولا يستدعي pushState إلا كأثر جانبي، بعد أن يكون انتقال المسار جارياً بالفعل. بحلول الوقت الذي يُطلق فيه pushState المصحَّح، قد لا يكون المسار الجديد قد عُرض بالكامل بعد، وفي بعض أنواع التنقل (استدعاءات goto() البرمجية، نقرات <a> مع التحميل المسبق)، ينتج التوقيت نسخاً مكررة أو أحداثاً مفقودة.
هذا هو السبب الجذري للمشكلة المُبلَّغ عنها على نطاق واسع حيث يسجل Google Analytics GA4 المشاهدة الأولى فقط عند التحميل الأولي في تطبيقات SvelteKit 2.
النهج الصحيح
أضف سكربت متعقب Monoid مرة واحدة إلى +layout.svelte الجذري باستخدام <svelte:head>:
<svelte:head>
<script
async
src="https://api.monoid.website/tracker.min.js"
data-site-id="YOUR_SITE_ID"
></script>
</svelte:head>
يُطلق مستمع DOMContentLoaded المدمج للمتعقب عند التحميل الأولي للصفحة. بالنسبة للتنقلات اللاحقة من جانب العميل، يُطلق ربط history.pushState للمتعقب بعد أن يكون التنقل الداخلي لـ SvelteKit قد اكتمل، مما يعني أن كل مسار، بما في ذلك الأول، يُتتبع مرة واحدة بالضبط دون نسخ مكررة أو أحداث مفقودة.
للتحقق، افتح علامة تبويب Network في DevTools وراقب طلبات POST إلى /collect. يجب أن ترى واحداً لكل تغيير مسار.
فصل حركة المرور التجريبية
تعمل مشاريع SvelteKit عادةً على localhost أثناء التطوير. سجل موقعاً منفصلاً واربط site_id الخاص به بمتغير بيئة حتى لا تلوث حركة المرور التطويرية مقاييس الإنتاج:
<script>
const siteId = import.meta.env.VITE_MONOID_SITE_ID
</script>
<svelte:head>
{#if siteId}
<script
async
src="https://api.monoid.website/tracker.min.js"
data-site-id={siteId}
></script>
{/if}
</svelte:head>
عيّن VITE_MONOID_SITE_ID في .env.local للتطوير (أو اتركه غير معيّن لمنع التتبع) وفي بيئة النشر للإنتاج. تضمن كتلة {#if siteId} أن المتعقب لن يُحقن أبداً عندما لا يكون المتغير معيناً.
ما لا تحتاجه
لا لافتة موافقة كوكيز. لا تحديث لسياسة الكوكيز. لا فحص navigator.cookieEnabled. تشتق نقطة نهاية التجميع تجزئة زائر يومية من عنوان IP وUser-Agent ومفتاح سري من جانب الخادم والتاريخ الحالي:
visitor_hash = SHA-256(IP + UA + SALT_SECRET + YYYY-MM-DD)
تُعاد التجزئة كل 24 ساعة ولا يمكن عكسها لاسترداد IP أو User-Agent. لا يُخزَّن شيء على جهاز الزائر. هذا يعني أن التكامل لا يُفعّل متطلبات موافقة ePrivacy أو PECR، لا يوجد شيء للموافقة عليه.
التحقق في لوحة التحكم
بعد النشر، افتح لوحة تحكم التحليلات وانتقل بين عدة مسارات على موقعك المباشر. يجب أن يُنتج كل تنقل إدخال مشاهدة صفحة جديد بالمسار الصحيح. إذا رأيت إدخالاً واحداً فقط بغض النظر عن التنقل، تحقق من أن السكربت محمَّل في التخطيط الجذري وأن VITE_MONOID_SITE_ID معيّن في بيئة الإنتاج.
محوّل SvelteKit الذي تستخدمه (Cloudflare، Vercel، Node، static) لا يؤثر على جمع التحليلات، حيث يحدث التتبع بالكامل في المتصفح بعد الترطيب (hydration).