ヘッダーロゴ

【事前準備〜ブラウザ表示編】Notion の記事でブログサイト作成

2022-02-11

Notion

API

hero画像

はじめに

Notion の記事でブログサイトを作成する課題、正直右も左もわからない状況でした。わからないことがわからないというカオスな状況でした。そのような状況でしたがひとつひとつ整理して取り組むことで、カオスな状況を脱却できたのでフェーズごとにまとめていきたいと思います。

同じように右も左もわからない方の参考になれば幸いです。

こんな方におすすめ

  • 大枠の流れを実装を通じて把握したい方
  • まずはブラウザに表示させることを最短で体験したい方

事前準備でやること

  • Notion を公開する鍵( Token )を取得
  • Notion でテーブルデータを作成
  • 作成したテーブルデータと公開する鍵( Token )を紐付ける
  • デーブルデータの ID を取得
  • Next.js でデータを取得してみる

Notion の公開鍵の取得に関しては、 こちら を確認してください。この後、公式ドキュメントをもとに流れを解説していきます。うまく実装できなかった方は確認してください。

Notion の鍵を取得しよう(秘密のチケット)

Notion の公式ドキュメントに入り、右上の My integrations に入ります。

画像

公式ドキュメントの動画通りにすすめていきます。

名前と紐付ける Notion のワークスペースを選択し送信します。

送信後、簡単に Token が発行されます。表示を押すと、Token が実際に表示されコピーボタンが表示されるのでコピーします。Token はこの後使用するので、任意の場所で保管しておきます。

画像画像

公開鍵はユーザーが Notion に渡す秘密のチケットです。このチケットを持っていないと、Notion という会場に入れません。

Notion でテーブルデータを作成

今回は 「Notion blog テスト用」のページ内に「アウトプット用のテーブルデータ」を作成します。

テーブル:フルページ で作成すること

画像

今回、テーブルデータは Title Data User にしてみました。このTitle などは Key として活用します。

画像

テーブルデータと 公開する鍵( Token )を紐付ける

右上の共有から招待を選択します。

画像

先程作成したインテグレーションが表示されていますので選択します。私は fwywd_blog という名前で作成しています。選択したら招待します。

画像

以下のように選択したインテグレーションが表示されていれば準備完了です。

画像

そうしたらリンクをコピーします。これもあとで使用するので、任意の場所で保存するか実装するときに必要になることを覚えておきます。

// 今回取得したリンク先 https://www.notion.so/75643bde82744edca9770c6d7c01cd9e?v=d5221eb0bef34e17a819ac2dd0499649

ながーいリンク先ですが、実際に使用するのは 75643bde82744edca9770c6d7c01cd9e これだけです。「notion.so/ リンクID ?v=」notion.so/から?の間だけ使用します。

Next.js 側でデータを取得してみよう

では実際に実装していきます。今回は Title Date User に入力されている値を取得し、ブラウザ上に表示させることをゴールとします。

画像

