Next.jsのPreview modeでページのプレビューを表示する
Next.js v9.3でpreview modeが追加されました
CMSっぽいの作ろうと思ってるので、ちょっと試してみました
めちゃシンプルで簡単にPreviewできたのでメモ
ドキュメントは↓ nextjs.org
サンプルコードは↓ github.com
Preview modeのAPIを用意する
ヘッドレスCMDなどからプレビューページを表示するためのエンドポイントを作成します
ぼくのサンプルコードではこんな感じ
// /pages/api/preview.ts export default (req, res) => { const id = req.query.id; res.setPreviewData({}); res.writeHead(307, { Location: `/posts/${id}` }); res.end(); };
クエリパラメータのid
で対象のURLへリダイレクトしているだけです
setPreviewData
には任意のデータを渡せますが、cookieで保持しているのでサイズには上限があります
previewDataのリミットは2KBだそうです
Pagesでpreview mdoeの振る舞いを記述する
Preview modeだとgetStaticPropsのpropsにpreview: true
とpreviewDataL {}
が渡ってきます
ぼくのサンプルコードではpreview
をcomponentに渡してラベルを表示するようにしました
// /pages/posts/[id].tsx import { useRouter } from 'next/router'; export const getStaticPaths = async () => { return { paths: [{ params: { id: '1' } }], fallback: true, }; }; export const getStaticProps = async ({ params, preview }) => { const isPreview = preview || false; return { props: { id: params.id, previewMode: isPreview } }; }; const Post = ({ id, previewMode }) => { const router = useRouter(); if (router.isFallback) { return <div>Loading...</div>; } return ( <> {previewMode ? 'Preview mode' : ''} <h1>{`Page's ID is ${id}`}</h1> </> ); }; export default Post;
これだけです!
http://localhost:3000/api/preview?id=1
にアクセスすると/pages/1
にリダイレクトされて、Preview modeのラベルが表示されるはずです
Previewモードを解除する
Preview modeを解除するには、cookieをクリアしてあげればOKです
解除用のエンドポイントを作成します
// /pages/api/preview-disable.ts export default (req, res) => { const location = req.headers.referer || '/'; res.clearPreviewData(); res.writeHead(307, { Location: location }); res.end(); };
pageにも解除用のリンクを追加します
// /pages/posts/[id].tsx import { useRouter } from 'next/router'; export const getStaticPaths = async () => { return { paths: [{ params: { id: '1' } }], fallback: true, }; }; export const getStaticProps = async ({ params, preview }) => { const isPreview = preview || false; return { props: { id: params.id, previewMode: isPreview } }; }; const Post = ({ id, previewMode }) => { const router = useRouter(); if (router.isFallback) { return <div>Loading...</div>; } return ( <> {previewMode ? 'Preview mode' : ''} <h1>{`Page's ID is ${id}`}</h1> {previewMode ? ( <a href="/api/preview-disable">Disable preview mode</a> ) : null} // リンクを追加 </> ); }; export default Post;
このリンクをクリックすると、posts/1
にリダイレクトしてPreview modeのラベルやリンクが表示されないはずです
まとめ
すごくシンプルで簡単にPreviewを実装できました
実際の運用では、previewのデータを取得する実装が必要になりますね
公開されているデータを取得するclinetとPreviewのデータを取得するclientを作って、getStaticProps
で切り替えるとかね
Enjoy Next.js ヘ(^o^)ノ