導入
素のHTMLに@genko-me/wcを入れ、import mapで読み込んで記事一覧・詳細を表示するまでの手順。
.htmlファイルと<script type="module">だけで、記事一覧と記事詳細を表示するまでの手順です。バンドラーは使いません。
ワークスペースの作成とブログAPIの用意はクイックスタートの手順1〜3にまとめています。
用意するもの
- genko.meのアカウントとワークスペース。APIの作成とAPIキーの発行にはオーナー権限が必要です。
- 記事が1件以上、保存済みかつ公開状態で入っているAPI。
- Node.js。 ブラウザを動かすためではなく、
npm installでパッケージを取得し、node_modulesをローカルに配信するために使います。 - import mapに対応したブラウザ(Chrome・Edge・Firefox・Safariの現行版はいずれも対応済みです)。
以下のyour-workspaceは自分のワークスペースIDに、blogは自分のエンドポイントに置き換えます。
インストール
npm install @genko-me/wc @genko-me/sdk@genko-me/wcは@genko-me/coreにも依存しますが、npm installで自動的に一緒に入ります。
バンドラーがない状態でブラウザにimport "@genko-me/wc"と書いても読み込めません。 ブラウザはnode_modulesのパッケージ名解決を知らないためです。HTMLの<head>にimport mapを書き、パッケージ名を実際のファイルへ対応づけます。
<script type="importmap">{ "imports": { "@genko-me/wc/define": "/node_modules/@genko-me/wc/dist/define.js", "@genko-me/wc": "/node_modules/@genko-me/wc/dist/index.js", "@genko-me/sdk": "/node_modules/@genko-me/sdk/dist/index.js", "@genko-me/core": "/node_modules/@genko-me/core/dist/index.js", "@genko-me/core/browser": "/node_modules/@genko-me/core/dist/browser.js" }}</script>@genko-me/coreと@genko-me/core/browserは、@genko-me/wcの内部が参照しているので、直接importしなくても対応づけが要ります。開発中は、index.htmlのあるディレクトリをnode_modulesごとそのまま配信できる静的サーバー(npx serveなど)で確認します。本番にデプロイするときは、node_modulesをまるごと置くのではなく、使っているdist/*.jsだけを自分のvendor/のようなディレクトリへコピーし、import mapのパスをそちらに向け直してください。
APIキーとワークスペースIDを設定する
APIキーは管理画面の「設定・プラン」→「APIキー」(/w/your-workspace/settings/api-keys)で発行します。「選択したAPIのみ」でblogだけを許可してください。
この構成では、APIキーはHTML・JavaScriptにそのまま書きます。ページを開いた誰からも読める前提で扱ってください。 隠す方法はありません(概要を参照)。
記事一覧を出す
<body> <main> <genko-list id="posts" href="/blog/{id}"> <article> <h2><genko-list-item field="title"></genko-list-item></h2> </article> <genko-loading template>読み込み中…</genko-loading> <genko-error template></genko-error> <genko-null>記事はまだありません。</genko-null> </genko-list> </main>
<script type="module"> import '@genko-me/wc/define'; import { createGenko, listApi, getApiBinding } from '@genko-me/sdk';
const genko = createGenko({ workspace: 'your-workspace', apiKey: '発行したキー', apis: { blog: listApi({ fields: [ { id: 'title', type: 'text' }, { id: 'body', type: 'richtext' }, ], }), }, }); const binding = getApiBinding(genko.apis.blog);
const list = document.getElementById('posts'); list.fields = binding.fields; list.schemas = binding.schemas; genko.apis.blog .list({ limit: 6, orders: '-publishedAt' }) .then((initial) => { list.initial = initial; }); </script></body>@genko-me/wc/defineをimportした時点でgenko-*要素が登録されます。import "@genko-me/wc"だけをimportしても要素は登録されません(クラスのexportだけを提供するエントリーです)。
genko-listはinitial(最初の1ページ分)を受け取るまでgenko-loadingの内容を表示します。fields・schemasはgetApiBinding()から取り出し、そのまま渡します。フィールドのマークアップはfield属性で指定します(id属性も受け付けますが、一覧の各行で同じ値が並ぶためfieldを使ってください)。ページ送りは実践で足します。
npx serveなどでこのディレクトリを配信し、ブラウザで開いて一覧が表示されることを確認します。開発者ツールのコンソールにエラーが出ていないことも確認してください。
記事詳細を出す
<body> <main> <genko-view id="detail"> <h1><genko-view-item field="title"></genko-view-item></h1> <genko-view-item field="body"></genko-view-item> <genko-loading template></genko-loading> <genko-error template></genko-error> <genko-null>記事がありません。</genko-null> </genko-view> <genko-share-buttons id="share" hidden></genko-share-buttons> </main>
<script type="module"> import '@genko-me/wc/define'; import { createGenko, listApi, getApiBinding } from '@genko-me/sdk';
const genko = createGenko({ workspace: 'your-workspace', apiKey: '発行したキー', apis: { blog: listApi({ fields: [{ id: 'title', type: 'text' }, { id: 'body', type: 'richtext' }] }) }, }); const binding = getApiBinding(genko.apis.blog);
const id = new URLSearchParams(location.search).get('id'); const detail = document.getElementById('detail'); const share = document.getElementById('share'); detail.fields = binding.fields; detail.schemas = binding.schemas;
genko.apis.blog .getOrNull(id) .then((entry) => { detail.removeAttribute('state'); if (!entry) detail.setAttribute('state', 'empty'); detail.entry = entry ?? undefined; if (entry) { share.url = location.href; share.shareTitle = entry.title; share.hidden = false; } }) .catch(() => detail.setAttribute('state', 'error')); </script></body>state属性を自分からloadingなどに固定しないでください。 何も指定しなければ「entryがまだ無ければ読み込み中、あれば本文」という既定の切り替えが働きますが、一度state属性を付けると自動では外れません。上のように、結果が届いた時点でremoveAttribute('state')してから必要な状態だけ付け直します。
genko-share-buttonsの見出し用属性はshare-titleです。HTMLのtitle属性はツールチップなど別の意味を持つ予約済みの属性なので、名前を変えてあります。
post.html?id=のあとに、一覧の記事IDを付けて開き、本文とシェアボタンが表示されることを確認します。
表示されないとき
| 状況 | 確認すること |
|---|---|
| 何も表示されない | @genko-me/wc/defineをimportしたか。import mapのパスが実際のnode_modulesの場所と合っているか(開発者ツールのコンソールにモジュール解決エラーが出ていないか) |
| 一覧が空 | 記事が保存済みで「公開」か |
401 | APIキーが有効期間内か |
403 | APIキーを発行したワークスペースと接続先が同じか |
| フィールドが出ない | field属性のIDと管理画面のフィールドIDが一致しているか。fields・schemasを要素に渡し忘れていないか |
次は実践で、ページ送りの補足・下書きプレビュー・コンテンツ更新の反映を扱います。
最終更新: 2026年9月17日