تطوير الويب

ربط Directus بـ Next.js و Astro: درس frontend 2026

6 دقائق للقراءة

Directus هو نظام إدارة محتوى headless مفتوح المصدر، يحوّل أي قاعدة بيانات SQL إلى REST/GraphQL API + لوحة تحكم احترافية. مع frontends حديثة مثل Next.js 15 و Astro 5، ينتج موقع سريع جداً مع تجربة محرر ممتازة. هذا الدرس يبني تكاملاً كاملاً في 8 خطوات.

المتطلبات

  • Node.js 22 LTS
  • Directus مثبّت (محلياً عبر Docker، أو Cloud)
  • أساسيات Next.js أو Astro
  • الوقت المقدر: 3 ساعات

الخطوة 1 — تثبيت Directus

أسرع طريقة: Docker. خدمة واحدة، PostgreSQL مدمج، يجاهز في 5 دقائق.

# docker-compose.yml
version: "3"
services:
  directus:
    image: directus/directus:11
    ports:
      - 8055:8055
    environment:
      KEY: random-key-32-chars
      SECRET: random-secret-32-chars
      DB_CLIENT: pg
      DB_HOST: postgres
      DB_DATABASE: directus
      DB_USER: directus
      DB_PASSWORD: directus_secret
      ADMIN_EMAIL: admin@example.com
      ADMIN_PASSWORD: admin
  postgres:
    image: postgres:18
    environment:
      POSTGRES_DB: directus
      POSTGRES_USER: directus
      POSTGRES_PASSWORD: directus_secret

# لإطلاق:
docker compose up -d

Directus 11 (مايو 2025) جلب AI-assisted content، تكامل MCP، وتحسينات أداء كبيرة. Directus 12 (متوقع 2026) يضيف Realtime native. للإنتاج، استبدل ADMIN_PASSWORD بكلمة قوية، KEY و SECRET بسلسلة عشوائية حقيقية. الوصول: http://localhost:8055 ثم admin@example.com / admin.

الخطوة 2 — إنشاء Collections

Collections هي جداول بقاعدتك مع لوحة تحكم. أنشئ « Articles » بصورة بصرية: Settings → Data Model → Create Collection.

# Collection: articles
الحقول:
  - id (UUID، رئيسي)
  - title (string، إلزامي)
  - slug (string، فريد، slug-friendly)
  - content (markdown)
  - cover_image (file)
  - author (M2O → directus_users)
  - published_at (datetime)
  - status (dropdown: draft/published/archived)

مع كل حقل، اضبط الواجهة (Interface): النص العادي، Markdown، رفع ملف، صورة، علاقة M2O/M2M، إلخ. الواجهة هي ما يراه المحرر — استثمر فيها الوقت لتجربة محرر ممتازة. مثلاً، حقل « Status » بدروب داون أفضل من حقل نص حر.

الخطوة 3 — Permissions و API

افتراضياً، Directus يقفل كل شيء. اضبط Permissions لجعل بيانات معينة مرئية للزوار غير المسجلين.

# Settings → Access Policies → Public:
  - articles
    - read: where status = "published"
  - directus_files (للصور)
    - read: all

# اختبر API:
curl http://localhost:8055/items/articles?fields=*,author.*
# يعطي JSON كل المقالات المنشورة + بيانات الكاتب

Permissions في Directus قوية لكن تحتاج فهم. القاعدة العامة: Public يقرأ المنشور فقط، Authenticated يقرأ الكل، Authors يكتبون مقالاتهم، Editors يحررون كل المقالات. للأمان، فلتر by user role دائماً، لا تجعل كل شيء public افتراضياً.

الخطوة 4 — Next.js 15 مع App Router

Next.js 15 + Server Components تستهلك Directus API مباشرة في الـ Server Component، بدون state management.

// app/articles/page.tsx
import Link from "next/link";

type Article = { id: string; title: string; slug: string; published_at: string };

export default async function ArticlesPage() {
  const res = await fetch(
    "http://localhost:8055/items/articles?fields=id,title,slug,published_at&sort=-published_at",
    { next: { revalidate: 60 } }   // ISR: تحديث كل 60 ثانية
  );
  const { data: articles } = (await res.json()) as { data: Article[] };

  return (
    <ul>
      {articles.map(a => (
        <li key={a.id}>
          <Link href={`/articles/${a.slug}`}>{a.title}</Link>
          <time>{new Date(a.published_at).toLocaleDateString("ar")}</time>
        </li>
      ))}
    </ul>
  );
}

next: { revalidate: 60 } يفعّل ISR (Incremental Static Regeneration). الصفحة مولّدة كصفحة ثابتة (سريعة جداً)، لكن تتجدد كل 60 ثانية إن طلبها زائر. توازن مثالي بين سرعة CDN ومحتوى محدّث.

