Fresh&MicroCMSで自分が書いた記事とかの集約サイトを作る


## 完成サイト

https://fresh-microcms.deno.dev/

## ソースコード

https://github.com/Stead08/fresh_microcms

## 動機
この記事を拝見して、

https://zenn.dev/ryusou/articles/alephjs-microcms

DenoのNext.js系フレームワークAleph.jsではなくて、Freshを使って同様のサイトを構築してみたいなと思ったから。というのも、筆者は以前Aleph.jsを使用してDB検索システムを作ったのだが、

https://github.com/Stead08/syllabus_search_system

デプロイがうまくいかず、Aleph.jsのアルファ版故のバグに悩まされたため、新しくサイトを作る際にはDenoで使えるフレームワークでより開発が進んでいるものを採用したかったという理由がある。もちろんAleph.jsでサイトを作ることも不可能ではないけれども、勉強がてらFreshで作ってみたいと思った。
ryusouさんの記事をとても参考にしたので、上記の記事をFreshでやってみたというのが正しい。役立つ情報ありがとうございます。

# Freshでの開発
## Freshプロジェクトの作成
Denoはすでにインストール済という前提で書いていく。
```
deno run -A -r https://fresh.deno.dev fresh-profile
```
プロジェクト名は適当に設定してプロジェクトを作成する。作成時に色々聞かれるが、僕はWebStromを利用しているのでVSCode用の設定は利用しない形でプロジェクトを作成しました。その他はyesで作成。

## ディレクトリの構成
```
fresh-profile
├── deno.json
├── deno.lock
├── dev.ts
├── fresh.gen.ts
├── import_map.json
├── lib
│   └── microcmsClient.ts
├── main.ts
├── routes
│   └── index.tsx
├── static
└── twind.config.ts
```


## MicroCMSの準備
新規サービスを作成してスキーマを作ります。
![スクリーンショット 2023-02-17 16.11.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687149/f84746ee-59c6-5e80-9973-41e5d5e1dab6.png)

今回は練習なのでシンプルな構成にしました。
あとは適当にサンプルデータを入れときましょう。

## MicroCMSと連携

### MicroCMS Clientの作成
/lib 下にmicrocmsClient.ts を作成する。
 ```typescript:microcmsClient.ts
import { createClient } from "microcms";
import "dotenv/load.ts";

export const microcmsClient = createClient({
    serviceDomain: "freshpractice",
    apiKey: Deno.env.get("X_API_KEY")
});
```
次に .envファイルをプロジェクトディレクトリ直下に作成し、MicroCMSのAPIKEYをここに保存する。
```.env
X_API_KEY=YOUR_API_KEY
```
## index.tsx
index.tsxの全容を紹介する。

```typescript:index.tsx
import {Handlers, PageProps} from "$fresh/server.ts";
import {Head} from "$fresh/src/runtime/head.ts";
import {microcmsClient} from "../lib/microcmsClient.ts";
import dayjs from "dayjs";

export interface Post {
    contents: [{
        id: string;
        url: string;
        title: string;
        published_article?: string;
    }];
}

//タイムゾーンを設定
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.tz.setDefault("Asia/Tokyo");

export const handler: Handlers<Post> = {
    async GET(_req, ctx) {
        const articles = await microcmsClient.get<Post>({
            endpoint: "articles",
            queries: {limit: 99},
        });
        if (!articles) {
            return new Response("Response not found", {status: 404});
        }
        return ctx.render(articles);
    },
};
export default function Home({data}: PageProps<Post>) {
    return (
        <div class="h-screen bg-yellow-200">
            <Head>
                <title>Stead Profile</title>
            </Head>
            <div
                class=
                    "max-w-screen-sm mx-auto px-4 sm:px-6 md:px-8 pt-12 pb-20 flex flex-col"
                >
                <h1 class="font-extrabold text-5xl text-gray-800 flex justify-center">Stead Profile</h1>
                <section class="m-8">
                    {data.contents.map((content) => {
                        return (
                            <div class="p-4" key={content.id}>
                                <a href={content.url} alt={content.title}>
                                    <p>{content.title}</p>
                                    <time
                                        class="text-gray-500 text-sm"
                                        dateTime={content.published_article}
                                    >
                                        {dayjs(content.published_article).format("YYYY-MM-DD HH:mm:ss")}
                                    </time>
                                </a>
                            </div>
                        )
                    })}
                </section>
                <a href="https://fresh.deno.dev">
                    <img width="197" height="37" src="https://fresh.deno.dev/fresh-badge.svg"
                         alt="Made with Fresh"/>
                </a>
            </div>
        </div>
    )
}

```

今回はhandlerで記事一覧を取得して、描画するだけのページを作成した。

:::note info
Fresh v1.1よりTwindがオフィシャルファーストパーティプラグインとなったので少し記述が楽になった。
```diff_typescript
 // pages/index.tsx
- import { tw } from "@twind";

  export default function IndexPage() {
    return (
-     <h1 class={tw`text-4xl font-bold`}>Hello, world!</h1>
+     <h1 class="text-4xl font-bold">Hello, world!</h1>
    );
  }
```
引用元：https://deno.com/blog/fresh-1.1
:::

## localhostで動作確認
```
deno task start
```
でローカルサーバーが立ち上がる。
watcherも動いてるので変更内容がすぐに反映されるので楽。

## deno deployでデプロイ。
あとはdenoのオフィシャルエッジサービス、deno deployでデプロイしてみる。

https://deno.com/deploy

Git hub上でプロジェクトを管理していると、デプロイが楽。
環境変数のところにAPI KEYを設定することを忘れないようにする。

## まとめ
これぐらいのレベルのサイト構築であるとFresh, MicroCMS & deno deployの組み合わせは爆速で開発できる気がする。とは言っても筆者はフロントエンド開発というのを初めてまだ一ヶ月ちょいのペーペーなので詳しいことはわからない。記事内にも用語の誤用が多数含まれていると思うので、ご指摘してくださるとありがたい。