佐藤 あゆみ
佐藤 あゆみ

necco Note

NotionをCMSとして使う、astro-notion-blogをVercelで動かしてみた

  • Web Development

NotionをCMSとして活用し、フレームワークにAstroを使ってブログサイトを生成するastro-notion-blogが2023年1月23日にリリースされました。

ブログは速さこそ正義である。
astro-notion-blogはそんなストイックで玄人志向な人のために作った新しいNotionブログです。

https://alpacat.com/blog/introduction-of-astro-notion-blog/

astro-notion-blogのREADME.mdではデプロイ(公開)先としてCloudflare Pagesが紹介されていますが、今回、私はVercelにデプロイできるかどうかを試してみました。

完成したブログサイト: LIMA note

なぜVercelを?

日ごろからVercelを使っているから、というのが大きな理由です。Vercelの管理画面は美しいです。

下準備

astro-notion-blogのREADME.mdに記載されている手順の通り、まずは規定のNotionデータベースを自分のNotionに複製します。

スクリーンショット:Notionのデータベースを表示しているページ

複製したページのURLから、データベースIDを抜き出し、 DATABASE_ID としてメモします

<https://notion.so/your-account/><ここがデータベースID>?v=xxxx

NotionのMy integrations ページから新しいインテグレーションを作成し、生成された “Internal Integration Token” を NOTION_API_SECRET としてメモします。

スクリーンショット:Notionの新しいインテグレーションを作成した画面

Notionページを開き、先ほど作成したインテグレーションを接続します。

スクリーンショット:インテグレーションをNoitonページに接続しているところ

astro-notion-blogのGitHubリポジトリをフォークし、フォークしたリポジトリを自分のPCにクローンします。

スクリーンショット:GitHubの「Fork」ボタンを矢印で示している
リポジトリをフォークする
スクリーンショット:GitHubの「Code」ボタンを矢印で示している
Codeボタンをクリックし、表示される選択肢からクローン方法を選ぶ

以後、公式のREADME.mdではここからCloudflare PagesにGitリポジトリを連係する手順を紹介していますが、私はVercelに繋ぎ込みたいので、いったんローカルで動作を確認してみます。

ローカル環境で動作確認

公式ではパッケージマネージャーとしてyarnが推奨されていますが、私はnpm派なので、npmでインストールし、Astroを立ち上げてみます。

npm i
npm run dev

無事にAstroが立ち上がりました(よかった)。

ただし、この時点ではまだ環境変数を設定していないため、記事は表示されず、Blogページに遷移しようとするとエラーが出ます。

2023/03/06追記:最新版のastro-notion-blogにはdotenvが入らなくなったため、以下の手順を進む前に npm i dotenv でdotenvをインストールしてください

プロジェクトフォルダー直下に、新しいファイル.env.localを作成し、メモしておいた環境変数を記入します。

DATABASE_ID="XXXXXXXXXXXXXXX"
NOTION_API_SECRET="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

※.env.localは秘密にすべき情報が含まれているため、GitHubにコミット/プッシュしないようにしましょう。.gitignoreに.env.localを追加すると、コミット時にファイルを無視できます。

設定したら、 npm run dev で Astroを立ち上げ直します。

無事に記事も表示されました!

スクリーンショット:astro-notion-blogで記事が無事に表示されている様子

ブログ名とブログの説明文は、src/server-constants.tsで定義されています。適宜、書き換えます。

同じファイル内で、1ページに表示する記事の数や、Google AnalyticsのトラッキングIDも設定できるようになっているんですね。至れりつくせりです。

export const NOTION_API_SECRET = import.meta.env.NOTION_API_SECRET
export const DATABASE_ID = import.meta.env.DATABASE_ID
export const PUBLIC_GA_TRACKING_ID = import.meta.env.PUBLIC_GA_TRACKING_ID
export const NUMBER_OF_POSTS_PER_PAGE = 10

