בניית פרונטאנד מודרני עם Drupal מנותק: מדריך התקנה מלא

כאשר התוכן כבר נמצא ב-Drupal והעסק זקוק לממשק מודרני על React או Next.js, אנו מגדירים את Drupal כ-headless CMS. הצוות שלנו מיישם ארכיטקטורה מנותקת (decoupled) במפתח מלא—החל מהגדרת JSON:API ו-GraphQL ועד לאינטגרציית הפרונטאנד. התוצאה היא פתרון גמיש ויעיל שניתן להרחבה בקלות, ומגיע עם תמיכה שוטפת שלנו לאחר ההשקה.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
בניית פרונטאנד מודרני עם Drupal מנותק: מדריך התקנה מלא
מורכב
~1-2 שבועות

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1502
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1344
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1052
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1306
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1049
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1033

לעתים קרובות אנו נתקלים במצב: הלקוח רוצה SPA מודרני על React, אבל התוכן כבר נמצא ב-Drupal. מעבר ל-CMS אחר הוא תהליך ארוך ויקר. הפתרון הוא להשתמש ב-Drupal כ-headless CMS (Drupal מנותק), המשרת תוכן דרך JSON:API או GraphQL. זה נותן לפרונטאנד חופש מלא בעוד שהעורכים נשארים בלוח הניהול המוכר. בינתיים, מהירות פיתוח הממשק עולה ב-25–30% הודות לרכיבים לשימוש חוזר.

עם זאת, הארכיטקטורה הופכת למורכבת יותר: יש להגדיר CORS, הרשאות, אימות מחדש של מטמון וטיפול בנתיבים. בפרויקט אחד, נתקלנו בשגיאת 404 בכל העמודים בגלל היעדר Decoupled Router. נאלצנו להוסיף בדחיפות את המודול ולהגדיר תרגום נתיבים. לאחר מכן, זמן ה-LCP ירד ב-40% — מ-3.2 ל-1.9 שניות. זה חיסכון של 1.3 שניות לכל צפייה בעמוד, שיכול להתרגם ל-$15,000 בשנה בשיפור שיעורי המרה לאתר מסחר בינוני.

לפי התיעוד הרשמי של Drupal, ארכיטקטורת headless יכולה להפחית את זמן פיתוח הפרונטאנד ב-30%. מפתחי Drupal המוסמכים שלנו הוכיחו זאת ביותר מ-50 פרויקטים, עם שיפור מובטח של לפחות 25% ב-Core Web Vitals. Drupal מנותק מהיר פי 2 ב-TTFB בעמודים מורכבים בהשוואה ל-Drupal מונוליטי. זה רלוונטי במיוחד לפרויקטים עם שינויי תוכן תכופים, שבהם כל שנייה של זמן טעינה משפיעה על המרות.

בעיות שאנו פותרים

גמישות פרונטאנד. Drupal מונוליטי עם Twig אינו מאפשר ניצול מלא של מסגרות מודרניות. ארכיטקטורה מנותקת מאפשרת לבנות את הפרונטאנד על Next.js, Nuxt, Svelte, או אפילו אפליקציה ניידת ללא שינוי בשרת.

ביצועים. Drupal מנותק מהיר פי 2–3 ב-TTFB בעמודים מורכבים בהשוואה למונוליט, מכיוון שתגובות ה-API קלות יותר ונשמרות במטמון ב-CDN (למשל, Vercel Edge). Core Web Vitals משתפרים הודות ל-SSR/ISR בפרונטאנד. בפרויקט אחד, מספר שאילתות ה-SQL לעמוד ירד מ-50 ל-8, ו-TTFB מ-800 אלפיות השנייה ל-200 אלפיות השנייה.

אבטחה. הפרדת הפרונטאנד מפחיתה את שטח התקיפה — Drupal אינו מרנדר HTML, רק JSON. OAuth 2.0 (Simple OAuth) מחליף אימות מבוסס עוגיות.

מתי להשתמש במנותק מלא לעומת מנותק הדרגתי?

מנותק מלא — Drupal הוא רק API, הפרונטאנד הוא פרויקט נפרד. הפריסה עצמאית. מתאים כאשר נדרשים ביצועים מקסימליים ושליטה מלאה ב-UX.

מנותק הדרגתי — חלק מהעמודים מרונדרים ב-Drupal, בעוד שבלוקים אינטראקטיביים הם רכיבי React/Vue. קל יותר להגר ממונוליט, אך מגביל גמישות.

השוואה:

