Spec-Zone.ru › Next.js

Режим предварительного просмотра

Примечание: Эта функция устарела и заменена на Режим черновика.

Примеры
  • Пример WordPress (Демо)
  • Пример DatoCMS (Демо)
  • Пример TakeShape (Демо)
  • Пример Sanity (Демо)
  • Пример Prismic (Демо)
  • Пример Contentful (Демо)
  • Пример Strapi (Демо)
  • Пример Prepr (Демо)
  • Пример Agility CMS (Демо)
  • Пример Cosmic (Демо)
  • Пример ButterCMS (Демо)
  • Пример Storyblok (Демо)
  • Пример GraphCMS (Демо)
  • Пример Kontent (Демо)
  • Пример Umbraco Heartcore (Демо)
  • Пример Plasmic (Демо)
  • Пример Enterspeed (Демо)
  • Пример Makeswift (Демо)

В документации по страницам и макетам и получению данных мы говорили о том, как выполнить предварительный рендеринг страницы во время сборки (Статическое создание) с использованием getStaticProps и getStaticPaths.

Статическое создание полезно, когда ваши страницы получают данные из бесголового CMS. Однако это не идеально, когда вы пишете черновик на бесголовом CMS и хотите сразу же предварительно просмотреть черновик на вашей странице. Вам нужно, чтобы Next.js рендерил эти страницы в режиме запроса, а не во время сборки, и получал содержимое черновика вместо опубликованного. Вам нужно, чтобы Next.js проигнорировал статическое создание только для этого конкретного случая.

Next.js имеет функцию Режим предварительного просмотра, которая решает эту проблему. Вот инструкция по ее использованию.

Шаг 1: Создание и доступ к маршруту API предварительного просмотра

Сначала ознакомьтесь с документацией по маршрутам API, если вы с ними не знакомы.

Сначала создайте маршрут API предварительного просмотра. Он может иметь любое имя, например pages/api/preview.js (или .ts при использовании TypeScript).

В этом маршруте API вам необходимо вызвать setPreviewData на объекте ответа. Аргумент для setPreviewData должен быть объектом, и это можно использовать в getStaticProps (подробнее об этом позже). Пока что будем использовать {}.

export default function handler(req, res) {
  // ...
  res.setPreviewData({})
  // ...
}

res.setPreviewData устанавливает некоторые куки в браузере, которые включают режим предварительного просмотра. Все запросы к Next.js, содержащие эти куки, будут считаться запросами в режиме предварительного просмотра, и поведение для статически сгенерированных страниц изменится (подробнее об этом позже).

Вы можете протестировать это вручную, создав маршрут API, как показано ниже, и обратившись к нему вручную в браузере:

// simple example for testing it manually from your browser.
export default function handler(req, res) {
  res.setPreviewData({})
  res.end('Preview mode enabled')
}

Если вы откроете инструменты разработчика браузера и посетите /api/preview, вы заметите, что куки __prerender_bypass и __next_preview_data будут установлены в этом запросе.

Безопасный доступ к нему из вашего бесголового CMS

На практике вы хотите вызвать этот маршрут API безопасно из вашего бесголового CMS. Конкретные шаги будут отличаться в зависимости от используемого бесголового CMS, но вот несколько общих шагов.

Эти шаги предполагают, что используемый вами бесголовый CMS поддерживает настройку специальных URL-адресов предварительного просмотра. Если это не так, вы все равно можете использовать этот метод для защиты URL-адресов предварительного просмотра, но вам нужно будет создать и получить URL-адрес предварительного просмотра вручную.

Во-первых, вы должны создать строку секретного токена с помощью генератора токенов по своему выбору. Этот секрет будет известен только вашей приложению Next.js и вашему бесголовом CMS. Этот секрет предотвращает доступ к URL-адресам предварительного просмотра людям, не имеющим доступа к вашему CMS.

Во-вторых, если ваш бесголовый CMS поддерживает настройку настраиваемых URL-адресов предварительного просмотра, укажите следующее как URL-адрес предварительного просмотра. Предполагается, что ваш маршрут API предварительного просмотра находится по адресу pages/api/preview.js.

https://<your-site>/api/preview?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.setPreviewData.
  • Затем перенаправьте браузер на путь, указанный в 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 preview mode from being enabled
  if (!post) {
    return res.status(401).json({ message: 'Invalid slug' })
  }
 
  // Enable Preview Mode by setting the cookies
  res.setPreviewData({})
 
  // 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)
}

Если это произойдет успешно, браузер будет перенаправлен на путь, который вы хотите предварительно просмотреть, при этом куки режима предварительного просмотра будут установлены.

Шаг 2: Обновление getStaticProps

Следующим шагом является обновление getStaticProps для поддержки режима предварительного просмотра.

Если вы запрашиваете страницу, которая имеет getStaticProps с установленными куками режима предварительного просмотра (через res.setPreviewData), то getStaticProps будет вызван в режиме запроса (а не во время сборки).

