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 |
للمزيد
- Directus Docs docs.directus.io
- Next.js 15 nextjs.org
- Astro 5 astro.build
- Directus + Next.js example github.com/directus/examples