ترکینگ بازدید از صفحات تو وب‌سایت‌های عادی خیلی ساده‌ س: کافیه کد ترکینگ رو به هر صفحه بچسبونی و تموم! هر وقت بازدیدکننده رو یه لینک داخلی کلیک کنه، مرورگر یه رفرش می‌کنه و یه ایونت پیج ویوی جدید به Google Analytics می‌فرسته.
ولی تو وب‌سایت‌های تک‌صفحه‌ای SPA (یا اپ‌های وب) ماجرا یه کم پیچیده‌تره. حتی با اینکه Google Analytics 4 الان خودش می‌تونه این بازدیدها رو ترک کنه، این کار به صورت خودکار عمل نمی‌کنه. بعضی وب‌سایت‌ها هم از نظر  وب ترکینگ خیلی اعصاب‌خردکنن!
نتیجه چی می‌شه؟ GA4 فقط اولین بازدید صفحه رو می‌گیره. بقیه صفحات تا وقتی بازدیدکننده صفحه رو کامل ریفرش نکنه، ثبت نمی‌شن.
باید یه سری تنظیمات اضافه بکنی تا بتونی این جور وب‌سایت‌ها/اپ‌ها رو ترک کنی. نگران نباش، من سه تا روش بهت نشون می‌دم که چطور با Google Analytics 4 و Google Tag Manager این کار رو بکنی. به این میگن: ترکینگ مجازی پیج ویوها به کمک GA4 و GTM.



 یه اپ/وب‌سایت تک‌صفحه‌ای (SPA) چی هست؟  
اپ تک‌صفحه‌ای (Single Page Application) یه اپ وب یا وب‌سایته که همه چیزای لازم برای گشتن تو سایت رو تو اولین بارگذاری صفحه می‌ریزه. وقتی کاربر رو لینک‌ها/دکمه‌ها کلیک می‌کنه یا با صفحه ور می‌ره، بقیه محتواها به صورت داینامیک بارگذاری می‌شن (و صفحه از نظر فنی ریفرش نمی‌شه، هرچند ممکنه ظاهرش عوض بشه).
تو نسخه‌های قدیم Google Analytics، این موضوع دردسرساز بود چون همه کدهای ترکینگ‌ فقط یه‌بار لود می‌شدن و صفحه تو کل سشن کاربر ریفرش نمی‌شد. به همین خاطر فقط یه بازدید تو گزارش‌ها می‌اومد. URL‌ها ممکن بود عوض بشن، ولی فقط برای این بود که حس جدا بودن صفحات رو بهمون بده.

تو بخش  Enhanced Measurement پلتفرم GA4 یه جور ترکینگ داخلی برای بازدید از پیج ها تو این موقعیت‌ها داریم. ولی این رو همه وب‌سایت‌های تک‌صفحه‌ای کار نمی‌کنه. پس ممکنه نیاز به تنظیمات اضافی GTM باشه.
اگه اصطلاح "اپلیکیشن تک‌صفحه‌ای" برات گنگه، شاید اسم‌هایی مثل React، Angular، Vue.js و Gatsby.js برات آشناتر باشه؟ وب‌سایت‌هایی که با این فریم‌ورک‌های جاوااسکریپت (یا مشابهشون) ساخته شدن، همون اپ های تک‌صفحه‌ای هستن.

 نصب Google Tag Manager  
اگه هنوز Google Tag Manager رو تو SPA یا وب‌سایتت نذاشتی، برو نصبش کن.
انجام شد؟ عالیشه، بیا یه قدم بریم جلو.

چند روش مختلف برای ترکینگ SPA ها
سه تا تکنیک تو این راهنما توضیح داده شده:  
- **روش #1:** ترکینگ داخلی Google Analytics 4 (سریع‌ترین راه)  
- **روش #2:** کار با لیسنر  History Change (از طریق GTM)  
- **روش #3:** استفاده از کمک به دولوپر که داده‌های بازدید رو هر بار که بازدیدکننده از یه صفحه به صفحه دیگه می‌ره به Data Layer بفرسته.  

ولی قبل از اینکه بپريم سراغ تنظیمات، اول باید موقعیت رو بفهمیم و ببینیم کدوم گزینه ترکینگ رو انتخاب کنیم. برای ساده‌تر کردن قضیه یه فلوچارت ساختم که بهت کمک می‌کنه بفهمی کدوم روش رو برداری (یا تو خیلی جاها فقط یه روش برات قابل استفاده س).
نکته: اگه هر سه روش برات قابل استفاده س، برو سراغ روش 3 (کمک دولوپر + dataLayer.push) چون ثابت شده س!
 
اول یه نگاه سریع به این فلوچارت بنداز، بعد عمیق‌تر تو هر مرحله می پردازیم.

google analytics 4 spa tracking - workflow

 اصلاً به این پست نیاز داری؟  
