こんにちは。グリーエックス株式会社の岡﨑 (@cakegaly) です。
グリーホールディングスでは、クライアント企業の DX に関するコンサルティングとソリューションの提供を通して、DX 事業に取り組んでいます。 グリーエックス株式会社は、グリーホールディングスの DX 事業を担う100%子会社として2025年2月に設立されました。
このタイミングで、グリーエックスの幅広い事業領域と技術スタックについて発信する場として、テックブログを開設することにしました。 この記事では、このテックブログのフロントエンド構成、設計方針、開発体験を高める工夫について紹介します。
技術スタック紹介
このブログを構成する技術について説明します。
カテゴリ | 名前 |
---|---|
Meta Framework | Astro |
CSS | Tailwind CSS |
Components (Headless UI) | shadcn/ui |
Contents Management | MDX |
Syntax Highlighting | Shiki |
Validation | Zod |
Astro
ブログの運用における KPI は、より多くの人に記事を読んでもらうことです。 フロントエンドにおいては、ページの表示速度、検索エンジンに適した HTML 構造 (テクニカル SEO)、アクセシビリティが担保されることを要件としました。
業務での経験を活かした選定
グリーエックスでは、メディア開発において Next.js を積極的に採用しています。静的ホスティングによる爆速表示、SEO 効果、開発体験の良さが大きな魅力です。
Next.js によるメディア開発については、GREE Tech Conference 2024 の発表資料 でも詳しく紹介しているので、ぜひあわせてご覧ください。
このテックブログも Next.js で構築することを検討しましたが、今回は別のフレームワークでの構築に挑戦しました。 候補には Astro や HonoX などがありましたが、最終的に Astro を採用しました。
運用体制に合った選択
このブログでは、記事の作成とレビューをエンジニアが担当するため、ヘッドレス CMS よりも、Markdown (MDX) + GitHub による運用がマッチすると判断しました。
Astro は、MDX との親和性が高く、静的エクスポートがデフォルトです。構成もシンプルで、必要に応じて React や Vue のコンポーネントを部分的に組み込んでカスタマイズすることも可能です。
MDX によるコンテンツ管理
記事コンテンツは MDX (Markdown + JSX) で管理しています。 これにより、Markdown の手軽さと、必要に応じたカスタムコンポーネントの埋め込みが両立できるようになっています。
Tailwind CSS + shadcn/ui
スタイリングに Tailwind CSS、UI コンポーネントとして shadcn/ui を採用しています。 この組み合わせにより、最小限のスタイルガイドに沿って統一感のあるデザインを保ちつつ、必要なパーツだけ柔軟に組み込めます。
今回は、.astro
ファイルを中心に UI を構築し、shadcn/ui は Avatar や Button など、一部のインタラクティブ要素を Island (部分的に React で実装) としての導入に留めました。
必要な依存ライブラリ(@radix-ui/react-\*
, clsx
, tailwind-merge
など)は、shadcn/ui に合わせて個別に導入し、Astro の静的サイト生成 (SSG) と両立する構成にしています。
基本的な UI の実現は .astro
ファイルで構築しつつ、必要な部分のみを React コンポーネントとして分離することで、ビルドサイズやパフォーマンスを最適化しています。
パフォーマンス最適化の工夫と Lighthouse スコア
パフォーマンスと SEO の観点から、以下のような工夫を入れています。
- Web フォント (Google Fonts) を CDN 読み込みではなく
.woff2
をローカルホスティングさせて運用する - 記事、著者の画像をビルド時に軽量化する
- Island アーキテクチャを活用し、必要最小限の JavaScript に限定する
これにより、Lighthouse でパフォーマンス・アクセシビリティ・ベストプラクティス・SEO の全項目で 100 点 を達成しました!
コンテンツ管理の仕組み(MDX + Zod)
Astro の コンテンツコレクション を使って、以下の3種類のコンテンツを管理しています。
コンテンツ種別 | ディレクトリ例 | 主な目的 |
---|---|---|
記事 | src/content/blog/ | ブログ記事本体 |
著者 | src/content/author/ | 投稿者プロフィール |
タグ | src/content/tag/ | 記事タグ |
定義した Zod スキーマにより、Frontmatter のバリデーションも自動で行われます。
記事コンテンツの例
---
title: テックブログを Astro でリニューアルしました!
date: 2025-03-22
author: toshiki-okazaki
summary: グリーエックス社の設立にともない、社内のエンジニアによるテックブログを Astro でリニューアルしました。この記事では、Astro + MDX + Tailwind CSSで構築した社内ブログの技術スタックを紹介します。
eyecatch: ./astro-blog.webp
tags:
- astro
- mdx
- tailwind
---
## はじめに
...
## 経緯
...
## おわりに
...
title
, date
, author
, tags
は、後述する Zod スキーマで型を定義しているため、入力ミスを防止できるようにしています。
なお、記事に関連する画像は、public/
ディレクトリではなく、記事ディレクトリに同梱する運用にしています。これにより、記事に対応する画像がわかりやすくなると同時に、Astro アプリのビルド時に画像を最適化できるようにしています。
著者コンテンツの例
---
name: 'toshiki.okazaki'
image: './avatar.webp'
website: 'https://x.com/cakegaly'
introduction: フロントエンド開発が大好きなエンジニアです。
---
著者ごとの自己紹介ページも自動で生成されます。
開発体験を高める工夫
社内のエンジニアによる記事投稿、レビュー対応へのハードルを下げる工夫もいれています。
記事テンプレート生成(Plop)
新しい記事を作るときは、以下のコマンドで対話形式でテンプレート生成されます。
pnpm generate
plopfile.mjs
に定義されたスキーマを使って、src/content/blog/
配下に index.mdx
ファイルを自動生成する仕組みです。
slug (ディレクトリ名) やタイトル、著者などを入力するだけで雛形が完成するため、投稿者の負担が減り、統一感も保てます。
画像の最適化(optimize-images.js)
画像ファイルは、記事ディレクトリや著者ディレクトリと同じ階層に配置されますが、そのままだとファイルサイズが大きくなりがちです。
そこで、以下のコマンドを用意し、画像のリサイズ・圧縮と MDX の参照パス修正を自動化しています。
pnpm optimize-image
これにより、ファイルサイズの軽量化だけでなく、軽量化前後の確認、再圧縮もスムーズに対応できるようになりました。
VSCode + Linter/Formatter 設定
チーム全体でコード品質を保つため、以下のような設定を .vscode/
にまとめています。
settings.json
: formatOnSave の有効化、推奨拡張機能の定義extensions.json
: Astro / ESLint / Prettier などの必須拡張機能の推奨
ESLint, Prettier は、Flat Config を使って構成しました。
Prettier は prettier-plugin-astro
, prettier-plugin-tailwindcss
を導入することで、Astro / Tailwind 両方に最適化された整形ルールを実現しています。
pnpm format
で整形できるよう、package.json
の scripts
にも登録済みです。
これにより、初めて触るメンバーでも、迷わず快適に記事執筆・コード修正ができる開発体験を実現しています。
ESLint の Flat Config 対応については、ここに書くと長くなるので、別の記事でまとめる予定です。
おわりに
このテックブログを構成するフロントエンドの技術を紹介しました。 この記事が Astro や MDX によるテックブログ構築の参考になれば、うれしいです。
次回は「インフラ編」として、masahiro.higuchi さんが GCS ホスティングや GitHub Actions でのデプロイについて紹介する予定です。お楽しみに!