genko.meDocs
SDK・CLI

List・Viewで表示する

スキーマに沿った表示、状態表示、ページ送り、下書きプレビューをSDKの部品で組み立てます。

Next.js App Router用の、取得から表示までを担当する部品です。Next.js 16以降、React 19、Node.jsランタイムを対象にしています。

取得・表示・ページ送りはSDKに任せ、ページのURLとレイアウトはアプリ側で用意します。CLIは接続用の2ファイルと設定を生成しますが、ページのひな形は生成しません。最初の一覧・詳細はクイックスタートの例を配置してください。

導入

npx @genko-me/cli init

CLIがSDK・React部品を追加し、lib/schema.tslib/client.ts を生成します。APIキーはサーバーの GENKO_API_KEY に設定します。Route HandlerやProxyの追加は不要です。

import { client } from '@/lib/client';
import { List, ListItem, Pagination, Error, Null } from '@genko-me/react/next';

export default function Page() {
  return <List api={client.blog} limit={6} orders="-publishedAt" href="/blog/{id}">
    <article>
      <h2><ListItem id="title" /></h2>
      <ListItem id="image" fallback={<span>画像なし</span>} />
    </article>
    <Pagination />
    <Error template />
    <Null>記事はまだありません。</Null>
  </List>;
}

List の通常の子要素が1件分のレイアウトです。PaginationLoadingErrorNull は直下に配置し、繰り返しません。状態部品を省略すると、その状態では何も表示しません。template を指定したときだけ標準メッセージを表示します。

詳細と下書き

import { client } from '@/lib/client';
import { View, ViewItem, Error, Null } from '@genko-me/react/next';

type Props = {
  params: Promise<{ id: string }>;
  searchParams: Promise<Record<string, string | string[] | undefined>>;
};

export default async function Page({ params, searchParams }: Props) {
  const { id } = await params;
  return <View api={client.blog} id={id} searchParams={searchParams}>
    <h1><ViewItem id="title" /></h1>
    <ViewItem id="body" />
    <Error template />
    <Null>記事がありません。</Null>
  </View>;
}

管理画面のプレビューURLを https://your-site.example/blog/{id}?draftKey={key} に設定します。searchParams を渡すと、保存済み下書きをキャッシュせず取得し、プレビュー表示と終了ボタンを出します。不正なキーで公開版へ切り替えることはありません。previewNotice={false} で表示を隠すか、previewNotice={{position:'bottom',className:'...'}} で調整できます。

オブジェクト形式のAPIでは id を省略します。記事がない場合は NullnotFound を指定するとNext.jsの404画面になります。ストリーミング開始後はNext.jsの仕様上HTTPステータスが200になる場合があります。

サーバーとブラウザの境界

client.tsList / Viewを使うページはサーバーコンポーネントにします。ページに"use client"を付けたり、APIクライアントをクライアントコンポーネントのpropsへ渡したりしないでください。ページ送りなどブラウザで必要な処理はSDK内部で扱います。

アニメーションなどのクライアント部品で囲む場合は、サーバー側で組み立てたList / Viewをその部品のchildrenとして渡せます。

デザインはサイト側で指定する

ListView・フィールド・ページ送り・状態表示は標準の装飾を付けません。classNamestyleと、見出しやdivなどのHTMLでサイトのデザインを適用します。本文の見出し・段落間隔・画像サイズもサイト側のCSSで設定してください。複数行テキストの改行を表示する場合はwhite-space: pre-wrapなどを指定します。

templateは状態用の標準メッセージを選ぶ指定で、枠線や余白は追加しません。unstyledは既存コードとの互換性のため受け付けますが、これらの部品の装飾は切り替えません。unstyled={false}でも標準デザインは付きません。

下書きプレビュー通知と終了ボタンだけは、親のunstyledに関係なく標準デザインを表示します。通知だけ装飾を外す場合はpreviewNotice={{ unstyled: true }}、通知自体を隠す場合はpreviewNotice={false}を指定します。

記事全体のリンクには、クリック領域とキーボードフォーカスを成立させる最小限のCSSを使います。これは見た目のテーマとは別の、操作に必要な処理です。

表示の指定

  • 表示項目は ListItem / ViewItem で明示します。テキスト・画像・HTMLなどの種類は生成スキーマから判断します。
  • classNamestyle を各部品に渡せます。<h1><div> などのラッパーでレイアウトを組めます。
  • 日時は id="publishedAt" format="yyyy/MM/dd HH:mm" timeZone="Asia/Tokyo"。既定のタイムゾーンはUTCです。
  • 参照は id="author.name"。複数参照は値を参照順で表示します。標準の参照展開は2階層までです。
  • 未入力の値は表示しません。fallback にJSXを渡せます。falseや0は未入力と扱いません。
  • リンクは Listhref="/blog/{id}" で記事全体に設定するか、内部に <ListLink href="/blog/{id}">読む</ListLink> を置きます。ネストしたリンクを壊さず操作できます。
  • フィールドIDは実行時に検証します。親の api から子の文字列IDをTypeScriptで推論する機能はありません。

