Last updated on

microCMSをAstroで使う


導入する

AstroとmicroCMSでつくるブログサイトが非常に丁寧に書いてあるのと、TypeScriptなのでエラーを見ながら適宜修正していけば移行は終わっていると思います

自分は

type heroImage = {
    url: string;
    height: number;
    width: number;
    };
    
export type Blog = {
    title: string;
    content: string;
    createdAt: string;
    updatedAt?: string;
    heroImage: heroImage;
    description: string;
} & MicroCMSListContent;

こんな感じで定義して使っています(microCMSでupdatedAtがnullになることはないかもしれません)

Syntax Highlight

microCMSを導入すると、Astroにbuilt-inのShikiが使えなくなってしまうので、こちらで適用してあげる必要があります

参考: microCMSのコードブロックをShikiで彩る

npm i cheerio
npm i -D shiki

して[blogId].astroでハイライトしたHTMLを生成すればOKです

自動デプロイ

microCMSはwebhookで特定のアクションをしたときに通知してくれる機能があるので、それを待ち受けてビルドするwebサーバーを作っておけばOK

Secretを使った検証も可能なのでNode.jsでささっと実装します

const crypto = require('crypto');
const express = require('express');
const AsyncLock = require('async-lock');

const app = express();
app.use(express.json());

const lock = new AsyncLock();

app.post('/deploy', (req, res) => {
    const expectedSignature = crypto
        .createHmac('sha256', process.env.MICROCMS_SECRET_TOKEN)
        .update(JSON.stringify(req.body))
        .digest('hex');
    const signature = req.headers['x-microcms-signature'];
    if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature))) {
        return res.status(401).send('Invalid signature.');
    }

    console.log('Webhook received successfully.');

    res.status(200).send('Webhook received successfully.');

    lock.acquire('deploy', () => {
        console.log('Deploying...');
        try {
            require('child_process').execSync('npm run build', { stdio: 'inherit' });
            console.log('Deployed successfully.');
        } catch (error) {
            console.error('Build failed:', error);
        }
    });
});

const PORT = process.env.PORT || 3002;
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});

一応AsyncLockでビルド中にビルドコマンドを実行しないようにしておきました

これをservice化して、cwdをサイトのあるディレクトリに設定すれば完了です