ブログをmorethan-logに引っ越しました
/ 9 min read
Updated:Table of Contents
はじめに
ふと思い立ち、osmiumで作っていたブログをmorethan-logというNext.js製のブログに引っ越しました。どちらもコンテンツはNotionで管理するので引っ越しは、Notionのプロパティを少し変更する程度で済みました。
GitHub - Tatsumi0000/morethan-log: 😎 A static blog using notion database
ただ一部だけmorethan-logに使いたい機能がなかったりしたので、少しコードに変更を加えました。今回は個人的に変更した箇所について、紹介します。
OG機能
動的にOGを出すためにもともとはvercel/og-imageを使っていたのですが、すでにDeprecatedになっていたので、後継版のvercel/ogに引っ越しました。
vercel/ogをローカルで動かしたところ、デフォルトでは日本語フォントに対応してないようでした(漢字が入るとエラーになっていました)。
これを解決するには日本語フォントを一緒にバンドルしてVercelのEdge Functionsにデプロイするという方法があります。ただ日本語フォントが容量が重く(4MB程度!)無料プランの容量制限(1MB)に引っかかってデプロイできませんでした。
サブセット化することでフォントサイズを500kb程度に減らしたのですが、それでも他のファイル関連の影響か、最終的な容量が1MBを超えて無理でした。
エラーになったログ
そこで、OGを生成するタイミングで毎回Google Fontsからフォントファイルを取得して、画像を生成するようにしました(これに関してはどこかでまた記事にします)。かなり通信量を無駄にしているのですが今回はこれでしのぐことにしました。
ただし、この方法は問題点もあります。毎回フォントファイルを取得している関係か、正常にOGを表示しないことがあります。おそらく、サービス(TwitterやInstagramなど)側でOG画像を表示する時間?を過ぎて正常に表示されないんじゃないかな〜と思っています。これもあってもう一度サブセット化のリベンジをしたいです…
OGの背景画像はここからいただきました。色々おしゃれな背景があるのでおすすめです。
RSS機能
RSS機能がなかったので作りました。工夫点としては、RSSを5件だけ表示するようにしました。
というのも既存のNotionとやりとりするClientでは、投稿を全部取得する処理になっておりこのままだと、記事数が増加した時にVercelのタイムアウトの時間である10秒に引っかかる可能性がありました(記事数60件近くの状態で7~8秒かかってました)。
そのため、記事数や公開状態を指定して取得できるクライアントを作って、それを使うようにしました。
const { Client } = require("@notionhq/client")const notionClient = new Client({ auth: process.env.NOTION_SECRET_KEY,})export const getPosts = async (page_size = 100) => { const response = await notionClient.databases.query({ database_id: process.env.NOTION_PAGE_ID, page_size: page_size, sorts: [ { property: "date", direction: "descending", }, ], filter: { property: "status", select: { equals: "Public", }, }, }) return response}
export interface RSS2 { title: string summary: string date: Date slug: string}Notionの方にstatusという記事の公開状態を設定するプロパティを持っています。この中には、PublicやPrivate といったパラメータを定義しているので、この値を使って公開状態の記事のみを取得するようにしました。他にも、公開日時を表すdate というプロパティがあるのでそちらを使って降順で取得します。
使うときはこのように使っています。
import { getPosts, RSS2 } from "./getPosts"
export const getPostsRSS2 = async (page_size = 100) => { let rss2: RSS2[] = [] const response = await getPosts(page_size) response.results.forEach((result: any) => { rss2.push({ title: result.properties.title.title[0].plain_text ?? "", summary: result.properties.summary.rich_text[0]?.plain_text ?? "", date: new Date(result.properties.date.date.start), slug: result.properties.slug.rich_text[0]?.plain_text ?? "", }) }) return rss2}RSSの生成自体はosmiumを参考にfeedライブラリを使って実装しました。
これらの工夫をした結果、6秒程度に短縮されてタイムアウトの心配もなくなりました!!1
キャッシュも設定しているので2回目のアクセスは1秒程度で返していました。Vercel上のログのスクショも貼っておきます。
初回アクセス時のログ
2回目のアクセスログ
その他
ローカルの開発環境でDockerを使っていなかったのでDocker上で開発できるようにしました。Dockerのコマンドを毎回入力するのは大変なので、ついでにMakefileも作りました。これに関しては本体の方にもPull Requestを送ってマージしていただきました。
フォント関連では、もともと入っていたPretendardをPretendardJPに変更しました。最初のフォントでも大きく違和感はなかったのですが、よく見るとひらがなと漢字のサイズ感が微妙に違っていたので変更したところ、きれいに表示するようになりました。
Pretendardフォントは初めて聞いたのですが、韓国だと結構有名なフォントみたいです。線の太さなどが自分好みですごく気に入りました🫰これからも積極的に使っていきたいです!
終わりに
morethan-logに引っ越すにあたり、修整した箇所を紹介しました。初めてがっつりNext.jsをさわったのですが、当初思っていたよりは簡単にコードを書くことができました。きっと以前Gatsbyのブログを改修するためにReactを触ったのが役にたったのかもです。
とりあえず気になるところは修正できたので、OGが時々表示されない問題をどうにかしたいなと思います。
参考文献
- morethanmin/morethan-log
- vercel/og-image
- Introducing OG Image Generation: Fast, dynamic social card images at the Edge – Vercel
- 【デザイン不要】@vercel/ogを使っていい感じの動的OGPをつくる
- Haikei
- Satori に Google Fonts を使う - つまみログ
- jpmonette/feed
- Query a database
- Filter database entries
- makenotion/notion-sdk-js
- orioncactus/pretendard