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를 테스트하려면 브라우저에서 서드 파티 쿠키와 로컬 스토리지 액세스를 허용해야 합니다.