ドキュメントの目次
  1. はじめに
  2. コンテンツとコレクション
  3. 公開API
  4. CMS SDK
  5. 素材ライブラリ
  6. データの受け渡し(ZIP)
  7. 管理API

CMS SDK

CMS SDK(npm パッケージ @magichtml/cms)は、公開API をブラウザから簡単に呼び出すための小さな JavaScript ライブラリです。通常の <script> タグで読み込むと window.MagicCMS が使えるようになり、get() で公開中のコンテンツやコレクションを取得できます。管理用の認証情報は受け付けず、必要もありません。

読み込み方

バージョンを固定した URL と SRI(integrity)ハッシュを指定して、クラシックな <script> タグで読み込みます(type="module" は不要です)。

<script src="https://cdn.jsdelivr.net/npm/@magichtml/cms@0.1.0/magic-cms.js" integrity="sha384-bako2vxKJyzsf7errApVfA4Lk2QkaKDmAvws2+gV4giOGqHNEeZBeet+qTlJD2qh" crossorigin="anonymous"></script>
  • 各リソース画面の「接続・公開履歴」タブにある「接続サンプル」に、現在のバージョンとハッシュを入れたタグが表示されます。
  • SDK は jsDelivr から配信されます。integrity を付けると、配信されたファイルが改ざんされていないことをブラウザが確認します。
  • SDK を使うページのオリジンを、サイトの「許可する接続元」に登録してください(公開API の「CORS と接続元」を参照)。

クライアントを作る

const cms = new MagicCMS('https://cms.magichtml.dev', 'SITE_ID');
引数 説明
baseUrl Magic CMS Cloud のURL。http: または https: のURLを指定します。オリジン部分だけが使われ、パスは無視されます。それ以外の形式では Invalid endpoint エラーになります。
siteId サイトID(UUID)。サイト画面の公開接続先URLや、リソース画面の接続サンプルで確認できます。

データを取得する:get(key, query)

const data = await cms.get('news', {page: 1, per_page: 10});
  • key:リソースの識別キー
  • query:省略可能。q、entry、page、per_page を指定できます。値が undefined・null・空文字の項目は送信されません。
  • 戻り値:{version, name, kind, fields, records, pagination} に解決される Promise。形式は 公開API のレスポンスと同じです。
  • リクエストは資格情報(Cookie)なしで送られます。

例:コンテンツを表示する

<h1 data-cms="title"></h1>
<div data-cms="lead"></div>

<script src="https://cdn.jsdelivr.net/npm/@magichtml/cms@0.1.0/magic-cms.js" integrity="sha384-bako2vxKJyzsf7errApVfA4Lk2QkaKDmAvws2+gV4giOGqHNEeZBeet+qTlJD2qh" crossorigin="anonymous"></script>
<script>
  const cms = new MagicCMS('https://cms.magichtml.dev', 'SITE_ID');
  cms.get('about').then(data => {
    const values = data.records[0].values;
    for (const element of document.querySelectorAll('[data-cms]')) {
      element.textContent = values[element.dataset.cms] ?? '';
    }
  });
</script>

例:検索とページ分けのあるお知らせ一覧

<form id="search">
  <input name="q" type="search" placeholder="キーワード">
  <button>検索</button>
</form>
<ul id="news"></ul>
<nav>
  <button id="prev" type="button">前へ</button>
  <span id="page"></span>
  <button id="next" type="button">次へ</button>
</nav>
<p id="error" hidden>お知らせを読み込めませんでした。</p>

