Skip to content
Putting technology to work.
Insights to guide decisions and action.

Search articles

Step-by-Step Guide to Building a Corporate Website with Astro × microCMS

Table of contents · 10 items

"WordPress is slow," "I'm worried about security," "Design flexibility is too limited"—do these challenges sound familiar when choosing a CMS for your corporate site? Combining Astro × microCMS resolves all these pain points at once.

As a static site generator (SSG), Astro pre-renders all HTML at build time. microCMS is an intuitive Japanese headless CMS that enables no-code content management. By pairing the two, you achieve a corporate website that is blazingly fast, highly secure, and editable even by non-engineers.

In this article, we walk through the entire process of building a corporate site with Astro + microCMS, including practical code samples. If you have not read Jamstack Architecture Fundamentals yet, please check that out first.


Why Astro × microCMS?

Why choose Astro?

Since its official release in 2022, Astro has seen rapid market share growth among frontend frameworks. Its primary hallmark is a "Zero-JS by Default" philosophy. It pre-renders HTML at build time and ships zero JavaScript to parts of the page that require no interactivity.

For content-focused sites like corporate websites, this architecture is a massive advantage. Its key features include:

  • Fast page rendering: Serving static HTML requires no server-side processing, making it easier to improve Core Web Vitals scores
  • Simple syntax: Component architecture allowing HTML, CSS, and JavaScript to be authored together in .astro files
  • Framework-agnostic: Ability to mix and match multiple UI frameworks, such as React, Vue, and Svelte
  • Standard TypeScript support: Type-safe development out of the box

Why choose microCMS?

microCMS is a Japanese headless CMS with an administrative dashboard offering complete Japanese-language support. Because it delivers content via API, it is decoupled from the frontend tech stack.

  • Intuitive Japanese UI: Easy content updates even for non-engineers
  • Flexible schema definitions: Configure diverse fields including text, images, rich text editors, and repeater fields
  • Free plan available: Free for up to 3 APIs, allowing small sites to launch at zero cost
  • Automated builds via webhooks: Triggers builds when content is updated, keeping the site fresh automatically

Architectural overview

The architecture of a corporate website built with Astro × microCMS is structured as follows.

┌─────────────────────────────────────────────────────┐
│                  開発・運用フロー                       │
│                                                     │
│  ┌──────────────┐   コンテンツ編集   ┌─────────────┐ │
│  │  担当者(非エンジニア)│ ──────────► │  microCMS   │ │
│  └──────────────┘              │  管理画面   │ │
│                                └──────┬──────┘ │
│                                       │ Webhook   │
│  ┌──────────────┐  git push   ┌───────▼──────┐  │
│  │  開発者        │ ──────────► │  CI/CDパイプライン │  │
│  └──────────────┘              │ (GitHub Actions)│  │
│                                └───────┬──────┘  │
│                                        │ ビルド    │
│                              ┌─────────▼──────┐   │
│                              │  Astro (SSG)   │   │
│                              │  静的HTML生成  │   │
│                              └─────────┬──────┘   │
│                                        │ デプロイ  │
│                              ┌─────────▼──────┐   │
│                              │  CDN配信        │   │
│                              │ (GCS/Vercel等)  │   │
│                              └────────────────┘   │
└─────────────────────────────────────────────────────┘

At build time, Astro fetches content from the microCMS API and generates static HTML. Deploying the generated files to a CDN enables fast and secure delivery.


Step 1: Environment setup and package installation

First, create an Astro project.

# Astroプロジェクトの作成
npm create astro@latest my-corporate-site
cd my-corporate-site

# microCMS SDKのインストール
npm install microcms-js-sdk

# 開発サーバーの起動確認
npm run dev

During project creation, selecting the following options in the setup wizard is recommended:

  • Template: Empty (empty project) or Blog (blog template)
  • TypeScript: Yes (recommended for type safety)
  • Integrations: Optional, as they can be added later

Configuring environment variables

To manage your microCMS API keys securely, specify them in your .env file.

# .env
MICROCMS_SERVICE_DOMAIN=your-service-domain
MICROCMS_API_KEY=your-api-key

Be sure to add .env to your .gitignore. If your API key is exposed on GitHub, you risk unauthorized manipulation of your content.


Step 2: Designing the content schema in microCMS

Create APIs in the microCMS admin dashboard. Here are common examples used for corporate sites.

News (Announcements) API

