サムネイル

Astroでポートフォリオサイトを作った

今回はAstroというwebフレームワークを使って、自分のポートフォリオサイトを作り直した時の話をしたいと思います。
https://watataku-portfolio.vercel.app/

Astro

まず初めにAstroというフレームワークを知らない方のために軽く触れておきます。

https://astro.build/

Astroとは、ReactやVue.jsのようにコンポーネント指向で開発ができるUIフレームワークです。さらに、ウェブアプリではなくウェブサイトを作るために用意されたWebフレームワークであったり、React、Preact、Svelte、Vue、Solidなど様々なUIフレームワークを用いて開発できる特徴もあります。


そしてAstroを語る上でもう一つ欠かせないのがAstro Islandsです。
これも公式のドキュメントで説明されています。
https://docs.astro.build/en/concepts/islands/
簡単に解説すると、ページの各UIコンポーネントを別モノとして扱うことができます。
これによりコンポーネント間の優先度設定によるパフォーマンス調整やコンポーネント毎にUIフレームワークを変えられることがメリットとなっています。

Astroを採用した理由

  • ウェブアプリではなくウェブサイトを作りたい
  • コンポーネント指向で開発したい
  • Typescriptで書きたい
  • 勉強コストをできるだけ抑えたい
  • Jamstack!!

などがありました。これらのことを考慮して今回マッチしたのが「Astro」でした。

プロジェクトのセットアップ

Node.jsはv16.12.0またはそれ以上のバージョンをインストールされている前提で、以下のコマンドでプロジェクトを作成します。

$ npm create astro@latest

コマンド入力後、プロジェクト名やTypescriptを使用するかなどを聞かれますのでいい感じに答える。
聞かれることは以下の通りです。

  • プロジェクト名を指定
Where would you like to create your new project? … ./watataku-portforio

『watataku-portforio』という名前のプロジェクト名で作成したいので ./watataku-portforio と入力して次に進みます。

  • テンプレートの指定
? Which template would you like to use? › - Use arrow-keys. Return to submit.
❯   Just the basics (recommended)
    Blog
    Portfolio
    Documentation Site
    Empty project

一番最初の『Just the basics (recommended)』の『基本のみ(推奨)』を選択します。

  • 依存モジュールのインストール
? Would you like to install yarn dependencies? (recommended) › (Y/n)

『Y』をしていして依存モジュールのインストールを開始させます。

  • Git リポジトリの初期化を実行
? Would you like to initialize a new git repository? (optional) › (Y/n)

Gitリポジトリの初期化をしたいので『Y』を入力して次に進みます。

  • TypeScriptの設定
? How would you like to setup TypeScript? › - Use arrow-keys. Return to submit.
❯   Relaxed
    Strict (recommended)
    Strictest
    I prefer not to use TypeScript

推奨となっている『Strict (recommended)』を選択します。

回答後、以下のコマンドで開発サーバを立ち上げ、http://localhost:3000にアクセスします。

$ cd ./watataku-portforio

$ npm run dev


Reactを追加する

以下のコマンドを叩けばReactを追加(使えるように)できます。

$ npx astro add react


 Resolving packages...


  Astro will run the following command:
  If you skip this step, you can always run it yourself later


 ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
 │ npm install @astrojs/react @types/react-dom@^18.0.6 @types/react@^18.0.21 react-dom@^18.0.0 react@^18.0.0  │
 ╰─────────────────────────────────────────────────────
? Continue? › (Y/n)

Y を指定します。

✔ Resolving packages...

  Astro will make the following changes to your config file:

 ╭ astro.config.mjs ─────────────────────────────╮
 │ import { defineConfig } from 'astro/config';  │
 │                                               │
 │ import react from "@astrojs/react";           │
 │                                               │
 │ // https://astro.build/config                 │
 │ export default defineConfig({                 │
 │   integrations: [react()]                     │
 │ });                                           │
 ╰───────────────────
? Continue? › (Y/n)

Y を指定します。
※今回はReactを追加しますがVue.jsやSvelteなども追加できます。詳しくはドキュメントをご覧ください。
https://docs.astro.build/ja/guides/integrations-guide/

microCMSの準備

今回のサイトでのコンテンツ管理には「microCMS」と言うHedress CMSを使っています。
https://microcms.io/
microCMSのアクセス方法や設定方法などは今回説明しないので自身でドキュメント等などでご覧ください。

この辺りを参考にしてみると良いかもです。
https://blog.microcms.io/astro-microcms-introduction

ポートフォリオに取り入れた機能

  • 慣性スクロール

https://www.weblio.jp/content/慣性スクロール
ぬるっと動く気持ちのいいスクロールですねw個人的にこのスクロール方式が好きなので、実装してみたいと思い実装しました。

今回は「ASScroll」と言うライブラリのお力をお借りして実装しました。
https://github.com/ashthornton/asscroll
導入方法は簡単です。
まず最初にライブラリをインストールします。

$ npm install --save @ashthornton/asscroll

次に下記Javascriptのコードを書いてあげます。

import ASScroll from "@ashthornton/asscroll";

const asscroll = new ASScroll();
window.addEventListener("load", () => {
  	asscroll.enable();
});

あとは慣性スクロールしたいところに<div asscroll-container>で囲むだけ。

<div asscroll-container>
	 <main>
	       <!-- The Y translation will be applied to this element -->
     </main>
</div>
  • ダークモード

こちらで詳しく記載しております。
https://watataku-blog.vercel.app/blog/tb7epr3_-z
ちなみにダークモードで見た際のサイト(ライトモードはサムネイル)

  • ページング

Astroではページング機能を簡単に実装できる関数があるので、それを今回使用させていただきました。
その関数がpaginate()です。早速ページングの実装方法を見ていきましょう。

./page/[...page].astroを作成し下記のようにpagenate()を使用します。

// --- 
import type { Page, GetStaticPathsOptions } from "astro";

type Props = {
  page: Page<Contents>;
};

type Work = {
  contents: Contents[];
}

type Contents = {
  // 以下略
};

const { page } = Astro.props;  

export async function getStaticPaths({ paginate }: GetStaticPathsOptions) {
    const myMicroCMSApiUrlWork = `https://${
	    import.meta.env.MICROCMS_SERVICE_DOMAIN_PORTFOLIO
    }.microcms.io/api/v1/works?orders=-publishedAt?limit=999`;
	
	const response = await fetch(myMicroCMSApiUrlWork, {
	    headers: {
	      "X-MICROCMS-API-KEY": import.meta.env.MICROCMS_API_KEY_PORTFOLIO,
	    },
	});
	const getFetchDataWork: Work = await response.json();
	return paginate(getFetchDataWork.contents, { pageSize: 6 });
}
// ---

getStaticPaths() 関数の戻り値でpaginate()を返すだけです。
※コメントにしている「---」はハイラウトの都合上、わざと付けています。Astroを書く際は「---」をお忘れなくお願いします。

中身を見てみると、表示したいコンテンツを第 1 引数に、ページ内に表示したいコンテンツの数を第 2 引数に設定しておきます。
これでページングの設定が完了しましたのでテンプレートで使っていきましょう。

<div>
  {
    page.data.map((work: Contents) =>
      <!-- 以下略 -->
    ))
  }
</div>
{
  page.total >= 6 && (
	<nav>
	    {/* page.currentPageで現在ページ、page.lastPageで総ページ数を表示 */}
	     <p>
	        page {page.currentPage}/{page.lastPage}
	     </p>
	     <ul>
	        {/* page.url.prevがある場合は前ページへのリンクを表示 */}
	        {page.url.prev && (
	           <li>
	              <a href={page.url.prev}>PREV</a>
	            </li>
	         )}
	          {/* page.url.nextがある場合は次ページへのリンクを表示 */}
	          {page.url.next && (
	             <li>
	                <a href={page.url.next}>NEXT</a>
	             </li>
	           )}
	       </ul>
    </nav>
  ) 
}

最後に

以上がAstroでポートフォリオサイトを作り直したと言うお話でした。
個人的にAstroとても書きやすくサクッと使える印象を受けました。また、他のUIフレームワークとも組み合わせて開発できるのも私としては嬉しいポイントでした。

みなさんもよければAstro使ってみてください