🚀

SvelteKitとmicroCMSで自作ブログを作ってVercelで公開してみた

2024/09/29に公開

はじめに

こんにちは!
SvelteKit、microCMSを使って自作ブログを作成してみたので共有したいと思います。

対象読者

  • 自作ブログを作成したい方
  • Svelte, SvelteKit, microCMS, Vercelを使ってみたい方

記事を読むメリット

  • Svelte, SvelteKit, microCMSを使った自作ブログの作成方法がわかります
  • Vercelへのデプロイ方法がわかります

結論

作成したブログはこちらです!爆速で作成できます。

https://github.com/siiiiisar/my-blog

使用技術

フロントエンド:Svelte(4.2.7) + SvelteKit v2

フロントエンドにはSvelteとそのフレームワークであるSvelteKitを使用します。
Svelteはコードの記述量が少ないことや、仮想DOMを使用しないのでコンパイル後のバンドルサイズが小さくなり高速に動作するなどのメリットがあります。
https://svelte.dev/blog/virtual-dom-is-pure-overhead
SvelteKitはReactで言うところのNext.jsの立ち位置で、ルーティング等の機能を提供します。
https://kit.svelte.dev/

ヘッドレスCMS:microCMS

ヘッドレスCMSとはコンテンツ管理の機能のみをもつ、ビューのないCMSのことです。
https://blog.microcms.io/what-is-headlesscms/
microCMSは国産のCMSなのでコンソールやドキュメントが日本語に対応していると言う良さがあります。

ホスティングサービス:Vercel

ホスティングサービスはVercelを使用します。
SvelteKitにも対応しており、Githubと連携して簡単にアプリケーションをデプロイできます。
https://vercel.com/solutions/svelte

プロジェクトの作成

下記のコマンドを実行してプロジェクトを作成して、開発環境を立ち上げます。

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というモジュールを使用して取得できます。
https://kit.svelte.dev/docs/modules#$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.sveltedatapropsを介してデータを渡すことができます。

https://kit.svelte.dev/docs/routing

ブログ一覧/詳細の取得

microCMSのAPIを簡単に扱うためのSDKが用意されています。
https://microcms.io/features/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/blogssrc/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を生成する事前レンダリングを行います。

https://kit.svelte.dev/docs/page-options

SvelteKitはこのオプションにより、SSRとSSGを切り替えることができ便利ですね!

ブログ一覧とブログ詳細画面を作成していきます。
src/routes/blogssrc/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.tsload()で取得したデータはexport let data: PageData;で受け取ります。
ブログ詳細は、HTML形式で取得されるので{@html}を使用して表示しています。
https://svelte.jp/docs/special-tags#html

表示用のブログカードやレイアウト等のコンポーネントの実装は省略しますが、自由にGithubリポジトリを参考にしてください。

画面の実装ができたらnpm run devで動作確認しましょう!

Vercelへのデプロイ

VercelにサインアップしてGithubと連携しましょう。
下記のリポジトリ一覧から「Import」します。

「Environment Variables」から.envに設定したMICROCMS_SERVICE_DOMAINMICROCMS_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を使って楽をしつつ、フロントでエンジニアのこだわりを入れられる構成かなと感じました。

GitHubで編集を提案

Discussion