راهنمای حفظ UTM برای پذیرندگان
چرا پارامترهای ترکینگ در مسیر خرید گم میشوند و چطور آن را روی هر زیرساخت فنی حل کنیم؟
چرا UTM در مسیر خرید گم میشود؟
اگر هنگام تست redirect یا لود صفحه متوجه شدهاید که پارامترهای UTM یا پارامترهای اختصاصی tracking شما پس از ورود به سایت از بین میروند، این راهنما دقیقاً برای شما نوشته شده است.
بر اساس بررسی انجامشده روی طیف گستردهای از پذیرندگان، ریشه گم شدن UTM در بیشتر موارد به یکی از این پنج نقطه برمیگردد: redirect، canonicalization، افزونههای کش و امنیت، routing سمت اپلیکیشن و تنظیمات وبسرور.
قاعده مشترک برای همه زیرساختهای فنی
فارغ از نوع تکنولوژی سایت شما، سه قاعده زیر باید در همه حال رعایت شود:
- پارامترهای ورودی مثل
utm_source،utm_medium،utm_campaign،spt_idوspt_sidباید در اولین URL ورودی، URL نهایی بعد از redirect و لینکهای داخلی مسیر خرید حفظ شوند. - هر redirect از http به https، از non-www به www، از صفحه اصلی به /main، از محصول به cart یا از cart به checkout باید query string را به مقصد منتقل کند.
- کش، CDN، WAF، افزونههای امنیتی و canonical redirect نباید query stringهای مجاز tracking را حذف کنند.
location.pathname استفاده میکنید، UTM قطعاً از بین میرود. همیشه location.search را هم همراه ببرید.
WordPress و WooCommerce
بیشترین موارد گم شدن UTM در سایتهایی دیده میشود که روی WordPress، WooCommerce، Elementor و jQuery ساخته شدهاند. ریشه مشکل معمولاً افزونههای redirect، تنظیمات permalink، canonical URL، کش، security plugin یا redirectهای WooCommerce است.
راهحلهای WordPress
- در تنظیمات WordPress Address و Site Address مطمئن شوید دامنه، پروتکل و www دقیقاً با دامنه اصلی یکسان است. اختلاف این دو مقدار باعث redirectهای اضافی و گاهی حذف query string میشود.
- افزونههایی مثل Redirection، Yoast، Rank Math، WP Rocket، LiteSpeed Cache، Wordfence و دیگر افزونههای security و optimization را بررسی کنید. هر rule که query string را drop میکند باید اصلاح یا برای UTMها مستثنی شود.
- در cache plugin، پارامترهای زیر را از حذف یا normalization خارج کنید:
spt_sidspt_idutm_campaignutm_mediumutm_source
- اگر قالب یا Elementor لینک داخلی میسازد، مطمئن شوید کد JS یا PHP لینک را فقط با
location.pathnameنمیسازد. بایدlocation.searchیا query فعلی هم حفظ شود.
مسیرهای WooCommerce که باید تست شوند
- product — صفحه محصول
- add to cart — افزودن به سبد
- cart — سبد خرید
- checkout — تسویه حساب
- login — ورود / ثبتنام
PHP سفارشی
در سایتهای PHP سفارشی، حذف UTM معمولاً از این موارد ناشی میشود:
headerredirect- rewriteهای
.htaccess - canonicalization دستی
- ساختن URL با
parse_urlبدون query
راهحلها
- هر redirect با
header Locationباید query string ورودی را حفظ کند. - اگر مقصد ثابت است، query فعلی را با همان مقصد ترکیب کنید.
- در Apache
.htaccessازQSAاستفاده کنید تا query string موجود به rewrite destination اضافه شود. - اگر کد از
parse_urlاستفاده میکند، فقط path را نگه ندارد. بخش query باید منتقل شود یا قبل از redirect در cookie/session ذخیره شود. - اگر sanitization امنیتی دارید، به جای حذف همه queryها، allowlist برای UTM و click id تعریف کنید.
نمونه کد PHP برای redirect با حفظ query string:
// PHP redirect preserving query string
$target = '/landing';
$query = $_SERVER['QUERY_STRING'] ?? '';
header('Location: ' . $target . ($query ? '?' . $query : ''), true, 302);
exit;.NET، ASP.NET و DNN
در این زیرساخت مشکل معمولاً از این موارد میآید:
- URL Rewrite
- canonical redirect
Response.Redirect- middleware
- تنظیمات portal/canonical در DNN
راهحلها
- در IIS URL Rewrite گزینه
appendQueryStringباید روشن باشد، مگر برای ruleهای خاصی که آگاهانه query را حذف میکنند. - در
Response.Redirectوreturn Redirect، مقصد را بدون query فعلی نسازید. - اگر مقصد ثابت است،
Request.QueryStringرا منتقل کنید. - در middlewareهای canonicalization برای https، trailing slash یا www، شی URL باید با query فعلی clone شود.
- در DNN تنظیمات portal alias، canonical URL و extension/providerهای redirect را بررسی کنید.
نمونه تنظیم IIS URL Rewrite برای حفظ query string:
<!-- IIS URL Rewrite: keep query string -->
<action type="Redirect"
url="https://www.example.com/{R:1}"
appendQueryString="true" />React، Next.js، Vue و SPA
در SPAها مشکل معمولاً از این موارد ایجاد میشود:
- redirect سمت کلاینت
- middleware
router.pushrouter.replace- redirect به route پیشفرض مثل
/main
راهحلها
- در هر
router.pushیاrouter.replace، query فعلی را حفظ کنید. اگر فقط pathname ارسال شود، UTM حذف میشود. - در Next.js middleware یا server redirects،
nextUrlرا clone کنید وsearchرا حذف نکنید. - اگر اپ در شروع کار، کاربر را از
/به/mainیا/homeمیفرستد، search params باید به مقصد منتقل شوند. - برای SPAها پیشنهاد میشود UTM در اولین route load در cookie یا local storage ذخیره شود و بعد از navigation داخلی از همان مقدار استفاده شود.
نمونه Next.js middleware:
// Next.js middleware style
const url = request.nextUrl.clone();
url.pathname = '/main';
// url.search is preserved unless explicitly overwritten
return NextResponse.redirect(url);نمونه navigation سمت کلاینت:
// Client-side navigation
router.replace(`${targetPath}${window.location.search}`);پلتفرمهای میزبانیشده
در پلتفرمهایی مثل PrestaShop، OpenCart، Shopfa و Digify دسترسی به کد ممکن است محدود باشد. راهحل باید از پنل پلتفرم، افزونهها، تنظیمات SEO/canonical، تنظیمات دامنه و پشتیبانی فنی پلتفرم دنبال شود.
راهحلها
- تنظیمات SEO friendly URL، canonical URL، redirect دامنه و force HTTPS بررسی شود.
- اگر پلتفرم امکان تعریف پارامترهای مجاز دارد، UTM و click id را allowlist کنید.
- از پشتیبانی پلتفرم بخواهید تضمین کند redirectهای زیر query string را نگه میدارند: http to https، www normalization و route normalization.
تنظیمات وبسرورها
این بخش برای تیم فنی پذیرندگان کاربردی است. در همه وبسرورها یک اصل مهم وجود دارد: redirect و rewrite باید query string را حفظ کند.
Nginx
- برای redirect دامنه یا HTTPS از
$request_uriاستفاده کنید، نه فقط$uri. متغیر$request_uriشامل path و query string است. - اگر rewrite استفاده میشود، مقصد نباید query را با علامت
?خالی کند، مگر اینکه عمدی باشد. - اگر پشت CDN هستید، تنظیمات cache key و query string forwarding را بررسی کنید.
# Good: preserves query string
return 301 https://www.example.com$request_uri;
# Risky: drops query string
return 301 https://www.example.com$uri;Apache
- در
RewriteRuleازQSAاستفاده کنید تا query string حفظ شود. - اگر ruleهای HTTPS یا www دارید، آنها را با URL دارای UTM تست کنید.
- اگر چند rule پشت سر هم اجرا میشود، مطمئن شوید rule اول query را حذف نکرده باشد.
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L,QSA]IIS
- در URL Rewrite مقدار
appendQueryStringراtrueنگه دارید. - در ruleهای canonical domain و force HTTPS، مقصد نباید QueryString را حذف کند.
- بعد از تغییر ruleها، تست را با UTM و
click_idانجام دهید، نه فقط با URL ساده.
پذیرندگان غیرفعال یا زیرساخت نامشخص
برای پذیرندگانی که سایتشان در وضعیت غیرفعال، خالی یا با زیرساخت نامشخص است، پیش از ارسال دستورالعمل فنی باید وضعیت سایت و زیرساخت واقعی دوباره تأیید شود.
اقدامات پیشنهادی
- ابتدا URL عمومی و landing page قابل دسترس را تأیید کنید.
- اگر سایت maintenance دارد، تست را روی URL واقعی محصول یا landing فعال تکرار کنید.
- اگر زیرساخت قابل تشخیص نیست، از پذیرنده وبسرور، فریمورک، CDN و CMS را بپرسید.
چکلیست تست برای پذیرندگان
برای هر پذیرنده، تست باید حداقل روی این مسیرها انجام شود: صفحه اصلی، صفحه محصول یا landing اصلی، مسیر cart یا checkout.
| مرحله | اقدام | انتظار |
|---|---|---|
| ۱ | URL ورودی با UTM باز شود | utm_source، utm_medium، utm_campaign و click_id در address bar باقی بمانند |
| ۲ | بعد از redirect نهایی بررسی شود | URL نهایی هنوز query string را داشته باشد یا UTM در cookie/session ذخیره شده باشد |
| ۳ | کلیک روی لینک داخلی انجام شود | اگر UTM از URL حذف میشود، attribution در cookie/event باقی بماند |
| ۴ | مسیر cart و checkout تست شود | WooCommerce یا اپلیکیشن query را در redirectهای خرید حذف نکند |
| ۵ | تست در حالت cache روشن انجام شود | CDN یا cache plugin پارامترهای tracking را حذف نکند |
جمعبندی
حفظ UTM فقط یک تنظیم فنی ساده نیست؛ برای attribution درست کمپینها حیاتی است. اگر حتی یکی از این نقاط باعث حذف query string شود، دادههای تحلیلی شما از همان روز به بعد نادرست خواهد بود.
- در همه redirectها و rewriteها، query string را حفظ کنید.
- کش، CDN و WAF را برای UTM و click id سفیدلیست کنید.
- بعد از هر تغییر در تنظیمات سایت، تست UTM را دوباره اجرا کنید.
سوالات متداول درباره حفظ UTM
در بیشتر موارد، یکی از redirectهای سایت شما (از http به https، از non-www به www یا از یک مسیر داخلی به مسیر دیگر) query string را به مقصد منتقل نمیکند. این موضوع در Nginx با استفاده از $uri به جای $request_uri، در Apache با نبود QSA و در IIS با appendQueryString=false رخ میدهد.
بله، بعضی افزونههای کش و سرویسهای CDN به صورت پیشفرض پارامترهای query را از URL حذف یا normalize میکنند تا cache hit rate بالاتر برود. باید utm_source، utm_medium، utm_campaign، spt_id و spt_sid را در لیست پارامترهای مجاز نگه دارید.
ابتدا تنظیمات WordPress Address و Site Address را چک کنید که یکسان باشند. سپس افزونههای Redirection، Yoast، Rank Math، WP Rocket، LiteSpeed Cache و افزونههای security را برای ruleهایی که query string را حذف میکنند بررسی کنید. در نهایت مسیرهای product، add to cart، cart، checkout و login را با URL دارای UTM تست کنید.
در هر router.push یا router.replace باید window.location.search را به مقصد پیوست کنید. در Next.js middleware نیز request.nextUrl.clone() بگیرید و url.search را دستکاری نکنید. بهترین کار این است که UTM را در اولین لود در cookie یا localStorage ذخیره کنید.
یک URL با UTM کامل بسازید (مثلاً ?utm_source=test&utm_medium=test&utm_campaign=test) و آن را در مرورگر باز کنید. اگر در address bar نهایی این پارامترها وجود نداشتند و در cookie یا event tracking هم ذخیره نشده بودند، یعنی سایت شما UTM را حذف میکند.
© ۱۴۰۵ · تمامی حقوق محفوظ است.


