پرش به محتوای اصلی
وب، سئو و فرانت‌اند
۶ دقیقه مطالعه

بازدیدهای اینستاگرام که بدون ارجاع‌دهنده می‌رسیدند و «مستقیم» ثبت می‌شدند

چرا بخش بزرگی از ترافیک لینک بیو اینستاگرام «مستقیم» ثبت می‌شد، و چطور با user-agent مرورگر داخلی منبع واقعی را بازیابی کردیم.

برنامه‌نویس فول‌استک

در گزارش منابع ورودی یکی از پروژه‌هایمان، سهم «مستقیم» به‌طرز مشکوکی بزرگ بود. می‌دانستیم بخش زیادی از این کاربرها از لینک بیو اینستاگرام می‌آیند، اما گزارش چیز دیگری نشان می‌داد. این یادداشت درباره همین شکاف است: چرا اینستاگرام در گزارش دیده نمی‌شد، چرا راه‌حل اول (utm روی همه لینک‌ها) کافی نبود، و چطور با یک قاعده ساده روی user-agent منبع را برگرداندیم.

ماجرا و علامت‌ها

علامت اصلی یک ناهمخوانی بود، نه یک خطا. هیچ چیز خراب نشده بود، صفحه‌ها باز می‌شدند و آمار ثبت می‌شد. مشکل این بود که آمار حرف درستی نمی‌زد. ما لینک سایت را در بیو اینستاگرام گذاشته بودیم و می‌دانستیم کاربرها از همان‌جا وارد می‌شوند، ولی در گزارش «منابع ورودی» سهم اینستاگرام کوچک بود و بخش بزرگی از بازدیدها زیر عنوان «مستقیم» جمع شده بود.

این فقط یک مسئله گزارشی نبود. وقتی منبع درست دیده نشود، نمی‌شود فهمید کدام محتوای اینستاگرام واقعاً کاربر می‌آورد. تصمیم‌هایی مثل «روی چه نوع پستی وقت بگذاریم» بر پایه‌ی عددی گرفته می‌شد که منبع بزرگ‌ترین بخش آن معلوم نبود. این موضوع برای پروژه‌هایی که با اینستاگرام سروکار دارند، مثل پیج‌یار؛ ادمین هوشمند اینستاگرام، مستقیماً اهمیت دارد.

نکات کلیدی

  • سهم «مستقیم» با انتظار ما از لینک بیو نمی‌خواند
  • خطا یا قطعی‌ای در کار نبود؛ فقط داده گمراه‌کننده بود

ردگیری علت

اولین فرضیه این بود که کاربرها واقعاً آدرس را مستقیم تایپ می‌کنند یا از بوکمارک می‌آیند. این فرضیه با آنچه از رفتار مخاطب می‌دانستیم جور درنمی‌آمد؛ برای این حجم، لینک بیو تنها مسیر منطقی بود. پس سراغ توضیح فنی رفتیم.

مرورگر داخلی اینستاگرام هدر Referer نمی‌فرستد. وقتی این هدر نباشد، ابزار آنالیتیکس چیزی برای تشخیص منبع ندارد و بازدید را «مستقیم» می‌نامد. تعریف پیش‌فرض گروه‌های کانال در مستندات گوگل آنالیتیکس هم همین منطق را دارد: کانال Direct یعنی منبعی شناسایی نشده، نه لزوماً کسی که آدرس را تایپ کرده.

راه‌حل اولمان utm بود: به هر لینکی که بیرون می‌گذاشتیم پارامترهای utm اضافه کنیم. این کار جواب می‌داد، ولی فقط برای لینک‌هایی که این پارامترها را داشتند. در عمل همیشه رعایت نمی‌شد. گاهی لینکی بدون utm در بیو یا در یک پیام می‌رفت، و همان بازدیدها دوباره «مستقیم» می‌شدند. راهی که به دست یک آدم برای یادآوری وابسته باشد، دیر یا زود می‌شکند.

نکات کلیدی

  • فرضیه اول (تایپ مستقیم آدرس) با رفتار واقعی کاربر نمی‌خواند
  • utm روی تک‌تک لینک‌ها به انضباط دستی وابسته بود و رعایت نمی‌شد

علت اصلی: Referer، سیاست ارجاع و معنای واقعی «مستقیم»

