現在運用している団体ホームページ
このサイトは2025年5月頃に初版を作成し、そこから必要な機能を継ぎ足しながら運用してきました。
使用している技術は主に以下。
- Next.js
- TailwindCSS
- Markdownベースの記事管理
当時は「Next.jsが流行っていた」「少し触ったことがあった」という理由で採用しましたが、正直この頃はWeb開発や設計についてそこまで理解していませんでした。
その結果、AIで生成したTailwindCSSが散乱、コンポーネント責務が曖昧、global.css と componentのCSS が混在、画像管理もカオスという状態になっていました。
今回は新年度ということもあり、
機能はほぼ維持したまま、保守性を優先してゼロから再設計していきます。
必要な機能
トップページ
- ヘッダー
- サイドバー
- Hero画像スライダー
- 最新ブログ一覧
- プロダクト紹介
- リンク一覧
- 募集欄
- フッター
ブログページ
- タイトル画像
- タイトル
- 筆者アイコン
- 筆者名
- Markdown本文
さらに、
XにブログURLを投稿した際にOGP画像が表示されるようにします。
メンバーページ
- スライド列挙
使用するもの
フレームワーク
- Next.js
Markdown表示
- gray-matter
- remark
- rehype
デザイン
- TailwindCSS
- @tailwindcss/typography
旧ディレクトリ構成
src/
├── app/
│ ├── (routes)/
│ ├── globals.css
│ └── layout.tsx
│
├── components/
│ ├── Header.tsx
│ ├── Button.tsx
│ └── Card.tsx
│
├── lib/
│ └── getMarkdown.ts
│
└── public/
└── 【執筆者名】/
└── 【ブログタイトル】/
└── 1.png
旧構成の問題点
Markdownファイルの管理がしづらい
最初は記事数も少なかったため、routes内にMarkdownを配置していました。
しかし記事が増えるにつれて、
- どこに何の記事があるのか分からない
- routes配下が肥大化
- 管理コスト増大
という問題が発生。
コンポーネント責務が曖昧
コンポーネントを事前に何も決めずに追加していったため、
- 何が汎用コンポーネントなのか
- どのページ専用なのか
- CSS責務はどこなのか
が分からなくなりました。
特にTailwindCSSをAI生成に頼っていた影響で、
- 同じデザインなのに別class
- 微妙に余白が違う
- 同じUIなのに実装が複数存在
など、かなりカオスでした。
結果として、後からデザイン変更するのが大変になりました。
画像管理が限界だった
画像を執筆者ごとに管理していたが、
public/
└── 【執筆者名】/
└── 【ブログタイトル】/
└── 1.png
という構造では、
- 記事数増加で探すのが困難
- 画像の再利用がしにくい
- png大量使用で容量増加
などの問題が出てきた。
新ディレクトリ構成
src/
│── content/
│ ├── blog/ # ブログ記事
│ └── members/ # メンバー情報
│
├── app/
│ ├── (routes)/
│ ├── globals.css
│ └── layout.tsx # 全体レイアウト(ここでHeaderやFooterを呼び出す)
│
├── components/
│ ├── ui/ # Button, Card などの汎用的なUIパーツ
│ ├── layouts/ # Header, Footer, Sidebarなど
│ └── features/ # ドメイン固有の少し大きな機能ブロック
│ ├── blog/ # BlogCard, BlogListなど
│ └── home/ # HeroSliderなど
│
├── lib/
│ └── markdown.ts # ここにMarkdownを読み込む関数を作る
│
│── public/
│ ├── common/ # ロゴ、ヘッダーなど
│ ├── home/ # トップページのスライダー画像
│ ├── blog/ # ブログ用(年/月で分ける)
│ │ └── 2025/
│ │ └── 05/
│ │ └── photo.webp
│ │
│ └── members/ # メンバーのアイコン写真等
│
│
└── types/ # 型定義
なぜこの構成にしたのか
content/ にMarkdownを集約
content/
├── blog/
└── members/
コードと記事データを分離することで、
- 投稿しやすい
- 管理しやすい
- routesが肥大化しない
というメリットがある。
YYYY-MM-DD-slug.md 形式で
ファイル名に日付を含める方法をとるとより管理しやすくなる。
components の責務分離
ui/
components/ui/
Button や Card など、
ドメイン知識を持たない純粋なUI部品を置く。
例:
- Button
- Card
layouts/
components/layouts/
レイアウト系。
例:
- Header
- Footer
- Sidebar
features/
components/features/
機能単位でまとめる。
例:
features/blog/
├── BlogCard.tsx
├── BlogList.tsx
└── BlogHeader.tsx
これによって、
- どこに何があるか分かりやすい
- ページ固有ロジックを閉じ込められる
- UIと責務を分離できる
ようになる。
CSS設計も整理する
以前は、
- global.css
- TailwindCSS
が混在していた。
今回は、
globals.css
- 背景色
- フォント
など、サイト全体に関わるものだけに限定。
TailwindCSS
コンポーネント内部の見た目だけを担当。
つまり、
- 「サイト全体」 → globals.css
- 「部品の見た目」 → Tailwind
という責務分離を徹底していく。
画像管理も整理
旧構成では執筆者ごとでしたが、
今回は日付ベースに変更。
public/blog/2025/05/
こうすることで、
- 探しやすい
- 時系列で整理できる
- 共通ルール化できる
という恩恵を受けられる。
さらに、
- pngを減らす
- webp中心にする
ことで容量削減も狙っていく。
今回意識すること
今回のリファクタリングで一番意識しているのは、
後から変更しやすい構成にすること
責務分離とディレクトリ整理をちゃんとやることで、
後々の保守コストを下げる。
まとめ
以前の自分は、
- とりあえず動けばOK
- AI生成コードをそのまま使う
- コンポーネントを深く考えない
という状態でした。
ただ実際に長期運用してみると、
最初の設計がかなり重要だったと痛感しました。
なので今回は、保守性、責務分離
を最優先にして、
ホームページを再構築していこうと思います。


