North Detail / ノースディテール

BLOG ブログ

ブログ
CATEGORY
TECH

【Nuxt.js + Notion API】Todoアプリを作る(前編)

最近タスク管理やメモアプリとして人気があるNotionですが、2022年3月にAPIが正式にリリースされました。
今回はNotionをデータベースとして利用し、Nuxt.jsでデータを取得する使い方をTodoアプリ構築で実践してみたいと思います!

※Todoアプリは、シンプルなCRUD(Create:生成・Read:読み取り・Update:更新・Delete:削除)操作を体験できるので、基礎的な学習にはとても向いています。

前提

  • Notionアカウント作成済み
  • Node.jsインストール済み(npmが利用可)
  • OS : Windows / macOS どちらでも可

※今回の記事はNotionページからデータを取得・更新のみを扱います。
(データ追加や削除は後日公開する予定です)

Notion APIとは

Notion API : https://developers.notion.com/

Notionのデータベースページ等をJSON形式で取得できるAPIです。
データベースページに対してCRUD操作を一通り行うことができます。

Nuxt.jsとは

Nuxt.js : https://nuxtjs.org/

Vue.jsの開発をより早く、簡単にするために作られたフレームワークです。
サーバーサイドレンダリングやアプリケーションの構築自体もシンプルに行うことができ、静的サイトジェネレータとしての機能も有します。

構築の流れ

  1. [Notion]API作成
  2. [Notion]ページ作成
  3. [Notion]API連携
  4. [Nuxt.js]プロジェクト作成・初期設定
  5. [Nuxt.js]データの取得処理
  6. [Nuxt.js]データの更新処理

Notion API作成

Notion API : https://developers.notion.com/

上記URLにアクセスし、画面右上にある View my integrations に進みます。

※ログイン画面が表示された方はそのままログインしてください。

次に New integrationCreate new integration をクリックします。
(最近Notionが日本語対応になったので、日本語表記になっているかもしれません)

Basic Information というページに遷移するので、ここでは今回利用するAPIの設定をします。

今回の作成するAPIでは、Nameは自由、他はデフォルトの設定のままで問題ありません。
Associated Workspaceについては今回利用するアカウントになっているかだけ確認してください)

その後、画面下にある Submit をクリックします。
すると Secrets という画面に遷移したと思います。

次の「Notionページ作成」の手順で Internal Integration Token を使うので、 一旦このSecretsページはこのままにしておきます。

Notionページ作成・API連携

Notion : https://www.notion.so/

ブラウザで別のタブを開き、自身のNotionを開きます。
自身のNotionが表示されたら画面左下の + New Page をクリックします。

タイトルはお好みで問題ありません。
この記事では「Nuxt_Notion_for_Blog」にしておきます。

続いて本文で「/」を入力するとテンプレートを設定するポップアップが表示されます。

そこで中段あたりの、DATABASE のすぐ下にある Table View を選択します。

すると下記画像のような表示になるので、右下の + New Database をクリックします。

テーブル形式の画面が表示されるはずなので、画面左上 Open as page をクリックします。

テーブルには好きなように入力しておいてください。
後ほど情報取得確認に利用します。

その後、右上の shareInvite をクリックし、先ほど作成したAPI ( Integration )が表示されるのでそちらを選択します。

少し長かったですが、これでNotion側の作業は完了です。

Nuxt.jsの実装

お好みのディレクトリでcreate-nuxt-appを実行します。

npx create-nuxt-app nuxt_notion

※npxが使えない場合、npmのバージョンが古いかもしれません。(npxはnpm 5.2.0以上で利用できます)

いくつか質問されますので今回は下記のように設定します。

create-nuxt-app v4.0.0
✨  Generating Nuxt.js project in nuxt_notion
? Project name: nuxt_notion
? Programming language: JavaScript
? Package manager: Npm
? UI framework: None
? Nuxt.js modules: Axios - Promise based HTTP client
? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? What is your GitHub username?

※ (Press <space> to select... となっている箇所は何も選択せずEnterで進んでください。
少し時間がかかりますが、これで初期設定状態のNuxtアプリが作成されます。

下記でブラウザにNuxt.jsの画面が表示されれば成功です。

cd nuxt_notion
npm run dev

確認できたら、一旦 ctrl + c で停止してください。

データの取得

まず nuxt_notionディレクトリ直下に .env ファイルを作成します。
.envは公開すべきではないファイルなので、Git管理する際は.envファイルは除外してください)

NOTION_TOKEN = 最初に作成したSecretsページのInternal Integration Token
DATABASE_ID  = データベースID (下で説明しています)

データベースIDはデータベースページのURL内に含まれています。 下記の*****の部分がデータベースIDです。

https://www.notion.so/*****?v=123456789>