هدر Referer آدرس صفحه‌ای را که درخواست از آن آمده به سرور می‌گوید (املای غلط «Referer» یک اشتباه تاریخی است که در استاندارد مانده). طبق مستندات MDN، محتوای آن به «سیاست ارجاع» (Referrer-Policy) درخواست محدود می‌شود و می‌تواند فقط origin باشد، مسیر کامل باشد، یا اصلاً ارسال نشود. مقدار پیش‌فرض مرورگرهای امروزی strict-origin-when-cross-origin است، اما این سیاست را صفحه یا اپلیکیشنی که لینک را باز می‌کند تعیین می‌کند. برنامه‌ای که وب‌ویو خودش را کنترل می‌کند هر تصمیمی بگیرد، سایت مقصد همان را می‌بیند. در مورد مرورگر داخلی اینستاگرام نتیجه برای ما این بود که هدر نمی‌رسید.

پس «مستقیم» در آنالیتیکس مجموع چند حالت متفاوت است: تایپ آدرس، بوکمارک، لینک داخل اپ‌های پیام‌رسان و شبکه اجتماعی که Referer نمی‌فرستند، و هر جا که سیاست ارجاع هدر را حذف کرده است. معنی عملی‌اش این است که «مستقیم» اغلب یعنی «نمی‌دانیم».

یک نکته‌ی مکمل: چون Referer را نمی‌شود ساخت، باید از سیگنال دیگری استفاده کرد. هدر User-Agent رشته‌ای است که کلاینت خودش را با آن معرفی می‌کند. مرورگرهای داخلی اپ‌ها معمولاً نام یا نشانه‌ی خودشان را در آن می‌گذارند (برای نمونه Instagram، یا FBAN/FBAV برای خانواده‌ی فیس‌بوک، یا Telegram). MDN توضیح می‌دهد که مرورگرهای معمولی نسخه‌ی کاهش‌یافته‌ای از User-Agent می‌فرستند تا اثر انگشت‌گیری سخت‌تر شود؛ این کاهش بیشتر روی جزئیات نسخه و دستگاه اثر دارد و در این کاربرد، فقط تشخیص نام اپ لازم است.

نکات کلیدی

  • مرورگر داخلی اینستاگرام هدر Referer را نمی‌فرستد
  • بدون Referer و utm، آنالیتیکس بازدید را «مستقیم» می‌نامد
  • User-Agent مرورگرهای داخلی معمولاً نام اپ را دارد

راه‌حل: تعیین منبع با ترتیب اولویت

قاعده‌ی نهایی ساده است و ترتیب اولویتش مهم است. اول utm، چون صریح‌ترین سیگنال است و نیت ما را نشان می‌دهد. بعد Referer، اگر وجود داشت. فقط وقتی هیچ‌کدام نبود، سراغ user-agent می‌رویم. اگر نشانه‌ای از مرورگر داخلی پیدا شد، منبع را همان اپ ثبت می‌کنیم و اگر نشد، همان «مستقیم» می‌ماند.

نمونه‌ی زیر یک نسخه‌ی عمومی و ساده است، نه کد دقیق پروژه. توجه کنید که تشخیص با user-agent یک heuristic است: اپ‌ها می‌توانند رشته‌شان را تغییر بدهند و باید گاهی نمونه‌های واقعی را بررسی کنید.

این منطق را در سمت سرور (یا هر جا که رویداد بازدید ساخته می‌شود) اجرا کنید تا به آنالیتیکس‌ای که استفاده می‌کنید بستگی نداشته باشد. در پروژه‌های فروشگاه اینترنتی و وب‌اپلیکیشن هم همین نقطه‌ی ثبت بازدید جای مناسبی برای این قاعده است. اگر ربات‌ها هم در آمار شما دیده می‌شوند، ربات‌هایی که جاوااسکریپت اجرا می‌کنند و آمار را خراب می‌کنند مکمل خوبی برای فیلتر کردن داده‌ی ورودی است.

javascript
const IN_APP = [
  { name: 'instagram', re: /Instagram/i },
  { name: 'facebook', re: /FBAN|FBAV|FB_IAB/i },
  { name: 'telegram', re: /Telegram/i },
];

