Режим черновика
Статический рендеринг полезен, когда ваши страницы извлекают данные из headless CMS. Однако, это не идеально, когда вы пишете черновик в вашей headless CMS и хотите сразу же просмотреть черновик на вашей странице. Вы хотите, чтобы Next.js рендерил эти страницы в момент запроса, а не во время сборки, и извлекал черновик контента, а не опубликованный контент. Вы хотите, чтобы Next.js переключился на динамический рендеринг только в этом конкретном случае.
Next.js имеет функцию, называемую Режим черновика, которая решает эту проблему. Ниже приведены инструкции по ее использованию.
Шаг 1: Создание и доступ к обработчику маршрута
Сначала создайте обработчик маршрута. Он может иметь любое имя — например, app/api/draft/route.ts
Затем импортируйте draftMode из next/headers и вызовите метод enable()
// route handler enabling draft mode
import { draftMode } from 'next/headers'
export async function GET(request: Request) {
draftMode().enable()
return new Response('Draft mode is enabled')
}Это установит cookie для включения режима черновика. Последующие запросы, содержащие этот cookie, будут вызывать Режим черновика, изменяя поведение статически сгенерированных страниц (подробнее об этом позже).
Вы можете проверить это вручную, посетив /api/draft и посмотрев инструменты разработчика вашего браузера. Обратите внимание на заголовок ответа Set-Cookie с cookie под именем __prerender_bypass
Безопасный доступ из вашей Headless CMS
На практике вы захотите вызвать этот обработчик маршрута безопасно из вашей headless CMS. Конкретные шаги будут различаться в зависимости от используемой headless CMS, но вот некоторые распространенные шаги, которые можно предпринять.
Эти шаги предполагают, что используемая headless CMS поддерживает установку специальных URL-адресов черновиков. Если нет, вы все равно можете использовать этот метод для защиты ваших URL-адресов черновиков, но вам нужно будет создавать и получать доступ к URL-адресу черновика вручную.
Сначала, вы должны создать строку секретного токена, используя генератор токенов по вашему выбору. Этот секрет будет известен только вашей приложению Next.js и вашей headless CMS. Этот секрет предотвращает доступ к URL-адресам черновиков лицам, не имеющим доступа к вашей CMS.
Во-вторых, если ваша headless CMS поддерживает установку пользовательских URL-адресов черновиков, укажите следующее в качестве URL-адреса черновика. Это предполагает, что ваш обработчик маршрута расположен по адресу app/api/draft/route.ts
https://<your-site>/api/draft?secret=<token>&slug=<path>
-
<your-site>должен быть вашим доменным именем развертывания. -
<token>должен быть заменен сгенерированным вами секретным токеном. -
<path>должен быть путем к странице, которую вы хотите просмотреть. Если вы хотите просмотреть/posts/foo, то вы должны использовать&slug=/posts/foo.
Ваша headless CMS может позволить вам включать переменную в URL черновика, чтобы <path> можно было динамически задавать на основе данных CMS, например: &slug=/posts/{entry.fields.slug}
Наконец, в обработчике маршрута:
- Проверьте, что секрет совпадает, и что параметр
slugсуществует (если нет, запрос должен завершиться ошибкой). - Вызовите
draftMode.enable()для установки cookie. - Затем перенаправьте браузер на путь, указанный в
slug.
// route handler with secret and slug
import { draftMode } from 'next/headers'
import { redirect } from 'next/navigation'
export async function GET(request: Request) {
// Parse query string parameters
const { searchParams } = new URL(request.url)
const secret = searchParams.get('secret')
const slug = searchParams.get('slug')
// Check the secret and next parameters
// This secret should only be known to this route handler and the CMS
if (secret !== 'MY_SECRET_TOKEN' || !slug) {
return new Response('Invalid token', { status: 401 })
}
// Fetch the headless CMS to check if the provided `slug` exists
// getPostBySlug would implement the required fetching logic to the headless CMS
const post = await getPostBySlug(slug)
// If the slug doesn't exist prevent draft mode from being enabled
if (!post) {
return new Response('Invalid slug', { status: 401 })
}
// Enable Draft Mode by setting the cookie
draftMode().enable()
// Redirect to the path from the fetched post
// We don't redirect to searchParams.slug as that might lead to open redirect vulnerabilities
redirect(post.slug)
}При успехе браузер будет перенаправлен на желаемый путь с cookie режима черновика.
Шаг 2: Обновление страницы
Следующим шагом является обновление вашей страницы для проверки значения draftMode().isEnabled.
Если вы запрашиваете страницу, на которой установлен cookie, данные будут извлекаться в момент запроса (а не во время сборки).
Кроме того, значение isEnabled будет true.
// page that fetches data
import { draftMode } from 'next/headers'
async function getData() {
const { isEnabled } = draftMode()
const url = isEnabled
? 'https://draft.example.com'
: 'https://production.example.com'
const res = await fetch(url)
return res.json()
}
export default async function Page() {
const { title, desc } = await getData()
return (
<main>
<h1>{title}</h1>
<p>{desc}</p>
</main>
)
}Вот и все! Если вы обращаетесь к обработчику маршрута черновика (с secret и slug) из своей headless CMS или вручную, вы теперь должны видеть черновик контента. И если вы обновите свой черновик без публикации, вы должны увидеть черновик.
Установите это в качестве URL-адреса черновика в вашей headless CMS или обратитесь вручную, и вы должны увидеть черновик.
https://<your-site>/api/draft?secret=<token>&slug=<path>
Дополнительные сведения
Очистка cookie режима черновика
По умолчанию сессия режима черновика завершается при закрытии браузера.
Чтобы вручную очистить cookie режима черновика, создайте обработчик маршрута, который вызывает draftMode().disable():
import { draftMode } from 'next/headers'
export async function GET(request: Request) {
draftMode().disable()
return new Response('Draft mode is disabled')
}Затем отправьте запрос на /api/disable-draft, чтобы вызвать обработчик маршрута. Если вы вызываете этот маршрут с помощью next/link, вы должны передать prefetch={false} для предотвращения случайного удаления cookie при предварительной загрузке.
Уникальный для каждой сборки Next.js
Новое значение cookie прохода будет генерироваться каждый раз, когда вы запустите next build.
Это гарантирует, что cookie прохода нельзя угадать.
Важно знать: Для тестирования режима черновика локально через HTTP ваш браузер должен разрешить доступ к файлам cookie сторонних сайтов и к локальному хранилищу.
© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/app/building-your-application/configuring/draft-mode