DEV Community

Cover image for How I Built a 2,000-Page Static Site for Cooking Times with Astro and Cloudflare Pages
meet dhanani
meet dhanani

Posted on

How I Built a 2,000-Page Static Site for Cooking Times with Astro and Cloudflare Pages

Every night, millions of people Google the same thing: "how long to cook chicken breast."

They land on a recipe blog. They scroll past a life story. They scroll past 14 ads. They finally find the answer buried in paragraph 19.

I hated this experience so much that I built CookTimeGuide.com, a free cooking time reference with 301 foods, 11 cooking methods, and zero fluff.

The site now has over 2,000 pages, loads in under 1 second, and the entire thing is statically generated from a single JSON file. Here's how I built it.

The Data Layer
Everything starts with one file: foods.json. Each food entry looks roughly like this:

{
  "name": "Chicken Breast",
  "slug": "chicken-breast",
  "category": "Poultry",
  "safe_temp_f": 165,
  "methods": {
    "bake": {
      "temps": {
        "350f": { "time_min": 25, "time_max": 30, "preheat": true },
        "400f": { "time_min": 20, "time_max": 25, "preheat": true },
        "425f": { "time_min": 15, "time_max": 20, "preheat": true }
      }
    },
    "air-fry": { ... },
    "grill": { ... }
  },
  "seo": {
    "primary_keyword": "how long to cook chicken breast",
    "related_keywords": ["chicken breast oven time", "chicken breast internal temp"]
  }
}
Enter fullscreen mode Exit fullscreen mode

301 foods. Each with multiple methods. Each method with multiple temperatures. This single JSON file generates the entire site.

Page Generation with Astro
I chose Astro because it's purpose-built for content-heavy static sites. The key feature: getStaticPaths() lets you generate thousands of pages from data at build time.

The site has three levels of dynamic cooking pages:

/cook/[food]/                    → 301 pages (food hub)
/cook/[food]/[method]/           → 615 pages (method-specific)
/cook/[food]/[method]/[temp]/    → 851 pages (temperature-specific)
Enter fullscreen mode Exit fullscreen mode

Plus prep guide pages:

/reheat/[food]/                  → 25 pages
/brine/[food]/                   → 11 pages
/soak/[food]/                    → 25 pages
/marinate/[food]/                → 16 pages
/thaw/[food]/                    → 15 pages
/rest/[food]/                    → 9 pages
Enter fullscreen mode Exit fullscreen mode

That's roughly 2,000 pages generated from data, plus hub pages, method indexes, and utility pages.

Each dynamic route reads from the JSON, validates that paths exist, and generates fully static HTML with zero client-side JavaScript for the core content.

SEO at Scale
When you have 2,000+ pages, SEO becomes an engineering problem, not a content problem. Here's what I had to solve:

Unique titles and descriptions for every page. I built a helper that generates them from templates:

Food hub: "How Long to Cook {Food}: Time & Temp for Every Method"
Method page: "How Long to Cook {Food} in {Method}: Time, Temp & Tips"
Temp page: "How Long to Cook {Food} in {Method} at {Temp}"
Every single page gets a unique title and meta description. No duplicates.

Structured data everywhere. Each page outputs JSON-LD for Recipe, HowTo, FAQPage, and BreadcrumbList schemas. This is what gets you rich snippets in Google results. I generate these programmatically from the same JSON data.

Canonical URLs to prevent duplicate content. The temperature-specific pages (like /cook/chicken-breast/bake/350f/) set their canonical URL to the method page (/cook/chicken-breast/bake/). This tells Google "index the method page, treat the temp pages as supporting content."

Internal linking. Every food page links to its methods. Every method page links to its temperature variants and back to the food hub. Every food hub cross-links to related prep guides (brine, marinate, thaw, rest). This creates a tight internal link graph that search engines love.

Sitemap generation. Astro's sitemap integration handles this automatically, but with 2,000+ URLs you need a sitemap index that splits into multiple sitemap files.

Deployment on Cloudflare Pages
The entire site deploys to Cloudflare Pages. For a fully static site like this, it's hard to beat:

  • Global CDN with edge caching
  • Free for this scale
  • Automatic deployments from git
  • Built-in analytics without extra JavaScript
  • Build time for 2,000+ pages is around 30-45 seconds. Astro's build is fast.

I also set up trailingSlash: 'always' in the Astro config to match Cloudflare Pages' default behavior. This is one of those small things that prevents redirect chains and duplicate URL issues that quietly tank your SEO.

Features That Made a Difference
Built-in kitchen timer. This was the feature that got the most positive feedback. It uses the Screen Wake Lock API so your phone screen stays on while cooking. No more tapping your phone with greasy hands to check the timer.

Weight calculator. A 4 oz chicken breast and an 8 oz chicken breast don't take the same time. The calculator scales cook time by weight. Simple math, but surprisingly few cooking sites do this.

Day/night theme. Kitchens are bright during the day, dark at night. The theme switch isn't just aesthetic, it's practical.

No client-side rendering for content. All cooking data is in the static HTML. JavaScript handles the timer, theme toggle, and weight calculator. If JS fails to load, you still get every cook time and temperature. This matters for Core Web Vitals and for the many users who cook with spotty kitchen WiFi.

What I Learned

  1. Long-tail SEO is underrated. "How long to cook chicken breast" is competitive. "How long to air fry chicken breast at 400 degrees" is not. With 851 temperature-specific pages, the site captures thousands of long-tail queries that bigger sites don't bother targeting.

  2. Data-driven sites scale better than content-driven sites. Adding a new food means adding one JSON entry. The build generates every page, every meta tag, every schema, every internal link automatically. I can add 10 foods in 20 minutes.

  3. Astro is excellent for this use case. The island architecture means interactive components (timer, calculator) work without shipping a full framework to the browser. Most pages ship under 50KB total.

  4. Speed is a feature users notice. Multiple users have mentioned that the site "just loads instantly." On Cloudflare's edge network with static HTML, Time to First Byte is typically under 50ms. Compare that to recipe blogs loading 15 ad scripts.

  5. Static doesn't mean limited. 2,000+ pages, structured data, dynamic internal linking, interactive components, all generated from one JSON file and deployed as static HTML. No database, no server, no ongoing infrastructure cost.

Check It Out
The site is live at cooktimeguide.com. A few pages worth looking at:

Browse all 301 foods
Air fryer cooking times
USDA temperature chart
Kitchen timer

If you've built a data-driven static site with Astro or a similar framework, I'd love to hear about your experience. What worked? What didn't?

Top comments (0)