8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

オークファングループAdvent Calendar 2023

Day 14

AstroとmicroCMSとCloudflare Pagesで無料ブログ制作

Last updated at Posted at 2023-12-13

image.png

はじめに

こんにちは。
オークファン開発部デザイナーの@af_etoです。

最近Astroに触れる機会があり、その開発の手軽さに感動しておりました。
またヘッドレスCMSのmicroCMSとの連携もとてもシンプルで、
動的コンテンツはmicroCMSに任せ、Astro側でmicroCMSのAPIを取得することで、
ウェブサイトの高速化とUXの向上が期待できます。

本稿ではAstroとmicroCMS、さらにCloudflare Pagesを組み合わせ、
コンテンツ更新をトリガーにした「ブログ自動デプロイ設計」のプロセスをご紹介します。

ブログと言っても書き残したいことは特に無いので、
行き場を失くした写真を活かして、写真ブログを作成しました。

画面設計

レイアウトは写真が縦に並んだシンプルなものにしました。

image.png

Astroのセットアップ

image.png

Astroのローカル環境を作るところから始めます。
下記のような前提条件があるので注意です。

  • Node.js - v18.14.1 またはそれ以上。
  • テキストエディタ - VS Codeと公式Astro拡張機能を推奨します。
  • ターミナル - Astroは、コマンドラインインターフェイス(CLI)からアクセスします。

プロジェクトの作成

プロジェクト名を「untitled」で、Astro用のディレクトリを作成/移動します。

$ mkdir untitled
$ cd untitled

インストールウィザードの起動

$ npm create astro@latest

いくつか質問されるので回答していきます。
Astroが必要なのでダウンロードしてもいいですか?は、yを入力します。

Need to install the following packages:
  create-astro@4.5.2
Ok to proceed? (y) 

どこにプロジェクトを作りますか?は、untitled/なので./を入力。

   dir   Where should we create your new project?
         ./capricious-conjunction

このプロジェクトにサンプルファイルを含めますか?は、
推奨となっているInclude sample filesを選択します。

  tmpl   How would you like to start your new project?
         ● Include sample files (recommended)
         ○ Use blog template 
         ○ Empty 

依存ファイルをインストールしますか?は、特別な理由が無い限りYesを選択。

  deps   Install dependencies? (recommended)
         ● Yes  ○ No 

TypeScriptで書きますか?には、Yesを選択しておきます。

    ts   Do you plan to write TypeScript?
         ● Yes  ○ No 

TypeScriptはどの程度厳密であるべきか?は、推奨となっているStrictを選択。

   use   How strict should TypeScript be?
         ● Strict (recommended)
         ○ Strictest 
         ○ Relaxed 

Gitリポジトリにしますか?は、Yesを選択します。

   git   Initialize a new git repository? (optional)
         ● Yes  ○ No 

以上で質問は終わりです。

  next   Liftoff confirmed. Explore your project!
         Run npm run dev to start the dev server. CTRL+C to stop.
         Add frameworks like react or tailwind using astro add.

         Stuck? Join us at https://astro.build/chat

╭─────╮  Houston:
│ ◠ ◡ ◠  Good luck out there, astronaut! 🚀
╰─────╯

セットアップが完了しました。
プロジェクトディレクトリは以下の構成です。

image.png

開発用サーバー起動

$ npm run dev

開発用のサーバーが立ち上がり、開発用URLができます。
http://localhost:4321/

> dev
> astro dev

  🚀  astro  v3.6.4 started in 182ms
  
  ┃ Local    http://localhost:4321/
  ┃ Network  use --host to expose

開発用URLをブラウザで表示すると、
「Welcome to Astro」というタイトルのサンプルページを確認できます。

image.png

Astroのファイル構成

srcディレクトリにはプロジェクトのソースコードが格納されています。

  • src/layouts
    複数のページで共有されるUI構造を定義するためのAstroコンポーネント。

  • src/pages
    サイト上に新しいページを作成するために使用される、特別な種類のコンポーネント。

  • src/components
    HTMLページで再利用可能なコンポーネント。

ざっくり表現すると構成イメージはこんな感じでしょうか。

image.png

上記のはじめから用意されているコードは使用せずに、
既存のsrc/pages/index.astroを上書きする形でHTMLを書いていきます。

src/page/index.astro
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Untitled</title>
</head>
<body>
    <header class="header">
        <h1 class="title"><a href="/">Untitled</a></h1>
    </header>
    <div class="frame">
        <main class="main">
            <div class="wrap">
                <ul class="posts">
                    <li><div class="cut"><img src="/assets/img/sample.jpg" alt=""></div></li>
                    <li><div class="cut"><img src="/assets/img/sample.jpg" alt=""></div></li>
                    <li><div class="cut"><img src="/assets/img/sample.jpg" alt=""></div></li>
                </ul>
            </div>
        </main>
        <div class="pagination">
            <a class="prev" href="">preview</a>
            <a class="next" href="">next</a>
        </div>
        <footer class="footer">
            <div class="copy">© 2023 Untitled</div>
        </footer>
    </div>