export const PUBLIC_SITE_TITLE = 'astro-notion-blog'
export const PUBLIC_SITE_DESCRIPTION = 'astro-notion-blog is generated statically by Astro'

GitリポジトリをVercelと連係する

Vercelで Add New…→ Projectから、新しいプロジェクトを作成し、先ほど作成したGitリポジトリをImportします。

設定のEnvironment VariablesにDATABASE_IDNOTION_API_SECRETを設定して、最下部のDeploy(公開)ボタンを押します。

…なんということでしょう!何の設定も変更せずにVercelにデプロイ(公開)できました🎉

スクリーンショット:astro-notion-blogで記事が無事に表示されている様子

見た目はもう完成しているように見えますが、OGP情報を正しく表示するために追加の設定が必要です。また、独自ドメインもあわせて設定をしていきます。

独自ドメインを設定する

Vercel上で、独自ドメインを設定していきます。今回はサブドメインを設定します。

Settings→Domainsとすすみ(1)、設定したいドメイン名を入力して(2)、Addボタンを押します(3)。

利用しているドメイン会社の管理画面で、Vercel上に表示された通りにCNAMEレコードを追加します。

私はGoogle Domainsを利用しているので、下記のような設定になりました。

上記を設定してからVercelの管理画面に戻ります。 CNAMEの設定が反映され次第、SSL証明書の発行が始まり、独自ドメインの設定が完了します。

設定が完了したので、Valid Configurationにチェックマークがついている

カスタムドメインを設定する

プロジェクトフォルダー直下のastro.config.jsCUSTOM_DOMAINを設定する箇所があります。こちらに先ほどの独自ドメインを設定します。
※独自ドメインを設定しない場合は、Vercelの初期公開ドメインを設定します。

また、CloudFlare向けの設定 process.env.CF_PAGES をVercel向けの設定process.env.VERCEL_URLに書き換え、その次の3行を削除します

下記のようなコードになります。

const CUSTOM_DOMAIN = "scrap.lima.world"; // <- Set your costom domain if you have. e.g. alpacat.com

const getSite = function () {
  if (!process.env.VERCEL_URL) {
    return "<http://localhost:3000>";
  }

  if (CUSTOM_DOMAIN) {
    return `https://${CUSTOM_DOMAIN}`;
  }

  return `https://${process.env.VERCEL_URL}`;
};

VercelのEnvironment Variablesに関する詳細はこちら

コードを保存してGitHubにプッシュすれば、Vercelでデプロイが始まります。

以上で、ブログの設定は完了です!

デプロイリンクを作成する

astro-notion-blogは、Notionで記事を作成したり、変更しても、公開サイト上には即時反映されません。Vercelでデプロイをかけた場合にのみ公開サイトに反映されます。

VercelのダッシュボードへのリンクをNotionに設置して、ダッシュボードでRe-deployボタンを押して更新するのも一案ですが、Vercelのデプロイフックを利用すれば、NotionページからURLをワンクリックするだけでデプロイを作動させられるようになります。

VercelのProject Settings→Gitを開きます(1)。Deploy Hooksにて、Hookの名称とブランチ名を指定して(2)、 Create Hookボタンを押して(3)新しいデプロイフックを作成します。

※スクリーンショットではブランチ名を指定し忘れていますが、mainを指定します

デプロイフックが作成できたら、Copyボタンをクリックして、デプロイフックのURLをコピーします。

スクリーンショット:デプロイフックURLのCopyボタンを矢印で示している

Notionでブログ用のデータベースのページを開き、先ほどコピーしたURLをリンクとして分かりやすい場所に設置します。このリンクをクリックしたタイミングで記事を公開できるようになります。

スクリーンショット:NotionでデプロイフックのURLを説明欄に追加している

リンクをクリックすると、下記のように文字列が表示されます。クリック後の画面上にはstateがPendingと表示されますが、Vercelのダッシュボードを確認すればデプロイがかかっているのが分かります。

