Пошук уроків, статей та іншого контенту
Оновлюватимете кеш конкретного маршруту за допомогою функції revalidatePath.
revalidatePathrevalidatePath — функція з next/cache, яка позначає кеш конкретного маршруту як неактуальний:
import { revalidatePath } from 'next/cache'Вона корисна після змінювання даних на сервері. Наприклад, користувач створив товар, а сторінка зі списком товарів уже була збережена в кеші. Після виклику revalidatePath('/products') Next.js повторно сформує цю сторінку з актуальними даними.
Функція працює в:
Server Actions;
Route Handlers.
revalidatePath(path)Наприклад:
revalidatePath('/products')Перший аргумент — шлях маршруту, кеш якого потрібно оновити.
Для динамічного маршруту можна вказати тип:
revalidatePath('/products/[id]', 'page')Другий аргумент може мати одне з двох значень:
'page' — оновити конкретну сторінку або сторінки, що відповідають маршруту;
'layout' — оновити кеш layout і вкладених маршрутів.
Розглянемо сторінку зі списком товарів. Після додавання товару потрібно оновити кеш маршруту /products.
Для прикладу використаємо масив у пам’яті. У реальному застосунку замість нього зазвичай буде база даних.
// app/lib/products.js
let products = [
{ id: 1, name: 'Keyboard' },
{ id: 2, name: 'Mouse' },
]
export function getProducts() {
return products
}
export function addProduct(name) {
const product = {
id: Date.now(),
name,
}
products = [...products, product]
return product
}Створимо Server Action, яка додає товар і скидає кеш сторінки /products.
// app/products/actions.js
'use server'
import { revalidatePath } from 'next/cache'
import { addProduct } from '../lib/products'
export async function createProduct(formData) {
const name = formData.get('name')?.toString().trim()
if (!name) {
throw new Error('Назва товару є обов’язковою')
}
addProduct(name)
// Після додавання товару сторінка має отримати актуальні дані
revalidatePath('/products')
}Директива 'use server' повідомляє Next.js, що функція виконується на сервері. Тому в ній можна змінювати дані та викликати revalidatePath.
// app/products/page.js
import { getProducts } from '../lib/products'
import { createProduct } from './actions'
export const revalidate = 3600
export default function ProductsPage() {
const products = getProducts()
return (
<main>
<h1>Товари</h1>
<form action={createProduct}>
<label>
Назва товару
<input name="name" type="text" required />
</label>
<button type="submit">Додати товар</button>
</form>
<ul>
{products.map((product) => (
<li key={product.id}>{product.name}</li>
))}
</ul>
</main>
)
}Після надсилання форми відбувається така послідовність:
Викликається createProduct.
Новий товар додається до джерела даних.
Викликається revalidatePath('/products').
Кеш маршруту /products позначається як неактуальний.
Під час наступного рендерингу сторінка читає актуальний список товарів.
У Server Action Next.js також оновлює стан поточної сторінки після її завершення, тому користувач побачить оновлений список без ручного перезавантаження браузера.
revalidatePath разом із кешованими данимиrevalidatePath має сенс тоді, коли маршрут або дані справді кешуються.
Наприклад, сторінка може мати періодичну повторну валідацію:
export const revalidate = 3600У такому разі сторінка може використовувати збережену версію протягом години. Виклик revalidatePath('/products') достроково робить її неактуальною після зміни товарів.
Також кешувати можна окремий запит:
const response = await fetch('https://example.com/api/products', {
next: {
revalidate: 3600,
},
})
const products = await response.json()Після зміни даних на сервері можна викликати:
revalidatePath('/products')Тоді сторінка /products буде повторно сформована з новими результатами запиту.
Припустімо, застосунок має такі маршрути:
/products
/products/keyboard
/products/mouseФайлова структура може виглядати так:
app/
└── products/
└── [slug]/
└── page.jsЯкщо змінено лише один товар, можна оновити тільки його сторінку:
revalidatePath('/products/keyboard')Якщо потрібно позначити неактуальними всі сторінки, які відповідають динамічному маршруту, використовуйте шаблон маршруту та тип 'page':
revalidatePath('/products/[slug]', 'page')Це відрізняється від конкретного URL:
revalidatePath('/products/keyboard')Перший варіант працює з маршрутом-шаблоном, а другий — з конкретним шляхом.
Іноді зміни стосуються не окремої сторінки, а спільного layout. Наприклад, layout показує кількість товарів у кошику.
Для цього можна вказати тип 'layout':
revalidatePath('/products', 'layout')Такий виклик позначає неактуальним layout маршруту /products та вкладені сторінки, які ним використовуються.
Використовуйте 'layout' обережно, оскільки область повторної генерації буде ширшою, ніж для 'page'.
revalidatePath можна викликати не лише в Server Action, а й у Route Handler.
// app/api/products/route.js
import { revalidatePath } from 'next/cache'
import { addProduct } from '../../lib/products'
export async function POST(request) {
const body = await request.json()
const name = body.name?.toString().trim()
if (!name) {
return Response.json(
{ error: 'Назва товару є обов’язковою' },
{ status: 400 },
)
}
const product = addProduct(name)
// Скидаємо кеш сторінки після зміни даних
revalidatePath('/products')
return Response.json(product, { status: 201 })
}Після POST-запиту до /api/products маршрут /products буде позначено для повторної генерації.
Важлива відмінність:
у Server Action оновлення поточного інтерфейсу відбувається одразу після завершення action;
у Route Handler маршрут буде повторно сформовано під час наступного запиту до нього.
revalidatePath і revalidateTagЦі функції вирішують різні задачі:
revalidatePath інвалідує кеш маршруту;
revalidateTag інвалідує дані, позначені певним тегом.
Якщо потрібно оновити конкретний маршрут після зміни даних, використовуйте revalidatePath:
revalidatePath('/products')Якщо одні й ті самі дані використовуються на багатьох маршрутах, зручнішим може бути тегування запитів. Але для інвалідації конкретної сторінки достатньо revalidatePath.
Неправильно:
'use client'
import { revalidatePath } from 'next/cache'revalidatePath — серверна функція. Її потрібно викликати в Server Action або Route Handler.
Неправильно:
revalidatePath('/products')
addProduct(name)У такому випадку маршрут може бути повторно сформований ще до того, як новий товар з’явиться в джерелі даних.
Правильно:
addProduct(name)
revalidatePath('/products')Спочатку змініть дані, а потім інвалідуйте кеш.
Якщо сторінка доступна за адресою /catalog/products, виклик для /products не вплине на неї:
revalidatePath('/products')Потрібно вказати фактичний маршрут:
revalidatePath('/catalog/products')revalidatePath('/products')оновлює кеш лише вказаного маршруту. Інші сторінки, які також показують товари, автоматично не обов’язково будуть інвалідовані.
Якщо після зміни товару потрібно оновити кілька сторінок, викличте функцію для кожної з них:
revalidatePath('/products')
revalidatePath('/dashboard')revalidatePath інвалідує кеш конкретного маршруту.
Функцію імпортують із next/cache.
Викликати її можна в Server Actions і Route Handlers.
Після зміни даних спочатку виконайте мутацію, а потім викличте revalidatePath.
Для конкретного URL використовуйте шлях на кшталт /products/keyboard.
Для динамічного маршруту використовуйте шаблон і тип 'page', наприклад revalidatePath('/products/[slug]', 'page').
Тип 'layout' застосовують, коли потрібно оновити layout і його вкладені маршрути.