SvelteKitとmicroCMSで自作ブログを作ってVercelで公開してみた
はじめに
こんにちは!
SvelteKit、microCMSを使って自作ブログを作成してみたので共有したいと思います。
対象読者
- 自作ブログを作成したい方
- Svelte, SvelteKit, microCMS, Vercelを使ってみたい方
記事を読むメリット
- Svelte, SvelteKit, microCMSを使った自作ブログの作成方法がわかります
- Vercelへのデプロイ方法がわかります
結論
作成したブログはこちらです!爆速で作成できます。
使用技術
フロントエンド:Svelte(4.2.7) + SvelteKit v2
フロントエンドにはSvelteとそのフレームワークであるSvelteKitを使用します。
Svelteはコードの記述量が少ないことや、仮想DOMを使用しないのでコンパイル後のバンドルサイズが小さくなり高速に動作するなどのメリットがあります。
SvelteKitはReactで言うところのNext.jsの立ち位置で、ルーティング等の機能を提供します。
ヘッドレスCMS:microCMS
ヘッドレスCMSとはコンテンツ管理の機能のみをもつ、ビューのないCMSのことです。
microCMSは国産のCMSなのでコンソールやドキュメントが日本語に対応していると言う良さがあります。ホスティングサービス:Vercel
ホスティングサービスはVercelを使用します。
SvelteKitにも対応しており、Githubと連携して簡単にアプリケーションをデプロイできます。
プロジェクトの作成
下記のコマンドを実行してプロジェクトを作成して、開発環境を立ち上げます。
npm create svelte@latest my-app
cd my-app
npm install
npm run dev
下記の画面が立ち上がれば成功です。
microCMSのセットアップ
サービスの作成
microCMSにサインアップしたら、任意のサービス名、サービスIDでサービスを作成します。
APIの作成
次にAPIを作成します。「APIを作成」画面でブログのテンプレートを選択します。
ブログAPIが自動で作成されます。
下記のように、「コンテンツ一覧」画面にはサンプルの記事が作成されています。
画面右上のAPIプレビューを押してみましょう!
下記のように、JavaScriptとmicrocms-js-sdkでのAPI使用例と
APIを叩いた結果が表示されています。
早速APIを叩いてみる
APIキーの設定
microCMSでAPIを叩くにはリクエストにAPIキーを含める必要があります。
外部に漏らしてしまうのはセキュリティの観点からよくないので、環境変数として定義します。
プロジェクト直下に.env
を作成して、下記のように記載しておきましょう。
MICROCMS_SERVICE_DOMAIN=microCMS管理画面URL(XXXX.microcms.io)のXXXX部分
MICROCMS_API_KEY=「権限管理」>「APIキー管理」から確認
設定した環境変数は$env-static-private
というモジュールを使用して取得できます。
ディレクトリ構成
SvelteKitはファイルベースのルーティングを提供しています。
今回、下記のようなディレクトリ構成としています。
├── lib
│ └── microcms.ts
└── routes
├── +page.svelte // ルート
└── blogs
├── +page.server.ts // ブログ一覧取得
├── +page.svelte // ブログ一覧
└── [slug]
├── +page.server.ts // ブログ詳細取得
└── +page.svelte // ブログ詳細
src/routes
がルートとなっており、blogs
でブログの一覧を表示します。
slug
と言うパラメータを使用して、/blog/hello-world
など動的にルーティングすることが可能です。
今回はslug
に記事のidを渡して記事詳細を表示します。
また、ファイル名は+
の接頭語で識別されて下記のような責務で分かれています。
-
+page.svelte
: 画面を定義します。 -
+page.server.ts
: サーバのみで実行されるload
関数を定義します。+page.svelte
にdata
propsを介してデータを渡すことができます。
ブログ一覧/詳細の取得
microCMSのAPIを簡単に扱うためのSDKが用意されています。
JavaScriptからの利用なのでmicrocms-js-sdkをインストールします。
npm install microcms-js-sdk
SDKを使用してAPIを叩くsrc/lib/microcms.ts
を作成していきます。
microcms.ts
import { createClient, type MicroCMSImage, type MicroCMSQueries } from 'microcms-js-sdk';
import { MICROCMS_SERVICE_DOMAIN, MICROCMS_API_KEY } from '$env/static/private';
const client = createClient({
serviceDomain: MICROCMS_SERVICE_DOMAIN,
apiKey: MICROCMS_API_KEY
});
export type Blog = {
id: string;
createdAt: string;
updatedAt: string;
publishedAt: string;
revisedAt: string;
title: string;
content: string;
eyecatch?: MicroCMSImage;
};
export type BlogResponse = {
totalCount: number;
offset: number;
limit: number;
contents: Blog[];
};
// ブログ一覧取得
export const getList = async (queries?: MicroCMSQueries) => {
return await client.get<BlogResponse>({
endpoint: 'blogs',
queries
});
};
// ブログ詳細取得
export const getDetail = async (contentId: string, queries?: MicroCMSQueries) => {
return await client.getListDetail<Blog>({
endpoint: 'blogs',
contentId: contentId,
queries
});
};
サーバ側でブログ一覧と詳細を取得する処理を実装していきます。
src/routes/blogs
とsrc/routes/blogs/[slug]
にそれぞれ+page.server.ts
を作成します。
src/routes/blogs/+page.server.ts
import type { PageServerLoad } from './$types';
import { getList } from '$lib/microcms';
export const load: PageServerLoad = async () => {
return await getList();
};
export const prerender = true;
src/routes/blogs/[slug]/+page.server.ts
import type { PageServerLoad } from './$types';
import { getDetail } from '$lib/microcms';
export const load: PageServerLoad = async ({ params }) => {
return await getDetail(params.slug);
};
export const prerender = true;
export const prerender = true;
を指定することで、ビルド時に表示用にHTMLを生成する事前レンダリングを行います。
SvelteKitはこのオプションにより、SSRとSSGを切り替えることができ便利ですね!
ブログ一覧とブログ詳細画面を作成していきます。
src/routes/blogs
とsrc/routes/blogs/[slug]
にそれぞれ+page.svelte
を作成します。
ブログ一覧画面(src/routes/blogs/+page.svelte)
<script lang="ts">
import type { PageData } from './$types';
import BlogCard from '../../components/BlogCard.svelte';
import CommonLayout from '../../components/CommonLayout.svelte';
export let data: PageData;
</script>
<CommonLayout title="Blogs">
<div class="grid grid-cols-1 gap-10 sm:grid-cols-2 md:grid-cols-3">
{#each data.contents as content}
<BlogCard {content} />
{/each}
</div>
</CommonLayout>
ブログ詳細画面(src/routes/blogs/[slug]/+page.svelte)
<script lang="ts">
import CommonLayout from '../../../components/CommonLayout.svelte';
import type { PageData } from './$types';
export let data: PageData;
</script>
<CommonLayout title={data.title}>
<article class="znc p-16 rounded-lg bg-white">
{@html data.content}
</article>
</CommonLayout>
+page.server.ts
のload()
で取得したデータはexport let data: PageData;
で受け取ります。
ブログ詳細は、HTML形式で取得されるので{@html}
を使用して表示しています。
表示用のブログカードやレイアウト等のコンポーネントの実装は省略しますが、自由にGithubリポジトリを参考にしてください。
画面の実装ができたらnpm run dev
で動作確認しましょう!
Vercelへのデプロイ
VercelにサインアップしてGithubと連携しましょう。
下記のリポジトリ一覧から「Import」します。
「Environment Variables」から.env
に設定したMICROCMS_SERVICE_DOMAIN
とMICROCMS_API_KEY
を設定します。
「Deploy」を押してデプロイ完了です。
サイトにアクセスできるか確認しましょう!
Webhookの設定
microCMSのコンテンツ更新でVercelでビルドされるようにWebhookの設定をします。
Vercelの管理画面から「Settings」>「Git」>「Deploy Hooks」にてWebhookを作成します。
Webhook URLをコピーしておきます。
次にmicroCMSの管理画面右上の「API設定」から「Webhook」にて「追加」を選択。
サービス選択画面で「Vercel」を選択して下記画面でコピーしたWebhook URLを設定します。
通知タイミングの設定は下記で良いかなと思います。
- コンテンツの公開時・更新時
- コンテンツの公開終了時
- 公開中コンテンツの削除時
これで設定は完了です。
microCMSで記事の作成や削除をしてみて、Vercelでビルドが走るかを確認しましょう!
まとめ
SvelteKitとmicroCMSを使って自作ブログを作成してVercelにデプロイする方法でした!
APIまで作り込むと大変ですがmictoCMSを使って楽をしつつ、フロントでエンジニアのこだわりを入れられる構成かなと感じました。
Discussion