getStaticProps

إذا قمت بتصدير دالة تسمى getStaticProps (إنشاء موقع ثابت) من صفحة، فإن Next.js سيقوم بتحضير عرض هذه الصفحة مسبقًا أثناء البناء باستخدام الخصائص التي تُرجعها 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 إذا:

  • كانت البيانات المطلوبة لعرض الصفحة متوفرة في وقت البناء قبل طلب المستخدم
  • تأتي البيانات من نظام إدارة محتوى (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 لجلب البيانات من نظام إدارة محتوى (CMS)

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

// سيتم ملء المنشورات في وقت البناء بواسطة 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 } }، سيستقبل مكون Blog
  // `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 } }، سيستقبل مكون Blog
  // `posts` كخاصية في وقت البناء
  return {
    props: {
      posts,
    },
  }
}

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

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

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

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

خذ المثال التالي. يتم استخدام مسار API لجلب بعض البيانات من نظام إدارة محتوى. ثم يتم استدعاء مسار 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 في كل طلب.

وضع المعاينة

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