مستوى المقال: متوسط — محتاج خبرة JavaScript أساسية، فهم للـ ESM imports، وحساب Cloudflare مجاني.
OG Image دايناميكي: من Figma يدوي لصور تتولّد لحظياً على الـ edge
المشكلة باختصار
كل مقال جديد على المدونة محتاج صورة Open Graph مقاس 1200×630 عشان لمّا حد يشاركه على X أو LinkedIn يظهر بكارت مظبوط بالعنوان واسم الكاتب. الطريقة الشائعة في 90% من الفرق: تفتح Figma، تنسخ template، تغيّر العنوان، تصدّر PNG، ترفعه على CDN، تربطه في الـ meta tag. متوسط الوقت الفعلي: 4.2 دقيقة لكل صورة. لو بتنشر 3 مقالات يومياً، ده ساعة كاملة من المصمم محروقة في عمل ميكانيكي ممكن يتأتمت بالكامل.
ليه Satori تحديداً ومش Puppeteer
في 3 خيارات شائعة لتوليد الصور دايناميكياً، وكل واحد ليه ثمن:
- Puppeteer أو Playwright — بتفتح Chromium headless وتاخد screenshot. شغّالة بس بتاخد 2 إلى 4 ثواني للصورة، بتحجز 300MB ذاكرة على الأقل، ومستحيل تشتغل على edge runtime زي Cloudflare Workers لأنها محتاجة Linux kernel كامل.
- node-canvas — مكتبة C++ سريعة، بس مش متاحة على Workers، ومحتاجة تركيب fonts على مستوى الـ system، يعني محتاج container.
- Satori من Vercel — بتحوّل JSX إلى SVG في عملية رياضية بحتة، بدون أي browser. زمن التنفيذ بين 30 و 60 مللي ثانية، تشتغل على V8 isolate نقي، وعندها rendering متطابق مع Flexbox spec.
الـ trade-off هنا: Satori بتدعم subset من CSS بس (Flexbox، بدون Grid، بدون transforms معقدة، بدون filter: blur). لكن للـ OG images، الـ Flexbox كفاية لـ 95% من الحالات الواقعية.
مثال للمبتدئ: فكرة الـ Template Engine اللحظي
تخيّل صاحب مطبعة عنده 200 شهادة تخرّج لازم يطبعها قبل حفل الجامعة بكرا. عنده طريقتين:
- يصمم كل شهادة من الصفر في Photoshop بالاسم والتاريخ والقسم — 200 ساعة شغل.
- يصمم template واحدة بمكان فاضي للاسم، ويربط Excel فيه الـ 200 اسم بـ mail merge، ويطبع كل الشهادات في ساعة واحدة بزيادة دقيقة لكل شهادة.
Satori بتشتغل بنفس المبدأ بالظبط، بس بدل ورق هي بترسم SVG، وبدل اسم الطالب هي بتاخد عنوان المقال واسم الكاتب من URL parameters. الـ template هو JSX، والـ engine اللي بيحسب الإحداثيات هو Yoga (نفس اللي React Native بيستخدمه) — بيحسب موقع كل عنصر بالظبط زي ما المتصفح بيعمل، بدون متصفح.
الشرح العلمي: ازاي Satori بتحوّل JSX لـ PNG في 47ms
العملية بتمشي على 3 مراحل متسلسلة داخل V8 isolate واحد:
- Layout calculation — Yoga (مكتوبة في C++ ومحوّلة لـ WebAssembly) بتاخد الـ JSX tree وتحسب موقع كل عنصر بتطبيق Flexbox spec الكامل (justify-content، align-items، gap، flex-basis). ده الجزء اللي بياخد 8 مللي ثانية.