نشر SvelteKit وتحسين محركات البحث: المحولات، والعرض المسبق، والعرض عند الحافة

تحدد إعدادات المحول والعرض المسبق لكل مسار في SvelteKit أين ومتى تُعرض صفحاتك — وهذا يؤثر على TTFB وLCP وميزانية الزحف. دليل معمق يركز على النشر: اختيار adapter-static/node/vercel/cloudflare/netlify، وprerender = true/false/'auto'، وقيود وقت التشغيل عند الحافة، وبناء sitemap.xml وrobots.txt.

نُشر أول مرة: 3 يوليو 2026 · آخر تحديث: 14 أغسطس 2026 · Advanced
اللغات

إعداد المحول والعرض المسبق لكل مسار في SvelteKit يحدد أين ومتى تُعرض الصفحة — HTML ثابت في وقت البناء، أو SSR على خادم، أو SSR عند الحافة — وهذا القرار يؤثر في TTFB، الذي يؤثر بدوره في LCP وسعة الزحف. اختر adapter-static للمواقع ذات المحتوى الخالص، ومحول node/vercel/cloudflare مع عرض مسبق لكل مسار للمواقع المختلطة (محتوى وتطبيق)، ومحول حافة عندما يكون TTFB العالمي مهمًا (مع قبول البدايات الباردة وعدم وجود نظام ملفات Node). prerender = 'auto' هو أداة المواقع المختلطة. لا يمكن لبيئات التشغيل عند الحافة قراءة نظام الملفات. ولا ينشئ SvelteKit sitemap.xml أو robots.txt — بل تبنيهما كنقطتي نهاية +server.js، وفق استراتيجية تعتمد على المحول الخاص بك.

TL;DR — لا يغيّر المُكيّف ماذا يقدّم SvelteKit — بل يغيّر أين ومتى: وقت البناء ثابت (adapter-static)، وقت الطلب على خادم تشغّله (adapter-node)، أو وقت الطلب على دوال serverless/edge (adapter-vercel/-netlify/-cloudflare). prerender = true لكل مسار يبني HTML ثابتًا ويُسقط المسار من قائمة التشغيل الديناميكية؛ prerender = 'auto' يبني مسبقًا ويُبقي المسار في القائمة — الأداة المناسبة لمواقع /blog/[slug] المختلطة. تعمل بيئات edge على عوازل V8: لا يوجد Node fs، والبدء البارد يضرّ بـ TTFB، مما يغذّي LCP و(وفقًا لوثيقة ميزانية الزحف من Google) سعة الزحف. لا يولّد SvelteKit أي sitemap.xml أو robots.txt — ابنِها كنقاط نهاية +server.js، ولاحظ أن الاستراتيجية تعتمد على المُكيّف. هذا دليل أضيق ومركّز على النشر، مكمّل لمقالة أساسيات SEO في SvelteKit في هذا القسم؛ أفترض أنك تعرف بالفعل أن SvelteKit يستخدم SSR افتراضيًا ولن أعيد مناقشة ذلك هنا.

الفكرة الواحدة التي تجعل كل هذا واضحًا

لا يغيّر المُكيّف ماذا يُقدَّم. بل يغيّر أين ومتى. هذا هو كل شيء. توثيق SvelteKit يوضح ذلك بدقة: المُكيّفات “تأخذ التطبيق المبني كمدخل وتولّد مخرجات للنشر.” Evidence for this claim SvelteKit adapters take the built application as input and generate deployment-specific output. Scope: Deployment output; adapter choice can still constrain supported runtime features. Confidence: high · Verified: SvelteKit: Adapters مكوّناتك، ودوال load الخاصة بك، وبيانات <svelte:head> الوصفية — متطابقة عبر كل مُكيّف. ما يختلف هو:

  • متى يُنتَج HTML: في وقت البناء (ثابت/مُبنى مسبقًا) أو في وقت الطلب (SSR على خادم، أو دالة serverless، أو دالة edge).
  • أين يُنتَج: على خادم أصلي واحد، أو على دالة serverless إقليمية، أو على شبكة edge قريبة من الزائر.

كل ما يلي هو نتيجة لهذين المحورين.

لماذا خيارات النشر هي خيارات SEO

السلسلة قصيرة وموثقة جيدًا: TTFB → LCP → سعة الزحف.

الوقت حتى أول بايت هو المدة التي يستغرقها المضيف لبدء إرسال الاستجابة. ملف مُبنى مسبقًا يُقدَّم من ذاكرة تخزين مؤقت CDN لديه TTFB قريب من الصفر. خادم يجب أن يقدّم الصفحة لديه TTFB أعلى. دالة serverless أو edge تبدأ باردًا يمكن أن يكون لديها TTFB أعلى بكثير عند أول زيارة. TTFB هو مدخل مباشر لـ Largest Contentful Paint — لا يمكنك رسم ما لم تستلمه — وLCP هو إشارة Core Web Vitals.

جانب الزحف هو حيث تكون Google الأكثر وضوحًا. من وثائق ميزانية الزحف: “إذا استجاب الموقع بسرعة لفترة، يرتفع الحد، مما يعني أنه يمكن استخدام المزيد من الاتصالات للزحف. إذا تباطأ الموقع أو استجاب بأخطاء خادم، ينخفض الحد وتزحف Google أقل.” وسطر أفضل الممارسات: “اجعل صفحاتك فعالة في التحميل. إذا كان بإمكان Google تحميل وعرض صفحاتك بشكل أسرع، فقد نتمكن من قراءة المزيد من المحتوى من موقعك.” دالة edge تبدأ باردًا وتستجيب ببطء تخضع لنفس الديناميكية كخادم أصلي بطيء.

ملاحظة صراحة في البداية: لا تنشر Google أي إرشادات خاصة بـ SvelteKit. لا توجد وثيقة أو حلقة Search Off the Record تذكر مُكيّفات SvelteKit، أو prerender = 'auto'، أو بدايات edge الباردة. ما أفعله هنا هو تطبيق إرشادات Google العامة حول العرض وميزانية الزحف على آليات SvelteKit المحددة — وليس اقتباس ممثل علّق على SvelteKit، لأنه لا يوجد. إطار Google الذي يقول “الخادم أو العرض المسبق لا يزال فكرة رائعة لأنه يجعل موقعك أسرع للمستخدمين والزاحفين، وليس كل الروبوتات يمكنها تشغيل JavaScript” هو أقرب مرساة رسمية، وهو مستقل عن الإطار.

اختيار مُكيّف لنتائج SEO

adapter-auto — الافتراضي بدون إعداد، وسقفه

مشاريع SvelteKit الجديدة تأتي مع adapter-auto. يكتشف المنصة — Vercel، Netlify، Cloudflare Pages، Azure، AWS — ويقوم بتثبيت المحول المطابق في وقت البناء. إنها نقطة بداية جيدة، لكن هناك سقف صلب يستحق المعرفة: adapter-auto لا يقبل أي خيارات. في اللحظة التي تحتاج فيها { edge: true }، أو ربطات Cloudflare، أو Vercel ISR، أو أي إعداد خاص بالمنصة، تقوم بتثبيت المحول الأساسي (adapter-vercel، adapter-cloudflare، إلخ) مباشرة. تعامل مع auto كسقالة، وليس قرارًا للإنتاج.

adapter-static — SSG كامل، للمواقع التي تركز على المحتوى

adapter-static يقوم بإنشاء موقعك بالكامل كملفات ثابتة في وقت البناء. لا يعمل خادم؛ يستضيف المضيف HTML مسطحًا. Evidence for this claim adapter-static prerenders a SvelteKit site as static files. Scope: Routes must be prerenderable; performance outcomes depend on hosting and page design. Confidence: high · Verified: SvelteKit: Static site generation بالنسبة لموقع يركز على المحتوى، هذا هو أقوى ملف تعريف SEO يمكن أن تحصل عليه — أقل TTFB، لا بدء بارد، لا شيء ينهار. الشرط الوحيد هو الفخ الذي تم تغطيته بالتفصيل في مقالة الأساسيات: يجب أن يظل SSR مفعلًا أثناء البناء، أو ستحصل على قوالب فارغة بدلاً من HTML المعروض. لن أشرح ذلك مرة أخرى هنا سوى بالإشارة إليه.

العيب هو الجمود. أي شيء يحتاج حقًا إلى منطق خادم لكل طلب (بحث حقيقي، محتوى مخصص لكل مستخدم، معالجة نماذج بدون نقطة نهاية طرف ثالث) لا يمكن أن يعيش على بناء ثابت بحت — وهذا بالضبط ما صُممت المحولات التالية من أجله.

adapter-node — خادم تتحكم فيه

adapter-node ينتج خادم Node.js مستقلًا. تقوم بتشغيله، وتوسيعه، وتمتلك TTFB. هذا هو الخيار الأكثر مرونة والأقل مفاجآت في وقت التشغيل — واجهات برمجة تطبيقات Node كاملة، بما في ذلك fs. إنه مناسب عندما يكون لديك بنية تحتية بالفعل، أو تحتاج إلى مكتبات Node لا يمكن لبيئات الحافة تشغيلها، أو تريد أوقات استجابة متوقعة (غير باردة البدء) من خادم دافئ. المقايضة هي تشغيلية: أنت تدير خادمًا، وسرعته ووقت تشغيله أصبحا الآن سعة الزحف الخاصة بك.

adapter-vercel — serverless، edge، وISR

adapter-vercel ينشر إلى دوال serverless الخاصة بـ Vercel افتراضيًا، مع عدة روافع متعلقة بـ SEO تُضبط لكل مسار عبر export const config:

  • runtime: 'edge' ينقل هذا المسار إلى بيئة edge الخاصة بـ Vercel (المزيد أدناه).
  • regions يتحكم في مكان تشغيل دوال serverless — الأقرب إلى مستخدميك (أو قاعدة بياناتك) يعني زمن استجابة أقل.
  • isr يتيح إعادة التوليد الثابتة المتزايدة: isr: { expiration: 60 } يقدم أصلًا ثابتًا مخزنًا مؤقتًا ويعيد توليده بعد النافذة، مما يعطي “مزايا الأداء والتكلفة للمحتوى المعالج مسبقًا مع مرونة المحتوى المعروض ديناميكيًا.” ISR هو مسار رابع حقيقي بين الثابت الخالص وSSR الخالص — لكن لاحظ تحذير الوثائق نفسه: “استخدام ISR على مسار مع export const prerender = true لن يكون له أي تأثير، لأن المسار يُعالج مسبقًا في وقت البناء.” ISR وprerender هما بديلان، وليسا قابلين للتكديس.

adapter-cloudflare — Workers/Pages، edge عالمي

adapter-cloudflare يستهدف Cloudflare Workers وPages — SSR على شبكة edge عالمية، غالبًا أقل TTFB لجمهور موزع جغرافيًا. القيد المهم هو بيئة التشغيل: Workers تعمل على V8 isolates، وليس Node. من الوثائق: “لا يمكنك استخدام fs في Cloudflare Workers.” بعض واجهات برمجة تطبيقات Node تعمل فقط خلف علامة التوافق nodejs_compat، وحتى ذلك الحين الدعم ليس واحدًا لواحد. إذا كنت تقرأ ملفات في وقت الطلب (خريطة إعادة توجيه، ملف بيانات، مدخلات صور OG مخصصة)، فأن هذا الكود يحتاج إلى إعادة تفكير — مغطى في قسم edge أدناه.

(المحول الأقدم adapter-cloudflare-workers مهمل؛ المشاريع الجديدة تستخدم adapter-cloudflare، الذي يتعامل مع كل من Workers وPages. إذا كنت على القديم، فالترحيل هو المسار الموصى به.)

adapter-netlify — دوال أو دوال Edge (Deno)

adapter-netlify ينشر إلى وظائف Netlify القائمة على Node افتراضيًا، أو إلى Edge Functions القائمة على Deno مع edge: true. نفس الشكل مثل Vercel: افتراضيًا serverless مع خيار edge اختياري. ملاحظة واحدة خاصة بـ SvelteKit — نماذج Netlify tتتطلب أن تكون صفحة النموذج مُسبقة التوليد حتى يتمكن Netlify من اكتشاف ترميز النموذج في وقت النشر، وهو متطلب صغير “prerender هذا المسار” يُضاف فوق اختيار المحول.

القرار، في سطر واحد لكل منها

  • موقع محتوى خالصadapter-static، قم بتوليد كل شيء مسبقًا.
  • موقع محتوى مع جيوب ديناميكيةadapter-node/-vercel/-cloudflare، prerender = true على المحتوى، false/'auto' على المسارات الديناميكية.
  • تطبيق/لوحة تحكم مع تخصيص → SSR أولاً (node أو edge)، قم بتوليد مسبقًا فقط الهيكل الثابت (التسويق، تسجيل الدخول).
  • جمهور عالمي حساس لـ TTFB → محول edge للمسارات الديناميكية، مع قبول قيود Node-API وواقع البرد البارد.

(تبويب شجرة القرار يعرض هذا كتدفق متفرع.)

استراتيجية التوليد المسبق للمواقع المختلطة

ما يفعله true / false / 'auto' فعليًا

export const prerender هو خيار صفحة لكل مسار (أو لكل تخطيط)، والقيم الثلاث ليست مجرد تشغيل/إيقاف:

  • true — قم ببناء هذا المسار إلى HTML ثابت في وقت البناء. الأهم، أنه “مستبعد من المانيفستات المستخدمة لـ SSR الديناميكي، مما يجعل خادمك (أو وظائف serverless/edge) أصغر.” بمجرد توليده مسبقًا، لا يمكن للمسار أن يتراجع إلى العرض الديناميكي — إنه ثابت، نقطة.
  • false — اعرض دائمًا عند الطلب. لا ملف ثابت.
  • 'auto' — أداة الموقع المختلط. يقوم بتوليد المسار مسبقًا ويبقيه في مانيفست الخادم الديناميكي، بحيث يمكن تقديم نفس المسار بشكل ثابت للمسارات المعروفة وعرضه من الخادم للباقي. هذا مبني بالضبط للحالة التي تصفها الوثائق: مسار مثل /blog/[slug] “حيث تريد توليد المحتوى الأحدث/الأكثر شعبية مسبقًا ولكن عرض الذيل الطويل من الخادم.”

لأن المسارات المولدة مسبقًا تقلل حزمة الخادم، موقع مُولد مسبقًا في الغالب مع عدد قليل من مسارات 'auto'/false ينشر وظيفة أصغر وأرخص وأسرع — كفاءة ربح مستقلة عن SEO.

المسارات الديناميكية تحتاج إلى دالة entries

يزحف مولّد prerender على الصفحات باتباع روابط <a> من نقاط الدخول الخاصة بك. هذا يعمل للمسارات الثابتة، لكن المسار الديناميكي مثل /blog/[slug] ليس له URL ثابت ليجده الزاحف. إذا لم يرتبط أي شيء بمعرف slug معين، لن يعرف SvelteKit بوجوده — وستواجه خطأ البناء الكلاسيكي أن المسارات “تم وضع علامة عليها كقابلة للتوليد المسبق، ولكن لم يتم توليدها مسبقًا.”

الحل هو دالة entries صريحة (أو config.kit.prerender.entries) التي تعدّد قيم المعاملات:

// src/routes/blog/[slug]/+page.server.js
export const prerender = true;

export function entries() {
  return [
    { slug: 'hello-world' },
    { slug: 'sveltekit-deployment-seo' },
  ];
}

في الممارسة العملية، تولّد هذه القائمة من CMS أو دليل المحتوى الخاص بك. بدونها، يغطي التوليد المسبق فقط المعرّفات التي يجدها زاحف الروابط بالصدفة.

نمط /blog/[slug] في الواقع

اجمع الاثنين معًا وستحصل على الإعداد المختلط القياسي: prerender = 'auto' بالإضافة إلى دالة entries التي ترجع منشوراتك الأحدث والأكثر شعبية. تلك تحصل على HTML ثابت في وقت البناء؛ أي شيء ليس في القائمة يتراجع إلى SSR عند الطلب. المنشورات الجديدة تُعرض ديناميكيًا حتى يقوم البناء التالي بتوليدها مسبقًا. إنها الوسط العملي بين “توليد جميع المنشورات الأربعين ألفًا مسبقًا في كل بناء” و “عرض كل منشور في كل طلب.”

قيود بيئة التشغيل Edge التي تؤثر على SEO

config.runtime = 'edge' لكل مسار (على Vercel)

Edge ليس مفتاحًا شاملًا أو لا شيء. على Vercel هو خيار صفحة لكل مسار:

// +page.server.js or +server.js
export const config = { runtime: 'edge' };

هذا يعني أنه يمكنك دفع المسارات عالية الحركة والقابلة للتخزين المؤقت إلى edge لـ TTFB منخفض بينما تبقى المسارات المعتمدة على Node على بيئة التشغيل القياسية serverless (Node) في نفس النشر. اخلط عمدًا.

لا fs، لا واجهات برمجة تطبيقات Node عشوائية

بيئات الحافة — Cloudflare Workers، وVercel Edge Functions، وNetlify’s Deno Edge Functions — لا توفر fs الخاصة بـ Node. توثيق Cloudflare: “You can’t use fs in Cloudflare Workers.” توثيق Vercel: “You can’t use fs in edge functions.” كلاهما يشير إلى نفس المخرجين: استخدم مساعد read من $app/server للوصول إلى الأصول المجمعة، أو “prerender the routes in question” بحيث يحدث الوصول إلى الملفات في وقت البناء بدلاً من وقت الطلب.

الحالات المرتبطة بـ SEO حيث يكون هذا مؤثرًا: توليد صور OG ديناميكية تقرأ ملف خط أو قالب، أو خرائط إعادة توجيه مبنية على ملفات، أو نقطة نهاية sitemap تقرأ محتوى من القرص. أي من هذه إما ينتقل إلى read() من $app/server أو ينتقل إلى وقت البناء/الترحيل المسبق. إنه ليس عائقًا — إنه قيد “اعرف قبل أن تختار الحافة”.

البدايات الباردة وTTFB — متى تساعد الحافة ومتى لا

وظائف الحافة لا تزال تبدأ ببرودة. وظيفة حافة باردة عند أول طلب يمكن أن تكون أبطأ من خادم Node دافئ، وأبطأ بشكل كبير من ملف مُرحَّل مسبقًا يُقدَّم من الذاكرة المؤقتة. تفوز الحافة عندما تبقى الوظيفة دافئة أو عندما تقترن بتخزين مؤقت عدواني بحيث لا تصل معظم الطلبات إلى الوظيفة على الإطلاق. إنها ليست تلقائيًا الخيار الأسرع — “النشر على الحافة” ليس مرادفًا لـ “أسرع”. لموقع محتوى، الإخراج الثابت المُرحَّل مسبقًا يتفوق على SSR الحافة في TTFB في كل مرة، لأنه لا توجد وظيفة لبدء تشغيلها.

توليد sitemap.xml و robots.txt (SvelteKit لن يفعل)

هذه هي الفجوة التي تتجاهلها معظم دروس SvelteKit وتكتشفها معظم عمليات التدقيق. SvelteKit يولد لا sitemap.xml و لا robots.txt تلقائيًا — بغض النظر عن المحول، بغض النظر عن عدد الصفحات التي تقوم بترحيلها مسبقًا. موقع ثابت بالكامل يحتوي على آلاف الصفحات المُرحَّلة مسبقًا لا يزال يُقدَّم بدون sitemap ما لم تقم ببنائه.

نمط نقطة نهاية +server.js

الطريقة الاصطلاحية لـ sitemap هي نقطة نهاية مسار تُرجع XML مع Content-Type الصحيح:

// src/routes/sitemap.xml/+server.js
export const prerender = true; // needed on adapter-static

export async function GET() {
  const urls = await getAllUrls(); // from your CMS/content
  const body = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map((u) => `  <url><loc>${u}</loc></url>`).join('\n')}
</urlset>`;

  return new Response(body, {
    headers: { 'Content-Type': 'application/xml' },
  });
}

الاستراتيجية تعتمد على المحول الخاص بك

إليك الجزء الذي يربط هذا المقال بأكمله: استراتيجية sitemap الخاصة بك هي نتيجة لاختيار المحول الخاص بك.

  • على adapter-static، تحتاج نقطة نهاية sitemap إلى export const prerender = true بحيث يتم تضمينها في الإخراج الثابت — لا يوجد خادم في وقت التشغيل لتوليدها عند الطلب. تُخبز في وقت البناء، مما يعني أنها فقط بحداثة آخر بناء لك.
  • على محول Node/serverless/edge، يمكن لنفس نقطة النهاية توليد sitemap ديناميكيًا لكل طلب من CMS أو قاعدة البيانات الخاصة بك — دائمًا حديث، بدون إعادة بناء. (على محول edge، تذكر قيد fs: اسحب عناوين URL من API أو binding، وليس من قراءة قرص.)

لذا فإن سؤال “هل يجب أن يكون sitemap الخاص بي ثابتًا أم ديناميكيًا؟” ليس قرارًا منفصلاً — إنه ينبع من المحول الذي اخترته بالفعل.

robots.txt: ملف ثابت مقابل نقطة نهاية

خياران. ضع robots.txt بسيطًا في مجلد static/ الخاص بك (يُقدَّم في /robots.txt تلقائيًا)، وهو الخيار الأبسط ومناسب لمعظم المواقع. أو قم بتوليده من نقطة نهاية src/routes/robots.txt/+server.js عندما تحتاج إلى أن يختلف حسب البيئة (منع الزواحف على staging، والسماح بها في الإنتاج، على سبيل المثال). في كلتا الحالتين، لا تحظر حزمة /_app/ أو CSS الخاصة بك — ذلك يكسر العرض للمحركات التي تقوم بالعرض.

إذا كنت قادمًا من زاوية الإطار الأوسع أو JavaScript-SEO، فإن منطق “أين ومتى يحدث العرض” هنا هو نفس المنطق الذي يحكم JavaScript SEO عمومًا، وجزء أساسيات SvelteKit في هذا القسم يغطي أوضاع العرض وأنماط البيانات الوصفية التي يبني عليها هذا المقال.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.