In the dashboard, select "Add API" → "List format", and configure the following fields:

Field nameField IDField type
TitletitleText field
BodybodyRich editor
CategoriescategorySelect field
ThumbnailthumbnailImage
Published datepublishedAtDate and time

Team Members API

Field nameField IDField type
Full namenameText field
RoleroleText field
ProfilebioText area
PhotophotoImage

The key to schema design is keeping in mind "who will be updating it." For fields edited by non-engineers, use rich text editors and select dropdowns to prevent input mistakes.


Step 3: Configuring the microCMS client

Define the API client in src/lib/microcms.ts.

// src/lib/microcms.ts
import { createClient } from 'microcms-js-sdk';

// 型定義
export type News = {
  id: string;
  title: string;
  body: string;
  category: string;
  thumbnail?: {
    url: string;
    width: number;
    height: number;
  };
  publishedAt: string;
  createdAt: string;
  updatedAt: string;
};

export type Member = {
  id: string;
  name: string;
  role: string;
  bio: string;
  photo?: {
    url: string;
    width: number;
    height: number;
  };
};

// クライアントの初期化
export const client = createClient({
  serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
  apiKey: import.meta.env.MICROCMS_API_KEY,
});

// ニュース一覧の取得
export const getNewsList = async (limit = 10) => {
  return client.getList<News>({
    endpoint: 'news',
    queries: {
      limit,
      orders: '-publishedAt', // 新しい順
    },
  });
};

// ニュース詳細の取得
export const getNewsDetail = async (contentId: string) => {
  return client.getListDetail<News>({
    endpoint: 'news',
    contentId,
  });
};

// メンバー一覧の取得
export const getMemberList = async () => {
  return client.getList<Member>({
    endpoint: 'members',
    queries: { limit: 100 },
  });
};

import.meta.env is Astro's method for accessing environment variables. Be sure to use this format rather than process.env.


Step 4: Fetching and rendering data in Astro components

Call the API inside the Astro component frontmatter (the section enclosed in ---) and render it within the template section.

News list page (src/pages/news/index.astro)

---
import Layout from '../../layouts/Layout.astro';
import { getNewsList } from '../../lib/microcms';

// ビルド時にAPIを呼び出す
const { contents: newsList } = await getNewsList(20);
---

<Layout title="ニュース | 会社名">
  <main>
    <h1>ニュース</h1>
    <ul class="news-list">
      {newsList.map((news) => (
        <li class="news-item">
          <a href={`/news/${news.id}/`}>
            <time datetime={news.publishedAt}>
              {new Date(news.publishedAt).toLocaleDateString('ja-JP')}
            </time>
            <span class="category">{news.category}</span>
            <span class="title">{news.title}</span>
          </a>
        </li>
      ))}
    </ul>
  </main>
</Layout>

News detail page with dynamic routing (src/pages/news/[id].astro)

---
import Layout from '../../layouts/Layout.astro';
import { getNewsList, getNewsDetail } from '../../lib/microcms';

// 静的生成に必要なIDを全件取得
export const getStaticPaths = async () => {
  const { contents } = await getNewsList(100);
  return contents.map((news) => ({
    params: { id: news.id },
  }));
};

// 個別ページのデータ取得
const { id } = Astro.params;
const news = await getNewsDetail(id!);
---

<Layout title={`${news.title} | ニュース`}>
  <article>
    <header>
      <time datetime={news.publishedAt}>
        {new Date(news.publishedAt).toLocaleDateString('ja-JP')}
      </time>
      <h1>{news.title}</h1>
    </header>
    <div class="body" set:html={news.body} />
  </article>
</Layout>

getStaticPaths is an essential Astro concept. It is the required function for statically generating dynamic routes ([id].astro), fetching all IDs at build time to pre-render the HTML for each page. Pairing it with How to Implement Breadcrumbs further enhances the navigation experience.


Step 5: Leveraging Astro 5 Content Loaders (Advanced)

Starting in Astro 5, a new feature called Content Loaders allows external CMS data to be handled as Astro Content Collections. This significantly improves type safety and the developer experience.

// src/content/config.ts
import { defineCollection, z } from 'astro:content';
import { createClient } from 'microcms-js-sdk';

const client = createClient({
  serviceDomain: import.meta.env.MICROCMS_SERVICE_DOMAIN,
  apiKey: import.meta.env.MICROCMS_API_KEY,
});