function resolveSource({ query, referrer, userAgent }) {
  if (query.utm_source) {
    return { source: query.utm_source, via: 'utm' };
  }
  if (referrer) {
    return { source: new URL(referrer).hostname, via: 'referrer' };
  }
  const hit = IN_APP.find((x) => x.re.test(userAgent || ''));
  if (hit) {
    return { source: hit.name, via: 'user-agent' };
  }
  return { source: '(direct)', via: 'none' };
}

نکات کلیدی

  • اولویت: utm، سپس Referer، سپس user-agent، و در نهایت «مستقیم»
  • فیلد via را ذخیره کنید تا بدانید هر منبع از کدام سیگنال آمده

درس‌ها و چک‌لیست

مهم‌ترین درس این بود که عدد «مستقیم» را نباید یک منبع واقعی فرض کرد. آن را سطل «نمی‌دانیم» بدانید و هر بار که بزرگ شد، بپرسید داخلش چه کسانی هستند. نکته‌ی دوم اینکه روشی که به رعایت دستی وابسته است (utm روی هر لینک) را باید با یک لایه‌ی خودکار پشتیبانی کرد، نه جایگزین یک قاعده‌ی تیمی.

چک‌لیست پیشنهادی:

۱. سهم «مستقیم» را با انتظار واقعی خودتان از کانال‌ها مقایسه کنید؛ اگر نمی‌خواند، دنبال منبع پنهان بگیرید.

۲. برای لینک‌هایی که خودتان کنترل می‌کنید (بیو، پیام‌ها، کمپین‌ها) utm بگذارید، و هم source و هم medium را.

۳. وقتی Referer و utm نیست، از user-agent برای تشخیص مرورگرهای داخلی اپ‌ها استفاده کنید و روش تشخیص را در فیلد جدا ثبت کنید.

۴. اگر منبع بازیابی‌شده را با ابزار آنالیتیکس مقایسه می‌کنید، بدانید گروه‌بندی کانال‌ها قواعد خودش را دارد؛ به مستندات کانال‌های پیش‌فرض نگاه کنید.

۵. به‌صورت دوره‌ای نمونه‌ای از user-agentهای ثبت‌شده را بخوانید، چون الگوها ممکن است عوض شوند.

اگر روی پروژه‌ای کار می‌کنید که تحلیل منابع ورودی و سئو در آن مهم است، موضوع به سئوی فنی و سرعت سایت هم نزدیک است، چون هر دو به داده‌ی قابل‌اعتماد از رفتار واقعی کاربر و خزنده‌ها تکیه دارند. نمونه‌ی دیگری از منبعی که در گزارش‌ها جا افتاده بود در اولین منبع ترافیک فروشگاه: نه گوگل، بلکه ChatGPT آمده است.

جمع‌بندی

«مستقیم» در آنالیتیکس اغلب یعنی «منبع را نمی‌دانیم»، نه «کاربر آدرس را تایپ کرده». مرورگر داخلی اینستاگرام Referer نمی‌فرستد و utm دستی هم همیشه رعایت نمی‌شود، پس بازدیدهای اینستاگرام در سطل مستقیم جمع می‌شدند. با ترتیب utm، Referer، user-agent منبع را بازیابی کردیم و روش تشخیص را هم ثبت می‌کنیم تا بدانیم به هر عدد چقدر می‌شود اعتماد کرد.

منابع

  1. Referer header - HTTP | MDNdeveloper.mozilla.org
  2. Referrer-Policy header - HTTP | MDNdeveloper.mozilla.org
  3. User-Agent header - HTTP | MDNdeveloper.mozilla.org
  4. Default channel group - Analytics Helpsupport.google.com
وب، سئو و فرانت‌اند
۶ دقیقه مطالعه

اولین منبع ترافیک فروشگاه: نه گوگل، بلکه ChatGPT

بعد از راه‌اندازی آنالیتیکس اختصاصی دیدیم بیشترین ورودی فروشگاه از ChatGPT است؛ و ربات‌های هوش مصنوعی پشت فایروال CDN بسته بودند.

مطالعه مقاله#سئو
وب، سئو و فرانت‌اند
۷ دقیقه مطالعه

عکسی که عوض شد ولی هیچ‌کس عکس جدید را ندید

تصویر محصول را با همان نام فایل عوض کردیم، اما کش یک‌ساله و immutable عکس قدیمی را نگه داشت. علت، قرارداد immutable و راه‌حل نام‌گذاری با hash.

مطالعه مقاله#Cache-Control