icon
🌞

🚀

tweet

ツイート

Astro使ってブログ作ってみた話

AstroAstro
ReactReact
TypeScriptTypeScript
techtech

はじめに

この度、このブログを作るにあたってAstroを使ってみたので、Astroでのブログの実装方法と、使ってみての感想を書いてみました。

Astroとは

Astroは、ビルド時に不必要なJavaScriptを可能な限り排除してレンダリングするため、めちゃくちゃ高速なWebフレームワークです。また、ReactやVueのコンポーネントを使い回しできるみたいです。

環境構築

下記のコマンドで新しいプロジェクトを、立ち上げられます。

$ npm create astro@latest

or

$ pnpm create astro@latest

or

$ yarn create astro

私はReactを使って実装していくので、下記のコマンドでReactを使うためのセットアップをしました。

$ npx Astro add react

※このコマンドを使っておらず手こずったので、React使う人は必ずやってください。

初期ファイル構成

.
├── astro.config.mjs

├── public/
│   └── favicon.svg

└── src/
    ├── components/
    │   └── Card.astro

    ├── layouts/
    │   └── Layout.astro

    └── pages/
        └── index.astro

astro.config.mjsファイル

  • Astroに関する設定をする

publicフォルダ

  • 画像ファイルなどを置く
  • faviconがデフォルトで置いてある

components

  • コンポーネントを配置
  • ReactやVueで作ったコンポーネントもここにおく

pages

  • ここにおファイルをおくとルーティングが追加される(Next.jsのpagesルーターに似てる)

サーバーの起動

ローカルでサーバーを立ち上げるためには、

$ npm run dev

ビルド時には、

$ npm run build

ビルドしたものをローカルで動かすには、

$ npm run start

この辺は、Next.jsとかと同じですね。

Astroファイルの書き方

大まかな構成

ファイルは下記のように記述します。

---
import DateBox from '../components/DateBox';
const {date,title} = Astro.props;
---

<div class='container'>
    <p class='title-text'>{title}</p>
    <DateBox date={date} />
</div>
<style>
    .container {
    }

    .title-text {
        font-size: 2rem;
    }
</style>

---で囲まれた場所(コードフェンス)には、必要なJavaScriptを記述することができます(Propsなどもここで記述する)。styleはstyleタグの中に記述してください。ReactやAstroなどでつくったコンポーネントはコードフェンス内でインポートして、呼び出すことができます。

Props

Propsは上記のように受け取ることができます。

const {title} = Astro.props;

ちなみに.astroファイルには標準で組み込まれているっぽいので、わざわざAstroをインポートする必要はありません。

slot

.astroファイルでは、<slot />を記述した場所に子要素をはめ込むことができます。

<div>
    <slot />
</div>

これはReactの{children}と同じですね。

画像の表示

Reactとかだと画像ファイルをインポートしてsrcプロパティに突っ込んだりしますが、Astroだと

<img src='/icon/icon.png' />

のように、publicフォルダのパスを入れる感じです。

相対パスurl

ReactやNext.jsと違って、Linkのようなものをインポートせずとも、aタグに’/‘のようなものを入れるだけで相対パスを指定できます。

<a href='/'>home</a>

コンポーネントの読み込み

Reactなどで作ったコンポーネントをインポートして、使う際、useStateやonClickなどクライアント側でJavaScriptを読み込む必要がある場合には、

---
import LoadComponent from '../comopnents/LoadComponent';
---

<div>
    <LoadComponent client:load />
</div>

上記のように、コンポーネント呼び出しの際、client:loadと記述すれば読み込まれるようになります。

状態管理を使用する場合

contextHookが使えない

カラーテーマ切り替えの際に、contextHookが使えなかった。なのでnanostoresというパッケージを用いてコンポーネント間の状態管理を実装しました。

nanostores

nanostoresを使うには、下記のコマンドでパッケージをインストールします。

$ npm i nanostores

私はReactのコンポーネントを、使っているので、

$ npm i @nanostores/react

でReact用のパッケージもインストールしました。

@nanostores/persistent

今回kコンポーネント間で状態を管理したいのは、カラーテーマの切り替えのためなので、永続的に保存するため@nanostores/persistentというパッケージをインストールします。

このパッケージは、ローカルストレージに保存することで状態を永続化するためのものです。

$ npm i @nanostores/persistent

これでインストールできます。

永続化のためのnanostores使い方

まずはStoreをsrc/stores/colorThemeStore.tsに作成します。

import {persistentAtom} from '@nanostores/persistent'

export const colorThemeStore = persistentAtom<'dark' | 'light' |  ''>('storage-key', '');

上記のコードを説明すると、Storeの持ちうる値を<>の中に入れます(今回の場合は’dark’, ‘light’, ”)。そして、persistentAtomの第一引数にはlocalStorageのkeyの名前、第二引数には初期値を指定します。

Storeの値を参照する

下記のように値を参照することができます

import {useStore} from '@nanostores/react';
import { colorThemeStore } from '../stores/colorTheme';

export default function UseStore() {
    const status = useStore(colorThemeStore);
};

mdファイルでブログページ作成

pagesフォルダにmdファイルをおく

pagesフォルダ下にmdファイルをおくと、そのファイル名のルーティングが作成されます。

(このブログだと/pages/articles/1.mdのファイルなので’/articles/1’というリンクになる)

mdファイルの構成

このファイルには下記のように、layoutとそのlayoutにtitleなどをpropsとして渡すことができます。

---
layout: ../../layouts/ArticleLayout.astro
title: Astro blog
---

## ブログです

コードフェンス内にlayoutなどを記述し、外にマークダウン形式を記述することで自動的にマークダウンがHTMLに変換されます。

mdファイルのレイアウトを作成

mdファイルのレイアウトは.astroファイルに記述します

---
const {frontmatter} = Astro.props;
---

<div>
    <p>{frontmatter.title}</p>
    <slot />
</div>

上記のようにmdファイルのpropsをfrontmatterを用いて一括で受け取り、そこから任意のpropsを読み取れます。

そして、<slot />の箇所にmdファイルに記述したマークダウンが挿入されます。

使ってみての感想

ReactやNext.jsなどをやってる方ならすぐに習得できると思います。

個人的には、小さな規模感のブログを作るには適してるんじゃないかなと思いました。やっぱり、mdファイルにマークダウン書くだけでいいのは楽ですね。

ただ、私はこれからもう一度作るならNext.jsを使うかなっていうのが正直な感想です。

簡易的な個人ブログを作るならAstroがおすすめです。