التحديث التدريجي للصفحات الثابتة (ISR)
يسمح لك Next.js بإنشاء أو تحديث الصفحات الثابتة بعد بناء موقعك. يتيح لك التحديث التدريجي للصفحات الثابتة (ISR) استخدام التوليد الثابت على أساس كل صفحة، دون الحاجة إلى إعادة بناء الموقع بالكامل. مع ISR، يمكنك الاحتفاظ بمزايا التوليد الثابت مع التوسع إلى ملايين الصفحات.
معلومة مفيدة: وقت التشغيل
edge
غير متوافق حاليًا مع ISR، على الرغم من أنه يمكنك الاستفادة منstale-while-revalidate
عن طريق تعيين رأسcache-control
يدويًا.
لاستخدام ISR، أضف خاصية revalidate
إلى getStaticProps
:
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
// يتم استدعاء هذه الدالة أثناء البناء على جانب الخادم.
// قد يتم استدعاؤها مرة أخرى، على دالة بدون خادم، إذا
// تم تمكين إعادة التحقق وجاء طلب جديد
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// سيحاول Next.js إعادة توليد الصفحة:
// - عند وصول طلب جديد
// - على الأكثر مرة كل 10 ثوانٍ
revalidate: 10, // بالثواني
}
}
// يتم استدعاء هذه الدالة أثناء البناء على جانب الخادم.
// قد يتم استدعاؤها مرة أخرى، على دالة بدون خادم، إذا
// لم يتم توليد المسار بعد.
export async function getStaticPaths() {
const res = await fetch('https://.../posts')
const posts = await res.json()
// الحصول على المسارات التي نريد تقديمها مسبقًا بناءً على المنشورات
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// سنقوم بتقديم هذه المسارات مسبقًا فقط أثناء البناء.
// { fallback: 'blocking' } سيقوم بتقديم الصفحات على الخادم
// عند الطلب إذا لم يكن المسار موجودًا.
return { paths, fallback: 'blocking' }
}
export default Blog
عند إجراء طلب إلى صفحة تم تقديمها مسبقًا أثناء البناء، سيتم عرض الصفحة المخزنة مؤقتًا في البداية.
- أي طلبات للصفحة بعد الطلب الأولي وقبل مرور 10 ثوانٍ يتم تخزينها أيضًا وتكون فورية.
- بعد نافذة الـ 10 ثوانٍ، سيظل الطلب التالي يعرض الصفحة المخزنة (القديمة)
- يقوم Next.js بتشغيل إعادة توليد الصفحة في الخلفية.
- بمجرد اكتمال توليد الصفحة بنجاح، سيقوم Next.js بإبطال التخزين المؤقت وعرض الصفحة المحدثة. إذا فشل التوليد في الخلفية، ستظل الصفحة القديمة كما هي دون تغيير.
عند إجراء طلب إلى مسار لم يتم توليده بعد، سيقوم Next.js بتقديم الصفحة على الخادم عند الطلب الأول. ستخدم الطلبات المستقبلية الملف الثابت من التخزين المؤقت. يحافظ ISR على Vercel على التخزين المؤقت عالميًا ويتعامل مع التراجعات.
معلومة مفيدة: تحقق مما إذا كان مزود البيانات الأعلى لديك قد مكّن التخزين المؤقت افتراضيًا. قد تحتاج إلى تعطيله (مثل
useCdn: false
)، وإلا لن تتمكن إعادة التحقق من سحب بيانات جديدة لتحديث تخزين ISR المؤقت. يمكن أن يحدث التخزين المؤقت في CDN (لنقطة نهاية يتم طلبها) عندما تُرجع رأسCache-Control
.
إعادة التحقق عند الطلب
إذا قمت بتعيين وقت revalidate
بقيمة 60
، فسيشاهد جميع الزوار نفس النسخة المولدة من موقعك لمدة دقيقة واحدة. الطريقة الوحيدة لإبطال التخزين المؤقت هي من خلال زيارة شخص ما لتلك الصفحة بعد مرور الدقيقة.
بدءًا من الإصدار v12.2.0
، يدعم Next.js التحديث التدريجي للصفحات الثابتة عند الطلب لإبطال التخزين المؤقت لـ Next.js يدويًا لصفحة محددة. وهذا يسهل تحديث موقعك عندما:
- يتم إنشاء محتوى جديد أو تحديثه من نظام إدارة المحتوى الخاص بك
- تتغير بيانات التجارة الإلكترونية (السعر، الوصف، الفئة، التقييمات، إلخ.)
داخل getStaticProps
، لا تحتاج إلى تحديد revalidate
لاستخدام إعادة التحقق عند الطلب. إذا تم حذف revalidate
، فسيستخدم Next.js القيمة الافتراضية false
(لا إعادة تحقق) وسيعيد التحقق من الصفحة عند الطلب فقط عند استدعاء revalidate()
.
معلومة مفيدة: لن يتم تنفيذ البرمجيات الوسيطة لطلبات ISR عند الطلب. بدلاً من ذلك، استدعِ
revalidate()
على المسار الدقيق الذي تريد إعادة التحقق منه. على سبيل المثال، إذا كان لديكpages/blog/[slug].js
وإعادة توجيه من/post-1
->/blog/post-1
، فستحتاج إلى استدعاءres.revalidate('/blog/post-1')
.
استخدام إعادة التحقق عند الطلب
أولاً، أنشئ رمزًا سريًا يعرفه فقط تطبيق Next.js الخاص بك. سيتم استخدام هذا الرمز السري لمنع الوصول غير المصرح به إلى مسار API إعادة التحقق. يمكنك الوصول إلى المسار (إما يدويًا أو عبر webhook) باستخدام هيكل URL التالي:
https://<your-site.com>/api/revalidate?secret=<token>
بعد ذلك، أضف الرمز السري كـ متغير بيئة إلى تطبيقك. أخيرًا، أنشئ مسار API إعادة التحقق:
export default async function handler(req, res) {
// تحقق من الرمز السري للتأكد من أن هذا طلب صالح
if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
return res.status(401).json({ message: 'Invalid token' })
}
try {
// يجب أن يكون هذا المسار الفعلي وليس مسارًا معاد توجيهه
// على سبيل المثال، بالنسبة لـ "/blog/[slug]" يجب أن يكون "/blog/post-1"
await res.revalidate('/path-to-revalidate')
return res.json({ revalidated: true })
} catch (err) {
// إذا كان هناك خطأ، سيستمر Next.js
// في عرض آخر صفحة تم توليدها بنجاح
return res.status(500).send('Error revalidating')
}
}
شاهد العرض التوضيحي لدينا لرؤية إعادة التحقق عند الطلب في العمل وتقديم ملاحظاتك.
اختبار ISR عند الطلب أثناء التطوير
عند التشغيل محليًا باستخدام next dev
، يتم استدعاء getStaticProps
عند كل طلب. للتحقق من صحة تكوين ISR عند الطلب، ستحتاج إلى إنشاء بناء إنتاج وبدء خادم الإنتاج:
$ next build
$ next start
ثم، يمكنك التأكد من أن الصفحات الثابتة قد تم إعادة التحقق منها بنجاح.
معالجة الأخطاء وإعادة التحقق
إذا حدث خطأ داخل getStaticProps
أثناء معالجة التوليد في الخلفية، أو إذا قمت برمي خطأ يدويًا، فستستمر الصفحة الأخيرة التي تم توليدها بنجاح في العرض. في الطلب التالي، سيعيد Next.js محاولة استدعاء getStaticProps
.
export async function getStaticProps() {
// إذا ألقى هذا الطلب خطأ غير معالج، فلن يقوم Next.js
// بإبطال الصفحة المعروضة حاليًا وسيتم
// إعادة محاولة getStaticProps في الطلب التالي.
const res = await fetch('https://.../posts')
const posts = await res.json()
if (!res.ok) {
// إذا كان هناك خطأ في الخادم، فقد ترغب في
// إلقاء خطأ بدلاً من الإرجاع حتى لا يتم تحديث التخزين المؤقت
// حتى الطلب الناجح التالي.
throw new Error(`Failed to fetch posts, received status ${res.status}`)
}
// إذا كان الطلب ناجحًا، قم بإرجاع المنشورات
// وإعادة التحقق كل 10 ثوانٍ.
return {
props: {
posts,
},
revalidate: 10,
}
}
استضافة ISR ذاتيًا
يعمل التحديث التدريجي للصفحات الثابتة (ISR) على مواقع Next.js المخصصة للاستضافة الذاتية مباشرة عند استخدام next start
.
تعلم المزيد عن استضافة Next.js ذاتيًا.
سجل الإصدارات
الإصدار | التغييرات |
---|---|
v14.1.0 | أصبح cacheHandler المخصص مستقرًا. |
v12.2.0 | أصبح ISR عند الطلب مستقرًا |
v12.1.0 | تمت إضافة ISR عند الطلب (بيتا). |
v12.0.0 | تمت إضافة التراجع المعتمد على الروبوتات لـ ISR. |
v9.5.0 | تمت إضافة مسار الأساس. |
getServerSideProps
جلب البيانات في كل طلب باستخدام `getServerSideProps`.
جلب البيانات من جانب العميل (Client-side Fetching)
تعرف على جلب البيانات من جانب العميل، وكيفية استخدام SWR، وهي مكتبة خطافات React لجلب البيانات التي تعالج التخزين المؤقت، إعادة التحقق، تتبع التركيز، إعادة الجلب على فترات والمزيد.