定時にデプロイする

公開ボタンを押すのは忘れそう、という場合は、上記で取得したデプロイフックと、GitHub Actionsを組み合わせれば、手軽に定時にデプロイをかけられます。詳しくは下記のWikiにて解説されています。

Astroは直感的にアレンジできる

Astroはシンプルなフレームワークです。いままでJekyllなどの静的サイトジェネレーターを使用した経験があれば、すぐに理解できます。また、動的ルーティングは Next.js にも似た getStaticPaths 関数を使うといった特徴もあり、双方の経験があればなお分かりやすく感じます。HTMLページを生成するという目的において、Astroは今まで存在していたサイトジェネレーターのいいとこ取りをしたフレームワークだと感じました。

コードを眺めつつ、私は下記のようなアレンジを加えてみました。

  • HTML(見出し)の構造変更
  • もろもろスタイル調整
  • トップページに(固定のコンテンツページではなく)記事の一覧を出す

astro-notion-blogは、必要な機能が揃いつつもシンプルな構成のため、とてもかんたんにアレンジできました。

※ Next.js → Astroへの乗り換えをご検討中の方には、「Next.js にあるアレ、Astro でどうするか」の記事もオススメです。

NotionをブログCMSとして使った感想

今回は、過去に作っていた、現在は閉鎖中のWordPressサイトからコンテンツを数ページ移行しました。また、WordPressは世界で一番有名なCMSでもあるため、比較として名前を出します(他意はありません…!)

Notionは文章を書きやすい

書きやすさでいえば、私はNotionの方がWordPressよりも書きやすいと感じます。WordPressのブロックエディタは、ブログ記事を書くためだけではなく、固定ページのレイアウトなどさまざまな用途に対応できるように作られているため、操作がやや複雑になります。一方、Notionは、本文欄は文書の作成に特化しているため、シンプルに保たれています。

移動中など、スマートフォンで記事を書いたり見たりする時も、ブラウザでWordPressにログインして書くよりも、Notionのネイティブアプリを利用して書く方が手軽だと感じました。実は、このneccoブログの記事も、下書きはNotionで行い、原稿が完成したらWordPressに投稿している状況です。WordPressは、同一記事の複数人の同時編集には対応していませんが、Notionは対応しているので、書きやすいです。

また、外部のユーザーに記事を公開前に共有して添削してもらうような場合も、Notionであれば組み込みのページ共有機能やコメント機能を使えて便利です。

さらに、ヘッドレス系CMSと比較した場合には、Notionにもastro-notion-blogにも「ブックマーク表示(ブログカード)」が実装してある点も非常にありがたいです。ぱっと見シンプルに実装できそうでいて、実はやることが多くて大変なんですよね…。

Notionはデータベース

私は、Notionの実体は、データベースだと考えています。構造を検討してからプロパティを作成し、適切に関連付けを行なって運用すれば、超手軽に低予算で管理運用できるデータベースになります(好きです)。このため、astro-notion-blogもアイデア次第で自分好みの分類や機能を自在に追加でき、拡張性があると感じます。WordPress本体に備わっているメタフィールドと比べると入力もしやすいです。

ただし、データベースではあるものの、入力フォームではありません。プロパティにも本文にも、必須入力欄を設けられません。また、入力内容のバリデーションもできません。一人で緩く運用するぶんには困りませんが、複数人で運用を始めるとマニュアルが必要になる可能性があります。また、フロント側には、どんな値が渡ってきてもエラーにならないような処理を必ず組み込む必要があります。

Notionの本文の限界

Notionはそもそもウェブでコンテンツを公開するためのツールとしては作られていないため、WordPressなどのCMSと比較してやはり限界は感じます。

例えば、「任意HTML/scriptの挿入ブロック」を持っていないため、アフィリエイトパーツなどは貼り付けられません。また、セクションごとに背景色を変えたり、特殊な装飾を用意したり、リンクをボタン風にデザインレイアウトして見せるといった処理もできません。