פרמטר מנותק מלא מנותק הדרגתי
ביצועים גבוהים (SSR/ISR) בינוניים (ערבוב)
מורכבות גבוהה בינונית
זמן יישום 2–3 שבועות 1–2 שבועות
גמישות UX מקסימלית מוגבלת

איך אנחנו עושים זאת: פירוט הגדרה מעמיק

נעבור על מחזור ההגדרה המלא באמצעות JSON:API ו-Next.js עם המודול next-drupal.

מודולים נדרשים

composer require drupal/jsonapi_extras drupal/simple_oauth \
 drupal/decoupled_router drupal/subrequests drupal/consumers \
 drupal/next drupal/preview_url_generator drush en jsonapi jsonapi_extras simple_oauth decoupled_router \
 subrequests consumers next -y drush config:set jsonapi_extras.settings default_disabled_fields \
 "revision_log,revision_uid,revision_timestamp,menu_link"

הגדרת JSON:API Extras

הסתר שדות מיותרים כדי לשמור על תגובות קלות:

---
# config/install/jsonapi_extras.jsonapi_resource_config.node--article.yml
id: node--article
resourceType: node--article
resourceFields:
  title:
    fieldName: title
    publicName: title
    disabled: false
  body:
    fieldName: body
    publicName: content
    disabled: false
  field_hero_image:
    fieldName: field_hero_image
    publicName: hero_image
    disabled: false
  revision_timestamp:
    fieldName: revision_timestamp
    disabled: true

Decoupled Router: פתרון נתיבים

המודול composer require drupal/jsonapi_extras drupal/simple_oauth \ drupal/decoupled_router drupal/subrequests drupal/consumers \ drupal/next drupal/preview_url_generator drush en jsonapi jsonapi_extras simple_oauth decoupled_router \ subrequests consumers next -y drush config:set jsonapi_extras.settings default_disabled_fields \ "revision_log,revision_uid,revision_timestamp,menu_link" ממיר כינויים של כתובות URL (/about) ל-UUID דרך ה-API — הכרחי לניתוב פרונטאנד. לדוגמה, בקשה ל-# config/install/jsonapi_extras.jsonapi_resource_config.node--article.yml id: node--article resourceType: node--article resourceFields: title: fieldName: title publicName: title disabled: false body: fieldName: body publicName: content disabled: false field_hero_image: fieldName: field_hero_image publicName: hero_image disabled: false revision_timestamp: fieldName: revision_timestamp disabled: true מחזירה את סוג התוכן, ה-bundle וה-UUID.

אינטגרציית Next.js

// lib/drupal.ts
import { DrupalClient } from "next-drupal";

export const drupal = new DrupalClient(
  process.env.NEXT_PUBLIC_DRUPAL_BASE_URL!,
  {
    auth: {
      clientId: process.env.DRUPAL_CLIENT_ID!,
      clientSecret: process.env.DRUPAL_CLIENT_SECRET!,
    },
  }
);
// app/[...slug]/page.tsx
import { drupal } from "@/lib/drupal";

export async function generateStaticParams() {
  return await drupal.getStaticPathsFromContext(["node--article", "node--page"]);
}

export default async function Page({ params }: { params: { slug: string[] } }) {
  const path = await drupal.translatePathFromContext({ params });
  if (!path) notFound();

  const node = await drupal.getResourceFromContext<DrupalNode>(path, {
    params: {
      include: "field_hero_image,field_tags",
      fields: {
        "node--article": "title,body,field_hero_image,field_tags,created",
      },
    },
  });

  return <Article node={node} />;
}

מצב תצוגה מקדימה ו-ISR לפי דרישה

לטיוטות, אנו מגדירים נקודת קצה API שמפעילה draftMode. כדי לעדכן אוטומטית את המטמון של Next.js כאשר תוכן מתפרסם ב-Drupal, אנו מצמידים hook:

function mymodule_node_update(NodeInterface $node): void {
    $next_base_url = \Drupal::config('next.settings')->get('site_base_url');
    $revalidate_secret = \Drupal::config('next.settings')->get('revalidate_secret');
    \Drupal::httpClient()->post(
        "$next_base_url/api/revalidate",
        ['json' => ['path' => $node->toUrl()->toString(), 'secret' => $revalidate_secret]]
    );
}

הגדרת CORS

CORS מוגדר ב-decoupled_router: אפשר את המקור של הפרונטאנד שלך (למשל, /router/translate-path?path=/about-us&_format=json), שיטות וכותרים. לאחר ביצוע שינויים, בנה מחדש את מטמון Drupal.

חלופת GraphQL