اولین لوزی تو فلوچارت می‌پرسه: وقتی بین صفحات سایت/اپ می‌چرخي، تو حالت پریویوی GTM صفحه‌های جدید رو می‌بینی؟
این سؤال یعنی چی؟ به‌طور پیش‌فرض، تگ Google Analytics هر بار که صفحه بارگذاری می‌شه (یعنی صفحه کامل از اول لود بشه) دوباره اجرا می‌شه.
همراه کد صفحه، اسنیپت جاوااسکریپتی Tag Manager هم از اول لود می‌شه. پس اگه از صفحه A به B بری، اینجا یه عنوان صفحه جدید می‌بینی. هر بار که این اتفاق بیفته، یعنی صفحه کامل (دوباره) لود شده.

پس اگه هر بار که صفحه رو لود میکنی و یه عنوان صفحه جدید رو تو سمت چپ سایدبار ببینی، یعنی با SPA مواجه نیستی.
ولی اگه واقعاً با یه SPA مواجهی، هر بار که از صفحه A به B میری، عنوان صفحه جدید رو نمی‌بینی. چرا؟
چون تو وب ترکینگ ، "بازدید" معمولاً وقتیه که داکیومنت صفحه لود می‌شه و کدهای جاوااسکریپت ترکینگ (شامل تگ‌های Pageview) با هم لود می‌شن. ولی تو SPA، بقیه "بازدیدها" داینامیک اتفاق می‌افتن بدون اینکه داکیومنت صفحه لود یا ریفرش بشه. به همین خاطر Tag Manager به‌طور پیش‌فرض "بازدیدهای داینامیک" رو ترک نمی‌کنه.
برای همین باید تنظیمات اضافی اعمال بکنی (و شاید هم از دولوپر کمک بگیری).
خب، اولین سؤالم جواب داده شد. 

اگه واقعاً با یه SPA مواجهی، بیا سراغ سؤال بعدی تو فلوچارت.
google analytics 4 spa tracking - workflow

 URL صفحه با رفتن از پیج A به B عوض می‌شه؟  
اگه URL عوض نشه، باید از دولوپر کمک بگیری. سریع برو به بخش "ترکینگ SPA با GTM و کمک دولوپر" تو این پست و از اونجا ادامه بده. اگه URL واقعاً عوض شده، هنوز می‌تونی ازلیسنر History Change استفاده کنی یا شاید قابلیت GA4 به صورت خودکار اینو حل کنه.

