Preview Mode
주의: 이 기능은 Draft Mode로 대체되었습니다.
예제
- WordPress 예제 (opens in a new tab) (Demo (opens in a new tab))
- DatoCMS 예제 (opens in a new tab) (Demo (opens in a new tab))
- TakeShape 예제 (opens in a new tab) (Demo (opens in a new tab))
- Sanity 예제 (opens in a new tab) (Demo (opens in a new tab))
- Prismic 예제 (opens in a new tab) (Demo (opens in a new tab))
- Contentful 예제 (opens in a new tab) (Demo (opens in a new tab))
- Strapi 예제 (opens in a new tab) (Demo (opens in a new tab))
- Prepr 예제 (opens in a new tab) (Demo (opens in a new tab))
- Agility CMS 예제 (opens in a new tab) (Demo (opens in a new tab))
- Cosmic 예제 (opens in a new tab) (Demo (opens in a new tab))
- ButterCMS 예제 (opens in a new tab) (Demo (opens in a new tab))
- Storyblok 예제 (opens in a new tab) (Demo (opens in a new tab))
- GraphCMS 예제 (opens in a new tab) (Demo (opens in a new tab))
- Kontent 예제 (opens in a new tab) (Demo (opens in a new tab))
- Umbraco Heartcore 예제 (opens in a new tab) (Demo (opens in a new tab))
- Plasmic 예제 (opens in a new tab) (Demo (opens in a new tab))
- Enterspeed 예제 (opens in a new tab) (Demo (opens in a new tab))
- Makeswift 예제 (opens in a new tab) (Demo (opens in a new tab))
Pages 문서 및 Data Fetching 문서에서 getStaticProps와 getStaticPaths를 사용하여 빌드 타임에 페이지를 사전 렌더링(정적 생성)하는 방법에 대해 이야기했습니다.
정적 생성은 페이지가 헤드리스 CMS에서 데이터를 가져올 때 유용합니다. 하지만 헤드리스 CMS에서 초안을 작성하고 페이지에서 바로 미리보기를 원할 때는 이상적이지 않습니다. 이러한 경우 Next.js가 이 페이지들을 빌드 타임이 아닌 요청 타임에 렌더링하고 게시된 컨텐츠 대신 초안 컨텐츠를 가져오도록 하고 싶을 것입니다. 이와 같이 Next.js가 특정 경우에 정적 생성을 우회하기를 원할 수 있습니다.
Next.js에는 이러한 문제를 해결하는 Preview Mode라는 기능을 제공합니다. 사용 방법은 다음과 같습니다.
Step 1: Create and access a preview API route
Next.js API Routes를 잘 모르는 경우 API Routes 문서을 먼저 참조하십시오.
먼저 미리보기 API route를 만듭니다. 이름은 자유롭게 설정할 수 있습니다 - 예: pages/api/preview.js (TypeScript를 사용하는 경우 .ts).
이 API route에서 응답 객체에 setPreviewData를 호출해야 합니다. setPreviewData의 인수는 객체여야 하며, 이는 getStaticProps에서 사용할 수 있습니다(이후에 더 설명함). 지금은 {}를 사용하겠습니다.
export default function handler(req, res) {
// ...
res.setPreviewData({})
// ...
}res.setPreviewData는 브라우저에 쿠키를 설정하여 preview mode를 활성화합니다. 이러한 쿠키를 포함한 Next.js로의 모든 요청은 preview mode로 간주되며, 정적으로 생성된 페이지의 동작이 변경됩니다(이후에 더 설명함).
아래와 같이 API route를 만들고 브라우저에서 직접 액세스하여 수동으로 테스트할 수 있습니다:
// 브라우저에서 수동으로 테스트할 수 있는 간단한 예제입니다.
export default function handler(req, res) {
res.setPreviewData({})
res.end('Preview mode enabled')
}브라우저의 개발자 도구를 열고 /api/preview를 확인하면 이 요청에 __prerender_bypass 및 __next_preview_data 쿠키가 설정되는 것을 확인할 수 있습니다.
Securely accessing it from your Headless CMS
실제로는 헤드리스 CMS에서 이 라우트 핸들러를 보안 방식으로 호출하고 싶을 것입니다. 사용 중인 헤드리스 CMS에 따라 구체적인 단계는 다를 수 있지만, 다음과 같은 일반적인 단계를 따를 수 있습니다.
이 단계는 사용 중인 헤드리스 CMS가 사용자 정의 미리보기 URL 설정을 지원한다고 가정합니다. 지원하지 않는 경우에도 이 방법을 사용하여 미리보기 URL을 보호할 수 있지만, 미리보기 URL을 수동으로 구성하고 접근해야 합니다.
먼저, 원하는 토큰 생성기를 사용하여 시크릿 토큰 문자열을 생성해야 합니다. 이 시크릿은 Next.js 앱과 헤드리스 CMS만 알고 있어야 합니다. 이 시크릿은 CMS에 액세스할 수 없는 사람들이 미리보기 URL에 접근하는 것을 방지합니다.
두 번째, 헤드리스 CMS가 사용자 정의 미리보기 URL 설정을 지원하는 경우, 다음을 미리보기 URL로 지정합니다. 이는 미리보기 API route가 pages/api/preview.js에 위치한다고 가정합니다.
https://<your-site>/api/preview?secret=<token>&slug=<path><your-site>는 배포 도메인이어야 합니다.<token>은 생성한 시크릿 토큰으로 교체해야 합니다.<path>는 미리보기 하려는 페이지의 경로여야 합니다./posts/foo를 보고자 한다면&slug=/posts/foo를 사용해야 합니다.
사용중인 헤드리스 CMS가 변수 삽입을 지원하는 경우 <path>를 CMS 데이터에 따라 동적으로 설정할 수 있습니다: &slug=/posts/{entry.fields.slug}
마지막으로, 미리보기 API route에서:
- 시크릿이 일치하고
slug매개변수가 존재하는지 확인합니다(존재하지 않으면 요청이 실패해야 합니다). res.setPreviewData를 호출합니다.- 그런 다음 브라우저를
slug로 지정된 경로로 리디렉션합니다(다음 예제에서는 307 redirect (opens in a new tab)을 사용합니다).
export default async (req, res) => {
// 시크릿과 다음 매개변수를 확인합니다.
// 이 시크릿은 이 API route와 CMS만 알고 있어야 합니다.
if (req.query.secret !== 'MY_SECRET_TOKEN' || !req.query.slug) {
return res.status(401).json({ message: 'Invalid token' })
}
// 제공된 `slug`가 존재하는지 확인하기 위해 헤드리스 CMS를 가져옵니다.
// getPostBySlug는 헤드리스 CMS에 필요한 fetching 로직을 구현합니다.
const post = await getPostBySlug(req.query.slug)
// slug가 존재하지 않으면 Preview Mode가 활성화되지 않도록 합니다.
if (!post) {
return res.status(401).json({ message: 'Invalid slug' })
}
// 쿠키를 설정하여 Preview Mode를 활성화합니다.
res.setPreviewData({})
// 가져온 게시물의 경로로 리디렉션합니다.
// req.query.slug로 리디렉션하지 않는 이유는 open redirect 취약점이 발생할 수 있기 때문입니다.
res.redirect(post.slug)
}성공하면 브라우저는 설정된 preview mode 쿠키와 함께 보고자 하는 경로로 리디렉션됩니다.
Step 2: Update getStaticProps
다음 단계는 getStaticProps를 업데이트하여 preview mode를 지원하는 것입니다.
Preview mode 쿠키가 설정된 상태로 getStaticProps가 있는 페이지를 요청하면 getStaticProps가 빌드 타임이 아닌 요청 타임에 호출됩니다.
또한, context 객체와 함께 호출되며:
context.preview는true입니다.context.previewData는setPreviewData에 사용된 인수와 동일합니다.
export async function getStaticProps(context) {
// preview mode 쿠키가 설정된 상태로 이 페이지를 요청하면:
//
// - context.preview는 true가 됩니다.
// - context.previewData는 `setPreviewData`에 사용된 인수와 동일합니다.
}우리는 미리보기 API route에서 res.setPreviewData({})를 사용했으므로 context.previewData는 {}가 됩니다. 필요하다면 미리보기 API route에서 getStaticProps로 세션 정보를 전달하는 데 사용할 수 있습니다.
getStaticPaths를 사용하는 경우, context.params도 사용할 수 있습니다.
Fetch preview data
getStaticProps를 업데이트하여 context.preview 및/또는 context.previewData에 따라 다른 데이터를 가져올 수 있습니다.
예를 들어, 헤드리스 CMS가 초안 게시물에 대해 다른 API 엔드포인트를 가지고 있는 경우, 아래와 같이 API 엔드포인트 URL을 수정하는 데 context.preview를 사용할 수 있습니다:
export async function getStaticProps(context) {
// context.preview가 true이면, 초안 데이터를 요청하기 위해 API 엔드포인트에 "/preview"를 추가합니다.
// 이는 사용하는 헤드리스 CMS에 따라 다릅니다.
const res = await fetch(`https://.../${context.preview ? 'preview' : ''}`)
// ...
}이제 미리보기 API route(시크릿 및 slug 포함)를 헤드리스 CMS 또는 수동으로 접근하면 미리보기 컨텐츠를 볼 수 있어야 합니다. 초안을 게시하지 않고 업데이트하더라도 초안을 미리 볼 수 있어야 합니다.
헤드리스 CMS에 이를 미리보기 URL로 설정하거나 수동으로 접근하면 미리보기를 볼 수 있습니다.
https://<your-site>/api/preview?secret=<token>&slug=<path>More Details
참고: 렌더링 중
next/router는isPreview플래그를 노출합니다. 자세한 내용은 router object docs를 참조하십시오.
Specify the Preview Mode duration
setPreviewData는 option 객체인 두 번째 매개 변수를 사용합니다. 이는 다음 키들을 사용합니다:
maxAge: 미리보기 세션이 지속되는 시간을 초 단위로 지정합니다.path: 쿠키가 적용될 경로를 지정합니다. 기본값은/이며, 이는 모든 경로에 대해 preview mode를 활성화합니다.
setPreviewData(data, {
maxAge: 60 * 60, // preview mode 쿠키는 1시간 후에 만료됩니다.
path: '/about', // preview mode 쿠키는 /about 경로에 적용됩니다.
})Clear the Preview Mode cookies
기본적으로, preview mode 쿠키에는 만료 날짜가 설정되지 않으므로 브라우저를 닫을 때 미리보기 세션이 종료됩니다.
Preview mode 쿠키를 수동으로 제거하려면 clearPreviewData()를 호출하는 API route를 만듭니다:
export default function handler(req, res) {
res.clearPreviewData({})
}그런 다음 /api/clear-preview-mode-cookies 에 요청을 보내 API Route를 호출합니다. next/link를 사용하여 이 라우트를 호출하는 경우 링크 사전 로딩 중에 clearPreviewData를 호출하지 않도록 prefetch={false}를 설정해야 합니다.
setPreviewData 호출에서 경로를 지정한 경우, 동일한 경로를 clearPreviewData에 전달해야 합니다:
export default function handler(req, res) {
const { path } = req.query
res.clearPreviewData({ path })
}previewData size limits
객체를 setPreviewData에 전달하여 getStaticProps에서 사용할 수 있습니다. 그러나 데이터가 쿠키에 저장되므로 크기 제한이 있습니다. 현재 미리보기 데이터는 2KB로 제한됩니다.
Works with getServerSideProps
Preview mode는 getServerSideProps에서도 작동합니다. context 객체에 preview 및 previewData가 포함되어 사용할 수 있습니다.
참고: Preview Mode를 사용할 때
Cache-Control헤더를 설정하면 우회할 수 없으므로 설정하지 않아야 합니다. 대신, ISR을 사용하는 것을 추천합니다.
Works with API Routes
API Routes는 요청 객체에서 preview 및 previewData에 접근할 수 있습니다. 예를 들어:
export default function myApiRoute(req, res) {
const isPreview = req.preview
const previewData = req.previewData
// ...
}Unique per next build
우회 쿠키 값과 previewData 암호화를 위한 개인 키는 next build가 완료될 때 변경됩니다.
이를 통해 우회 쿠키를 추측할 수 없도록 합니다.
참고: 로컬에서 HTTP를 통해 Preview Mode를 테스트하려면 브라우저에서 서드 파티 쿠키와 로컬 스토리지 액세스를 허용해야 합니다.