Notion APIでは便利なパッケージが用意されているので npm でインストールしてください。

npm install @notionhq/client

今回、最低限のデザインとしてBootstrapを利用するのでNuxt.config.jsを開き下記のように追記してください。 初期状態では16行目あたりに追記することになります。

link: [
  { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
  {
    rel: 'stylesheet',
    href: '<https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css>'
  }
]

ここまでの作業がとても長かったと思いますが、
ここでやっとNotion APIからデータを取得し、画面に出力します!

pages/index.vue を下記のように記述します。

<template>
  <ul class="list-group w-50 m-auto p-3">
    <li v-for="item in results"
        :key="item.id"
        :id="item.id"
        class="list-group-item d-flex align-items-center justify-content-between">
      <p contenteditable class="mb-0">{{item.properties.Name.title[0].text.content}}</p>
      <button @click="updateItem" class="btn btn-info flex-shrink-0">更新</button>
    </li>
  </ul>
</template>

<script>
import { Client } from '@notionhq/client';
const notion = new Client({auth: process.env.NOTION_TOKEN});

export default {
  async asyncData() {
    const myPage = await notion.databases.query({
      database_id: process.env.DATABASE_ID,
    })
    return myPage
  }
}
</script>

※buttonタグにある@click属性のupdate関数は後で実装します。
ローカルサーバーを起動してみます。
これで画像のように情報が表示されていたら成功です。

npm run dev

データの更新

データの取得ではasyncData()を利用できたため、サーバー側でAPI通信を行うことができました。

ここでは
「更新ボタンをクリックしてタイトルを更新する処理」
を実装しますが、ブラウザからAPI通信を行うとCORSエラーになり、上手く情報を更新できません。
そこでCORSを回避する為、Nuxt.jsで用意されている serverMiddleware を利用してサーバー側からAPI通信を行います。
まずpages/index.js に更新ボタンをクリックした時の処理を追記します。

下記に pages/index.js の全コードを表示しますが、
追記したのは<script>配下の methods: { 以降のみです。

<template>
  <ul class="list-group w-50 m-auto p-3">
    <li v-for="item in results"
        :key="item.id"
        :id="item.id"
        class="list-group-item d-flex align-items-center justify-content-between">
      <p contenteditable class="mb-0">{{item.properties.Name.title[0].text.content}}</p>
      <button @click="updateItem" class="btn btn-info flex-shrink-0">更新</button>
    </li>
  </ul>
</template>

<script>
import { Client } from '@notionhq/client';
const notion = new Client({auth: process.env.NOTION_TOKEN});

export default {
  async asyncData() {
    const myPage = await notion.databases.query({
      database_id: process.env.DATABASE_ID,
    })
    return myPage
  },
  methods: {
    updateItem(e) {
      const li = e.target.parentNode;
      const pageId = li.id;
      const text = li.querySelector('p').innerText;

      this.$axios.get(`${location.origin}/server-middleware-update?pageId=${pageId}&text=${text}`);
    }
  }
}
</script>

次にserverMiddleware を設定します。

nuxt_notion直下に serverMiddleware ディレクトリを作成して、その下に update.js を作成します。

import { Client } from '@notionhq/client';
import url from 'url';
const notion = new Client({auth: process.env.NOTION_TOKEN});

module.exports = (req, res) => {
  req.query = url.parse(req.url, true).query
  const pageId = req.query.pageId;
  const text = req.query.text;

  (async () => {
    const response = await notion.pages.update({
      page_id: pageId,
      properties: {
        Name: {
          title: [
            {
              text: {
                content: text
              }
            }
          ]
        },
      }
    });
    console.log(response);
  })();
  
};

最後にserverMiddlewareを使えるようにnuxt.config.jsに追記します。
記述する行はどこでも構いません。

serverMiddleware: [
  { path: '/server-middleware-update', handler: '~/serverMiddleware/update' }
],

これで更新処理も完了しました。
http://localhost:3000/
にアクセスしリロードしてください。

その後、タイトルをクリックして編集、更新ボタンをクリックでNotionのデータベースが更新されていることを確認してみてください。

以上でデータ更新もできるようになりました!

まとめ

今回、データベースへの追加と削除は説明しませんでしたが、更新と似た考え方で実装できます。
近いうちにそちらもブログで紹介したいと思います。
Notionは今後も発展していくWebサービスだと思うので、覚えておいて損はないかと思います!
またAPIを使わなくても、とても便利なサービスなので是非使ってみてください!
(といっても僕はあまり使いこなせていませんが...)
読んでいただきありがとうございました!!

次回(予定):追加・削除機能の実装

gk
WRITER:gk
自然と野生動物が好きですがインドア派のコーダーです。
主な記事 一覧へ

一覧へ

IS 501383 / ISO 27001