Режим черновика
В документации по страницам и макетам и документации по получению данных мы говорили о том, как выполнить предварительный рендеринг страницы во время сборки (Статическое генерирование) с использованием getStaticProps и getStaticPaths.
Статическое генерирование полезно, когда ваши страницы извлекают данные из бессерверной CMS. Однако это не лучший вариант, когда вы пишете черновик в своей бессерверной CMS и хотите сразу же просмотреть черновик на своей странице. Вам потребуется, чтобы Next.js рендерил эти страницы в момент запроса, а не во время сборки, и извлекал данные черновика, а не опубликованные данные. Вам нужно, чтобы Next.js обошел Статическое генерирование только в этом конкретном случае.
Next.js имеет функцию под названием Режим черновика, которая решает эту проблему. Вот инструкции по ее использованию.
Шаг 1: Создание и доступ к API-маршруту
Сначала ознакомьтесь с документацией по API-маршрутам, если вы не знакомы с API-маршрутами Next.js.
Сначала создайте API-маршрут. Он может иметь любое имя — например, pages/api/draft.ts.
В этом API-маршруте вам необходимо вызвать setDraftMode на объекте ответа.
export default function handler(req, res) {
// ...
res.setDraftMode({ enable: true })
// ...
}
Это установит cookie для включения режима черновика. Последующие запросы, содержащие этот cookie, вызовут Режим черновика, изменив поведение статически сгенерированных страниц (подробнее об этом позже).
Вы можете проверить это вручную, создав API-маршрут, как показано ниже, и обратившись к нему из своего браузера вручную:
// simple example for testing it manually from your browser.
export default function handler(req, res) {
res.setDraftMode({ enable: true })
res.end('Draft mode is enabled')
}Если вы откроете инструменты разработчика вашего браузера и посетите /api/draft, вы заметите заголовок ответа Set-Cookie с cookie под именем __prerender_bypass.
Безопасный доступ из вашей бессерверной CMS
На практике вы захотите безопасно обратиться к этому API-маршруту из своей бессерверной CMS. Конкретные шаги будут зависеть от используемой вами бессерверной CMS, но вот несколько распространенных шагов.
Эти шаги предполагают, что используемая вами бессерверная CMS поддерживает настройку настраиваемых URL-адресов черновиков. Если этого не поддерживает, вы все равно можете использовать этот метод для защиты URL-адресов черновиков, но вам нужно будет вручную создать и получить доступ к URL-адресу черновика.
Во-первых, вы должны создать строку секретного токена, используя генератор токенов по вашему выбору. Этот секрет известен только вашему приложению Next.js и вашей бессерверной CMS. Этот секрет предотвращает доступ к URL-адресам черновиков для людей, которые не имеют доступа к вашей CMS.
Во-вторых, если ваша бессерверная CMS поддерживает настройку настраиваемых URL-адресов черновиков, укажите следующее в качестве URL-адреса черновика. Предполагается, что ваш API-маршрут черновика расположен по адресу pages/api/draft.ts.
https://<your-site>/api/draft?secret=<token>&slug=<path>
-
<your-site>должен быть вашим доменным именем развертывания. -
<token>должен быть заменен сгенерированным вами секретным токеном. -
<path>должен быть путем к странице, которую вы хотите просмотреть. Если вы хотите просмотреть/posts/foo, используйте&slug=/posts/foo.
Ваша бессерверная CMS может позволить вам включить переменную в URL черновика, чтобы <path> можно было динамически установить на основе данных CMS, как показано ниже: &slug=/posts/{entry.fields.slug}
Наконец, в маршруте API черновика:
- Проверьте, что секрет совпадает, и что параметр
slugсуществует (в противном случае запрос должен завершиться ошибкой). - Вызовите
res.setDraftMode. - Затем перенаправьте браузер на путь, указанный в
slug. (В следующем примере используется перенаправление 307).
export default async (req, res) => {
// Check the secret and next parameters
// This secret should only be known to this API route and the CMS
if (req.query.secret !== 'MY_SECRET_TOKEN' || !req.query.slug) {
return res.status(401).json({ message: 'Invalid token' })
}
// 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(req.query.slug)
// If the slug doesn't exist prevent draft mode from being enabled
if (!post) {
return res.status(401).json({ message: 'Invalid slug' })
}
// Enable Draft Mode by setting the cookie
res.setDraftMode({ enable: true })
// Redirect to the path from the fetched post
// We don't redirect to req.query.slug as that might lead to open redirect vulnerabilities
res.redirect(post.slug)
}
В случае успеха браузер будет перенаправлен на нужный путь с cookie режима черновика.
Шаг 2: Обновить getStaticProps
Следующим шагом является обновление getStaticProps для поддержки режима черновика.
Если вы запрашиваете страницу, на которой getStaticProps установлен cookie (через res.setDraftMode), то getStaticProps будет вызван в момент запроса (а не во время сборки).
Кроме того, он будет вызван с объектом context, где context.draftMode будет true.
export async function getStaticProps(context) {
if (context.draftMode) {
// dynamic data
}
}
Мы использовали res.setDraftMode в маршруте API черновика, поэтому context.draftMode будет true.
Если вы также используете getStaticPaths, то context.params также будет доступно.
Получение данных черновика
Вы можете обновить getStaticProps для извлечения разных данных на основе context.draftMode.
Например, у вашей бессерверной CMS может быть другой API-точкой для черновиков. В этом случае вы можете изменить URL API-точки, как показано ниже:
export async function getStaticProps(context) {
const url = context.draftMode
? 'https://draft.example.com'
: 'https://production.example.com'
const res = await fetch(url)
// ...
}
Вот и все! Если вы обратитесь к API-маршруту черновика (с secret и slug) из вашей бессерверной CMS или вручную, вы теперь сможете увидеть содержимое черновика. И если вы обновите свой черновик без публикации, вы сможете увидеть черновик.
Установите это в качестве URL черновика в своей бессерверной CMS или обратитесь вручную, и вы сможете увидеть черновик.
https://<your-site>/api/draft?secret=<token>&slug=<path>
Дополнительные сведения
Очистка cookie режима черновика
По умолчанию сессия режима черновика завершается при закрытии браузера.
Чтобы вручную очистить cookie режима черновика, создайте API-маршрут, который вызовет setDraftMode({ enable: false }):
export default function handler(req, res) {
res.setDraftMode({ enable: false })
}Затем отправьте запрос на /api/disable-draft для вызова API-маршрута. Если вы вызываете этот маршрут с помощью next/link, вы должны передать prefetch={false} для предотвращения случайного удаления cookie при предварительной загрузке.
Работает с getServerSideProps
Режим черновика работает с getServerSideProps, и доступен в качестве ключа draftMode в объекте context.
Важно знать: Не следует устанавливать заголовок
Cache-Controlпри использовании режима черновика, поскольку его нельзя обойти. Вместо этого мы рекомендуем использовать ISR.
Работает с API-маршрутами
API-маршруты будут иметь доступ к draftMode в объекте запроса. Например:
export default function myApiRoute(req, res) {
if (req.draftMode) {
// get draft data
}
}
Уникальный для каждой сборки Next
Новое значение cookie обхода генерируется каждый раз, когда вы запускаете next build.
Это гарантирует, что cookie обхода невозможно угадать.
Важно знать: Для тестирования режима черновика локально через HTTP ваш браузер должен разрешать доступ к cookie сторонних сайтов и к хранилищу локального хранилища.
© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/pages/building-your-application/configuring/draft-mode