genko.meDocs

実践

Next.jsでPaginationによるページ送り、保存済み下書きのプレビュー、nextRevalidateプラグインによるキャッシュ再検証を設定する手順。

導入で作った一覧・詳細ページに、運用で必要になる3つを足します。

ページ送り

Listの直下にPaginationを置くだけで、limitの件数ごとに切り替わります。既定のmode="local"はURLを変えずに一覧だけを差し替えます。

app/blog/page.tsx
<List api={client.blog} limit={6} orders="-publishedAt" href="/blog/{id}">  <article><h2><ListItem id="title" /></h2></article>  <Pagination />  <Error template />  <Null>公開されている記事はありません。</Null></List>

URLに残したいときはmode="url"にして、ページのsearchParamsをListにも渡します。ブラウザの戻る・進む・再読み込みに対応し、?page=2を直接開いてもサーバー側で2ページ目を描画します。

app/news/page.tsx
import { client } from "@/lib/client";import { List, ListItem, Pagination, Error, Null } from "@genko-me/react/next";
type Props = {  searchParams: Promise<Record<string, string | string[] | undefined>>;};
export default function NewsPage({ searchParams }: Props) {  return (    <main>      <h1>お知らせ</h1>      <List api={client.blog} limit={10} orders="-publishedAt" href="/blog/{id}" searchParams={searchParams}>        <article><h3><ListItem id="title" /></h3></article>        <Pagination mode="url" param="page" previousLabel="前へ" nextLabel="次へ" />        <Error template />        <Null>お知らせはありません。</Null>      </List>    </main>  );}

Paginationが描画するのは<nav aria-label="ページ送り">と、前後のボタン・現在位置(1 / 3)だけです。標準の装飾は付かないので、classNameでサイトのデザインを当ててください。先頭・末尾のページでは対応するボタンがdisabledになり、1ページに収まる件数のときはPagination自体を描画しません。

1つのページでURL連動の一覧を2つ使う場合は、paramを別々の名前にします。

制約。 PaginationはSDK内のServer Actionで次のページを取得します。静的エクスポート(output: "export")とEdgeランタイムでは動作しません。カスタムfetchやwrapRequestを設定したクライアントも対象外です。署名の有効期限は1時間で、期限切れやAPIキーの交換後はページを再読み込みしてください。

保存済み下書きのプレビュー

詳細ページのsearchParamsをViewに渡していれば、追加のRoute Handlerなしでプレビューになります。導入のコードのままで動きます。

管理画面のAPI設定(/w/your-workspace/apis/blog/settings)で、プレビューURLテンプレートを設定します。

text
https://your-site.example/blog/{id}?draftKey={key}

{id}と{key}は管理画面が置き換えます。ローカルで確認するときはホストをhttp://localhost:3000に変えてください。

記事を保存して「プレビュー」を押すと、同じ詳細ページに下書きが表示されます。このときViewは次の処理を行います。

  • 下書きをキャッシュせず取得する(公開表示にcacheを指定していても影響しません)。
  • ページにnoindex, nofollowとno-referrerのmetaを出す。
  • プレビュー中であることの通知と、終了ボタンを表示する。

終了ボタンはURLからdraftKeyを外して公開表示に戻ります。キーが正しくない場合は、公開版へ切り替えずにNull(notFoundを指定していれば404画面)になります。

通知の位置と装飾はpreviewNoticeで調整します。

tsx
<View api={client.blog} id={id} searchParams={searchParams}  previewNotice={{ position: "bottom", className: "preview-bar" }}>

previewNotice={false}で非表示、previewNotice={{ unstyled: true }}で標準の装飾だけを外せます。通知は親のunstyledの影響を受けません。

プレビュー用のRoute Handlerを別に用意し、Draft Modeを有効にしてから詳細ページへ飛ばす構成にもできます。@genko-me/sdk/nextのnextPreviewが、idとdraftKeyを読んで307でリダイレクトするハンドラーを提供します。詳しくはプラグインとNext.js連携を参照してください。

Webhookで再生成・再検証する

記事を更新したときにキャッシュを作り直すには、genko.me側のWebhookとnextRevalidateプラグインを使います。

まずlib/client.tsのクライアントにプラグインを足します。

lib/client.ts
import "server-only";import { createGenko } from "@genko-me/sdk";import { nextRevalidate } from "@genko-me/sdk/next";import { apis } from "./schema";
export const genko = createGenko({  workspace: "your-workspace",  apiKey: process.env.GENKO_API_KEY!,  apis,  plugins: [    nextRevalidate({      secret: process.env.GENKO_WEBHOOK_SECRET!,      revalidate: (event) => {        if (event.api !== "blog" || event.workspace !== "your-workspace") return [];        if (event.event === "webhook.test") return ["/blog"];        return event.entry ? ["/blog", `/blog/${event.entry.id}`] : ["/blog"];      },    }),  ],});export const client = genko.apis;

プラグインのPOSTをRoute Handlerとして公開します。

app/api/revalidate/route.ts
import { genko } from "@/lib/client";
export const POST = genko.revalidate.POST;

管理画面のAPI設定から「Webhookを追加」で、通知先にhttps://your-site.example/api/revalidate、シークレットにGENKO_WEBHOOK_SECRETと同じ値を設定します。署名が一致するとrevalidateが返したパスごとにrevalidatePath()を呼び、{"revalidated":["/blog","/blog/1"]}のようなJSONを返します。一致しない場合は401です。シークレットが空だとクライアントの初期化時にエラーになります。

キャッシュしていないページには効果がありません。 List・Viewは既定で毎回取得します。再検証が意味を持つのはcache={60}のように秒数を指定した一覧・詳細です。

tsx
<List api={client.blog} limit={6} orders="-publishedAt" cache={60}>

削除・公開終了のイベントでは、一覧だけでなく個別ページのパスも再検証してください。entry.statusがdraftに戻ったときも同じです。手動で「公開」にして保存した場合のイベントはentry.publishedではなくentry.created / entry.updatedになります。イベントの一覧と配送の制限はWebhookにまとめています。

ホスティング先の再ビルドで運用する場合は、受信URLをデプロイフックにします。その場合このプラグインは不要です。

次に読む

最終更新: 2026年9月17日

目次