שילוב Sanity CMS עבור Next.js, Nuxt ו-Remix

מנהלי תוכן מבזבזים זמן בהמתנה לבנייה מחדש של האתר לאחר כל עריכה, ועורכים לא רואים שינויים בזמן אמת. אנו משלבים את Sanity CMS עם Next.js, Nuxt או Remix, ומגדירים ISR, מצב תצוגה מקדימה ו-webhooks באופן סוהר. הצוות שלנו מטפל בכל המחזור—מביקורת ועד תמיכה—כך שמקבלים תהליך פרסום תוכן מהיר ונוח.

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

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

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
שילוב Sanity CMS עבור Next.js, Nuxt ו-Remix
בינוני
~3-5 ימים

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

שאלות נפוצות

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

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

אינטגרציית CMS ראשית מלאה: Sanity עם Next.js, Nuxt ו-Remix

אינטגרציית Sanity המפתח-ביד שלנו כוללת הגדרת Sanity Client, webhooks ועוד. כאשר בונים עם Next.js, הידרציה של תוכן מ-Sanity הופכת לעיתים קרובות לצוואר בקבוק, ויש צורך בהטמעת מצב תצוגה מקדימה עבור עורכים. ללא ISR, כל פרסום תוכן גורם לבנייה מחדש מלאה, ומעלה את TTFB ב-30–50%. אנו מקימים אינטגרציה מלאה: ISR, webhooks וטיפוסים. רקורד שלנו: 10+ פרויקטי Sanity, 5 שנים בשוק. אנו מבטיחים 100% שביעות רצון עם תהליך האינטגרציה המוכח שלנו. צרו קשר לקבלת ייעוץ והערכה לפרויקט שלכם. עלות ממוצעת לחבילת Basic היא $1,500. לקוחות בדרך כלל חוסכים 20-30% בעלויות שרת עם ISR.

Sanity עובד על HTTP API — כל framework יכול לקרוא את התוכן שלו. ספריות רשמיות: next-sanity עבור Next.js, @sanity/client עבור אחרים. עם ה-CDN, Sanity Client מגיב ב-50–80 אלפיות השנייה בממוצע, מהיר פי 2–3 מבקשות fetch פשוטות ל-REST API טיפוסי. תיעוד Sanity הרשמי

יתרונות Sanity עם Server Frameworks

Sanity הוא CMS ראשי בזמן אמת: עורכים רואים שינויים מיידית. בשילוב עם Next.js או Nuxt, מקבלים דפים סטטיים שמתעדכנים רק כשהתוכן משתנה. שימוש ב-ISR מפחית עומס שרת בעד 40% ומשפר TTFB ב-25%. בנוסף, שאילתות GROQ מאפשרות לבחור רק את השדות הדרושים — נפח הנתונים המועבר קטן ב-60–70%.

חיבור Sanity ל-Next.js דרך App Router

התקינו חבילות: npm install next-sanity @sanity/client. הגדירו את ה-client. עבור טיוטות, השתמשו ב-client תצוגה מקדימה עם token.

// lib/sanity/client.ts
import { createClient } from 'next-sanity'

export const client = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || 'production',
  apiVersion: process.env.SANITY_API_VERSION, // установите актуальную версию
  useCdn: process.env.NODE_ENV === 'production',
})

export const previewClient = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || 'production',
  apiVersion: process.env.SANITY_API_VERSION,
  useCdn: false,
  token: process.env.SANITY_API_TOKEN,
  perspective: 'previewDrafts',
})

ב-server components, השתמשו ב-// lib/sanity/client.ts import { createClient } from 'next-sanity' export const client = createClient({ projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!, dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || 'production', apiVersion: process.env.SANITY_API_VERSION, // установите актуальную версию useCdn: process.env.NODE_ENV === 'production', }) export const previewClient = createClient({ projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!, dataset: process.env.NEXT_PUBLIC_SANITY_DATASET || 'production', apiVersion: process.env.SANITY_API_VERSION, useCdn: false, token: process.env.SANITY_API_TOKEN, perspective: 'previewDrafts', }) עם שאילתות GROQ. דוגמה לדף פוסט:

// app/posts/[slug]/page.tsx
import { client, previewClient } from '@/lib/sanity/client'
import { groq } from 'next-sanity'
import { draftMode } from 'next/headers'

const query = groq`*[_type == "post" && slug.current == $slug][0] {
  _id,
  title,
  body,
  publishedAt,
  "author": author->{ name },
  "slug": slug.current
}`

export default async function PostPage({ params }: { params: { slug: string } }) {
  const { isEnabled } = draftMode()
  const activeClient = isEnabled ? previewClient : client
  const post = await activeClient.fetch(query, { slug: params.slug }, { next: { tags: [`post-${params.slug}`] } })

  if (!post) notFound()

  return <Article post={post} />
}

export async function generateStaticParams() {
  const slugs = await client.fetch<string[]>(`*[_type == "post"].slug.current`)
  return slugs.filter(Boolean).map(slug => ({ slug }))
}

Revalidation לפי דרישה דרך ISR ו-Webhooks

ISR מעדכן דפים רק כשהתוכן משתנה — מפחית עומס שרת. צרו webhook ב-Sanity ו-endpoint שקורא ל-client.fetch. דוגמה:

// app/api/revalidate/route.ts
import { revalidateTag } from 'next/cache'
import { parseBody } from 'next-sanity/webhook'

export async function POST(req: Request) {
  try {
    const { isValidSignature, body } = await parseBody<{ _type: string; slug?: { current: string } }>(
      req,
      process.env.SANITY_WEBHOOK_SECRET!
    )

    if (!isValidSignature) {
      return Response.json({ message: 'Invalid signature' }, { status: 401 })
    }

    if (body._type === 'post') {
      revalidateTag('posts')
      if (body.slug?.current) {
        revalidateTag(`post-${body.slug.current}`)
      }
    }

    return Response.json({ revalidated: true })
  } catch (err) {
    return Response.json({ message: 'Invalid request' }, { status: 400 })
  }
}

אינטגרציה עם Nuxt 3

התקינו את מודול // app/posts/[slug]/page.tsx import { client, previewClient } from '@/lib/sanity/client' import { groq } from 'next-sanity' import { draftMode } from 'next/headers' const query = groq`*[_type == "post" && slug.current == $slug][0] { _id, title, body, publishedAt, "author": author->{ name }, "slug": slug.current }` export default async function PostPage({ params }: { params: { slug: string } }) { const { isEnabled } = draftMode() const activeClient = isEnabled ? previewClient : client const post = await activeClient.fetch(query, { slug: params.slug }, { next: { tags: [`post-${params.slug}`] }, }) if (!post) notFound() return <Article post={post} /> } export async function generateStaticParams() { const slugs = await client.fetch<string[]>(`*[_type == "post"].slug.current`) return slugs.filter(Boolean).map(slug => ({ slug })) } והוסיפו הגדרה ב-revalidateTag.

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/sanity'],
  sanity: {
    projectId: process.env.NUXT_PUBLIC_SANITY_PROJECT_ID,
    dataset: 'production',
    apiVersion: process.env.SANITY_API_VERSION,
    useCdn: process.env.NODE_ENV === 'production',
  },
})

ברכיב, השתמשו ב-// app/api/revalidate/route.ts import { revalidateTag } from 'next/cache' import { parseBody } from 'next-sanity/webhook' export async function POST(req: Request) { try { const { isValidSignature, body } = await parseBody<{ _type: string; slug?: { current: string } }>( req, process.env.SANITY_WEBHOOK_SECRET! ) if (!isValidSignature) { return Response.json({ message: 'Invalid signature' }, { status: 401 }) } if (body._type === 'post') { revalidateTag('posts') if (body.slug?.current) { revalidateTag(`post-${body.slug.current}`) } } return Response.json({ revalidated: true }) } catch (err) { return Response.json({ message: 'Invalid request' }, { status: 400 }) } } עבור שאילתות fetch:

<template>
  <article v-if="post">
    <h1>{{ post.title }}</h1>
    <SanityContent :blocks="post.body" />
  </article>
</template>

<script setup lang="ts">
const { $sanity } = useNuxtApp()
const route = useRoute()
const { data: post } = await useAsyncData(`post-${route.params.slug}`, () =>
  $sanity.fetch(
    `*[_type == "post" && slug.current == $slug][0] { title, body }`,
    { slug: route.params.slug }
  )
)
</script>

אינטגרציה של Sanity עם Remix

ב-Remix, נתונים נטענים בפונקציות @nuxtjs/sanity בשרת — הדף מרנדר עם תוכן כבר, ללא עיכובי הידרציה או בקשות waterfall מצד הלקוח. השתמשו ב-nuxt.config.ts ישירות ב-loader: // nuxt.config.ts export default defineNuxtConfig({ modules: ['@nuxtjs/sanity'], sanity: { projectId: process.env.NUXT_PUBLIC_SANITY_PROJECT_ID, dataset: 'production', apiVersion: process.env.SANITY_API_VERSION, useCdn: process.env.NODE_ENV === 'production', }, }) , ואז העבירו נתונים לרכיב דרך $sanity.

Remix אינו תומך ב-ISR מחוץ לקופסה. עבור caching, השתמשו ב-HTTP headers כמו <template> <article v-if="post"> <h1>{{ post.title }}</h1> <SanityContent :blocks="post.body" /> </article> </template> <script setup lang="ts"> const { $sanity } = useNuxtApp() const route = useRoute() const { data: post } = await useAsyncData(`post-${route.params.slug}`, () => $sanity.fetch( `*[_type == "post" && slug.current == $slug][0] { title, body }`, { slug: route.params.slug } ) ) </script> ב-loader — Cloudflare ו-Vercel Edge קולטים אותם אוטומטית. Webhook של Sanity מבטל את ה-cache דרך Cloudflare Purge API כשמפרסמים תוכן חדש. זמן תגובה ממוצע עם CDN מוגדר כראוי הוא 60–100 אלפיות השנייה.

טיפוסי תוכן עם Sanity TypeGen

הפקודה loader יוצרת טיפוסי TypeScript מסכמת הסטודיו. שאילתות GROQ הופכות ל-type-safe: ה-IDE מציע שדות, TypeScript תופס שגיאות כתיב בזמן בנייה. זה חוסך 1–2 שעות לכל סוג תוכן חדש ומפחית באגים בייצור.

השוואת Frameworks: מהירות עם Sanity Client

Framework זמן תגובה ראשון (TTFB) קלות הגדרה תיעוד
Next.js נמוך (ISR/SSR) גבוהה מצוין
Nuxt 3 בינוני (SSR/SSG) גבוהה טוב
Remix נמוך (loader) בינוני טוב

בפועל, Sanity Client מהיר פי 2–3 מבקשות fetch פשוטות בזכות CDN ו-caching יעיל.

טעויות אינטגרציה נפוצות
  • חוסר התאמה בהידרציה עקב הבדל נתונים בין שרת ללקוח — נפתר על ידי סנכרון שאילתות דרך @sanity/client.
  • שגיאות CORS בעת ביצוע בקשות מהדפדפן — הגדירו CORS origins בלוח הבקרה של Sanity.
  • שאילתות N+1 עם הפניות מקוננות — השתמשו באופרטור GROQ client.fetch(query, { slug: params.slug }) כדי להביא מסמכים קשורים.
  • Cache מיושן עם ISR — ודאו ש-webhook secret נכון וה-endpoint נגיש.

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

  • הגדרת Sanity Client ותצורת גרסת API
  • הטמעת מצב תצוגה מקדימה (draft mode) עם tokens
  • Webhook עבור revalidation לפי דרישה
  • שאילתות GROQ וטיפוסי תוכן (טיפוסים שנוצרו)
  • אופטימיזציית תמונות דרך Sanity Image CDN
  • תיעוד והדרכת צוות

איך התהליך עובד

  1. ניתוח: דיון בארכיטקטורת תוכן וצרכי שאילתות
  2. עיצוב: סכמות שאילתות GROQ, טיפוסים
  3. הטמעה: אינטגרציית client, דפים, תצוגה מקדימה
  4. בדיקות: אימות הידרציה, שגיאות revalidation
  5. פריסה: הגדרת משתני סביבה, webhook

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

חבילה מה כלול לוח זמנים
Basic Next.js + ISR + Webhooks 1–2 ימים
Extended +Nuxt או Remix, מצב תצוגה מקדימה 2–3 ימים
Turnkey כל ה-frameworks + TypeGen + תיעוד 3–5 ימים

העלות נקבעת לאחר ניתוח הפרויקט הספציפי שלכם. זמן משוער: Next.js App Router — 1–2 ימים, Nuxt 3 — יום אחד, Remix — יום אחד, כל שלושת ה-frameworks — 3–5 ימים. עלות ממוצעת לאינטגרציה של framework יחיד היא $1,500–$3,000. הזמינו את האינטגרציה — נכין הערכה מדויקת. קבלו ייעוץ: המהנדסים שלנו יעזרו לכם לבחור את הארכיטקטורה האופטימלית.