Пошук уроків, статей та іншого контенту
Застосуєте параметр revalidate для налаштування повторної валідації даних і маршрутів.
revalidaterevalidate визначає, як часто Next.js має повторно перевіряти та оновлювати закешовані дані або згенеровану сторінку.
Значення вказується в секундах:
revalidate = 60Це означає:
результат можна використовувати протягом 60 секунд;
після завершення цього часу Next.js вважає кеш застарілим;
під час наступного запиту дані можуть бути повторно отримані, а сторінка — згенерована заново.
Такий підхід називається Incremental Static Regeneration, або ISR. Він дає змогу поєднати переваги статичних сторінок і актуальних даних.
fetchУ компоненті або серверній функції можна вказати revalidate у властивості next:
// app/products/page.tsx
type Product = {
id: number
title: string
price: number
}
async function getProducts(): Promise<Product[]> {
const response = await fetch('https://dummyjson.com/products', {
next: {
revalidate: 60,
},
})
if (!response.ok) {
throw new Error('Не вдалося отримати список товарів')
}
const data: { products: Product[] } = await response.json()
return data.products
}
export default async function ProductsPage() {
const products = await getProducts()
return (
<main>
<h1>Товари</h1>
<ul>
{products.map((product) => (
<li key={product.id}>
{product.title} — ${product.price}
</li>
))}
</ul>
</main>
)
}У цьому прикладі:
Next.js кешує результат запиту fetch.
Протягом 60 секунд використовується кешований результат.
Після завершення 60 секунд Next.js повторно перевіряє дані.
Сторінка отримує оновлений список товарів після успішної повторної валідації.
Значення revalidate для fetch застосовується саме до результату цього запиту.
Для сторінки або іншого сегмента маршруту можна експортувати змінну revalidate:
// app/news/page.tsx
export const revalidate = 300
type NewsArticle = {
id: number
title: string
}
async function getNews(): Promise<NewsArticle[]> {
const response = await fetch('https://dummyjson.com/posts')
if (!response.ok) {
throw new Error('Не вдалося отримати новини')
}
const data: { posts: NewsArticle[] } = await response.json()
return data.posts
}
export default async function NewsPage() {
const articles = await getNews()
return (
<main>
<h1>Новини</h1>
{articles.map((article) => (
<article key={article.id}>
<h2>{article.title}</h2>
</article>
))}
</main>
)
}export const revalidate = 300 задає період повторної валідації для цього маршруту — 5 хвилин.
Такий варіант зручний, коли потрібно налаштувати період оновлення всієї сторінки, а не окремого запиту.
revalidate у fetchfetch(url, {
next: {
revalidate: 60,
},
})Налаштовує кешування конкретного запиту.
Це корисно, коли на одній сторінці є кілька джерел даних із різною частотою оновлення:
async function getProducts() {
const response = await fetch('https://api.example.com/products', {
next: {
revalidate: 60,
},
})
return response.json()
}
async function getCategories() {
const response = await fetch('https://api.example.com/categories', {
next: {
revalidate: 3600,
},
})
return response.json()
}У цьому прикладі:
товари оновлюються приблизно кожні 60 секунд;
категорії — приблизно кожну годину.
export const revalidateexport const revalidate = 300Налаштовує період повторної валідації маршруту.
Це корисно, коли всі дані сторінки повинні оновлюватися з однаковою частотою.
Якщо для одного маршруту вказано кілька значень revalidate, ефективний період може визначатися найменшим значенням.
Наприклад:
export const revalidate = 300
async function getProducts() {
const response = await fetch('https://api.example.com/products', {
next: {
revalidate: 60,
},
})
return response.json()
}У цьому випадку один запит потрібно оновлювати кожні 60 секунд, тому сторінка не може вважатися повністю актуальною рідше, ніж цей запит.
Практично:
revalidate маршруту — загальне правило для сторінки;
fetch(..., { next: { revalidate } }) — точніше правило для конкретних даних;
значення для конкретного запиту може бути меншим за значення маршруту.
false і 0Для конфігурації маршруту можна використовувати спеціальні значення:
export const revalidate = falsefalse означає, що періодичну повторну валідацію не задано. Для статичних даних вони можуть залишатися кешованими необмежено довго, доки кеш не буде очищено або оновлено іншим способом.
export const revalidate = 00 вимикає статичне кешування для маршруту та змушує його динамічно генеруватися під час запиту.
У більшості випадків для регулярного оновлення даних краще використовувати додатне значення в секундах:
export const revalidate = 60revalidate можна використовувати не лише для сторінок, а й для Route Handler:
// app/api/products/route.ts
export const revalidate = 60
export async function GET() {
const response = await fetch('https://dummyjson.com/products')
if (!response.ok) {
return Response.json(
{ error: 'Не вдалося отримати товари' },
{ status: 500 },
)
}
const data = await response.json()
return Response.json(data)
}У цьому прикладі відповідь для GET /api/products може кешуватися та повторно перевірятися кожні 60 секунд.
Такий підхід підходить для публічних API-ендпоїнтів, де дані не повинні оновлюватися після кожного запиту.
revalidaterevalidate добре підходить для даних, які:
змінюються періодично;
не потребують оновлення в реальному часі;
однакові для багатьох користувачів;
можуть бути трохи застарілими протягом короткого часу.
Приклади:
каталог товарів;
список новин;
статті блогу;
публічні категорії;
курси валют із періодичним оновленням;
дані з зовнішнього CMS.
Для приватних даних користувача або інформації, яка повинна бути актуальною на момент запиту, періодичне кешування може бути непридатним.
export const revalidate = 60Це 60 секунд, а не 60 мілісекунд.
Приклади:
export const revalidate = 30 // 30 секунд
export const revalidate = 300 // 5 хвилин
export const revalidate = 3600 // 1 годинаПісля завершення заданого періоду Next.js не обов’язково перегенерує сторінку ще до першого наступного запиту.
Можливий такий сценарій:
Сторінка була згенерована о 12:00.
revalidate дорівнює 60 секунд.
О 12:01 кеш вважається застарілим.
Наступний запит запускає повторне отримання даних.
Після завершення процесу нова версія сторінки зберігається в кеші.
Тому revalidate слід сприймати як мінімальний інтервал між оновленнями, а не як точний розклад запуску.
Використання таких механізмів, як cookies або заголовки запиту, робить сторінку залежною від конкретного запиту. Для таких сторінок статична повторна генерація може бути непридатною.
Параметр revalidate найкраще працює для сторінок із публічними даними, які однакові для всіх відвідувачів.
revalidate як опцію звичайного fetchНеправильно:
fetch(url, {
revalidate: 60,
})Правильно:
fetch(url, {
next: {
revalidate: 60,
},
})Для fetch параметр має бути вкладений у властивість next.
Неправильно:
export const revalidate = 60000Це означає 60 000 секунд, а не 60 секунд.
Правильно:
export const revalidate = 60Неправильно вважати, що:
export const revalidate = 60означає виконання запиту кожні 60 секунд для кожного користувача.
Next.js використовує кеш маршруту або даних. Повторна валідація відбувається для кешованого результату, а не окремо для кожного відвідувача.
Якщо дані змінюються щохвилини, але вказано:
export const revalidate = 86400сторінка може показувати неактуальну інформацію протягом доби.
Період потрібно вибирати відповідно до допустимої застарілості даних.
revalidate механізмом реального часуrevalidate не призначений для миттєвої синхронізації даних. Якщо інформація повинна оновлюватися одразу після зміни, періодична повторна валідація може бути недостатньою.
Орієнтовно можна використовувати такі значення:
// Дані змінюються часто
export const revalidate = 30
// Звичайний список або каталог
export const revalidate = 300
// Рідко змінювані категорії
export const revalidate = 3600
// Майже незмінний контент
export const revalidate = 86400Це не фіксовані правила. Значення залежить від того, наскільки застарілими можуть бути дані та яке навантаження створює їх повторне отримання.
revalidate задається в секундах.
fetch(..., { next: { revalidate: 60 } }) налаштовує повторну валідацію конкретного запиту.
export const revalidate = 60 налаштовує період повторної валідації маршруту.
Кешовані дані не обов’язково оновлюються точно в момент завершення інтервалу.
Для різних джерел даних можна встановити різні періоди.
revalidate підходить для публічних даних, які змінюються періодично.
Значення потрібно вказувати в секундах, а не в мілісекундах.