DEV Community

miccho27
miccho27

Posted on

How I Built 510 Calculator Tools with Next.js SSG and Zero Hosting Cost

I built a site with 510 free calculation tools — and every single page is statically generated at build time. No database. No server-side rendering. Just Next.js SSG and JSON.

Here's the architecture behind keisan-tools.

The Concept

Japanese users search for specific calculators constantly: BMI, mortgage payments, age calculators. Each query has decent search volume but low competition.

Instead of building 10 tools manually, I built a system that generates tools from configuration files.

Architecture

keisan-tools/
├── data/
│   └── tools.json          # 510 tool definitions
├── app/
│   └── [category]/
│       └── [slug]/
│           └── page.tsx     # Dynamic route
├── lib/
│   ├── calculator.ts        # Calculation engine
│   └── tools.ts             # Tool loader
└── next.config.js           # SSG configuration
Enter fullscreen mode Exit fullscreen mode

Each tool is defined as a JSON object:

{
  "slug": "bmi-calculator",
  "category": "health",
  "title": "BMI Calculator",
  "inputs": [
    { "name": "height", "label": "Height (cm)", "type": "number" },
    { "name": "weight", "label": "Weight (kg)", "type": "number" }
  ],
  "formula": "weight / ((height / 100) ** 2)",
  "output_label": "Your BMI"
}
Enter fullscreen mode Exit fullscreen mode

Add a JSON entry, get a fully functional calculator page with SEO metadata, structured data, and responsive UI. No code changes needed.

Static Generation at Scale

Next.js generateStaticParams creates all 510 pages at build time:

export async function generateStaticParams() {
  const tools = getAllTools();
  return tools.map(tool => ({
    category: tool.category,
    slug: tool.slug,
  }));
}
Enter fullscreen mode Exit fullscreen mode

Build time for 510 pages: ~45 seconds on Vercel. Each page is a static HTML file served from the CDN.

SEO: JSON-LD Structured Data

Every tool page includes structured data:

{
  "@context": "https://schema.org",
  "@type": "WebApplication",
  "name": "BMI Calculator",
  "applicationCategory": "UtilityApplication",
  "offers": {
    "@type": "Offer",
    "price": "0"
  }
}
Enter fullscreen mode Exit fullscreen mode

This tells Google: "This is a free web application." It helps with rich snippets in search results.

Categories

The 510 tools span 20+ categories:

Category Tools Examples
Health 35 BMI, calories, ideal weight
Finance 68 Loan, compound interest, tax
Math 45 Percentage, ratio, statistics
Date/Time 28 Age, date diff, countdown
Unit Conversion 52 Length, weight, temperature
Real Estate 22 Mortgage, rent vs buy
Investment 31 NISA, iDeCo, dividends
Energy 18 Solar panel, electricity savings

Performance

  • Lighthouse score: 95+
  • First Contentful Paint: < 1s
  • Time to Interactive: < 1.5s
  • Bundle size: ~80KB gzipped

Static files + CDN = fast everywhere.

Key Takeaway: Configuration Over Code

The biggest lesson: don't build 510 pages, build 1 page that reads 510 configurations.

This pattern works for any content-heavy site:

  • Recipe sites (ingredients + steps as JSON)
  • Product comparison pages (specs as JSON)
  • Documentation sites (API endpoints as JSON)

If your pages share the same layout but different data, SSG + JSON is the answer.

Tech Stack

  • Next.js 16 (App Router, SSG)
  • TypeScript + Tailwind CSS
  • Vercel (hosting, free tier)
  • Google Analytics 4

Total monthly cost: $0.


Have you built content-heavy static sites? What patterns have worked for scaling to hundreds or thousands of pages?

Top comments (0)