Кроме того, он будет вызван с объектом context, где:

  • context.preview будет true.
  • context.previewData будет таким же, как аргумент, используемый для setPreviewData.
export async function getStaticProps(context) {
  // If you request this page with the preview mode cookies set:
  //
  // - context.preview will be true
  // - context.previewData will be the same as
  //   the argument used for `setPreviewData`.
}

Мы использовали res.setPreviewData({}) в маршруте API предварительного просмотра, поэтому context.previewData будет {}. Вы можете использовать это для передачи информации о сеансе из маршрута API предварительного просмотра в getStaticProps при необходимости.

Если вы также используете getStaticPaths, то context.params также будет доступен.

Получение данных предварительного просмотра

Вы можете обновить getStaticProps для извлечения различных данных на основе context.preview и/или context.previewData.

Например, ваш бесголовый CMS может иметь другой API-точку для черновиков статей. В таком случае вы можете использовать context.preview для изменения URL API-точки, как показано ниже:

export async function getStaticProps(context) {
  // If context.preview is true, append "/preview" to the API endpoint
  // to request draft data instead of published data. This will vary
  // based on which headless CMS you're using.
  const res = await fetch(`https://.../${context.preview ? 'preview' : ''}`)
  // ...
}

Вот и все! Если вы обращаетесь к маршруту API предварительного просмотра (с secret и slug) из вашего бесголового CMS или вручную, вы теперь должны увидеть содержимое предварительного просмотра. А если вы обновите свой черновик без публикации, вы должны увидеть предварительный просмотр черновика.

Установите этот URL предварительного просмотра в вашем бесголовом CMS или откройте его вручную, и вы сможете увидеть предварительный просмотр.

END_OF_DOCUMENT_MARKER
https://<your-site>/api/preview?secret=<token>&slug=<path>

Дополнительные сведения

Важно знать: во время отрисовки next/router экспонирует флаг isPreview, см. документацию по объекту роутера для получения дополнительной информации.

Укажите продолжительность режима предварительного просмотра

setPreviewData принимает необязательный второй параметр, который должен быть объектом параметров. Он принимает следующие ключи:

  • maxAge: Указывает количество секунд, в течение которых должен длиться сеанс предварительного просмотра.
  • path: Указывает путь, по которому должен применяться cookie. По умолчанию /, что позволяет включить режим предварительного просмотра для всех путей.
setPreviewData(data, {
  maxAge: 60 * 60, // The preview mode cookies expire in 1 hour
  path: '/about', // The preview mode cookies apply to paths with /about
})

Очистка файлов cookie режима предварительного просмотра

По умолчанию для файлов cookie режима предварительного просмотра не устанавливается дата истечения срока действия, поэтому сеанс предварительного просмотра завершается при закрытии браузера.

Чтобы вручную очистить файлы cookie режима предварительного просмотра, создайте маршрут API, который вызовет clearPreviewData():

export default function handler(req, res) {
  res.clearPreviewData({})
}

Затем отправьте запрос на /api/clear-preview-mode-cookies для вызова маршрута API. Если вы вызываете этот маршрут с помощью next/link, вы должны передать prefetch={false} для предотвращения вызова clearPreviewData во время предварительной выборки ссылки.

Если путь был указан в вызове setPreviewData, вы должны передать тот же путь в clearPreviewData:

export default function handler(req, res) {
  const { path } = req.query
 
  res.clearPreviewData({ path })
}

Пределы размера previewData

Вы можете передать объект в setPreviewData и сделать его доступным в getStaticProps. Однако, поскольку данные будут храниться в cookie, существует ограничение по размеру. В настоящее время данные предварительного просмотра ограничены 2 КБ.

Работа с getServerSideProps

Режим предварительного просмотра работает и с getServerSideProps. Он также будет доступен в объекте context, содержащем preview и previewData.

Важно знать: Не следует устанавливать заголовок Cache-Control при использовании режима предварительного просмотра, так как его нельзя обойти. Вместо этого мы рекомендуем использовать ISR.

Работа с API-маршрутами

API-маршруты получат доступ к preview и previewData в объекте запроса. Например:

export default function myApiRoute(req, res) {
  const isPreview = req.preview
  const previewData = req.previewData
  // ...
}

Уникальные для каждого последующего сборки

Значение cookie для обхода и закрытый ключ для шифрования previewData изменяются после завершения next build. Это гарантирует, что cookie для обхода нельзя угадать.

Важно знать: Чтобы протестировать режим предварительного просмотра локально через HTTP, вашему браузеру потребуется разрешить использование файлов cookie сторонних сайтов и доступ к локальному хранилищу.

© 2024 Vercel, Inc.
Licensed under the MIT License.
https://nextjs.org/docs/pages/building-your-application/configuring/preview-mode

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API