🚀

Astro version2 の新機能試してみた【Hybrid Rendering】

2023/01/26に公開

昨日Twitterを見ていたら気になる通知が。

https://astro.build/blog/astro-2/

お~Astro version2 出たのか。どれどれ...と中を見ると特に気になるtopicが

Hybrid Rendering

ま じ か ! !

というわけで実際に試してみて導入方法などまとめました。

Hybrid Rendering とは

ざっくり言うと SSR / SG を page 毎に分けられるようになりました!
これ Next.js では備わっているのですが、Astro version1 ではない機能でした。

これによって 基本的には SG なんだけど、頻繁に更新が起こるページをリアルタイムに出したい! といった要望が対応できそう!!!
ということで歓喜していました。

ALL SG or SSR だとどうしても product で導入できないこと多いよな...と思っていたのですが、これを気に導入できる案件が増えそうだというのが所感です。

実践パート

環境

  • astro
  • typescript
  • vercel
  • microCMS

SG / microCMS / vercel までは以下の記事を参考に作成しました。

https://blog.microcms.io/astro-microcms-introduction/

導入方法 SSR on vercel

yarn astro add vercel

のコマンド入力するだけで設定ファイルも同時に書き換えてくれます。
これだけで全ページSSR対応に完了です。

astro.config.mjs
import { defineConfig } from 'astro/config';

// https://astro.build/config
import vercel from '@astrojs/vercel/serverless';

// https://astro.build/config
export default defineConfig({
  output: 'server',
  adapter: vercel(),
});

https://docs.astro.build/en/guides/server-side-rendering/

導入方法 Hybrid Rendering on vercel

今の状態は全体が SSR となっているので SG に変更したい file のコードフェンス内に以下の一文を加えてください。

export const prerender = true;

この一文だけで対応完了です。

[blogId].astro
---
import Layout from '../layouts/Layout.astro';
import { Blog, getBlogDetail, getBlogs } from '../lib/micromcs';

export async function getStaticPaths() {
  const response = await getBlogs({ fields: ['id'] });
  return response.contents.map((content: Blog) => ({
    params: {
      blogId: content.id,
    },
  }));
}

// この一文を加えただけ
export const prerender = true;

const { blogId } = Astro.params;
const blog = await getBlogDetail(blogId as string);
---

<Layout title="My first blog with Astro">
  <main>
    <h1 class="title">{blog.title}</h1>
    <p class="publishedAt">公開日時:{blog.publishedAt}</p>
    <div class="post" set:html={blog.content} />
  </main>
</Layout>

<style>
  main {
    margin: auto;
    padding: 1em;
    max-width: 60ch;
  }
</style>

https://docs.astro.build/en/guides/server-side-rendering/#prerendering

確認

あとは実際に動きを確認してみます。
今回は確認のためにSSR用の page を追加しました。
SSR用の page では query から id を取得し fetch しています。

pages/index.astro
    // 追加箇所のみ抜粋
    <h2>SSR</h2>
    <ul>
      {
        response.contents.map((content: Blog) => (
          <li>
            <a href={`ssr?blogId=${content.id}`}>{content.title}</a>
          </li>
        ))
      }
    </ul>
pages/ssr/index.astro
---
import Layout from '../../layouts/Layout.astro';
import { getBlogDetail } from '../../lib/micromcs';

// データの取得方法変更
const blogId = Astro.url.searchParams.get('blogId') ?? '';
const blog = await getBlogDetail(blogId);
---

上記の通り SSR の page だけデータの取得に成功しました!

補足

  • デモ動画の環境ではmicroCMS側の webhook を vercel に設定していないので、microCMSを更新しても build はかかりません(top pageはSSRなのでlistは更新されます)
    = SSR では取得できて、SG では build が走っておらず error になるという想定通りの状態です
  • query は SSR でしか取得できません
  • astro version1 から update する方は @astrojs/vercel の update も対応しないとおそらくbuild時にerrorでます

さいごに

Next.js と同じぐらい簡易的にレンダリング方法変更できましたね。便利。
元々注目していた技術なのですが、今回のバージョンアップで俄然追いかける意欲が沸きました。
近々使う予定もありますし、自身のサイトもこれで立ち上げてみたいと思える内容なので Tips など順次ご紹介できればと思います。

chot Inc. tech blog

Discussion