</body>
</html>

Astroのファイル構成へ書き換えます。

src/pages/index.astro
---
import Layout from '../layouts/Layout.astro';
---

<Layout>
    <main class="main">
        <div class="wrap">
            <ul class="posts">
                <li><div class="cut"><img src="/assets/img/sample.jpg" alt=""></div></li>
                <li><div class="cut"><img src="/assets/img/sample.jpg" alt=""></div></li>
                <li><div class="cut"><img src="/assets/img/sample.jpg" alt=""></div></li>
            </ul>
        </div>
    </main>
    <div class="pagination">
        <a class="prev" href="">preview</a>
        <a class="next" href="">next</a>
    </div>
</Layout>

<style>
/* ここにスタイルを記述する */
</style>
src/layouts/Layout.astro
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Untitled</title>
</head>
<body>
    <header class="header">
        <h1 class="title"><a href="/">Untitled</a></h1>
    </header>
    <div class="frame">
        <slot />
        <footer class="footer">
            <div class="copy">© 2023 Untitled</div>
        </footer>
    </div>
</body>
</html>

<style>
/* ここにスタイルを記述する */
</style>

Layout.astroに書かれた<slot />の中にindex.astroが読み込まれます。
CSSをHTMLと同じastroファイル内に記述すれば、レイアウトは完成です。

ちなみにSCSSを書くためにはSASSのパッケージをインストールしましょう。

$ npm install sass

<style>タグにlang="scss"という属性を付ければSCSSが使用できます。

<style lang="scss">

画面収録 2023-12-08 0.53.18.gif

画面設計が完了しました。
上記の通り写真はダミー画像のままなので、
microCMSに写真をアップロードして、APIで写真データを取得します。

microCMSの設定

image.png

https://microcms.io/

アカウントの作成

アカウントがない場合は作成しましょう。
料金プランは無料の「Hobby」でひとまず問題ありません。

サービスを作成

ログイン後は左メニューの+ボタンより新たにサービスを作成していきます。
サービスを一から作成するを選択します。

image.png

サービス情報の入力

サービス名サービスIDは自由に入力できます。

image.png

サービス作成完了

サービスが作成されたので、サービスにアクセスするを押します。

image.png

APIを作成

ブログのテンプレートもあるのですが、自分で決めるを選択します。

image.png

APIの基本情報を入力

API名エンドポイントも自由に入力できます。
エンドポイントは後で使用するので覚えておきましょう。

image.png

APIの型を選択

JSON配列を返却するリスト形式を選択します。

image.png

APIスキーマを定義

入力画面の項目を設定します。今回は写真ブログなので
フィールドID:photo
表示名:写真
種類:画像
のみを用意します。

image.png

APIの作成完了

コンテンツを作成する準備が整いました。

image.png

写真を3点追加しました。

image.png

自分でデータベースやAPIを用意しなくても、
microCMSにアクセスすればブログデータを取り出せるようになりました。

AstroとmicroCMSの接続

AstroとmicroCMSを簡単に連携させるため、
microCMS JavaScript SDKというプログラムをプロジェクトにインストールします。

$ npm i microcms-js-sdk

連携させるためのファイルを作成していきます。

API呼び出し設定

環境変数を設定

Astroのプロジェクトルートに.envファイルを作成します。
MICROCMS_SERVICE_DOMAINには、サービス名、
MICROCMS_API_KEYにはAPIキーを入れます。

.env
MICROCMS_SERVICE_DOMAIN=untitled-blog
MICROCMS_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

APIキーはmicroCMSのページ左上歯車⚙️マークから表示される
サービス設定:APIキーページからコピーできます。

image.png

microcms.tsファイルの作成

src/libs/にmicroCMSに関するファイルmicrocms.tsを作成し、
ブログデータを取得する関数を書いていきます。
エンドポイントは設定したblogsを入力します。

src/libs/microcms.ts
// SDK利用準備
import { createClient } from 'microcms-js-sdk';
import type {
    MicroCMSListResponse,
    MicroCMSQueries,
    MicroCMSImage,
} from 'microcms-js-sdk';

// 型定義
export type Blogs = {
    photo: {
        url: string;
        image: MicroCMSImage;
    };
};
export type BlogsResponse = MicroCMSListResponse<Blogs>;

// clientの作成
const client = createClient({
    serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
    apiKey: import.meta.env.MICROCMS_API_KEY,
});

// 'blogs' APIからIDを指定して個別データを取得する関数
export const getBlogs = async (queries?: MicroCMSQueries) => {
    return await client.get<BlogsResponse>({ endpoint: 'blogs', queries });
};

写真をindex.astroで呼び出します。

src/pages/index.astro
---
import Layout from '../layouts/Layout.astro';
// microCMS呼び出し
import { getBlogs } from '../libs/microcms';

