Инкрементальная статическая регенерация (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>
)
}
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every 10 seconds
revalidate: 10, // In seconds
}
}
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// the path has not been generated.
export async function getStaticPaths() {
const res = await fetch('https://.../posts')
const posts = await res.json()
// Get the paths we want to pre-render based on posts
const paths = posts.map((post) => ({
params: { id: post.id },
}))
// We'll pre-render only these paths at build time.
// { fallback: 'blocking' } will server-render pages
// on-demand if the path doesn't exist.
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 для конкретной страницы. Это упрощает обновление сайта, когда:
- Содержимое вашего headless CMS создается или обновляется
- Изменяется метаданные электронной коммерции (цена, описание, категория, отзывы и т. д.)
Внутри 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 ревалидации. Вы можете получить доступ к маршруту (вручную или с помощью веб-хука) с помощью следующей структуры URL:
https://<your-site.com>/api/revalidate?secret=<token>
Далее, добавьте секрет в качестве Переменной окружения в ваше приложение. Наконец, создайте маршрут API ревалидации:
export default async function handler(req, res) {
// Check for secret to confirm this is a valid request
if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
return res.status(401).json({ message: 'Invalid token' })
}
try {
// this should be the actual path not a rewritten path
// e.g. for "/blog/[slug]" this should be "/blog/post-1"
await res.revalidate('/path-to-revalidate')
return res.json({ revalidated: true })
} catch (err) {
// If there was an error, Next.js will continue
// to show the last successfully generated page
return res.status(500).send('Error revalidating')
}
}Посмотрите нашу демонстрацию, чтобы увидеть ревалидацию по запросу в действии и оставить отзыв.
Тестирование ISR по запросу во время разработки
При выполнении локально с next dev, getStaticProps вызывается при каждом запросе. Чтобы убедиться, что ваша конфигурация ISR по запросу правильная, вам нужно создать сборку для производства и запустить сервер для производства:
$ next build $ next start
Затем вы можете подтвердить, что статические страницы успешно перепроверены.
Обработка ошибок и ревалидация
Если при обработке фоновой регенерации внутри getStaticProps возникает ошибка или вы вручную вызываете ошибку, последняя успешно сгенерированная страница будет продолжаться. При следующем запросе Next.js повторно вызовет getStaticProps.
export async function getStaticProps() {
// If this request throws an uncaught error, Next.js will
// not invalidate the currently shown page and
// retry getStaticProps on the next request.
const res = await fetch('https://.../posts')
const posts = await res.json()
if (!res.ok) {
// If there is a server error, you might want to
// throw an error instead of returning so that the cache is not updated
// until the next successful request.
throw new Error(`Failed to fetch posts, received status ${res.status}`)
}
// If the request was successful, return the posts
// and revalidate every 10 seconds.
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 |
Добавлен базовый путь. |
© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration