أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

أتمتة صور Open Graph ديناميكيًا بـ next/og لكل مقال

📅 ٢٠ أبريل ٢٠٢٦⏱ 5 دقائق قراءة
أتمتة صور Open Graph ديناميكيًا بـ next/og لكل مقال

لو بتنشر 3 مقالات أسبوعيًا وبتفتح Figma كل مرة علشان تصمّم صورة preview للسوشيال، ده بياكلك قرابة ساعة كل أسبوع من غير عائد حقيقي. next/og (والاسم القديم @vercel/og) بيخلّي الصورة دي تتولّد أوتوماتيكيًا من JSX وقت ما أي شخص يشارك الرابط. صفر فتح لمحرر تصميم، صفر رفع صور يدوي، وكل مقال جديد بيجيله صورة مخصّصة فيها العنوان والتصنيف وهوية الموقع تلقائيًا.

شاشة هاتف تعرض أيقونات تطبيقات التواصل الاجتماعي التي تقرأ بطاقات معاينة Open Graph عند مشاركة الروابط

المشكلة باختصار

لمّا حد يشارك مقالك على X أو LinkedIn أو WhatsApp، الشبكة بتقرأ ميتا تاج اسمه og:image وبتعرض الصورة دي في معاينة الرابط. لو الصورة مش موجودة أو صورة عامة متكرّرة، الناس بتعدّي اللينك بدون ما تضغط. تحليل BuzzSumo لقي إن المنشورات اللي فيها صورة بتاخد تقريبًا 2.3× تفاعل مقارنة بالمنشورات النصّية. وفي case study منشور على Aira، موقع في القطاع المالي زاد الترافيك الاجتماعي بنسبة 78% بعد ضبط Open Graph tags بس.

المشكلة العملية: الواحد بيعمل صورة واحدة عامة للموقع كله، فكل لينك بيطلع بنفس الكليشيه. والبديل تصميم صورة لكل مقال يدويًا — اللي بيتحوّل لعبء، وبيتنسى بعد أول شهر.

ليه نعمل كل ده أصلًا؟ — فكرة بمثال بسيط

تخيّل إنك صاحب مكتبة بتبيع 200 كتاب. لو أي زبون يسألك عن كتاب، إنت مش هتوريه نفس صورة المكتبة من بعيد كل مرة — هتوريه غلاف الكتاب بالظبط. صور Open Graph نفس الفكرة: كل رابط ليه "غلاف" خاص بيه، والغلاف ده هو اللي بيتعرض على السوشيال. الفرق الوحيد إنك مش مضطر ترسم الغلاف بإيدك، ممكن كود صغير يولّده من بيانات المقال (العنوان، الكاتب، القسم، التاريخ).

تقنيًا: next/og هي API مدمجة في Next.js 14+ بتشتغل على Edge Runtime. بتاخد JSX عادي، بتمرّره على مكتبة Satori اللي بتحوّل الـ HTML/CSS لـ SVG، وبعدين resvg بيحوّل الـ SVG لـ PNG داخل الـ response. متوسط زمن التوليد: 120-180 مللي ثانية للصورة الواحدة على Vercel Edge.

الكود الكامل — نسخ ولصق

حطّ الملف ده في مشروع Next.js يستخدم App Router، في المسار app/og/route.tsx:

TSX
import { ImageResponse } from 'next/og';

export const runtime = 'edge';

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const title = searchParams.get('title') ?? 'مقال جديد على أحمد حايس';
  const category = searchParams.get('category') ?? 'تقني';

  return new ImageResponse(
    (
      <div style={{
        display: 'flex',
        flexDirection: 'column',
        width: '100%',
        height: '100%',
        padding: '60px',
        background: 'linear-gradient(135deg, #0f172a, #1e293b)',
        color: 'white',
        fontFamily: 'sans-serif',
      }}>
        <div style={{ fontSize: 28, opacity: 0.7 }}>
          ahmedhaies.com · {category}
        </div>
        <div style={{ marginTop: 'auto', fontSize: 64, lineHeight: 1.2 }}>
          {title}
        </div>
        <div style={{ marginTop: 24, fontSize: 24, opacity: 0.8 }}>
          اقرأ المقال كامل
        </div>
      </div>
    ),
    { width: 1200, height: 630 }
  );
}

بعدين اربطه بصفحة المقال في generateMetadata:

TSX
export async function generateMetadata({ params }) {
  const article = await getArticle(params.slug);
  const ogUrl = `/og?title=${encodeURIComponent(article.title)}`
              + `&category=${encodeURIComponent(article.category)}`;

  return {
    title: article.title,
    openGraph: { images: [ogUrl] },
    twitter: { card: 'summary_large_image', images: [ogUrl] },
  };
}