実現したい場合は、ショートコードのような仕組みを自作して、Astro側でNotion本文をパースして処理をかけるなどの工夫が必要です。どうしても色々実現したい場合は、既存のNotionでウェブサイトを構築できるツールで採用している方法を模す形になりそうです(パクれとはいえませんが…!)

また、公開サイトのデザインや配色がNotionと大きく異なる場合、Notion側での見え方は調整できないため、プレビュー実装が必要になる可能性があります。特に、背景色が黒で本文が白文字などの場合は書きにくくなる可能性があります。WordPresssであれば公開サイトの配色に合わせたエディタースタイルが適用できるところです。NotionをCMSとして使う場合は、公開ページのデザインを可能な限りNotionに寄せておけば、プレビュー機能が不要なままで運用できますね。

さらには、例えば一部のコンテンツを更新予約するといった機能も、Notionに「バージョン(版)」の概念がなく、指定時にデプロイフックを叩くような機能もないため、難しいと思います。色々と頑張れば自作できなくはないとは思いますが…。WordPressであればこのような変更はプラグインやテーマの機能で対応できるところです。

使いどころ

個人のブログにはとても向いていると感じました。Notionは無料から使えますし、Vercelも非営利であれば無料で利用できます。Notionで手軽に書けるうえに、管理運用コストがかからないので維持しやすいでしょう。私もこれを機に趣味のブログを復活させてみようと思えました。これだけ手軽に書けるのですから。

また、よくある質問をまとめたサポートサイトなど、文章中心のサイト構築にも向いていると思います。

astro-notion-blogのすごさ

astro-notion-blogは全体的に丁寧に作られており、アレンジもしやすいです。

実は私も過去にNotionをCMSとして活用できないかと思い立ち、APIについて調べた経験がありますが、本文の仕様がとても複雑で、これは趣味の範囲でちょっと活用するには重すぎる、とその時には諦めました。NotionのAPIが本文をまるっとHTMLで返してくれるならアレンジしやすいのですが、本文のブロックごとにコンテンツを返してくる仕様になっていて、ひとつひとつのブロックに対応した処理を書かなければなりませんでした。さらに一度に取得できるブロック数やAPIへのアクセス頻度に上限があるため、さまざまな対策が必要です。NotionのAPIドキュメントはあまり充実しているとは言えないと感じており(公開してくれているだけでありがたくはありますが)、その面でも自力で対応するのは無理だと感じていました。

astro-notion-blogは基本的なブロック構成に対応済みで、自作する手間がなくなるため、それらを利用できることをとてもありがたく感じます。TwitterやYouTubeなどのembedにも対応しています…が、あまりメジャーではないその他の埋め込み系のブロックは自作する必要がありそうです。自作したらastro-notion-blogにプルリクエストを送りたいです。

ビルドの高速化にも対応

astro-notion-blogのv0.2 アップデートにて、Nx Cloudというサービスを利用したビルドの高速化にも対応しています。詳しくは「astro-notion-blog v0.2 アップデート内容の紹介」記事にて解説されていますが、ローカルで生成したキャッシュをCloudflare Pagesなどのリモートでのビルド時に使用することで高速にビルドできるそうです。すごい!

さっそくWikiに掲載されている手順にそって設定してみました。

私はnpmを利用しているので、コマンドが下記の表記に変わります。

npm i && npx nx g @nrwl/nx-cloud:init
npm run cache:fetch

また、Vercelへの設定になりますので、環境変数の設定は下記の画面から行ないました。

Settings -> Environment Variables

ビルドコマンドも下記の画面から変更します。

Settings -> General -> Build & Development Settings

しかしながら、私のブログは8記事しかないためか、恩恵が少なく、ビルド時間はほぼ変わりませんでした…!記事が多くなってきた場合に効力を発揮しそうです。
(Nx Cloudで確認するとremote-cache-hitになっているので、設定そのものはできているはずです)

