Как использовать режим предварительного просмотра Next.js с безголовой CMS Cosmic

Генерация статических веб-страниц практична при получении данных из безголовой CMS. Однако при добавлении нового контента в CMS после создания сайта нам понадобится способ предварительного просмотра чернового контента, который еще не готов к публикации.

Используя Next.js Preview Mode, мы решаем эту проблему путем рендеринга страниц во время запроса, позволяя нам увидеть неопубликованный контент, которого не было во время статической генерации. Давайте рассмотрим, как мы можем использовать Next.js Preview Mode с безголовой CMS для предварительного просмотра чернового контента для себя и коллег.

В этом примере мы используем Cosmic в качестве нашей безголовой CMS. Вы можете посмотреть демонстрацию в реальном времени и клонировать шаблон Портфолио разработчика в репозитории GitHub.

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

Чтобы гарантировать, что только те, кто имеет доступ, смогут увидеть наши URL-адреса предварительного просмотра, давайте создадим строку для нашего секретного токена предварительного просмотра. Вы можете использовать этот генератор ключей API для получения секретной строки base64 или просто использовать простую текстовую строку, которую вы создадите.

Теперь мы зададим пользовательский URL предварительного просмотра, который будет расположен по адресу ‘pages/api/preview.js’ в нашем проекте Next.js.

  https://<YOUR-SITE>/api/preview?secret=<YOUR_SECRET_PREVIEW_TOKEN>&slug=[object_slug]
Вход в полноэкранный режим Выход из полноэкранного режима

Установить URL-адрес предварительного просмотра в Cosmic очень просто. Мы можем перейти к настройкам типа объекта и установить ссылку предварительного просмотра, используя приведенное выше соглашение. Для тестирования во время разработки установите localhost, в противном случае установите желаемый URL. Используя Cosmic, установите параметр slug в [object_slug]. Cosmic автоматически преобразует этот короткий код в slug данного объекта.

Получение превью поста по slug

Сначала создадим асинхронную функцию для получения данных о превью-посте из нашей безголовой CMS с помощью модуля Cosmic NPM.

const Cosmic = require('cosmicjs')
const api = Cosmic()

const bucket = api.bucket({
  slug: YOUR_BUCKET_SLUG,
  read_key: YOUR_READ_KEY,
})
const is404 = error => /not found/i.test(error.message)

export async function getPreviewPostBySlug(slug) {
  const params = {
    query: { slug },
    status: 'any',
    props: 'slug',
  }

  try {
    const data = await bucket.getObjects(params)
    return data.objects[0]
  } catch (error) {
    // Don't throw if a slug doesn't exist
    if (is404(error)) return
    throw error
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Установив параметр status в значение any, мы получим по запросу все неопубликованные объекты со статусом draft, а также последний черновик опубликованного объекта.

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

Теперь, когда мы настроили секретный токен предварительного просмотра в нашей CMS, мы создаем API-маршрут, который проверяет соответствие токена и затем получает неопубликованный пост, который мы запросили, с URL-адресом предварительного просмотра, который мы установили ранее (если он существует).

Если маркер совпадает и если запрашиваемый нами slug существует в нашей CMS, мы включаем режим предварительного просмотра и устанавливаем cookies с помощью res.setPreviewData({}), используя временное перенаправление на местоположение нашего неопубликованного поста.

export default async function preview(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 !== process.env.COSMIC_PREVIEW_SECRET ||
    !req.query.slug
  ) {
    return res.status(401).json({ message: 'Invalid token' })
  }

  // Fetch the headless CMS to check if the provided `slug` exists
  const post = await getPreviewPostBySlug(req.query.slug)

  // If the slug doesn't exist prevent preview mode from being enabled
  if (!post) {
    return res.status(401).json({ message: 'Object not found' })
  }

  // 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.writeHead(307, { Location: `/posts/${post.slug}` })
  res.end()
}
Вход в полноэкранный режим Выход из полноэкранного режима

Обновление getStaticProps

Теперь, когда мы установили cookies режима предварительного просмотра с помощью res.setPreviewData, getStaticProps будет вызываться по запросу.

На странице, где мы отображаем наш пост предварительного просмотра, getStaticProps примет объект в качестве аргумента, который будет неопубликованными данными, которые мы извлекли из нашей headless CMS.

export async function getStaticProps({ params, preview = null }) {
  const data = await getPostAndMorePosts(params.slug, preview)
  return {
    props: {
      preview,
      post: {
        ...data.post,
      },
    },
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

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

Теперь, когда мы настроили наши маршруты API и функциональность для режима предварительного просмотра, использовать его в Cosmic так же просто, как нажать на кнопку. Cosmic возьмет URL-адрес предварительного просмотра, который мы настроили ранее, и сгенерирует запрос для каждого создаваемого объекта, автоматически добавляя в его конец метку объекта.

Выход из режима предварительного просмотра

Мы можем создать еще один маршрут API для выхода из режима предварительного просмотра. Мы просто очистим куки предварительного просмотра и перенаправим на главную страницу.

export default async function exit(_, res) {
  // Exit the current user from "Preview Mode". This function accepts no args.
  res.clearPreviewData()

  // Redirect the user back to the index page.
  res.writeHead(307, { Location: '/' })
  res.end()
}
Вход в полноэкранный режим Выход из полноэкранного режима

Поскольку мы устанавливаем cookies для текущей сессии нашего приложения, мы можем рассматривать эти данные как контекст для всего приложения. В демонстрационном примере, используемом в этом руководстве, я создал баннер, который отображается, когда приложение находится в режиме предварительного просмотра. В баннере мы используем ссылку Next.js для маршрутизации к API-маршруту exit-preview, очищая cookies режима предварительного просмотра и возвращая приложение на главную страницу.

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

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

Оцените статью
devanswers.ru
Добавить комментарий