Scaling to 1,200+ Calculator Pages with Astro: A Data-Driven Approach
These articles are AI-generated summaries. Please check the original sources for full details.
How I built 1,200+ calculator pages in Astro without writing 1,200 templates
Martin Rodriguez developed Hacé Cuentas, a collection of over 4,100 Spanish-language calculators. He utilized a single template and JSON-driven content to manage thousands of routes while keeping the codebase smaller than when he had only 50 pages.
Why This Matters
Traditional page-per-feature architectures create unsustainable maintenance overhead; updating a single CTA or CSS class across thousands of hand-built templates is computationally and operationally expensive. By decoupling structured content (JSON) from business logic (TypeScript) and presentation (Astro), developers can achieve O(1) template maintenance regardless of the number of generated pages.
Key Insights
- Separation of Concerns: Use JSON for structured content like labels and FAQs, but TypeScript for math logic to maintain type safety (Rodriguez, 2026).
- Dynamic Route Generation: Implementing
getStaticPathsin Astro allows for build-time generation where adding a new page only requires a new JSON file (Build time increase: +8ms per calc). - Hybrid Hydration: Static HTML is generated at build time with client-side hydration reserved exclusively for the calculator widget to ensure a First Contentful Paint of 0.3s on 3G.
- Automated SEO Scaling: A single JSON source can simultaneously populate multiple schema.org blocks including SoftwareApplication, Article, BreadcrumbList, and Dataset.
Working Examples
Example of isolating calculator logic into separate TypeScript modules.
export interface Inputs { capital: number; tna: number; dias: number }
export interface Outputs { montoFinal: number; interesGanado: number; }
export function plazoFijo(i: Inputs): Outputs {
const interesGanado = i.capital * (i.tna / 100) * (i.dias / 365);
return {
montoFinal: Math.round(i.capital + interesGanado),
interesGanado: Math.round(interesGanado),
};
}
Dynamic route implementation using Astro’s getStaticPaths.
---
export async function getStaticPaths() {
const calcs = import.meta.glob('../content/calcs/*.json', { eager: true });
return Object.values(calcs).map((mod) => {
const c = mod.default;
return {
params: { slug: c.slug },
props: { calc: c },
};
});
}
const { calc } = Astro.props;
---
<Layout title={calc.title}>
<Calculator config={calc} />
<Explanation markdown={calc.explanation} />
<FAQ items={calc.faq} />
</Layout>
Practical Applications
References:
Continue reading
Next article
Reducing SaaS Overhead: Building a Web Component Email Editor to Replace Costly SDKs
Related Content
Building 1:1 WebRTC Video Calls without Signaling Server Boilerplate
Build a production-ready WebRTC video chat using @metered-ca/peer with automatic reconnection and 20 GB/month of free TURN bandwidth.
UnfoldCMS: The First Production CMS Built Entirely on shadcn/ui
UnfoldCMS launches as a production-ready CMS featuring 51 shadcn/ui components and 205 admin pages built with Laravel 12 and React 19.
Building a Real-Time TCG Price Tracker: Scraping Virtual DOMs with MutationObserver
Developer John A Madrigal engineered a Chrome Extension using MutationObserver to inject real-time TCGPlayer price data into Curiosa.io card collections.