AfterDay Project — このサイトについて
一日の終わりから始まった個人プロジェクト。その方向性と構築の過程についての記録。
概要
以前から、仕事とは別に自分だけの個人プロジェクトをやってみたいとずっと思っていた。 どんな方向で作っていくか長い間考えて、ひとつの基準が生まれた。
「一日のすべてが終わった後の時間」
仕事から完全に切り離された状態で、 気になること、作ってみたいこと、そして自分を成長させることを記録していく場所。
そうして始まったのが AfterDay Project だ。
この記事では、その構築の過程と考えたことを整理してみようと思う。
サイトのコンテンツ構成
最初に考えたのは「何を載せるか」だった。 結果的に三つの軸に整理した。
Tools
開発をしていると、よく使うユーティリティというものが出てくる。 そのたびに検索して広告の多いサイトを経由して使うのが、なかなか面倒だった。
それで自然とこう思った。
自分で作ってしまえばいいんじゃないか
このスペースには以下のようなツールを置いている。
- パスワードジェネレーター
- Unixタイムスタンプ変換
- IPアドレス確認
- 画像最適化ツール など。
これからも必要になったら追加していく予定だ。
Daily UI
UIコンポーネントをひとつずつ作っていくチャレンジのスペースだ。
仕事やリサーチ中に面白いと思ったインタラクションを 自分で実装して、実験して、記録する。
ここは結果を見せる場所というより、 過程を積み上げていく研究室に近い。
Insight
開発をしながら感じたことを記録していく場所だ。
- 仕事中に悩んだこと
- 技術選択についての考え
- 変化の速いこの業界の中で気づいたこと
- よかった点と反省点の振り返り
こういった記録が積み重なることで、自分なりの基準と方向性ができていくと思っている。
技術スタックの選択
Next.js → Astro
最初は慣れ親しんだNext.js(React)で始めた。 ルーティングが直感的で、既存の知識をそのまま使えたからだ。
ただ、運用していくうちにいくつか不便なことが見えてきた。
- クライアントサイドのJSがほぼ不要なのにバンドルサイズが大きくなる
- Markdownベースのコンテンツ管理が面倒
- 静的サイトとして扱うには制約がある
結論は明確だった。
このプロジェクトにNext.jsは大げさすぎる
そこでAstroに切り替えた。
Astroは静的サイトに最適化されていながら、 必要な場合はReact、Vue、Svelteも組み合わせて使える。
デフォルトは軽く保ちつつ、必要な部分だけを選択的に使う構造が このプロジェクトとうまく合っていた。
Tailwind CSS v4の設定
AstroのオフィシャルなTailwindインテグレーションはv3向けなので、 v4を使うには直接設定する必要がある。
// astro.config.mjs
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
vite: {
plugins: [tailwindcss()],
},
});
CSSでは以下の一行だけで済む。
@import 'tailwindcss';
Node.jsのバージョン問題
Astro 5からはVite 8を使うようになり、 そこで使われているrolldownがNode 20以上を必要とする。
既存の環境(Node 21.7.3)では動かなかったため、 VoltaでNode 22を固定した。
volta pin node@22
Content Collectionsの変更
Astro 5以降でentry.render()がdeprecatedになり、 使い方が変わった。
import { render } from 'astro:content';
const { Content } = await render(entry);
Canvas APIの活用
画像最適化、クロップ、favicon生成はすべてCanvas APIで処理した。
- サーバーへのアップロードが不要
- プライバシーの面で有利
- サーバーレス環境の制約から自由
多言語対応
日本語をベースに、韓国語と英語もあわせてサポートしている。
Astroの[lang]ルーティングとシンプルなユーティリティだけで、 i18nライブラリを使わずに実装した。
Markdownベースのコンテンツ
src/content/insight/にファイルを追加すれば、 自動的に一覧と静的ページが生成される。
Daily UI実装で悩んだこと
Daily UIのカードでiframeを使ってデモをプレビューする機能が、思ったより手こずった。
function updateIframeScales() {
document.querySelectorAll('.scale-wrapper').forEach(wrapper => {
const scale = wrapper.offsetWidth / 1280;
wrapper.querySelectorAll('.demo-iframe').forEach(iframe => {
iframe.style.transform = `scale(${scale})`;
});
});
}
これから
今の段階で一番大事なのは機能追加より継続性だ。
- コンテンツをコツコツ積み上げる
- ツールを少しずつ増やす
- 記録を止めない
このプロジェクトは完成形を目指すより、 変化しながら積み上がっていく場所に近い。
AfterDayという名前の通り、 一日が終わった後の時間をどう使うかが このサイトの方向をつくっていくのだと思う。