تغییرات URL بسته به وب‌سایتی که توشی فرق داره. تو بعضی‌ها، بخش fragment (بعد از علامت #) از URL عوض می‌شه. تو بعضیای دیگه، مثل یه وب‌سایت عادی می‌شه (مثلاً از /home/ به /home/contact-us میریم).  
اگه مطمئن شدی URL عوض می‌شه، بیا سراغ قدم بعدی.


روش #1: ترکینگ بازدید از پیج ها به کمک Enhanced Measurement  
نکته: Enhanced Measurement یه عالمه قابلیت ترکینگ ایونت داره، ولی خیلی‌هاش ممکنه درست کار نکنن (مثل ترکینگ اسکرول). پس بهتره همه ترکینگ‌های غیرمرتبط با بازدید (اسکرول، جستجوی سایت، کلیک و اینجور چیزا) رو خاموش کنی.
بیا ببینیم قابلیت ترکینگ داخلی بازدید تو GA4 برامون کار می‌کنه یا نه.
تو Google Analytics 4 برو به Admin > Data Streams و رو  دیتا استریم وب‌ سایتت کلیک کن.

بعد رو آیکون چرخ‌دنده کنار Enhanced Measurement بزن (مطمئن شو که فعاله).

بعد رو Show advanced settings زیر Page views کلیک کن و ببین کادر Page changes based on browser history events روشنه. این باعث می‌شه GA4 هر بار که URL عوض می‌شه (یا حداقل سعی کنه) این قضیه رو ترکینگ کنه.


بعد همه تغییرات رو تو GA4 ذخیره کن. تو Google Tag Manager حالت Preview و Debug رو روشن کن و بعد برو تو SPA خودت. چک کن که وقتی از یه صفحه به صفحه دیگه میری.
تو حالت پریویوی GTM باید ایونت‌های History Change رو ببینی(اسم فنی‌شون gtm.historyChange-v2 هست). اینو وقتی کانتینر GTM رو تو بالای پیش‌نمایش انتخاب کنی می‌بینی.

اگه دیدیش، رو مژرمنت آیدی GA4 تو بالای تب پریویو کلیک کن و چک کن یه تعداد ایونت Page View به Google Analytics 4 فرستاده شده باشه. اگه اینطور بود، خبر خوبیه. GA4 خودش بازدیدهای SPA رو ترک می‌کنه و نیازی به تنظیمات بیشتر نیست.

همون موقع توی GA4 بیا و DebugView رو هم چک کن ببین ایونت‌های page_view با پارامترهای page_title و page_location درست لاگ میشن یا نه.
اگه ایونت‌های History Change رو ندیدی (یا ایونت‌های page_view به GA4 نرفت)، برو به بخش بعدی این پست.

روش #2: امتحان کردن تگ History Change  
محکم‌ترین راه برای ترکینگ اپ‌های تک‌صفحه‌ای همکاری با دولوپرهاس. بدون شک! ولی گاهی اونها در دسترس نیستن، پس باید با چیزی که داریم بسازیم. برای همین این روش پایین رو توضیح میدم.

تو Google Tag Manager برو به این مسیر:  Triggers > New > History Change  و یه تگ با این تنظیمات بساز:

بعد باید تست کنیم کار می‌کنه یا نه. حالت Debug رو توی تگ منیجر روشن کن. دکمه Preview رو تو گوشه بالا سمت راست رابط GTM (نزدیک Submit) بزن.

بعد از زدن Preview، یه تب جدید مرورگر با tagassistant.google.com باز می‌شه.
یه پاپ‌آپ می‌خواد URL‌ای که می‌خوای تست کنی رو بدی. می‌تونه آدرس صفحه اصلی یا URL یه صفحه خاص باشه، بعد Start بزن.

یه تب (یا پنجره) جدید باید باز شه که URL‌ای که دادی رو نشون می‌ده. تو پایین اون صفحه/تب باید این آیکون رو ببینی:

رو بخش‌های مختلف اپ وب تک‌صفحه‌ای (یا وب‌سایت) کلیک کن (یا اسکرول کن) تا URL عوض شه. بعد از تغییر، دقیق به جریان ایونت‌ها تو کنسول Preview و Debug نگاه کن.
ایونت History اومد؟ اگه آره، خبر خوبیه! اگه نه، برو به تایتلی که توضیح می‌ده چطور با دولوپر کار کنی.

تو بعضی اپ‌های تک‌صفحه‌ای، ممکنه چند تا ایونت History با هم بیاد. برای همین باید به یه سؤال دیگه جواب بدی.

 چند تا ایونت History وقتی از صفحه A به B می‌ری می‌بینی؟  
بعضی وب‌سایت‌ها جوری کدنویسی شدن که چند تا ایونت History با هم تو حالت پیش‌نمایش GTM میاد. اگه با این موقعیت روبه‌رو شدی، 



راه‌حل‌های احتمالی چی می‌تونه باشه؟

یکی از راه‌ها اینه که بی‌خیال  تریگر History Change بشی و بری با دولوپر گپ بزنی. بهش بگو هر وقت URL واقعاً عوض شد، یه ایونت کاستوم پوش کنه توی Data Layer. کنار این ایونت، باید URL درست  و عنوان صفحه رو هم بفرسته. 

ولی احتمالاً دنبال یه راه حل دیگه‌ای، نه؟ خب، یه راه دیگه هم هست. نمی‌گم 100% روی همه SPAها جواب می‌ده، ولی رو خیلی از اونا که من باهاشون کار کردم و این دردسر چندتا ایونت History رو داشتن، کار کرده.

نکته ای که اینجا میگم اینه: بیا  سورس History Change  رو محدودتر کنیم.

وقتی تو حالت پیش‌نمایش و دیباگ GTM کلی ایونت History می‌بینی، رو اولی کلیک کن و برو سراغ تب Data Layer. دنبال مقدار gtm.historyChangeSource بگرد. مقدارش چیه؟ مقدارش یادت باشه. تو مورد من، مقدارش pushState بود.


بعد برو سراغ ایونت History بعدی که تقریباً هم‌زمان با قبلی اتفاق افتاده. حالا این دفعه مقدار gtm.historyChangeSource چیه؟ تو مورد من، replaceState بود.


بعضی اپ‌ها رو دیدم که تو هر بازدید صفحه (pageview) 3 یا 4 تا ایونت History دارن. اگه واسه تو هم اینجوریه، همه‌شون رو چک کن.

هدف اینه که بفهمی: آیا یه ایونت History  هست که مقدار gtm.historyChangeSourceش با بقیه ایونت‌های History که هم‌زمان اتفاق افتادن فرق داشته باشه؟

مثلاً اگه 3 تا ایونت History هم‌زمان داری، شاید فقط یکیش pushState باشه و بقیه‌شون replaceState؟.

تو مورد من، دو تا ایونت History می‌بینم. یکی با pushState و یکی با replaceState. هنوز نفهمیدم کدومو باید انتخاب کنم. واسه همین تو SPA گشت می‌زنم ببینم چه خبره. نکته: اگه 3 تا ایونت داشتم (یکیش pushState و دوتاش replaceState)، احتمالاً باید می‌رفتم سراغ pushState. ولی چون تو موقعیت من فقط دو تا ایونت History هم‌زمان بود، هنوز شک دارم کدوم حالت رو بردارم.

صفحه‌ای که داشتم چک می‌کردم یه اسلایدر داشت که کاربر می‌تونست باهاش به یه سؤال از 1 تا 10 جواب بده. هر دفعه که اسلایدر یه ذره جابه‌جا می‌شد، یه ایونت History جدید پوش میشد تو Data Layer.


بعد از چک کردن، دیدم همه‌شون replaceState بودن. حالا من اصلاً دلم نمی‌خواد هر وقت یکی اسلایدر رو یه کم جابه‌جا کرد، یه بازدید صفحه مجازی به GA بفرستم. فقط می‌خوام وقتی صفحه عوض می‌شه (مثلاً می‌رم صفحه بعدی) تگ فعال بشه.

خلاصه، replaceState به درد من نمی‌خوره (چون زیادی تند تند فعال می‌شه). ولی pushState خوبه (چون فقط وقتی تو SPA جابه‌جا می‌شم یه بار فعال می‌شه).

واسه مطمئن شدن، باید تو SPA بیشتر بچرخی و چک کنی که هر وقت از یه "صفحه" می‌ری به یه صفحه دیگه، فقط یه ایونت History تو حالت پیش‌نمایش و دیباگ با pushState اتفاق بیفته.

یادت باشه: SPA خودت رو حسابی زیر و رو کن. تو مثال من، ترکینگ ایونت‌های History به تنهایی با pushState راه حل درست بود. ولی تو مورد تو شاید فرق کنه و لازم باشه یه حالت دیگه رو انتخاب کنی. پس همیشه یه کم بازی کن و چک کن ببین کدوم History Change Source به دردت می‌خوره.

 تریگر History Change رو آپدیت کن

اگه همه‌چیز روبه‌راه بود و تونستی مقدار درست gtm.historyChangeSource رو پیدا کنی (که فقط وقتی کاربر از یه "صفحه" SPA می‌ره به صفحه بعدی، یه بار تو Data Layer میاد)، وقتشه که ببريش تو تنظیمات تریگر History Change .

برو تو کانتینر Google Tag Manager > Triggers و  تریگر History Changeی که قبلاً ساختی رو باز کن. این شرط رو اضافه کن: History Source برابر باشه با pushState


این شرط حساس به حروف بزرگ و کوچیکه.

اگه متغیر History Source رو تو لیست نمی‌بینی، رو Choose built-in variable کلیک کن و بعد History Source رو انتخاب کن.


اگه تگ پیچ ویوی GAت از قبل داره از این تریگر استفاده می‌کنه، بیا ببینیم آیا تگ واقعاً در زمان درست (فقط تو ایونت‌های History با pushState) فعال می‌شه یا نه.

حالت پریویو و دیباگ رو رفرش کن (با کلیک روی بنر نارنجی تو رابط GTM) و بعد پنجره مرورگر رو با SPAت رفرش کن. شروع کن به گشت زدن و ببین چه اتفاقی می‌افته.

نکته مهم: هنوزم کلی ایونت History تو حالت پریویو و دیباگ می‌بینی. ولی اگه روشون کلیک کنی، باید ببینی تگ پیج ویوی  GA فقط برای اون ایونت هایی فعال می‌شه که وریبل History Source برابر با pushState باشه.

دو جا تو حالت پریویو می‌تونی مقدار History Source رو چک کنی:

  • تب Variables تو حالت پریویوی GTM


  • تب Data Layer


URL صفحه رو درست بفرست

اگه URL های SPA شما # داره و همه اطلاعات مهم که کمک می‌کنه یه URL رو از اون یکی تشخیص بدی بعد از # تو URLه (مثلاً example.com/#/pages/contact-us)، باید یه سری تنظیمات اضافی بکنی (چون به‌صورت پیش‌فرض، Google Analytics بخش‌های URL بعد از علامت هش (#) رو نشون نمی‌ده).

این بخش از راهنمای ردیابی SPA من رو بخون تا بیشتر بدونی. چندتا گزینه داری، باید اونی که به دردت می‌خوره رو انتخاب کنی.

چک کردن دیتالیرپوش (مربوط به ایونت History) و ساخت وریبل ها  
وقتی ایونت History رو تو حالت پیش‌نمایش GTM می‌بینی، روش کلیک کن و API call رو باز کن (برای دیدن محتوای dataLayer.push).
مهم‌ترین چیزا برای ما ایناس:  
- URL فعلی  
- و URL قبلی  
تو مثال پایین، اینا به اسم gtm.oldUrl و gtm.newUrl هستن.

بیا دیتالیروریبل براشون بسازیم. اگه ساختار dataLayer‌ واسه تو فرق داره، باید خودت مسیر دسترسی به اون وریبل رو بدی.

توی تگ منیجر به این مسیر برو: Variables > Variable Configuration > New > Data Layer variable و عبارت "gtm.oldUrl" رو وارد کن.

وریبل رو ذخیره کن. همین کار رو برای gtm.newUrl هم بکن.

به این وریبل تو تایتل بعدی نیاز داریم.

فرستادن داده‌ها به Google Analytics (با تگ History Change)  
بعد از اینکه مطمئن شدی تگ History Change درست کار می‌کنه، باید این پیج ویوها رو به Google Analytics بفرستی.
اگه این راهو انتخاب کردی، اول ترکینگ ایونت History رو تو GA4 خاموش کن. این کار روو می‌تونی با رفتن به Admin > Data Streams  انتخاب وب استریم وبسایت و رفتن به بخش Enhanced Measurement و خاموش کردن "Page changes based on browser history events" بکنی.

نکته مهم : تو بعضی وب‌سایت‌ها ممکنه ببینی بازدیدهای SPA درست ترک می‌شه، ولی تو گزارش‌ها عنوان صفحه همیشه مال صفحه قبلیه. اگه اینو دیدی، باید ترکینگ رو با کمک دولوپر راه بندازی یا ایونت History Change رو به تأخیر بندازی.

  تگ ایونت برای ایونت page_view  
Google Analytics 4 یه پلتفرم بر پایه ایونته. یعنی همه چیز یه ایونت حساب می‌شه. بازدید، کلیک، خرید و اینجور چیزا. هر بار که ایونت History میاد، باید یه ایونت page_view به GA4 بفرستیم.
تو Google Tag Manager برو به این مسیر: Tags > New > Google Analytics > GA4 event tag  و این تنظیمات رو بده. اگه قبلا این تگ رو ساختی نیازی به ساختن تگ چدید نیست و روی همون تگ قبلی اصلاحات رو انجام بده.

مژرمنت آیدی مربوط به GA4 شما باید فرق داشته باشه. تو این تگ، دو تا پارامتر ایونت اضافه کردم:  
- page_location (ارزشش همون مقدار وریبل دیتالیری  gtm.newUrl هست)  
- page_referrer (ارزشش همون مقدار وریبل دیتالیری gtm.oldUrl هست)  

اگه از event settings variable  استفاده می‌کنی، این پارامترهای بالا رو اونجا بذار.
اگه URL‌هات علامت hash (#) دارن، ممکنه نیاز باشه متغیرهای دیگه بسازی (چون gtm.newUrl و gtm.oldUrl # رو شامل نمی‌کنن). راه‌حل می‌تونه یه وریبل جاوااسکریپت به اسم window.location.href باشه.

می‌تونی از مقدار این وریبل به‌عنوان مقدار page_location استفاده کنی.
آخر سر، تریگر History Event رو به تگ ایونت GA4 (page_view) وصل کن.

**نکته مهم:** اگه از Event Setting Variable استفاده نمی‌کنی، باید page_location و page_referrer رو تو همه تگ‌های ایونت GA4 دستی عوض کنی.

تگ Google با پارامتر "update"  
تا حالا باید دو تا تگ مرتبط با ترکینگSPA داشته باشی:  
- تگ ایونت page_view  
- و تگ Google (که قبل از خوندن این مقاله باید داشته باشی). این همونیه که باید GA4 رو باهاش نصب کرده باشی.  

یه مثال از تگ Google این هست:


ولی وقتی URL صفحه عوض می‌شه، باید به تگ کانفیگ گوگل بگی که یه سری آپدیت پیش اومده.
این کار با کپی کردن تگ اصلی کانفیگ گوگل و اضافه کردن این تغییرات ممکنه (بقیه تنظیمات اصلی رو دست‌نخورده بذار):  

"update" یعنی تگ Google از تغییرات خبر داره (هیچ ایونت page_view اضافی با این تگ نمی‌فرسته). این برای ایونت‌های خودکار مثل user_engagement لازمه. با این دستور، نوع تغییراتی که بوده رو می‌فرستیم:  
- مقدار page_location عوض شده  
- page_referrer هم عوض شده  

این برای جلوگیری از یه مشکل به اسم rogue referral لازمه. این به بهتر شدن اتریبیوشن کمک می‌کنه. حتی اگه تو یه زمانی گوگل گفته باشه اینو خودکار درست می‌کنه ولی من بهشون اعتماد ندارم 🙂 بارها گیر کردم؛ پس خودم دست به کار می‌شم.
نکته مهم: این تگ نباید تریگر داشته باشه. این تگ رو بدون تریگر ذخیره کنی (به زودی می‌فهمی چرا).


فایر کردن تگ "update" قبل از تگ page_view  
به تگ ایونت page_view برگرد و بعد برو به این مسیر: Advanced settings > Tag Sequencing > Fire a tag before GA4 page_view و تگ "update" که بالا ساختی رو انتخاب کن.
تگ رو ذخیره کن.


 آیا تگ کانفیگ گوگل باید اولین page_view رو خودکار ترک کنه؟  
به‌طور پیش‌فرض، وقتی تگ Google اجرا می‌شه، یه page_view به GA4 می‌فرسته. ولی تو بعضی اپ‌های تک‌صفحه‌ای، این ممکنه باعث تکرارهای page_view بشه.
چیکار باید کرد؟ چک کن ببین بعد از لود/ریفرش صفحه اپ تک‌صفحه‌یت چه اتفاقی میفته.
آیا ایونت History تو حالت پریویو و هر بار که صفحه رو ریفرش می‌کنی میاد؟
اگه صفحه رو ریفرش کنی (بدون کلیک تو جای دیگه تو وب‌سایت) و اینو میبینی:

…باید ترکینگ خودکار page_view رو تو تگ کانفیگ گوگل غیرفعال کنی. به این صورت:

اگه قبلاً send_page_view=true داری، ارزشش رو به false تغییر بده.

ولی اگه ایونت‌های History بلافاصله بعد از ریفرش صفحه نیان و فقط وقتی تو وب‌سایت/اپت میگردی شروع به ظاهر شدن کنن، تگ کانفیگ گوگل رو تغییر نده.

 خلاصه ستاپ History Change 
می‌فهمم بعضی مراحل  این پست ممکنه گنگ و نامفهوم باشه (چون ترکینگ SPA با GA4 کار ساده‌ای نیست). اینا چیزاییه که باید توی ستاپت داشته باشی:  
- یه تگ کانفیگ گوگل معمولی (که قبل از خوندن این راهنما باید اضافه شده باشه). اینجا تغییری ندادیم.  
- یه تگ History Change که وقتی URL عوض می‌شه اجرا بشه. اگه چند تا ایونت History Change می‌بینی، باید تگت رو دقیق‌تر کنی.  
- یه تگ ایونت GA4 که ایونت page_view رو به GA4 می‌فرسته  
- همراه با ایونت، page_referrer و page_location رو هم می‌فرستیم. page_referrer برای دور زدن مشکلات احتمالی اتریبیوشن لازمه. تو مثالم از وریبل های دیتالیری gtm.oldUrl و gtm.newUrl استفاده کردم، ولی مورد شما ممکنه نیاز به چیز دیگه داشته باشه. مهم اینه که newUrl URL درست رو نشون بده (شامل fragment  (#) و پارامترهای URL مثل UTM و oldUrl  دامنه صفحه قبلی رو درست بخونه  
- این تگ باید از تگ History Change استفاده کنه  
- تو تگ ایونت page_view، باید  tag sequencing رو تنظیم کنی. قبل از اجرا شدن این تگ، یه تگ کانفیگ Google (با پارامتر "update") باید فعال شه  

 تست کردن ستاپ  
بعد از اینکه همه چی رو ست و ذخیره کردی، وقتشه تنظیمات رو چک کنی. من به‌طور خلاصه توضیح می‌دم چطور ترکینگ page_view رو تست کنی.

بررسی DebugView

همه تغییرات رو تو کانتینرت ذخیره کن و با کلیک روی دکمه Preview تو کانتینر GTM، حالت پیش‌نمایش رو فعال یا رفرش کن. بعد برو به DebugView تو GA4 (اینو تو مسیر Admin > DebugView پیدا می‌کنی).

وقتی صفحه اول SPA لود می‌شه، باید یه ایونت page_view تو DebugView ببینی.


چک کن ببین پارامترهای page_location و page_title درستن و به صفحه‌ای که داری نگاه می‌کنی مربوط می‌شن یا نه.

بعد شروع کن تو وب‌سایت یا اپت بچرخ و ببین تعداد بازدیدهای صفحه‌ای که تو DebugView می‌بینی درسته یا نه، و اینکه پارامترهاشون هم درست ثبت میشن یا نه.

طی 24 ساعت آینده، باید داده‌های بازدید صفحه‌ات رو تو گزارش‌های GA4 تو این مسیر ببینی: Reports > Engagement > Pages and Screens 


روش #3: ترکینگ برنامه‌های SPA با گوگل تگ منیجر و کمک دولوپر  
احتمالاً وقتی به اینجا رسیدی که تلاش‌هات برای ترکینگ History Change جواب نداده یا فقط کنجکاوی بیشتر داری.
اگه (به هر دلیلی) تگ History Change برات کار نمی‌کنه ، یه راه دیگه برای ترکینگ  SPA با گوگل تگ منیجر هست.
از دولوپر بخواه هر بار که کاربر بین صفحات/حالت های یه وب‌سایت/اپ وب می‌چرخه، کد dataLayer.push رو فعال کنه.
این یه نمونه کد هست که توسعه‌دهنده می‌تونه ازش استفاده کنه:dtl-pageviww.txt
نکته: مقادیر پارامترهای ‘pageUrl’,‘previousUrl’ و ‘pageTitle’ (تو این کد) باید داینامیک باشن و با URL (و عنوان) صفحه‌ای که بازدیدکننده داره می‌بینه عوض بشن. دولوپر باید اینو ببنده. اگه URL شامل # یا علامت‌های سؤال و پارامترها باشه، باید اون ها رو هم در نظر بگیره. اگه URL پارامترهای کوئری (مثل UTMs) داشته باشه، اونام باید اضافه بشن.
به هر حال، این تیگه کد یعنی چی؟
هر وقت کاربر به یه بخش خاص از صفحه‌ت بره، توسعه‌دهنده باید این تکه کوچیک کد جاوااسکریپت رو فعال کنه. این نشون می‌ده یه "virtual Pageview" اتفاق افتاده و URL جدید هست.
بعد، از این dataLayer.push به‌عنوان شرط تریگر شدن تو GTM (که تگ GA Pageview رو فایر می‌کنه) استفاده می‌کنی و در کنارش عنوان و مسیر صفحه رو به GA می‌فرستی.

برای این کار، این مراحل رو انجام بده:  
- سه تا وریبل بساز (و اونا رو تو تگ ایونت GA4 بذار). اگه pageTitle نداری، دو تا وریبل بساز. حداقل pageUrl و previousUrl رو باید داشته باشی  
- یه تریگر بساز (و اونو به تگ ایونت GA4 وصل کن)  

وریبل ها
- عنوان: dlv – pageUrl (dlv مخفف "Data Layer Variable" هست)  
- نوع متغیر: Data Layer Variable  
- نام دیتالیر وریبل: pageUrl  
این متغیر مقدار pageUrl رو که دولوپر به  دیتالیر فرستاده رو می‌خونه.

وریبل دوم رو بساز:  
- عنوان: dlv – pageTitle  
- نوع وریبل: Data Layer Variable  
- نام وربل دیتالیری: pageTitle  


وریبل سوم رو بساز:  
- عنوان: dlv – previousUrl  
- نوع وریبل: Data Layer Variable  
- نام دیتالیر وریبل: previousUrl  


 

تریگر  
- عنوان:Custom – virtualPageview  
- نوع: Custom ایونت  
- نام ایونت: virtualPageview  
- این تریگر تو: همه ایونت‌های سفارشی فایر میشه



ساخت تگ ایونت GA4  
به این مسیر برو Tags > New > GA4 event tag   و این پیکربندی رو ست کن.

این بار، سه تا پارامتر رو اصلاح می‌کنم (page_location، page_referrer و page_title). مقادیرشون وریبل های دیتالیری هستن که تو یکی از بخش های قبلی ساختم. 

مهم: باید این پارامترها رو برای همه تگ‌های ایونت GA4 آینده هم اضافه بکنی.
این تگ رو طوری تنظیم کن که رو تریگر کاستوم ایونتی که اخیراً ساختی فایر شه.

تگ Google با پارامتر "update"  
تا حالا باید دو تا تگ مرتبط با ترکینگ SPA داشته باشی:  
- تگ ایونت page_view  
- و تگ کانفیگ گوگل (که قبل از خوندن این مقاله باید داشته باشیش). این همونیه که باید GA4 رو باهاش نصب کرده باشی.  

یه  تگ کانفیگ گوگل می‌تونه اینجوری باشه:

شما ممکنه موارد سفارشی‌سازی بیشتری داشته باشی. من فقط حداقل‌ها رو توی این تگ دارم.
ولی وقتی URL صفحه عوض می‌شه، باید به تگ کانفیگ Google بگی که یه سری آپدیت پیش اومده.
این کار با کپی کردن تگ اصلی کانفیگ گوگل و اضافه کردن این تغییرات ممکنه (بقیه تنظیمات اصلی رو دست‌نخورده بذار):  

"update" یعنی تگ Google از تغییرات خبر داره (هیچ ایونت page_view اضافی با این تگ نمی‌فرسته). این برای ایونت‌های خودکار مثل user_engagement لازمه. با این دستور، نوع تغییراتی که پیش اومده رو می‌فرستیم:  
- ارزش page_location عوض شده  
- page_title تغییر کرده  
- page_referrer هم عوض شده  
این برای جلوگیری از یه مشکل به اسم rogue referral لازمه. این به بهتر شدن اتریبیوشن کمک می‌کنه. حتی اگه تو یه زمانی گوگل گفته باشه اینو خودکار درست می‌کنه، من بهشون اعتماد ندارم 🙂 بارها گیر کردم؛ پس خودم دست به کار می‌شم.
مهم: این تگ نباید تریگری داشته باشه. این تگ رو بدون تریگر ذخیره کن (به زودی می‌فهمی چرا).

فایر کردن تگ "update" قبل از تگ page_view  
به تگ ایونت page_view برگرد و بعد برو به این مسیر:

 dvanced settings > Tag Sequencing > Fire a tag before GA4 page_view

 تگ "update" که ساختیش رو انتخاب کن. تگ رو ذخیره کن.



 تگ کانفیگ گوگل باید اولین page_view رو به صورت خودکار ترک کنه؟  
به‌طور پیش‌فرض، وقتی تگ کانفیگ گوگل اجرا می‌شه، یه page_view به GA4 می‌فرسته. ولی تو بعضی SPA ها، این ممکنه باعث تکرارهای page_view بشه.
چیکار باید کرد؟ چک کن ببین بعد از لود/ریفرش صفحه SPA چی می‌شه.
آیا ایونت History تو حالت پیش‌نمایش هر بار که صفحه رو ریفرش می‌کنی میاد؟
اگه صفحه رو ریفرش کنی (بدون کلیک تو جای دیگه تو وب‌سایت) و اینو ببینی:

…باید ترکینگ خودکار page_view رو تو تگ کانفیگ گوگل خاموش کنی.

اگه قبلاً پارامتر send_page_view=true رو میفرستادی، مقدارش رو به false تغییر بده.
ولی اگه ایونت‌های History بلافاصله بعد از ریفرش صفحه نیان و فقط وقتی تو وب‌سایت/اپت گشتی شروع به ظاهر شدن می کنن، تگ کانفیگ گوگل رو تغییر نده.

خلاصه این بخش  
می‌فهمم بعضی مراحل  این بخش ممکنه گنگ و نامفهوم باشه (چون ترکینگ SPA با GA4 کار ساده‌ای نیست). اینا خلاصه‌ چیزایی هست که بهشون نیاز داریم:
- یه تگ کانفیگ گوگل عادی (که قبل از خوندن این راهنما باید داشته باشی). اینجا تغییری توش ندادیم.  
- از دولوپر خواستیم که ایونت virtualPageview رو به دیتالیر بفرسته وقتی URL صفحه عوض می‌شه. همراهش، ازش خواستیم pageUrl، pageTitle و previousUrl رو  همبفرسته. ما یه تگ و ۳ وریبل برای این ساختم  
- یه تگ ایونت GA4 که ایونت page_view رو به GA4 می‌فرسته  
- همراه با ایونت، page_title، page_referrer و page_location رو هم می‌فرستیم. page_referrer برای دور زدن مشکلات احتمالی اتریبیوشن لازمه. تو مثالم از وریبل های دیتالیری pageUrl و previousUrl استفاده کردم. مهم اینه که pageUrl بتونه URL درست رو نشون بده (شامل fragment URL (#) و پارامترهای URL مثل UTMs) و previousUrl حداقل دامنه صفحه قبلی رو درست ارایه کنه  
- این تگ باید از تگ History Change استفاده کنه  
- تو تگ ایونت page_view، باید ترتیب تگ‌ها رو ست کنی. قبل از اجرا شدن این تگ، یه تگ کانفیگ گوگل (با پارامتر "update") باید فایر شه  

تست کردن ستاپ  
بعد از اینکه همه چی رو تنظیم و ذخیره کردی، وقتشه تنظیمات رو چک کنی. من به‌طور خلاصه توضیح می‌دم چطور ترکینگ page_view رو تست کنی.

چک کردن DebugView  
تمام تغییرات رو تو کانتینرت ذخیره کن و حالت پیش‌نمایش رو با زدن دکمه Preview تو کانتینر GTM روشن/ریفرش کن. بعد توی GA4 برو به DebugView (تو Admin > DebugView پیداش می‌کنی).
وقتی اولین صفحه SPA رو لود می‌کنی، باید یه ایونت page_view تو DebugView ببینی.

چک کن ببین پارامترهای page_location و page_title درستن و به صفحه فعلی که داری می‌بینی تعلق دارن.
بعد شروع کن به گشتن تو وب‌سایت/اپت  و ببین تعداد ایونت‌های page_view که تو debugview می‌بینی درستن و پارامترهاشون اوکیه یا نه.
طی ۲۴ ساعت آینده، باید داده‌های بازدید صفحه‌ت رو توی GA4 از این مسیر ببینی:
Reports > Engagement > Pages and Screens


نکات آخر
مشکل اپ‌ یا وب‌سایت‌های تک‌صفحه‌ای اینه که ترکینگ معمولی پیج ویو کار نمی‌کنه. همه کدهای لازم یه‌بار بارگذاری می‌شن و صفحه تو کل سشن کاربر ریفرش نمی‌شه. تو بعضی موارد، GA4 ممکنه بتونه ایونت‌های صفحه SPA رو ترک کنه، ولی این همه سناریوها رو پوشش نمی‌ده.
با تنظیمات خاصی تو گوگل تگ منیجر (و شاید یه کم کمک از دولوپر)، هنوز می‌تونی اونا رو ترک کنی. تو این پست وبلاگی، راه‌حل داخلی GA4 و دو تا گزینه دیگه برای ترکینگ وب‌سایت‌های تک‌صفحه‌ای رو توضیح دادم: استفاده از تگ History Change در پلتفرم GTM یا همکاری با دولوپر.
اگه مطمئن نیستی کدوم روش رو بکار بگیری، این یه قاعده کلی هست:  
- اگه تیم دولوپر داری، همکاری با دولوپر گزینه محکم‌تریه (از نظر کیفیت ترکینگ)  
- ولی اگه این تیم الان در دسترس نیست، فلوچارتی که تو ابتدای این پست گذاشتم رو چک کن. با این حال، هنوز شانس این هست که آخرش به کمک دولوپر نیاز پیدا کنی