في مقال قياس التسويق كتبنا روابط بمعاملات UTM مثل https://example.com/features/backup?utm_source=newsletter&utm_medium=email&utm_campaign=launch-2026-10، وهذا الرابط صحيح ولكنه طويل، ولا يصلح لمنشور في X أو لرسالة نصية أو لرمز QR على مطبوعة في معرض. والحل المعروف هو الرابط المختصر Short Link: عنوان قصير مثل s.example.com/launch يحول الزائر إلى الرابط الطويل، ويعد النقرات في الطريق. والخدمة الأشهر Bitly، ولكن الرابط المختصر يعيش في منشوراتك ومطبوعاتك سنوات، فإذا أغلقت الخدمة أو غيرت أسعارها أو حجبت حسابك تعطلت كل روابطك القديمة، لذلك من المنطقي أن يكون الرابط على نطاقك أنت.
دليلقياس التسويق: روابط UTM والإسناد Attributionكيف تعرف القناة التي جاءت بكل عميل: روابط UTM بقواعد تسمية ثابتة، وتحويل تعرفه أنت، ونموذج إسناد تفهم ما يحسبه.
دليلتحليلات الموقع دون Google Analytics: مقارنة عمليةشغلنا Umami وPlausible وMatomo على نفس الموقع وقارناها بـ Google Analytics في حجم السكربت والـ Cookies والعربية وملكية البيانات.وفي هذا المقال سوف نتناول:
- ماذا يحدث عند الضغط على رابط مختصر، ولماذا لا يتطابق عدد النقرات مع عدد الزوار.
- Bitly وDub بأسعارهما، وShlink وYOURLS كبديلين تستضيفهما بنفسك.
- تجربة عملية على Shlink في Docker: رابط بمعاملات UTM، ورابط باسم عربي، وزيارات من متصفحات وتطبيقات، وكيف ميز Shlink الـ Bots.
- من يختار ماذا.
ماذا يحدث عند الضغط على رابط مختصر؟
الرابط المختصر طلب HTTP عادي تجيب عنه الخدمة بتحويل Redirect إلى الرابط الطويل، وقبل أن تجيب تسجل الزيارة. والصورة التالية تبين الخطوتين، والأرقام فيها من تجربتنا في آخر المقال:

ولاحظ أن الرابط المختصر لا يغني عن UTM، فهو يعطيك عدد من ضغطوا، أما أداة التحليلات في موقعك فلا تعرف أن الزائر جاء من رابط مختصر إلا من معاملات UTM في الرابط الطويل. لذلك ضع UTM في الرابط الطويل دائماً، والرابط المختصر يخفيها عن القارئ فقط. وعندما تقارن الرقمين سوف تجد أن نقرات الرابط المختصر أكبر من زيارات الحملة في أداة التحليلات، والسبب أن تطبيقات مثل WhatsApp وSlack وLinkedIn تطلب الرابط لتعرض معاينته Link Preview قبل أن يضغط أحد، وأن بعض من يضغط يغلق الصفحة قبل أن يحمل كود التتبع.
وهناك قرار تقني واحد مهم: نوع التحويل. فالتحويل الدائم 301 تحفظه المتصفحات، فإذا غيرت وجهة الرابط لاحقاً قد لا يرى الزائر الوجهة الجديدة ولا تسجل الخدمة زيارته، أما المؤقت 302 فيمر بالخدمة في كل مرة. وShlink يستخدم 302 افتراضياً ويسمح بتغييره بالمتغير REDIRECT_STATUS_CODE كما في توثيق متغيراته، ولروابط الحملات أبقه 302.
الخدمات التجارية: Bitly وDub
Bitly أشهر الخدمات، ويجمع الروابط المختصرة ورموز QR وصفحات هبوط بسيطة. وهذه أسعاره كما ظهرت في 25 أكتوبر 2026:
| الخطة | السعر | ما تحصل عليه |
|---|---|---|
| Free | 0 | 5 روابط و2 رمز QR شهرياً، مع إعلانات |
| Core | 10 دولارات شهرياً بالدفع السنوي (120 دولاراً) | 100 رابط شهرياً، وبيانات النقرات لثلاثين يوماً، وأداة لبناء UTM |
| Growth | 29 دولاراً شهرياً بالدفع السنوي (348 دولاراً) | 500 رابط شهرياً، ونطاق خاص Custom Domain، وبيانات لأربعة أشهر |
ولاحظ حدود الخطط: عدد روابط شهري، وبيانات النقرات تحفظ لفترة محددة، والنطاق الخاص في الخطط الأعلى فقط، أي أن روابط الخطة المجانية على bit.ly لا على نطاقك.
Dub خدمة أحدث تقدم نفسها كمنصة لإسناد الروابط Link Attribution، وفيها بناء UTM بقوالب وتتبع التحويلات وبرامج الشركاء، وصفحة أسعارها تعرض خطط Business وAdvanced وEnterprise بتجربة 14 يوماً. وكودها مفتوح على GitHub، ولكن ترخيصه بحسب ملف الترخيص مزدوج: AGPL-3.0 لأغلب الكود، وترخيص تجاري منفصل لمجلدات ee. وأما الاستضافة الذاتية فدليلها في توثيق Dub يمر بخدمات سحابية عدة: Tinybird لـ ClickHouse وUpstash لـ Redis وPlanetScale لـ MySQL وCloudflare R2 والنشر على Vercel، أي أنها ليست استضافة على سيرفرك بالمعنى الذي نقصده هنا.
البدائل التي تستضيفها بنفسك: Shlink وYOURLS
Shlink خدمة روابط مختصرة مكتوبة بـ PHP وتعمل بخادم RoadRunner، بترخيص MIT، وصدر الإصدار 5.1.8 في 21 أكتوبر 2026. وهي مبنية حول REST API، أي أن كل شيء من إنشاء الرابط إلى قراءة الزيارات يتم من الـ API، والواجهة الرسومية تطبيق منفصل اسمه Shlink Web Client يعمل في المتصفح ويتصل بالخادم بمفتاح API. وتدعم نطاقات متعددة، والوسوم Tags، وقواعد تحويل حسب الجهاز واللغة، وتمييز الـ Bots، وتحديد الموقع الجغرافي إذا أعطيتها مفتاح GeoLite2.
YOURLS أقدم المشاريع، بترخيص MIT، وآخر إصداراته 1.10.6 في 30 أغسطس 2026. ويعمل بـ PHP وMySQL مع واجهة إدارة مدمجة، وقوته في الإضافات Plugins الكثيرة التي كتبها مجتمعه، وفي بساطته لمن يستضيف موقع PHP أصلاً. ولم نشغله في هذه التجربة، فما نذكره عنه من توثيقه ومستودعه.
- نقاط القوة في Shlink: API كامل يسهل ربطه بنظامك أو بأداة النشرات، وتمييز الـ Bots، ونطاقات متعددة، وتحديثات شهرية، وDocker Image رسمية.
- نقاط الضعف في Shlink: الواجهة تطبيق منفصل، ولم يعد الخادم ينشئ رموز QR منذ الإصدار 5.0 فانتقلت هذه الميزة إلى الواجهة كما في سجل التغييرات، والموقع الجغرافي يحتاج مفتاح GeoLite2 من MaxMind.
- نقاط القوة في YOURLS: الأبسط تثبيتاً لمن لديه استضافة PHP، وواجهة إدارة مدمجة، ومكتبة إضافات كبيرة.
- نقاط الضعف في YOURLS: ميزات مثل تمييز الـ Bots ونطاقات متعددة تأتي من الإضافات لا من النواة، وجودة الإضافات تختلف من واحدة لأخرى.
تجربة عملية: Shlink في Docker
شغلنا Shlink مع PostgreSQL والواجهة في ملف Compose واحد. وShlink يقبل SQLite افتراضياً، ولكن PostgreSQL أنسب للإنتاج لأنه يتحمل الكتابة المتزامنة للزيارات ويسهل نسخه احتياطياً:
name: mkd-sl
services:
shlink:
image: shlinkio/shlink:5.1.8
ports: ["127.0.0.1:18780:8080"]
environment:
DEFAULT_DOMAIN: s.example.test:18780
IS_HTTPS_ENABLED: "false"
INITIAL_API_KEY: ${SHLINK_API_KEY}
DB_DRIVER: postgres
DB_HOST: db
DB_NAME: shlink
DB_USER: shlink
DB_PASSWORD: ${SHLINK_DB_PASSWORD}
TIMEZONE: Asia/Riyadh
depends_on:
db: { condition: service_healthy }
db:
image: postgres:18.6
environment:
POSTGRES_DB: shlink
POSTGRES_USER: shlink
POSTGRES_PASSWORD: ${SHLINK_DB_PASSWORD}
volumes: ["db:/var/lib/postgresql"]
healthcheck:
test: ["CMD-SHELL", "pg_isready -U shlink -d shlink"]
interval: 5s
start_period: 2m
retries: 30
web-client:
image: shlinkio/shlink-web-client:4.8.1
ports: ["127.0.0.1:18781:8080"]
volumes:
db:في الإعداد أعلاه لاحظ التالي:
DEFAULT_DOMAINهو النطاق الذي تظهر به الروابط، وفي الإنتاج يكون نطاقاً قصيراً لك مثلs.example.comخلف Reverse Proxy بشهادة TLS، ومعهIS_HTTPS_ENABLED: "true".INITIAL_API_KEYينشئ أول مفتاح API عند أول تشغيل، وولدناه بـopenssl rand -hex 24في ملف.envلا يرفع إلى المستودع.- المنفذان على
127.0.0.1فقط، ولا تنشر الواجهة على الإنترنت إلا خلف دخول، لأن من يملك المفتاح يملك كل الروابط.
إنشاء الروابط
بعد التشغيل كتبنا سكربتاً بـ Node.js يستدعي الـ API، فأنشأ رابطاً باسم launch يحول إلى صفحة الميزة بمعاملات UTM للنشرة، ورابطاً ثانياً باسم عربي إطلاق بمعاملات UTM لواتساب، ثم حاول إنشاء launch مرة ثانية. والطلب الأول كان كما يلي:
curl -s -X POST http://127.0.0.1:18780/rest/v3/short-urls \
-H "X-Api-Key: $SHLINK_API_KEY" -H "Content-Type: application/json" \
-d '{"longUrl":"https://example.com/features/backup?utm_source=newsletter&utm_medium=email&utm_campaign=launch-2026-10","customSlug":"launch","tags":["launch-2026-10"],"title":"Backup launch (newsletter)"}'والمخرج للطلبات الثلاثة سوف يكون كما يلي:
200 http://s.example.test:18780/launch
200 http://s.example.test:18780/إطلاق
400 Provided slug "launch" is already in use.ولاحظ أن الاسم العربي قبل كما هو، وظهر في قائمة الواجهة بشكل صحيح. ولكن قبل أن تستخدم أسماء عربية في روابطك تذكر أن الرابط ينسخ ويلصق في أماكن كثيرة، وبعضها يحوله إلى ترميز طويل مثل %D8%A5%D8%B7%D9%84%D8%A7%D9%82، فيفقد الرابط القصير قصره، لذلك الأسماء الإنجليزية القصيرة أسلم للمطبوعات والرسائل النصية.