const data = await getBlogs({ limit: 100 });
const blogs = data.contents;
---

<main class="main">
    <div class="wrap">
        <ul class="posts">
            {blogs.map((blog) => {
                return (
                    <li>
                        <div class="cut">
                            <img src={blog.photo.url} />
                        </div>
                    </li>
                );
            })}
        </ul>
    </div>
</main>
<div class="pagination">
    <a class="prev" href="">preview</a>
    <a class="next" href="">next</a>
</div>

microCMSでアップロードした写真が確認できました!

画面収録 2023-12-08 0.40.37.gif

ページ送りも実装する

今のところコンテンツはが3点なので、
ひとまず1データ1ページ(pageSize: 1)で確認します。

src/pages/[...page].astro
---
import Layout from '../layouts/Layout.astro';
import { getBlogs } from '../libs/microcms';
import type { GetStaticPathsOptions } from 'astro';

export const getStaticPaths = async ({ paginate }: GetStaticPathsOptions) => {
    const blogs = await getBlogs({ limit: 100 });
    return paginate(blogs.contents, { pageSize: 10 });
};
const { page } = Astro.props;
---

<Layout>
    <main class="main">
        <div class="wrap">
            <ul class="posts">
                {page.data.map((blog) => {
                    return (
                        <li>
                            <div class="cut">
                            <img src={blog.photo.url} />
                            </div>
                        </li>
                    );
                })}
            </ul>
        </div>
    </main>
    <div class="pagination">
        {page.url.prev && (
            <a class="prev" href={page.url.prev}>preview</a>
        )}
        {page.url.next && (
            <a class="next" href={page.url.next}>next</a>
        )}
    </div>
</Layout>

ブログのほとんどの場合、トップページは/1というURLではなく/にしたいと思うので、
レストパラメーターを使ってファイル名を[...page].astroとしておきます。

画面収録 2023-12-08 0.32.43 (1).gif

ページ送りも実装できました!
これでmicroCMSとAstroの連携が完了です。

GitHubとCloudflare Pagesの連携

GitHubからのCloudflare Pagesへの自動デプロイ設定を作ります。

リポジトリの作成

GitHubにプロジェクトのリポジトリを作成し、ローカルファイルをpushします。

image.png

Cloudflare Pages設定

こちらもアカウントが必要です。
無料プランで問題ありません。

image.png

Cloudflare Pages設定

左メニューのWorkers & Pages:概要からアプリケーションの作成ボタンを押します。

image.png

PagesタブのGitに接続ボタンから連携していきます。

image.png

連携するGitHubリポジトリが表示されていない場合は、
GitHubからCloudflare Pagesにリポジトリアクセス権限を与えてください。

image.png

アクセス権限を与えると該当のリポジトリを選択できます。
セットアップの開始ボタンを押して進みます。

image.png

プロダクションブランチはmasterブランチを指定します。

image.png

フレームワークプリセットはAstroを選択します。
ビルドコマンド出力先ディレクトリはプリセットのままで構いません。

環境変数の設定

環境変数はプロジェクトルートに作成していた.envファイルを参照して入力します。
入力が完了したら「保存してデプロイする」ボタンを押します。

.env
MICROCMS_SERVICE_DOMAIN=untitled-blog
MICROCMS_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

image.png

「成功しました!」というメッセージとデプロイ先のURLが表示されます。

image.png

microCMSとCloudflare Pagesの連携

microCMSからCloudflare Pagesへの自動デプロイ設定を作ります。

Cloudflare Pagesのアプリケーション設定

アプリケーションの設定の左メニュービルド&デプロイページを表示します。

image.png

デプロイフック

ページ下部のデプロイフック項目にあるデプロイフックを追加しますボタンを押してください。

image.png

デプロイフック名を入力して、ブランチを選択して追加ボタンを押します。

image.png

デプロイフックのURLが生成されますので、コピーしておきます。

image.png

microCMSのAPI設定

microCMSのAPI画面の右上API設定からWebhookページを開き追加ボタンを押します。

image.png

サービスの選択

Cloudflare Pagesを選択します。

image.png

webhookの識別名を入力し、デプロイフックのURLをペーストします。
以下の通知タイミングの設定はそのままでも問題ありません。

image.png

動作確認として、新たなコンテンツを追加/公開します。

image.png

ビルドされ、新しい写真が表示されました。

image.png

https://untitled-4ne.pages.dev/

おわりに

比較的、簡単にブログを構築することができました。

プロジェクトの要件に基づいて、導入を検討するのもちろんですが、
例えばコーポレートサイトの「お知らせ」など、
静的サイトの一部にだけ動的コンテンツを導入したい場合では、
AstroとヘッドレスCMSの構成は非常に実用的であると思われます。

是非、Astroを利用したウェブサイトを作ってみてください。
わかりやすい公式ガイドも用意されています。

参考記事

8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?