ゴールにたどり着くまでやることは…

  • Notion の公開鍵( Token )とデータベースのリンクID を環境変数で保存する
  • Notion の要素を Next.js 側でも作成できるパッケージ( "@notionhq/client” )をインストール
  • Notion のデータ要素の全体像を把握する
  • 全体像からどの要素を取得したいのかを把握する
  • 取得したい要素に対しての API リファレンスを実行する(公式ドキュメントは
  • 取得した要素をJSX で表示されるようにする

環境変数に公開鍵とデータベースのリンクID を保存する

環境変数に関して、詳しい説明は fwywd の記事で詳しく書いていますのでこちらを確認します。確認しましたが、.env ファイルとはなにかがわからず、かなり調べ時間を費やしました…非常に簡単でした…

メインディレクトリに .env ファイルを作成するだけでした。

画像

作成した .env.local に保存する前に Notion の公式ドキュメンを確認します。今からやる作業はどこに紐付いているのかを把握していきます。

Guides ➣ Getting started ➣ Step 3 のことをやっていきます。ここで export NOTION_KEY=secret_... とあるように毎回、公開鍵とデータベースIDを入力する必要があります。その手間を事前に .env ファイルに保存しいつでも呼び出せる状態にしていきます。

mkdir notion-example cd notion-example export NOTION_KEY=secret_... export NOTION_DATABASE_ID=...

“ ” や ‘ ’ で括る必要はなく、そのまま貼り付けて保存します。

画像

注意点として、.env ファイルはリポジトリされないように設定する必要があります。公開したくないファイルを設定できるのが .gitignore です。だたし初期設定で既に .env ファイルが指定されているので問題はありません。

画像

"@notionhq/client” をインポート

インポートするだけですが、もう一度公式ドキュメントの Step 3 に戻ります。なにやらこの3行がポイントになりそうです。

import { Client } from "@notionhq/client" const notion = new Client({ auth: process.env.NOTION_KEY }) const databaseId = process.env.NOTION_DATABASE_ID

①"@notionhq/client” から Client という技を取得。

②Client を利用して Notion の公開鍵を使用し、Notionにアクセスできるようにします。アクセスする前に許可をもらう必要があるので、 auth(認証)というキーに公開鍵を渡して notion という変数に 取得した要素を保存しています。

画像

③アクセスしたいデータベースID をdatabaseId という変数に保存。

②③で共通している process.env は envファイルから指定したデータを取得する手順になっています。process が必要なんだな、程度の理解で問題ないです。

前置きが長くなりましたが、"@notionhq/client” をインストールします。

// npm の場合 npm install @notionhq/client // yarn の場合 yarn install @notionhq/client

package.json の dependences に “@notionhq/client” が入っていれば成功です。

画像

Notion のデータ要素の全体像を把握する

では実際に Notion から情報を取得していきたいところですが、ここで Notion の全体像を把握していきます。

この把握が曖昧だと、後々どこのデータを取得しようとしているのか?そのためにはどのようにアクセスする必要があるのか?がわからず、迷子になります。

画像

先程でてきた Client の部分、これは要素が一番大きい Notion 全体、databaseId は次に要素が大きいdatabaseId にアクセスする準備であることが理解できます。

const notion = new Client({ auth: process.env.NOTION_KEY }) const databaseId = process.env.NOTION_DATABASE_ID

欲しいデータを取得

実装しながら確認していきます。今回は index.tsx ファイルを使用していきます。最初はこの状態からスタートします。

※今回、TypeScript で記述していますが型定義は全て any で一旦回避しています

import Head from 'next/head'; export default function Home() { return ( <> </> ); }

公式ドキュメント通り追記していきます。

// 追記 import { Client } from '@notionhq/client'; import Head from 'next/head'; // 追記 const notion = new Client({ auth: process.env.NOTION_KEY }) const databaseId = process.env.NOTION_DATABASE_ID export default function Home() { return <></>; }

でもこれだけだと本当に取得したデータ、値が取れているか不安になりますね。そんな場合は console.log() でこまめに確認していくことをおすすめします。

import { Client } from '@notionhq/client'; import Head from 'next/head'; const notion = new Client({ auth: process.env.NOTION_KEY }) const databaseId = process.env.NOTION_DATABASE_ID // 追記 console.log(notion) console.log(databaseId) export default function Home() { return <></>; }

ローカルサーバーを立ち上げます。ブラウザ上は、今の状態では真っ白ですがターミナルに console.log の結果が出力されています。

// console.log(notion)の結果 Client { blocks: { retrieve: [Function: retrieve], update: [Function: update], delete: [Function: delete], children: { append: [Function: append], list: [Function: list] } }, databases: { list: [Function: list], retrieve: [Function: retrieve], query: [Function: query], create: [Function: create], update: [Function: update] }, pages: { create: [Function: create], retrieve: [Function: retrieve], update: [Function: update], properties: { retrieve: [Function: retrieve] } }, users: { retrieve: [Function: retrieve], list: [Function: list], me: [Function: me] } } // console.log(databaseId)の結果 75643bde82744edca9770c6d7c01cd9e

変数 notion databaseId にしっかりと欲しかったデータが代入されていることが確認できました。

今回はデータベースから情報を取得します。Notion の公式ドキュメントの左側に、それぞれの要素に対してどのようにアクセスするのか書いていますので、こちらを参考にしてください。

画像画像

今回のゴールはデータベースの値を送りたいので、POSTメソッドの Query a database を使用します。

完成したコードを先に確認してみましょう。

import { Client } from '@notionhq/client'; import Head from 'next/head'; const notion = new Client({ auth: process.env.NOTION_KEY }); const databaseId = process.env.NOTION_DATABASE_ID; export default function Home({posts}: {posts:any}) { return ( <> <p className='p-2'>{`タイトル:${posts.posts.results[0].properties.Title.title[0].plain_text}`}</p> <p className='p-2'>{`日付:${posts.posts.results[0].properties.Date.date.start}`}</p> <p className='p-2'>{`著者:${posts.posts.results[0].properties.User.people[0].name}`}</p> </> ); } export async function getStaticProps() { const response = await notion.databases.query({ database_id: databaseId! }); return { props: { posts: response }, }; }

ローカルサーバーを立ち上げブラウザで確認してみます。

画像

タイトル、日付、名前が取得できました。

全体の流れを確認します。

export async function getStaticProps()〜

export default function Home({posts}: {posts:any})

return (<>....</>)

できましたが、私は③で苦労しましたので、タイトルを取得するまでの手順を例にして解説していきたいと思います。

JSX 内でデータの出力を都度確認していこう

getStaticProps で渡されたデータを正しく受け取っているか確認します。

export default function Home({posts}: {posts:any}) { // 追記 {console.log(posts)} return ( <> <p className='p-2'>{`タイトル:${posts.results[0].properties.Title.title[0].plain_text}`}</p> <p className='p-2'>{`日付:${posts.results[0].properties.Date.date.start}`}</p> <p className='p-2'>{`著者:${posts.results[0].properties.User.people[0].name}`}</p> </> ); }
// ターミナルの出力結果 { object: 'list', results: [ { object: 'page', id: 'ed36a8df-806e-4507-868b-c548cc1418ee', created_time: '2022-02-10T21:51:00.000Z', last_edited_time: '2022-02-10T22:47:00.000Z', cover: null, icon: null, parent: [Object], archived: false, properties: [Object], url: 'https://www.notion.so/ed36a8df806e4507868bc548cc1418ee' } ], next_cursor: null, has_more: false }

しっかりデータが渡されていることが確認できました。ここでポイントになるのが、データがJSON形式であることです。

posts のオブジェクトに、object と results の2つの要素が入っています。オブジェクト指向のイメージはこちらです。posts が下図でいうと一人の男性に当たります。

画像

一つ一つ丁寧に console.log していき、欲しいデータを取得していきます。

{console.log(posts.results)} // ターミナルの出力結果
{console.log(posts.results[0].properties)} // ターミナルの出力結果 { Date: { id: 'iUzE', type: 'date', date: { start: '2022-02-11', end: null, time_zone: null } }, User: { id: 'wYUn', type: 'people', people: [ [Object] ] }, Title: { id: 'title', type: 'title', title: [ [Object] ] } }

タイトルが欲しいので、タイトルのキーを確認します。Title で作成していましたので Title を選びます。

{console.log(posts.results[0].properties.Title)} // ターミナルの出力結果 { id: 'title', type: 'title', title: [ { type: 'text', text: [Object], annotations: [Object], plain_text: 'テスト用の記事①', href: null } ] }

だんだん近づいてきました。

{console.log(posts.results[0].properties.Title.title[0])} // ターミナルの出力結果 { type: 'text', text: { content: 'テスト用の記事①', link: null }, annotations: { bold: false, italic: false, strikethrough: false, underline: false, code: false, color: 'default' }, plain_text: 'テスト用の記事①', href: null }

次で完成します!長い!!

{console.log(posts.results[0].properties.Title.title[0].plain_text)} // ターミナルの出力結果 テスト用の記事①

できました…長い道のりですね…

あとは return() 内へコピーしてあげれば完成です!

まとめ

細かい部分は、また別の記事でまとめていきたいと思います。

Notion のデータを取得してブラウザに反映する、流れはすごい簡単ですがその過程にいくつもの壁が待っています…

まだまだ不明点があるので、アウトプットしながら理解を深めていきたいと思います。

created by

片山 真介

フッター画像
Twitter画像Facebook画像

© Shinsuke Katayama