الزيارات: من الإنسان ومن الـ Bot؟
بعد ذلك طلبنا الرابطين ست مرات بمتصفحات مختلفة: iPhone قادم من LinkedIn، وChrome على Windows، وAndroid أضاف إلى الرابط utm_content=qr، ثم Slackbot وWhatsApp كما يطلبانه عند عرض معاينة الرابط، ثم iPhone على الرابط العربي. والمخرج سوف يكون كما يلي:
302 launch -> https://example.com/features/backup?utm_source=newsletter&utm_medium=email&utm_campaign=launch-2026-10 | Mozilla/5.0 (iPhone; CPU iPhon
302 launch -> https://example.com/features/backup?utm_source=newsletter&utm_medium=email&utm_campaign=launch-2026-10 | Mozilla/5.0 (Windows NT 10.0;
302 launch?utm_content=qr -> https://example.com/features/backup?utm_source=newsletter&utm_medium=email&utm_campaign=launch-2026-10&utm_content=qr | Mozilla/5.0 (Linux; Android 15
302 launch -> https://example.com/features/backup?utm_source=newsletter&utm_medium=email&utm_campaign=launch-2026-10 | Slackbot-LinkExpanding 1.0 (+h
302 launch -> https://example.com/features/backup?utm_source=newsletter&utm_medium=email&utm_campaign=launch-2026-10 | WhatsApp/2.24.6.77 A
302 إطلاق -> https://example.com/features/backup?utm_source=whatsapp&utm_medium=social&utm_campaign=launch-2026-10 | Mozilla/5.0 (iPhone; CPU iPhonثم قرأنا زيارات launch من الـ API:
15:43:45 human https://www.linkedin.com/ (no geolocation) | Mozilla/5.0 (iPhone; CPU iPhone OS 18_6
15:43:46 human - (no geolocation) | Mozilla/5.0 (Windows NT 10.0; Win64; x64
15:43:47 human - (no geolocation) | Mozilla/5.0 (Linux; Android 15) Chrome/1
15:43:47 bot - (no geolocation) | Slackbot-LinkExpanding 1.0 (+https://api
15:43:48 bot - (no geolocation) | WhatsApp/2.24.6.77 A
visitsSummary {"total":5,"nonBots":3,"bots":2}في المخرج أعلاه لاحظ التالي:
- كل التحويلات
302كما في الإعداد الافتراضي. - المعامل الذي أضفناه إلى الرابط المختصر
?utm_content=qrانتقل إلى الرابط الطويل وأضيف إلى معاملاته، وهذا يعني أنك تستطيع أن تطبع نفس الرابط على أكثر من مطبوعة وتفرق بينها بمعامل واحد دون أن تنشئ رابطاً لكل واحدة. - Shlink سجل Slackbot وWhatsApp كـ Bot، فأعطانا 5 زيارات منها 3 لأشخاص. وهذا هو الفرق الذي تحدثنا عنه بين عدد النقرات وعدد الزوار، فإذا عرضت على فريقك «5 نقرات» فقد ضاعفت الحملة دون قصد.
- الـ Referrer وصل في الزيارة الأولى فقط لأننا أرسلناه، وفي الواقع ستجده فارغاً في أغلب الزيارات القادمة من التطبيقات كما شرحنا في مقال قياس التسويق.
- لا يوجد موقع جغرافي، لأننا لم نعط Shlink مفتاح
GEOLITE_LICENSE_KEY، وبحسب التوثيق فغيابه يعطل تحديد الموقع تماماً.
وهذه صفحة زيارات نفس الرابط في الواجهة:

وأما الموارد فكان Shlink بعد التجربة يستهلك 507 MiB من الذاكرة، وهذا أكبر مما توقعنا لخدمة روابط، والسبب أن خادم RoadRunner يشغل عدة Workers من PHP مسبقاً. وكانت قاعدة البيانات 42 MiB والواجهة 8 MiB.
قبل أن تعتمد عليه في الإنتاج
- النسخ الاحتياطي Backup: كل الروابط والزيارات في قاعدة PostgreSQL، فانسخها بـ
pg_dumpمع بقية قواعدك، وتذكر أن خسارة هذه القاعدة تعني أن كل رابط مطبوع يتعطل. - النطاق: اختر نطاقاً قصيراً لا تغيره أبداً، والسبب أن الروابط المطبوعة لا يمكن تحديثها.
- التحديث Upgrade: ثبت رقم الإصدار في Compose، واقرأ سجل التغييرات قبل الانتقال إلى إصدار رئيسي، فالإصدار 5.0 مثلاً أزال رموز QR من الخادم.
- الواجهة: لا تنشرها للعامة، أو ضعها خلف دخول، لأن المفتاح يخزن في متصفح من يستخدمها.
من يختار ماذا؟
- فريق ينشر عدداً قليلاً من الروابط ولا يريد أي إدارة: Bitly، وانتبه إلى أن النطاق الخاص في الخطط الأعلى فقط.
- فريق نمو يريد ربط الروابط بالتحويلات وبرامج الشركاء: Dub كخدمة سحابية.
- شركة تقنية تريد الروابط على نطاقها وتربطها بأنظمتها عبر API: Shlink، وهو ما جربناه هنا.
- موقع على استضافة PHP يريد أبسط حل بواجهة مدمجة: YOURLS مع ما يحتاجه من إضافات.
الخلاصة
وصلنا لنهاية الموضوع، وأهم ما فيه:
- الرابط المختصر يعد النقرات، وUTM في الرابط الطويل هو ما يخبر أداة التحليلات بالمصدر، فاستخدمهما معاً.
- عدد النقرات أكبر من عدد الزوار، ففي تجربتنا كان 2 من 5 زيارات معاينات من Slackbot وWhatsApp ميزها Shlink كـ Bots.
- أبق التحويل
302لروابط الحملات حتى تمر كل نقرة بالخدمة وتستطيع تغيير الوجهة. - Shlink نقل المعاملات المضافة إلى الرابط المختصر إلى الرابط الطويل، وقبل اسماً عربياً، ورفض تكرار الاسم.
- الرابط المطبوع يعيش سنوات، فضعه على نطاقك وانسخ قاعدة الروابط احتياطياً.
وأقرب المقالات إلى هذا الموضوع:
دليلقياس التسويق: روابط UTM والإسناد Attributionكيف تعرف القناة التي جاءت بكل عميل: روابط UTM بقواعد تسمية ثابتة، وتحويل تعرفه أنت، ونموذج إسناد تفهم ما يحسبه.
دليلتحليلات الموقع دون Google Analytics: مقارنة عمليةشغلنا Umami وPlausible وMatomo على نفس الموقع وقارناها بـ Google Analytics في حجم السكربت والـ Cookies والعربية وملكية البيانات.
دليلأنظمة التسويق الرقمي Digital Marketing في السعوديةما تشترطه الأنظمة السعودية في موافقة العميل والرسائل التسويقية والإعلان الإلكتروني وإعلانات المؤثرين، وكيف تطبقه في الكود.سجل التحديثات
- أكتوبر 2026: كتابة المقال واختبار Shlink 5.1.8 مع Shlink Web Client 4.8.1 وPostgreSQL 18.6 في Docker Engine 29.8.0، والأسعار كما ظهرت في 25 أكتوبر 2026.