ページ送り・キャッシュ

既定の Pagination はURLを変えず一覧だけを切り替えます。<Pagination mode="url" param="page" /> はURLと連動し、戻る操作にも対応します。List にも searchParams を渡すと、URL指定のページを最初からサーバーで描画します。渡さない場合はブラウザで同期します。複数のURL連動一覧には別々の param を指定してください。

Listlimit(1〜100)、offsetfiltersordersq を指定できます。既定は毎回取得し、cache={60} などの秒数を明示した場合だけ初回取得をキャッシュします。ページ送りによる取得と下書き表示は毎回最新です。

ページ送りはSDK内のServer Actionを利用します。APIキーをブラウザへ送らず、サーバーが発行した取得先・条件だけを受け付けます。署名の有効期限は1時間です。期限切れ・キー交換後はページを再読み込みしてください。ページ送りを使うクライアントのキーは GENKO_API_KEY と一致させてください。カスタム fetch / wrapRequest はページ送りには対応しません。静的エクスポート・Edgeランタイムは対象外です。

主なprops

List / View

両方にapi、表示用のchildrenclassNamestyleunstyledを指定できます。表示フィールドは自動選択されません。

prop対象既定値・使い方
api両方生成されたclient.blogなど。Listはリスト形式のみ
cache両方false。キャッシュする場合は正の秒数
depth両方2。参照展開の深さ。012
searchParams両方Promiseまたは解決済みの値。Viewの下書き判定、ListのURL連動ページ送りに使用
idViewリスト形式では必須、オブジェクト形式では省略
notFoundViewfalsetrueで記事なしをNext.jsの404へ切り替える
previewNoticeViewプレビュー時に表示。falseで非表示、オブジェクトで位置・装飾を調整
limitList10。1〜100の整数
offsetList0。先頭から読み飛ばす件数
orders / filters / qList並び替え・条件・検索
hrefList/blog/{id}など、1件全体のリンク先

ListItem / ViewItem

prop使い方
id必須。titlepublishedAtauthor.nameなど
fallback未入力時の代替JSX
format日時の書式。既定はyyyy.MM.ddyyyyMMddHHmmssを使用
locale / timeZone日時表示。既定はja-JP / UTC
className / styleサイト側のフィールド装飾

テキストを見出しにする場合は<h1><ViewItem id="title" /></h1>のようにHTMLで囲みます。リッチテキストは保存済みHTMLの見出しや段落を表示します。通常のテキストフィールドにHTMLを書いてもHTMLとしては描画しません。

状態表示 / Pagination

ErrorNullLoadingには自由なJSX、またはtemplateを指定します。Viewの404応答はNull、認証・通信などの失敗はErrorの対象です。Listの空配列はNull、取得エラーはErrorになります。

読み込み中…
コンテンツがありません。

Paginationmode(既定はlocal)、param(既定はpage)、previousLabelnextLabelと装飾用のpropsを受け取ります。状態部品とページ送りは親の直下に1つずつ置きます。独自コンポーネントやdivの内側に隠さないでください。

スキーマ同期

npx @genko-me/cli pull
# 開発時の任意の自動同期(別ターミナル)
npx @genko-me/cli pull --watch

schema.ts のAPI一覧も同期するため、API追加時に client.ts を編集する必要はありません。同期対象を限定している場合は pull --select-apis で選択に追加します。--watch は10秒ごとに確認し、変更時だけファイルを更新します。

CLIを使わず手動で導入する

npm install @genko-me/sdk @genko-me/react

.env.localGENKO_API_KEY を設定し、次の2ファイルを作成します。例では管理画面に blog APIと titlebody フィールドがあることを想定しています。種類・IDは実際のスキーマに合わせてください。

lib/schema.ts
import { listApi } from '@genko-me/sdk';
export type Blog = { title: string; body: string };
export const apis = {
  blog: listApi<Blog>({ fields: [
    { id: 'title', type: 'text' },
    { id: 'body', type: 'richtext' },
  ] }),
};
lib/client.ts
import 'server-only';
import { createGenko } from '@genko-me/sdk';
import { apis } from './schema';
export const client = createGenko({
  workspace: 'your-workspace',
  apiKey: process.env.GENKO_API_KEY!,
  apis,
}).apis;

後はページから client と部品をimportします。手動導入ではスキーマ変更も自分で反映します。同期を自動化する場合はCLIを使用してください。

低レベルの部品

取得を自分で扱う場合は、従来の RichText@genko-me/react)と ShareButtons@genko-me/react/share-buttons)も利用できます。

最終更新: 2026年9月8日

目次