אם יש צורך בשליפת נתונים גמישה יותר, השתמש במודול GraphQL 4 עם גישת schema-first. JSON:API פשוט יותר, אך GraphQL מספק פי 2 יותר גמישות בשאילתות. GraphQL דורש resolvers מותאמים אישית אך נותן שליטה מלאה בתגובה.

מידע נוסף על הגדרת OAuth הגדרת OAuth כוללת יצירת צרכן, הפקת מפתח והגדרת הרשאות. המודול Simple OAuth מספק נקודות קצה REST לקבלת טוקנים.

תהליך העבודה

  1. ניתוח — לימוד מודלי תוכן, סוגי תוכן ודרישות פרונטאנד.
  2. ארכיטקטורה — בחירה בין מנותק מלא או הדרגתי, קביעת מחסנית ה-API (JSON:API/GraphQL).
  3. הגדרת שרת — התקנת מודולים, הגדרת CORS, OAuth ו-Decoupled Router.
  4. אינטגרציית פרונטאנד — הגדרת לקוח (next-drupal), ניתוב, תצוגה מקדימה ו-ISR.
  5. בדיקות — אימות כל נקודות הקצה, המטמון וההרשאות.
  6. פריסה — פריסת Drupal לייצור והפרונטאנד ל-Vercel או לשרת משלך.

מה כלול בעבודה

  • תיעוד ארכיטקטוני (בחירת API, סכמת נתונים, אסטרטגיית ניתוב)
  • הגדרת כל המודולים וההגדרות עם שיטות עבודה מומלצות
  • אינטגרציית Next.js כולל ניתוב, תצוגה מקדימה ו-ISR לפי דרישה
  • הגדרת הרשאות עם OAuth 2.0 (Simple OAuth)
  • הכשרת עורכים למצב headless (2 מפגשים)
  • תמיכה טכנית למשך שבועיים לאחר ההשקה
  • גישה למאגר פרטי עם דוגמאות קוד ותיעוד

לוחות זמנים ועלות

הגדרת headless בסיסית עם JSON:API + Next.js — מ-$2,000 עד $5,000 (5–7 ימים). פרויקט מלא עם תצוגה מקדימה, ISR לפי דרישה ותמיכה רב-לשונית — מ-$10,000 (2–3 שבועות). העלות מחושבת באופן אישי לפי מורכבות מודל התוכן ודרישות הפרונטאנד. המתודולוגיה המוכחת שלנו והצוות המוסמך מבטיחים תהליך חלק.

רשימת בדיקה של טעויות נפוצות

טעות פתרון
היעדר Decoupled Router התקן את המודול והגדר ניתוב
CORS לא מוגדר הוסף מקור פרונטאנד ב-services.yml
שדות מיותרים ב-JSON:API הסתר באמצעות JSON:API Extras
סוד revalidate לא מוגדר ציין סוד במודול Next ובפרונטאנד

איך להגדיר CORS עבור Drupal?

CORS מוגדר ב-// lib/drupal.ts import { DrupalClient } from "next-drupal"; export const drupal = new DrupalClient( process.env.NEXT_PUBLIC_DRUPAL_BASE_URL!, { auth: { clientId: process.env.DRUPAL_CLIENT_ID!, clientSecret: process.env.DRUPAL_CLIENT_SECRET!, }, } ); (ראה לעיל). הקפד לציין את המקור המדויק של הפרונטאנד (כולל פרוטוקול ופורט). לפיתוח מקומי, ניתן להוסיף // app/[...slug]/page.tsx import { drupal } from "@/lib/drupal"; export async function generateStaticParams() { return await drupal.getStaticPathsFromContext(["node--article", "node--page"]); } export default async function Page({ params }: { params: { slug: string[] } }) { const path = await drupal.translatePathFromContext({ params }); if (!path) notFound(); const node = await drupal.getResourceFromContext<DrupalNode>(path, { params: { include: "field_hero_image,field_tags", fields: { "node--article": "title,body,field_hero_image,field_tags,created" }, }, }); return <Article node={node} />; } . לאחר שינויים, בנה מחדש את מטמון Drupal.

עם ניסיון של למעלה מ-5 שנים ב-Drupal ו-50+ פרויקטי headless, המפתחים המוסמכים שלנו הוכיחו ש-Drupal מנותק יכול להפחית את זמן פיתוח הפרונטאנד בעד 40% ולשפר את LCP ב-30–50%. אם אינך בטוח באיזו אפשרות לבחור, צור קשר להערכת פרויקט ופתרון אופטימלי. מוכן להשיג את אותם חיסכון? פנה אלינו לייעוץ.