導入手順の説明が親切

リポジトリのREADME.mdにて詳しく導入方法が説明されているほか、Wikiもあります。さらには、追加してほしいドキュメントのリクエストも受け付けていますTwitterコミュニティもあり、今後、ユーザー同士の交流も多くなってきそうですね。

Contributeしました

astro-notion-blogには、記事の詳細ページにタグを表示するエリアがあります。元々のタグのデザインはシンプルなリンクスタイルでした。これを、Notionで設定したタグの色をブログ側にも反映できるようにしたいと思いました。

スクリーンショット:タグが1色で表示されている
変更前のタグデザイン

src/lib/notion/client.ts内でAPIから取得したデータの整形を行なっているため、整形時にタグの色情報を含めるようにコードを変更しました。また、タグ表示のHTMLとCSSを変更して、取得したデータをもとにNotion風に表示できるように整えました。

スクリーンショット:タグが複数の背景色で表示されている
Notionに寄せたタグデザイン

もしかしたら、同じように表示したい方がほかにいるかも?と思い、プルリクエストを送ったところ、こころよく取り込んでくださいました!

現在は、詳細ページだけではなく、サイドバーのカテゴリー(タグ)一覧にもタグの色が反映されるように変更されています。

Notionのタグについて

Notion上でタグを追加すると、タグに自動的に色が割り振られるようになっています。このタグのUIは、私がNotionらしさを感じるもののひとつです。他のサービスで、タグやカテゴリーの追加時に「勝手に色が割り振られる」ものを私は見たことがありませんでした。自動的に色とりどりになるタグ一覧、面白いですよね。

アップデートが続々(予定)

このブログを書いている今日の時点にて、バージョン0.3が開発されています。

スクリーンショット: GitHub上で v0.3で対応予定の機能一覧が表示されている

実はこの中の「ファイルブロック対応」に関しては私が実装を予定していたのですが、想定していなかった罠「Notionにアップロードしたファイルのリンクの有効期限は1時間」があり、(私の)時間切れにて対応しきれず…開発者のotoyoさんにバトンタッチしています🙏中途半端で申し訳ないです。

astro-notion-blogはプルリク歓迎&コミュニティもありますので、気になる方は参加してみてはいかがでしょうか。
私も時間やタイミングの許す限り、本能の赴くままに、自分が素敵だなと感じるプロジェクト&プロダクトに参加できればと思っています。

これからの進化も楽しみにしています!

佐藤 あゆみ

佐藤 あゆみ

Ayumi Sato

ニューヨーク生まれ。まもなく東京に移住し、1994年から2年間のオーストラリアでの生活を経て、ふたたび東京へ戻り、今も暮らす。1997年頃より趣味としてWeb制作を始め、以後も独学で学ぶ。 音楽専門学校中退後、音楽活動での成功を夢見ながら、PCパーツショップやバイク輸出入会社、楽器店など、掛け持ち含めて計20以上(?)の業種でアルバイトを重ね、ECサイトの運営管理や自社サーバの管理、プログラミングなども学ぶ。音楽活動を展開する中で、集客やフライヤー制作、プロモーションビデオ制作を行い、周辺技術を身につけるきっかけとなるも、2011年頃に区切りをつけ、ウェブ制作で生計を立てることを決意。その後は画廊やウェブ制作会社などで勤め、2014〜2022年まではフリーランスとして活動。2018年より、CSS NiteやBAU-YAなどのイベント、スクールにて登壇。2019年に「HTMLコーダー&ウェブ担当者のためのWebページ高速化超入門」を出版。 趣味はガジェットいじり&新しいサービスを試すこと。

SHARE

Other Note

necco Note

フロントエンドエンジニア志望の初学者からアシスタントにお勧めしたい課題図書5選!