getStaticProps

تصدير دالة تسمى getStaticProps سيقوم بعرض الصفحة مسبقًا أثناء البناء باستخدام الخصائص (props) التي تُرجعها الدالة:

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
}

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

معامل Context

معامل context هو كائن يحتوي على المفاتيح التالية:

الاسمالوصف
paramsيحتوي على معلمات المسار للصفحات التي تستخدم المسارات الديناميكية. على سبيل المثال، إذا كان اسم الصفحة هو [id].js، فإن params سيبدو مثل { id: ... }. يجب استخدام هذا مع getStaticPaths، والذي سنشرحه لاحقًا.
preview(مهمل لصالح draftMode) preview يكون true إذا كانت الصفحة في وضع المعاينة و false بخلاف ذلك.
previewData(مهمل لصالح draftMode) بيانات المعاينة المحددة بواسطة setPreviewData.
draftModedraftMode يكون true إذا كانت الصفحة في وضع المسودة و false بخلاف ذلك.
localeيحتوي على اللغة النشطة (إذا كانت ممكّنة).
localesيحتوي على جميع اللغات المدعومة (إذا كانت ممكّنة).
defaultLocaleيحتوي على اللغة الافتراضية المكونة (إذا كانت ممكّنة).
revalidateReasonيقدم سببًا لاستدعاء الدالة. يمكن أن يكون أحد: "build" (يعمل أثناء البناء)، "stale" (انتهت فترة إعادة التحقق، أو يعمل في وضع التطوير)، "on-demand" (يتم تشغيله عبر إعادة التحقق عند الطلب)

قيم إرجاع getStaticProps

يجب أن تُرجع دالة getStaticProps كائنًا يحتوي إما على props، redirect، أو notFound متبوعًا بخاصية اختيارية revalidate.

props

كائن props هو زوج مفتاح-قيمة، حيث يتم استقبال كل قيمة بواسطة مكون الصفحة. يجب أن يكون كائنًا قابلاً للتسلسل بحيث يمكن تسلسل أي خصائص تمريرها باستخدام JSON.stringify.

export async function getStaticProps(context) {
  return {
    props: { message: `Next.js is awesome` }, // سيتم تمريرها إلى مكون الصفحة كخصائص
  }
}

revalidate

خاصية revalidate هي المقدار بالثواني الذي بعدها يمكن أن يحدث إعادة إنشاء للصفحة (الافتراضي هو false أو بدون إعادة تحقق).

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

  return {
    props: {
      posts,
    },
    // ستحاول Next.js إعادة إنشاء الصفحة:
    // - عند وصول طلب
    // - على الأكثر مرة كل 10 ثوانٍ
    revalidate: 10, // بالثواني
  }
}

تعلم المزيد عن التجديد الثابت التدريجي.

يمكن تحديد حالة التخزين المؤقت لصفحة تستخدم ISR عن طريق قراءة قيمة رأس الاستجابة x-nextjs-cache. القيم الممكنة هي التالية:

  • MISS - المسار غير موجود في التخزين المؤقت (يحدث مرة واحدة على الأكثر، في الزيارة الأولى)
  • STALE - المسار موجود في التخزين المؤقت ولكن انتهت فترة إعادة التحقق لذا سيتم تحديثه في الخلفية
  • HIT - المسار موجود في التخزين المؤقت ولم تنته فترة إعادة التحقق

notFound

القيمة المنطقية notFound تسمح للصفحة بإرجاع حالة 404 وصفحة 404. مع notFound: true، سترجع الصفحة 404 حتى لو كان هناك صفحة تم إنشاؤها بنجاح من قبل. هذا مخصص لدعم حالات الاستخدام مثل المحتوى الذي ينشئه المستخدم ويتم إزالته من قبل المؤلف. ملاحظة، notFound يتبع نفس سلوك revalidate الموضح هنا.

export async function getStaticProps(context) {
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  if (!data) {
    return {
      notFound: true,
    }
  }

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

جيد للمعرفة: notFound غير مطلوب لوضع fallback: false حيث سيتم فقط عرض المسارات التي تم إرجاعها من getStaticPaths مسبقًا.

redirect

كائن redirect يسمح بإعادة التوجيه إلى موارد داخلية أو خارجية. يجب أن يتطابق مع الشكل { destination: string, permanent: boolean }.

في بعض الحالات النادرة، قد تحتاج إلى تعيين رمز حالة مخصص لعملاء HTTP القديمة لإعادة التوجيه بشكل صحيح. في هذه الحالات، يمكنك استخدام خاصية statusCode بدلاً من خاصية permanent، ولكن ليس كلاهما. يمكنك أيضًا تعيين basePath: false مشابهًا لإعادة التوجيه في next.config.js.

export async function getStaticProps(context) {
  const res = await fetch(`https://...`)
  const data = await res.json()

  if (!data) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
        // statusCode: 301
      },
    }
  }

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

إذا كانت عمليات إعادة التوجيه معروفة أثناء البناء، فيجب إضافتها في next.config.js بدلاً من ذلك.

قراءة الملفات: استخدم process.cwd()

يمكن قراءة الملفات مباشرة من نظام الملفات في getStaticProps.

للقيام بذلك، يجب الحصول على المسار الكامل للملف.

نظرًا لأن Next.js يقوم بتجميع الكود الخاص بك في دليل منفصل، لا يمكنك استخدام __dirname حيث أن المسار الذي سيعود به سيكون مختلفًا عن مسار الصفحات.

بدلاً من ذلك، يمكنك استخدام process.cwd() الذي يعطيك الدليل حيث يتم تنفيذ Next.js.

import { promises as fs } from 'fs'
import path from 'path'

// سيتم ملء posts أثناء البناء بواسطة getStaticProps()
function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>
          <h3>{post.filename}</h3>
          <p>{post.content}</p>
        </li>
      ))}
    </ul>
  )
}

// يتم استدعاء هذه الدالة أثناء البناء على جانب الخادم.
// لن يتم استدعاؤها على جانب العميل، لذا يمكنك حتى
// إجراء استعلامات قاعدة بيانات مباشرة.
export async function getStaticProps() {
  const postsDirectory = path.join(process.cwd(), 'posts')
  const filenames = await fs.readdir(postsDirectory)

  const posts = filenames.map(async (filename) => {
    const filePath = path.join(postsDirectory, filename)
    const fileContents = await fs.readFile(filePath, 'utf8')

    // بشكل عام ستقوم بتحليل/تحويل المحتويات
    // على سبيل المثال يمكنك تحويل Markdown إلى HTML هنا

    return {
      filename,
      content: fileContents,
    }
  })
  // بإرجاع { props: { posts } }، سيستقبل مكون Blog
  // `posts` كخاصية أثناء البناء
  return {
    props: {
      posts: await Promise.all(posts),
    },
  }
}

export default Blog

سجل الإصدارات

الإصدارالتغييرات
v13.4.0App Router أصبح الآن مستقرًا مع جلب بيانات مبسط
v12.2.0التجديد الثابت التدريجي عند الطلب أصبح مستقرًا.
v12.1.0تمت إضافة التجديد الثابت التدريجي عند الطلب (بيتا).
v10.0.0تمت إضافة خيارات locale، locales، defaultLocale، و notFound.
v10.0.0تمت إضافة خيار الإرجاع fallback: 'blocking'.
v9.5.0أصبح التجديد الثابت التدريجي مستقرًا
v9.3.0تم تقديم getStaticProps.