Case Studies
8 min

Still Fast with 1000 Articles! Building a Scalable Article Management Workflow

The inevitable increase in build time for static site generators. Introducing a revolutionary workflow that doesn't depend on article count, dramatically improving development efficiency.

Next.jsGitHubCI/CDスケーラビリティワークフロー

Introduction: Easy to Build with AI, But What About Operations?

With AI assistance, building an article management system is surprisingly easy. However, once you start actual operations, you may face unexpected challenges.

In our case, we faced this problem:

20 articles → Build time: 1 minute
100 articles → Build time: 5 minutes?
1000 articles → Build time: 50 minutes???

At this rate, we'd need a coffee break every time we add an article.

Problems with Traditional Approaches

Typical Static Site Configuration

Project/
├── public/data/
│   ├── news.json      # All article data
│   └── tips.json      # All TIPS data
└── pages/
    └── [slug].tsx     # Static generation
    With this configuration, every time you add an article:
  1. Update JSON files
  2. Rebuild all pages
  3. Wait for deployment to complete

As articles increase, this wait time grows exponentially.

Revolutionary Solution: External Repository + ISR

New Architecture

Main Site (Vercel)          Article Data (GitHub)
     ↓                           ↓
  web repository         gizin-content repository
     ↓                           ↓
 GitHub API ← - - - - - - - → Article JSON
     ↓
 ISR Cache (1 hour)

Implementation Points

1. Improved Data Loader

typescript
// lib/data-loader.ts
async function fetchFromGitHub(path: string): Promise<string | null> {
  const response = await fetch(
    `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents/${path}`,
    {
      headers: {
        'Authorization': `Bearer ${GITHUB_TOKEN}`,
        'Accept': 'application/vnd.github.v3.raw'
      },
      next: { revalidate: 3600 } // ISR: 1 hour cache
    }
  )
  return await response.text()
}

2. Local Preview Feature

Development experience is also important. Added a mechanism to check locally before production release:

typescript
// Load temporary articles in development
if (IS_DEVELOPMENT) {
  const tempArticles = await loadTempArticles('news')
  articles = [...tempArticles, ...articles]
}

Practical Workflow

Step 1: Article Creation

bash
# AI creates article
→ temp/articles/tips/2025-06-19-example.json

Step 2: Local Confirmation

bash
npm run dev
# Instant preview on development server
# Identified by "Unpublished (Preview)" badge

Step 3: One-Command Publishing

bash
npm run article:publish tips temp/articles/tips/2025-06-19-example.json
    This command automatically:
  • Copies file to external repository
  • Git commit & push
  • Deletes temporary file

Step 4: Automatic Reflection

With ISR, it's reflected on the production site within 1 hour. No build required!

Implementation Results

Build Time Comparison

Articles Traditional New Method
20 1 min 1 min
100 5 min 1 min
1000 50 min 1 min

Build time no longer depends on article count!

Other Benefits

  1. Instant Article Publishing
  2. - Zero build wait time - Just push to GitHub
  1. Improved Development Efficiency
  2. - Safe with local preview - One-command publishing
  1. Scalability
  2. - No problem with 10,000 articles - Fast delivery with CDN cache

Implementation Considerations

1. Environment Variable Settings

bash
# Set in Vercel
GITHUB_OWNER=your-org
GITHUB_REPO=content-repo
GITHUB_TOKEN=ghp_xxxxxxxxxxxx

2. Security Considerations

  • Read-only GitHub token is sufficient
  • Watch for rate limits (5000/hour authenticated)

3. Migration Strategy

    Gradual migration recommended:
  1. Externalize only News and Tips first
  2. Keep low-update-frequency data static
  3. Additional migration as needed

Implementation Code Example

Publishing Script (Excerpt)

bash
#!/bin/bash
# scripts/publish-to-content.sh

# Move to gizin-content repository
cd "$CONTENT_REPO"

# Get latest
git pull origin main

# Copy file
cp "$ORIGINAL_DIR/$FILE" "$TYPE/articles/$FILENAME"

# Commit & push
git add .
git commit -m "feat: New article added - $FILENAME"
git push origin main

Conclusion: The Importance of Operations-Minded Design

Initial construction with AI is a great starting point. However, true value is demonstrated in the operations phase.

    With this improvement:
  • Developer wait time: 50 min → 0 min
  • Article publishing effort: Complex → One command
  • Scalability: Limited → Infinite

Unchanging comfort whether you have 1000 or 10,000 articles. This is the power of operations-minded design.

Next Steps

Ideas to further improve this workflow:

  1. GitHub Actions Integration
  2. - Auto-publish on PR merge - Establish review flow
  1. Preview URL Generation
  2. - Shareable URLs for temporary articles - Efficient team reviews
  1. Version Control
  2. - Article history tracking - Rollback functionality

Please try this approach in your projects too!