Skip to Content
Rotion とは

はじめに

Rotion は、Notion のページとデータベースから静的な Web サイトを作るための npm パッケージです。 2つの部分からなります。 1つは rotion として import するエクスポーターで、Notion API を通じてワークスペースを読み出します。 もう1つは rotion/ui として import する React コンポーネント群で、エクスポーターが返したデータを描画します。 処理はすべてビルド時に行われるので、成果物はどの静的ホスティングでも配信できる HTML、CSS、ファイルだけになります。

仕組み

Rotion を使ったビルドは、次の4段階で進みます。

  1. Notion API:エクスポーターは、インテグレーションのトークン(NOTION_TOKEN)を使って公式の Notion API を呼び出します。見えるのは、そのインテグレーションに共有したページとデータベースだけです。
  2. 取得とキャッシュFetchDatabaseFetchPageFetchBlocks がデータを取得し、ネストしたブロック(トグル、カラム、同期ブロック、テーブルなど)もたどって、各レスポンスを JSON として .cache に書き込みます。次のビルドでは API を呼ばずにこの JSON を読みます。
  3. ファイルのダウンロード:Notion にアップロードされた画像やファイルの URL は1時間ほどで失効します。そのためエクスポーターはそれらを public/(デフォルトでは public/imagespublic/files)にダウンロードし、画像を WebP に変換して、ローカルのパスを src として返すデータに書き込みます。ブックマーク、埋め込み、リンクプレビューも、このとき HTML とメタデータに変換します。
  4. 描画:返ってきたオブジェクトを <Page><Table><Gallery> などのコンポーネントに渡します。コンポーネントは Notion に似たマークアップを出力し、参照するのはローカルのファイルだけです。そのため、生成された HTML は Notion にも Notion の URL にも依存しません。

エクスポーターはビルド中に Node.js で動きます。 呼び出す場所は、Next.js のサーバーコンポーネント、getStaticProps、Astro のページのフロントマターなどです。 コンポーネントは通常の React コンポーネントで、サーバー側で描画されます。 一部(カレンダーの月送り、トグル、コードのハイライト、Mermaid の図、PDF ビューア)はブラウザでも動きます。

向いている用途

Rotion が向いているのは、コンテンツを Notion で書き、変更の頻度が再ビルドで間に合うサイトです。 ブログ、ドキュメント、ポートフォリオ、変更履歴、イベントカレンダーなどが該当します。 編集者は Notion で書き続け、公開するときにサイトを再ビルドします。 出力が静的なので、GitHub Pages、Cloudflare Pages、S3、任意の CDN でホストでき、Notion のトークンがビルド環境の外に出ることもありません。

一方で、Notion をそのまま映すものではありません。 変更がサイトに反映されるのは次のビルドの後です。 サイトから Notion へ書き込むことも、閲覧者のログインが必要なページを見せることもできません。 また、Rotion が扱うのはこのドキュメントに載っているブロックとデータベースプロパティの種類で、Notion が表示できるものすべてではありません。 対応していないブロックは描画されません。

対応するフレームワーク

  • Next.js App Router:サーバーコンポーネントからエクスポーターを呼び、createClientLinknext/link を Rotion のコンポーネントに渡します。App Router を参照してください。
  • Next.js Pages RoutergetStaticPropsgetStaticPaths からエクスポーターを呼び、データを props として渡します。Pages Router を参照してください。
  • Astro.astro のフロントマターからエクスポーターを呼び、@astrojs/react を通じて Rotion の React コンポーネントを描画します。サンプル を参照してください。

ビルド時に Node.js のコードを実行できる React の環境であれば、ほかの構成でも同じように使えます。

次に読むページ

Last updated on