الخطوة 5 — Astro 5 كبديل

Astro متخصص في « content sites » حيث الـ JS الديناميكي قليل. مثالياً للمدونات، التوثيق، صفحات التسويق. الـ output ثابت بالكامل افتراضياً.

---
// src/pages/articles/index.astro
const response = await fetch(
  "http://localhost:8055/items/articles?fields=id,title,slug"
);
const { data: articles } = await response.json();
---

<html lang="ar" dir="rtl">
  <body>
    <h1>المقالات</h1>
    <ul>
      {articles.map((a) => (
        <li><a href={`/articles/${a.slug}`}>{a.title}</a></li>
      ))}
    </ul>
  </body>
</html>

Astro يولّد HTML ثابت في وقت البناء — أسرع من Next.js لمعظم المدونات. لكن إن كنت تحتاج تحديثاً فورياً (متجر مع stock real-time)، Next.js + ISR أفضل. القاعدة: Astro للمحتوى، Next.js للتطبيقات.

الخطوة 6 — On-Demand Revalidation

ISR يحدّث كل دقيقة، لكن أحياناً تريد التحديث فوراً (نشر مقال جديد). webhook من Directus يطلب من Next.js إعادة بناء صفحة محددة.

// app/api/revalidate/route.ts (Next.js)
import { revalidatePath } from "next/cache";
import { NextResponse } from "next/server";

export async function POST(req: Request) {
  const secret = req.headers.get("x-directus-secret");
  if (secret !== process.env.REVALIDATE_SECRET) {
    return NextResponse.json({ error: "unauthorized" }, { status: 401 });
  }
  const body = await req.json();
  // body.payload.slug = slug المقال المحدّث
  revalidatePath(`/articles/${body.payload.slug}`);
  revalidatePath("/articles");
  return NextResponse.json({ revalidated: true });
}

# في Directus:
Settings → Webhooks → New Webhook
  - Method: POST
  - URL: https://your-site.com/api/revalidate
  - Headers: x-directus-secret: super-secret
  - Triggers: items.create, items.update on collection "articles"

هذا النمط يجمع أفضل ما في العالمين: السرعة الكاملة لـ CDN لـ 99% من الزيارات، والتحديث الفوري عند تغيير المحتوى. أداء Lighthouse يبقى 100/100 بدون تأخير في النشر.

الخطوة 7 — تحسين الصور

Directus يعرض API لتحويل الصور تلقائياً (تصغير، تكبير، WebP، AVIF). هذا يلغي الحاجة لـ Cloudinary أو ImageKit في معظم الحالات.

// عرض صورة محسّنة في Next.js:
<img 
  src={`http://localhost:8055/assets/${article.cover_image}?width=800&quality=80&format=webp`}
  alt={article.title}
  loading="lazy"
/>

// خيارات API:
// width, height, quality, format (webp, avif, jpg)
// fit (cover, contain, inside)
// transforms مخصصة للحدود

للأداء الأمثل، أضف <picture> مع srcset لـ responsive images. Next.js يقدم Component <Image /> يدير ذلك تلقائياً، لكن مع Directus URLs خارجية، اضبط next.config.js لإضافة domain Directus في images.remotePatterns.

الخطوة 8 — النشر للإنتاج

الإعداد الموصى: Directus على VPS أو Coolify (للتحكم والاقتصاد)، Next.js/Astro على Vercel/Netlify (مجاناً).

المكوّن الاستضافة التكلفة
Directus + PostgreSQL Hetzner CX22 / DigitalOcean 5-10 USD/شهر
Directus Cloud directus.cloud 15-99 USD/شهر
Next.js Vercel 0 USD (Hobby)
Astro Cloudflare Pages 0 USD
الصور S3/R2 ~ 1 USD/شهر

Stack 2026 الموصى للمشاريع المتوسطة: Directus على Coolify VPS (5 USD)، Next.js على Vercel (مجاني)، صور على Cloudflare R2 (مجاني)، CDN عبر Cloudflare. التكلفة الإجمالية أقل من 10 USD/شهر لموقع بأداء عالمي.

أخطاء شائعة

المشكلة السبب الحل
Public لا يرى المحتوى Permissions غير مفعّلة اضبط Public role في Access Policies
API بطيء طلبات N+1 fields=*,relation.* لتحميل علاقات
صور ثقيلة غياب transformations ?width=&quality=&format=webp
cache لا يتجدد غياب revalidation webhook اربط on-demand revalidation
CORS errors Directus لا يسمح بالـ origin CORS_ORIGIN في .env
تحرير محتوى يحطم الموقع غياب schema validation required + length validators

للمزيد

مقالات ذات صلة

مشاركة