const news = defineCollection({
  loader: async () => {
    const { contents } = await client.getList({
      endpoint: 'news',
      queries: { limit: 100 },
    });
    // idフィールドが必須
    return contents.map((item) => ({ ...item, id: item.id }));
  },
  schema: z.object({
    title: z.string(),
    body: z.string(),
    category: z.string(),
    publishedAt: z.string(),
  }),
});

export const collections = { news };

Using Content Loaders eliminates the need to call APIs inside page components, allowing you to fetch data via getCollection('news'). Type checking is also performed automatically based on schema definitions, helping catch implementation errors early.


Step 6: Setting up automated builds on content updates

By combining microCMS webhooks with GitHub Actions, your site can be built and deployed automatically whenever content is updated.

GitHub Actions workflow (.github/workflows/deploy.yml)

name: Deploy on microCMS Update

on:
  push:
    branches: [main]
  repository_dispatch:
    types: [microcms-update]  # Webhookで発火

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build
        env:
          MICROCMS_SERVICE_DOMAIN: ${{ secrets.MICROCMS_SERVICE_DOMAIN }}
          MICROCMS_API_KEY: ${{ secrets.MICROCMS_API_KEY }}
        run: npm run build

      - name: Deploy to GCS
        uses: google-github-actions/upload-cloud-storage@v2
        with:
          path: dist
          destination: your-bucket-name

In the microCMS admin dashboard, navigate to "Webhook Settings" → "GitHub" and register it as a repository_dispatch event. This completes an operational workflow where an automated build and deployment runs the moment an editor publishes news in microCMS.


Common implementation pitfalls and solutions

Pitfall 1: Build failures caused by API rate limits

The microCMS free plan has limits on API calls. If you have a large volume of content, API calls during build time may exceed these limits and trigger errors.

Solution: The limit parameter in getList caps out at 100 items. When handling large datasets, prepare a utility function to paginate through all entries using offset.

// 全件取得のユーティリティ
export const getAllContents = async <T>(endpoint: string): Promise<T[]> => {
  const first = await client.getList<T>({ endpoint, queries: { limit: 1 } });
  const totalCount = first.totalCount;
  const { contents } = await client.getList<T>({
    endpoint,
    queries: { limit: totalCount },
  });
  return contents;
};

Pitfall 2: Sanitizing rich editor HTML

When rendering HTML directly from the microCMS rich editor using set:html, you may need to add target="_blank" to external links or strip unnecessary tags.

Solution: Using a cheerio library to parse and sanitize HTML before rendering is an effective approach.

Pitfall 3: Previewing draft articles

To preview unpublished content, you must pass microCMS's draft key as a query parameter. Because Astro's SSG mode generates fixed post-build URLs, preview functionality requires an architecture utilizing SSR (output: 'server') or ISR (Incremental Static Regeneration).


Conclusion: Sites best suited for Astro × microCMS

The Astro × microCMS architecture is particularly well suited for:

  • Corporate sites with low to moderate update frequency: Primarily structured content like news, team profiles, and case studies
  • Sites prioritizing loading speed: Where improving Core Web Vitals and maximizing SEO ROI are top goals
  • Sites maintained daily by non-engineers: microCMS's Japanese administrative interface provides a major advantage
  • Sites planning for future architectural redesigns: The headless structure allows you to reuse existing content even if you completely rewrite the frontend

On the other hand, it is less suited for services with heavy dynamic processing, such as e-commerce platforms or membership portals. In those cases, choosing a different framework, such as Astro's SSR mode or Next.js, is advisable.

If you are considering adopting Astro × microCMS for your corporate website, please feel free to reach out to us.


If you want to rebuild your corporate site using Astro and a headless CMS, or feel concerned about the performance of your current WordPress site, consult GleamHub. We handle everything end-to-end, from technology selection and architecture design to implementation and ongoing maintenance support.

Free consultation here
Share this articleXFacebook
Rui Teruya

Former corporate league baseball player and founder of an IT venture. Founded the company with the drive to ride the fast-moving waves of the world and deliver truly valuable services to society.

Turn this article's theme into your company's next step

Concrete steps forward for your organization.

We organize your desired architecture, legacy systems, and operational requirements to formulate your next steps toward execution.

  • Desired architecture
  • Integration with existing environments
  • Operational requirements
Consult on development & operations initiatives

You can consult with us from the initial conceptual stage. Details from this article will be carried over to the inquiry form.

Receive the latest articles by email