<script src="https://cdn.jsdelivr.net/npm/@magichtml/cms@0.1.0/magic-cms.js" integrity="sha384-bako2vxKJyzsf7errApVfA4Lk2QkaKDmAvws2+gV4giOGqHNEeZBeet+qTlJD2qh" crossorigin="anonymous"></script>
<script>
  const cms = new MagicCMS('https://cms.magichtml.dev', 'SITE_ID');
  const state = {q: '', page: 1, per_page: 10};

  async function render() {
    try {
      const data = await cms.get('news', state);
      const list = document.getElementById('news');
      list.replaceChildren(...data.records.map(record => {
        const li = document.createElement('li');
        const link = document.createElement('a');
        link.href = 'detail.html?id=' + encodeURIComponent(record.key);
        link.textContent = record.values.title;
        li.append(link);
        return li;
      }));
      const {page, per_page, total} = data.pagination;
      const pages = Math.max(1, Math.ceil(total / per_page));
      document.getElementById('page').textContent = page + ' / ' + pages;
      document.getElementById('prev').disabled = page <= 1;
      document.getElementById('next').disabled = page >= pages;
      document.getElementById('error').hidden = true;
    } catch (error) {
      document.getElementById('error').hidden = false;
      console.error(error.status, error.message);
    }
  }

  document.getElementById('search').addEventListener('submit', event => {
    event.preventDefault();
    state.q = new FormData(event.target).get('q');
    state.page = 1;
    render();
  });
  document.getElementById('prev').addEventListener('click', () => { state.page--; render(); });
  document.getElementById('next').addEventListener('click', () => { state.page++; render(); });
  render();
</script>

例:1件を表示する(詳細ページ)

entry にレコードの識別キーを指定すると、その1件だけを取得できます。

const id = new URLSearchParams(location.search).get('id');
const data = await cms.get('news', {entry: id});
const record = data.records[0];
if (record) {
  document.querySelector('h1').textContent = record.values.title;
}

値の表示についての注意

  • テキストなどの値は textContent で挿入してください。
  • 「装飾文(HTML)」「文書(HTML)」の値は、許可されたタグ・属性だけで構成されていることが保存時に検証された HTML 文字列です。HTML として表示する場合は innerHTML などで挿入します。
  • 「リンク」型の値は {url: '...'} の形です。
  • 「素材URL」型の値が /assets/ で始まるパスの場合は、'https://cms.magichtml.dev' + value のように Magic CMS Cloud のURLを前に付けてください(素材ライブラリ を参照)。

エラー処理

取得に失敗すると、Promise は Error で reject されます。

プロパティ 内容
status HTTP ステータス(例:404、429)
message サーバーが返したメッセージ。ない場合は Magic CMS request failed
try {
  const data = await cms.get('news');
} catch (error) {
  if (error.status === 404) {
    // リソースがない、または公開されていない
  } else if (error.status === 429) {
    // リクエスト数の上限。時間をおいて再試行
  } else if (error.status === undefined) {
    // ネットワークエラー、または接続元が許可されていない(CORS)
  }
}

接続元が登録されていない場合、ブラウザは応答を読み取れないため、status のない通信エラーになります。開発者ツールのコンソールに CORS のエラーが出ていないか確認してください。

API が使えない場合に備えて、静的HTMLに初期の文言を書いておき、取得できたときだけ置き換える構成にすると安全です。

バージョンの確認:MagicCMS.VERSION

読み込んだ SDK のバージョンを文字列で返します。

console.log(MagicCMS.VERSION); // 例: "0.1.0"

バージョンの方針

  • 常にバージョンを固定した URL と integrity ハッシュを使ってください。
  • magic-cms.js を変更するときは必ず新しいバージョンとして公開されます。一度公開されたバージョンのファイルは変わりません。
  • 新しいバージョンに切り替えるときは、リソース画面の接続サンプルに表示される URL とハッシュの組み合わせに、両方まとめて差し替えてください。片方だけ変えると、ブラウザは SDK を読み込みません。

そのほか

  • SDK は CommonJS 形式でも読み込めます(require('@magichtml/cms'))。サーバー側から公開データを取得する場合などに使えます。
  • 第3引数で fetch の実装を渡せます(new MagicCMS(baseUrl, siteId, {fetch: myFetch}))。

関連ページ