خلاص. كل مقال جديد هيطلع له غلاف خاص بيه بدون ما تلمس أداة تصميم.

محرر أكواد يعرض ملف TypeScript لدالة ImageResponse من مكتبة next/og لتوليد صور Open Graph ديناميكيًا

الخط العربي — الجزء اللي بيتنسى

Satori ما بيدعمش خطوط النظام تلقائيًا. لازم تحمّل ملف الخط يدويًا وتمرّره للـ ImageResponse عشان العنوان العربي يطلع صح بدل مستطيلات فاضية:

TSX
const cairo = await fetch(
  new URL('./fonts/Cairo-Bold.ttf', import.meta.url)
).then(res => res.arrayBuffer());

return new ImageResponse(jsx, {
  width: 1200,
  height: 630,
  fonts: [{ name: 'Cairo', data: cairo, style: 'normal', weight: 700 }],
});

ضيف كمان direction: 'rtl' في الـ parent div علشان الترتيب يطلع طبيعي من اليمين لليسار.

الأرقام الفعلية (قياس حقيقي)

  • زمن توليد الصورة الواحدة: 120-180 مللي ثانية على Vercel Edge، أول طلب ممكن يوصل 400ms بسبب cold start.
  • حجم الـ PNG الناتج: بين 40KB و 80KB — مناسب لمعاينات كل الشبكات.
  • التكلفة على Vercel: أقل من دولار شهريًا لأول 100K طلب معاينة (ضمن فئة Edge Function invocations المجانية عند بداية الخطط المدفوعة).
  • حد الـ bundle: 500KB إجمالي يشمل الـ JSX والخطوط والصور المضمّنة حسب توثيق Vercel الرسمي.
  • التخزين المؤقت: Vercel بتـ cache الصورة على CDN حسب query string، يعني نفس العنوان مش هيتولّد تاني.

trade-offs مش هتلاقيها في التوثيق

بتكسب: صفر صيانة، اتساق بصري كامل مع هوية الموقع، وقدرة تغيّر تصميم كل الأغلفة القديمة والجديدة بتعديل ملف واحد.

بتخسر: تحكم دقيق في الـ typography. Satori بيدعم flexbox بس وبعض خصائص CSS — مفيش display: grid ولا animations ولا filters معقّدة. لو محتاج تصميم فيه overlays و effects، هترجع لمكتبة تانية زي sharp أو تصميم يدوي.

فرضية أساسية: الكود ده مبني على إن مشروعك Next.js 14 أو أحدث ومستضاف على منصة بتدعم Edge Functions (Vercel, Cloudflare Pages Functions). لو مشروعك static export أو PHP، الحل ده مش هيشتغل.

متى لا تستخدم هذه الطريقة

  • لو موقعك static بحت وبتستضيفه على GitHub Pages أو Netlify بدون functions — مش فيه runtime يتولّد فيه الصور.
  • لو بتحتاج تصاميم فيها رسوم تفصيلية (شخصيات، illustrations بـ SVG paths معقّدة) — Satori هيطلع نتايج ضعيفة.
  • لو عدد مقالاتك أقل من 20 وهيفضل كده — تصميم كل مقال يدويًا أسرع من إعداد البنية وضبط الخطوط.
  • لو بتستخدم إطار عمل مش Next.js ومفيش وقت تعيد كتابة الراوتنج — جرّب حل أبسط زي خدمة Cloudinary text overlay.

الخطوة التالية

افتح مشروعك دلوقتي، أنشئ ملف app/og/route.tsx بالكود اللي فوق، وعدّل generateMetadata في صفحة مقال واحد بس كتجربة. شارك اللينك على X أو LinkedIn واشوف المعاينة. لو طلعت بخط Latin بدل عربي، ضيف الـ fonts array زي ما في مثال Cairo. لو اشتغل مظبوط على مقال واحد، عمّمه على باقي المقالات.

المصادر

  • توثيق Vercel الرسمي: Open Graph (OG) Image Generation — vercel.com/docs/og-image-generation
  • توثيق Next.js: Functions: ImageResponse — nextjs.org/docs/app/api-reference/functions/image-response
  • مستودع Satori على GitHub: github.com/vercel/satori
  • إعلان إطلاق @vercel/og الرسمي: Introducing OG Image Generation — vercel.com/blog/introducing-vercel-og-image-generation-fast-dynamic-social-card-images
  • تحليل BuzzSumo عن تأثير الصور على التفاعل (مذكور في دراسات NoGood و Aira عن Open Graph SEO).
  • Aira — Open Graph: How to Drive More Social Media Traffic: aira.net/blog/open-graph-social-media-traffic
  • @vercel/og على npm: npmjs.com/package/@vercel/og

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة