getStaticProps

إذا قمت بتصدير دالة تسمى getStaticProps (توليد موقع ثابت) من صفحة، فإن Next.js سيقوم بتحضير عرض هذه الصفحة مسبقًا في وقت البناء باستخدام الخصائص (props) التي تُرجعها getStaticProps.

import type { InferGetStaticPropsType, GetStaticProps } from 'next'

type Repo = {
  name: string
  stargazers_count: number
}

export const getStaticProps = (async (context) => {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}) satisfies GetStaticProps<{
  repo: Repo
}>

export default function Page({
  repo,
}: InferGetStaticPropsType<typeof getStaticProps>) {
  return repo.stargazers_count
}
export async function getStaticProps() {
  const res = await fetch('https://api.github.com/repos/vercel/next.js')
  const repo = await res.json()
  return { props: { repo } }
}

export default function Page({ repo }) {
  return repo.stargazers_count
}

لاحظ أنه بغض النظر عن نوع العرض، سيتم تمرير أي props إلى مكون الصفحة ويمكن رؤيتها على جانب العميل في HTML الأولي. هذا للسماح للصفحة بأن يتم ترطيبها (hydrate) بشكل صحيح. تأكد من عدم تمرير أي معلومات حساسة لا يجب أن تكون متاحة على العميل في props.

مرجع واجهة برمجة التطبيقات getStaticProps يغطي جميع المعاملات والخصائص التي يمكن استخدامها مع getStaticProps.

متى يجب علي استخدام getStaticProps؟

يجب عليك استخدام getStaticProps إذا:

  • البيانات المطلوبة لعرض الصفحة متوفرة في وقت البناء قبل طلب المستخدم
  • البيانات تأتي من نظام إدارة محتوى بدون واجهة (headless CMS)
  • يجب تحضير عرض الصفحة مسبقًا (لتحسين محركات البحث SEO) وأن تكون سريعة جدًا — getStaticProps يولد ملفات HTML و JSON، وكلاهما يمكن تخزينه مؤقتًا بواسطة CDN لتحسين الأداء
  • يمكن تخزين البيانات مؤقتًا بشكل عام (غير خاص بمستخدم). يمكن تجاوز هذا الشرط في حالات محددة باستخدام Middleware لإعادة كتابة المسار.

متى يتم تشغيل getStaticProps

getStaticProps يعمل دائمًا على الخادم ولا يعمل أبدًا على العميل. يمكنك التحقق من إزالة الكود الموجود داخل getStaticProps من حزمة جانب العميل باستخدام هذه الأداة.

  • getStaticProps يعمل دائمًا أثناء next build
  • getStaticProps يعمل في الخلفية عند استخدام fallback: true
  • getStaticProps يتم استدعاؤه قبل العرض الأولي عند استخدام fallback: blocking
  • getStaticProps يعمل في الخلفية عند استخدام revalidate
  • getStaticProps يعمل عند الطلب في الخلفية عند استخدام revalidate()

عند استخدامه مع التجديد الثابت التدريجي (Incremental Static Regeneration)، سيعمل getStaticProps في الخلفية أثناء إعادة التحقق من الصفحة القديمة، وسيتم تقديم الصفحة الجديدة للمتصفح.

getStaticProps لا يمكنه الوصول إلى الطلب الوارد (مثل معلمات الاستعلام أو رؤوس HTTP) لأنه يولد HTML ثابت. إذا كنت بحاجة إلى الوصول إلى الطلب لصفحتك، ففكر في استخدام Middleware بالإضافة إلى getStaticProps.

استخدام getStaticProps لجلب البيانات من نظام إدارة محتوى

يوضح المثال التالي كيف يمكنك جلب قائمة من منشورات المدونة من نظام إدارة محتوى.

// سيتم ملء المنشورات في وقت البناء بواسطة getStaticProps()
export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

// هذه الدالة يتم استدعاؤها في وقت البناء على جانب الخادم.
// لن يتم استدعاؤها على جانب العميل، لذا يمكنك حتى إجراء
// استعلامات قاعدة بيانات مباشرة.
export async function getStaticProps() {
  // استدعاء نقطة نهاية API خارجية للحصول على المنشورات.
  // يمكنك استخدام أي مكتبة لجلب البيانات
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // بإرجاع { props: { posts } }، سيستقبل مكون المدونة
  // `posts` كخاصية في وقت البناء
  return {
    props: {
      posts,
    },
  }
}
// سيتم ملء المنشورات في وقت البناء بواسطة getStaticProps()
export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

// هذه الدالة يتم استدعاؤها في وقت البناء على جانب الخادم.
// لن يتم استدعاؤها على جانب العميل، لذا يمكنك حتى إجراء
// استعلامات قاعدة بيانات مباشرة.
export async function getStaticProps() {
  // استدعاء نقطة نهاية API خارجية للحصول على المنشورات.
  // يمكنك استخدام أي مكتبة لجلب البيانات
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // بإرجاع { props: { posts } }، سيستقبل مكون المدونة
  // `posts` كخاصية في وقت البناء
  return {
    props: {
      posts,
    },
  }
}

مرجع واجهة برمجة التطبيقات getStaticProps يغطي جميع المعاملات والخصائص التي يمكن استخدامها مع getStaticProps.

كتابة كود جانب الخادم مباشرة

بما أن getStaticProps يعمل فقط على جانب الخادم، فلن يعمل أبدًا على جانب العميل. لن يتم تضمينه حتى في حزمة JS للمتصفح، لذا يمكنك كتابة استعلامات قاعدة بيانات مباشرة دون إرسالها إلى المتصفحات.

هذا يعني أنه بدلاً من جلب مسار API من getStaticProps (الذي يقوم نفسه بجلب البيانات من مصدر خارجي)، يمكنك كتابة كود جانب الخادم مباشرة في getStaticProps.

خذ المثال التالي. يتم استخدام مسار API لجلب بعض البيانات من نظام إدارة محتوى. ثم يتم استدعاء هذا المسار مباشرة من getStaticProps. هذا ينتج عنه استدعاء إضافي، مما يقلل الأداء. بدلاً من ذلك، يمكن مشاركة منطق جلب البيانات من نظام إدارة المحتوى باستخدام دليل lib/. ثم يمكن مشاركته مع getStaticProps.

lib/load-posts.js
// الدالة التالية يتم مشاركتها
// مع getStaticProps ومسارات API
// من دليل `lib/`
export async function loadPosts() {
  // استدعاء نقطة نهاية API خارجية للحصول على المنشورات
  const res = await fetch('https://.../posts/')
  const data = await res.json()

  return data
}
pages/blog.js
// pages/blog.js
import { loadPosts } from '../lib/load-posts'

// هذه الدالة تعمل فقط على جانب الخادم
export async function getStaticProps() {
  // بدلاً من جلب مسار `/api` الخاص بك، يمكنك استدعاء نفس
  // الدالة مباشرة في `getStaticProps`
  const posts = await loadPosts()

  // الخصائص التي يتم إرجاعها سيتم تمريرها إلى مكون الصفحة
  return { props: { posts } }
}

بدلاً من ذلك، إذا كنت لا تستخدم مسارات API لجلب البيانات، فيمكن استخدام واجهة fetch() مباشرة في getStaticProps لجلب البيانات.

للتحقق مما يتم إزالته من Next.js من حزمة جانب العميل، يمكنك استخدام أداة next-code-elimination.

توليد HTML و JSON بشكل ثابت

عند تحضير عرض صفحة تحتوي على getStaticProps مسبقًا في وقت البناء، بالإضافة إلى ملف HTML للصفحة، يقوم Next.js بإنشاء ملف JSON يحتوي على نتيجة تشغيل getStaticProps.

سيتم استخدام ملف JSON هذا في التوجيه من جانب العميل عبر next/link أو next/router. عند الانتقال إلى صفحة تم تحضير عرضها مسبقًا باستخدام getStaticProps، يقوم Next.js بجلب ملف JSON هذا (المحسوب مسبقًا في وقت البناء) واستخدامه كخصائص لمكون الصفحة. هذا يعني أن انتقالات الصفحة من جانب العميل لن تستدعي getStaticProps حيث يتم استخدام ملف JSON المصدر فقط.

عند استخدام التجديد الثابت التدريجي، سيتم تنفيذ getStaticProps في الخلفية لإنشاء JSON المطلوب للتنقل من جانب العميل. قد ترى هذا في شكل طلبات متعددة لنفس الصفحة، ولكن هذا مقصود وليس له تأثير على أداء المستخدم النهائي.

أين يمكنني استخدام getStaticProps

يمكن تصدير getStaticProps فقط من صفحة. لا يمكنك تصديره من ملفات غير صفحات، أو من _app، أو _document، أو _error.

أحد أسباب هذا القيد هو أن React يحتاج إلى جميع البيانات المطلوبة قبل عرض الصفحة.

أيضًا، يجب عليك تصدير getStaticProps كدالة مستقلة — لن تعمل إذا أضفت getStaticProps كخاصية لمكون الصفحة.

ملاحظة جيدة: إذا قمت بإنشاء تطبيق مخصص، فتأكد من تمرير pageProps إلى مكون الصفحة كما هو موضح في المستند المرفق، وإلا ستكون الخصائص فارغة.

التشغيل في كل طلب في وضع التطوير

في وضع التطوير (next dev)، سيتم استدعاء getStaticProps في كل طلب.

وضع المعاينة

يمكنك تجاوز التوليد الثابت مؤقتًا وعرض الصفحة في وقت الطلب بدلاً من وقت البناء باستخدام وضع المعاينة. على سبيل المثال، قد تستخدم نظام إدارة محتوى بدون واجهة وتريد معاينة المسودات قبل نشرها.