ITSkillsCenter
تطوير الويب

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

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

📍 المقالة الرئيسية: Directus 2026.

Backend Directus جاهز، Frontend للربط. هذا الدرس يفصل التكامل في Next.js 15 (App Router) و Astro 4.

المتطلبات

Directus في الإنتاج مع collections + بيانات. Next.js 15 أو Astro 4. API key Directus للـ frontend. المستوى: متوسط.

إعداد Next.js 15

التثبيت

npm install @directus/sdk
# للأنواع التلقائية: npx directus-sdk-typegen

عميل Directus

// lib/directus.ts
import { createDirectus, rest, staticToken } from '@directus/sdk';
import type { Schema } from '@/types/directus';

export const directus = createDirectus<Schema>(process.env.NEXT_PUBLIC_DIRECTUS_URL!)
  .with(rest())
  .with(staticToken(process.env.DIRECTUS_TOKEN!));

Server Component قائمة منتجات

// app/produits/page.tsx
import { directus } from '@/lib/directus';
import { readItems } from '@directus/sdk';

export const revalidate = 60;  // ISR 60s

export default async function ProductsPage() {
  const products = await directus.request(readItems('products', {
    fields: ['*', 'category.name', 'images.*'],
    filter: { status: { _eq: 'published' } },
    sort: ['-date_created'],
    limit: 24,
  }));

  return (
    <div className="grid grid-cols-3 gap-6">
      {products.map(p => (
        <article key={p.id}>
          <img src={`${process.env.NEXT_PUBLIC_DIRECTUS_URL}/assets/${p.images[0]?.id}?width=400`} />
          <h3>{p.name}</h3>
          <p>{p.price.toLocaleString()} {p.currency}</p>
        </article>
      ))}
    </div>
  );
}

صفحة منتج ديناميكية

// app/produits/[slug]/page.tsx
export async function generateStaticParams() {
  const products = await directus.request(readItems('products', {
    fields: ['slug'],
    filter: { status: { _eq: 'published' } },
  }));
  return products.map(p => ({ slug: p.slug }));
}

Webhook ISR Revalidate

// app/api/revalidate/route.ts
import { revalidatePath } from 'next/cache';

export async function POST(req: Request) {
  const { searchParams } = new URL(req.url);
  if (searchParams.get('secret') !== process.env.REVALIDATE_SECRET) {
    return new Response('Unauthorized', { status: 401 });
  }
  revalidatePath('/produits');
  return Response.json({ revalidated: true });
}

إعداد Astro 4

// src/lib/directus.ts
import { createDirectus, rest, staticToken } from '@directus/sdk';

export const directus = createDirectus(import.meta.env.DIRECTUS_URL)
  .with(rest())
  .with(staticToken(import.meta.env.DIRECTUS_TOKEN));

صفحة قائمة مقالات

---
// src/pages/blog/index.astro
import { directus } from '@/lib/directus';
import { readItems } from '@directus/sdk';

const articles = await directus.request(readItems('articles', {
  fields: ['*', 'author.name', 'cover_image.*'],
  filter: { status: { _eq: 'published' } },
}));
---
<Layout>
  {articles.map(a => (
    <article>
      <a href={`/blog/${a.slug}`}>{a.title}</a>
    </article>
  ))}
</Layout>

الأداء و caching

CDN Cloudflare في الواجهة

Cache assets Directus (الصور) مع Cache-Control لمدة سنة. API responses cache عبر SWR Next.js.

تحويلات الصور

<img src="https://cms.../assets/IMG_ID?width=400&height=300&fit=cover&format=webp" />

الأخطاء الشائعة

الخطأ الحل
API 401 Token غير صحيح
Relations فارغة fields=*,relation.*
صور CORS CORS_ENABLED=true
ISR لا يعمل revalidate مفقود

التكيف مع السياق

CDN Cloudflare مجاني: أساسي لخدمة صور Directus بزمن استجابة منخفض من داكار/أبيدجان. WebP + AVIF: Directus يولد تلقائياً، توفير 50% حجم. SSG vs SSR: Astro SSG للمدونة + Next.js ISR للتجارة الإلكترونية.

دروس الإخوة

الأسئلة المتكررة

GraphQL أو REST؟ REST أبسط.

SDK إجباري؟ لا، fetch قياسي يعمل أيضاً.

للاستزادة

Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 250.000 FCFA
Parlons de Votre Projet
Publicité