DEV Community

Cover image for ## How I Built a Free Age & Date Calculator Hub — From Zero to 1,500 Visits/Week in 2 Weeks
Roxana Dinu
Roxana Dinu

Posted on

## How I Built a Free Age & Date Calculator Hub — From Zero to 1,500 Visits/Week in 2 Weeks

I recently launched QuickAgeCalc.com — a free collection of age, date, and pregnancy calculators. Two weeks in, we're at 1,500+ organic visits per week across 47 countries, with zero ad spend.

Here's exactly how I built it, what worked, and what I'd do differently.


The Idea

I noticed that most age calculator sites are:

  • Slow to load
  • Cluttered with aggressive ads
  • Mobile-unfriendly
  • Missing obvious related tools (pregnancy due date, dog age, date difference)

The opportunity: build a fast, clean, genuinely useful hub of date calculators with programmatic SEO pages for long-tail keywords.


The Tech Stack

Deliberately simple:

  • Pure HTML/CSS/JavaScript — no frameworks, no build tools
  • Cloudflare Workers — hosting, global CDN, free tier
  • GitHub — version control + auto-deploy via GitHub Actions
  • Cloudflare Pages — deploy on every push to main

Zero monthly cost. Zero maintenance overhead.

# .github/workflows/deploy.yml
name: Deploy to Cloudflare Workers

on:
  push:
    branches:
      - main

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

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

      - name: Prepare public folder
        run: |
          mkdir -p public
          cp -r index.html robots.txt sitemap.xml favicon.ico nav.js \
            about age-difference birthday-countdown contact \
            date-difference privacy retirement-calculator \
            born-in-year pregnancy-due-date dog-age public/
          cp -r born-pages/* public/

      - name: Deploy to Cloudflare Workers
        uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          wranglerVersion: '4.87.0'
          command: deploy
Enter fullscreen mode Exit fullscreen mode

Every commit to main deploys in ~30 seconds. No manual steps.


The Tools I Built

Core calculators:

  • Age Calculator — exact age in years, months, days, hours, minutes
  • Date Difference Calculator — days between any two dates
  • Birthday Countdown — days until your next birthday
  • Age Difference Calculator — compare two birthdays
  • Retirement Calculator — when can you retire

Niche calculators:

  • Pregnancy Due Date Calculator — adjusts for cycle length, shows trimester + milestones
  • Dog Age Calculator — converts dog years to human years by breed size (not the inaccurate 7x rule)

Programmatic SEO pages:

  • 50 pages: /born-in-1960/ through /born-in-2009/
  • Hub page: /born-in-year/

Each born-in page targets keywords like "how old am I if born in 1985" and "1985 to 2026 age".


The Architecture — Global Navigation Without a Framework

One pattern I'm proud of: a single nav.js file that injects header and footer into every page automatically.

// nav.js — modify once, updates all pages instantly
(function() {
  var tools = [
    { href: '/',                    icon: '\uD83C\uDF82', label: 'Age Calc' },
    { href: '/date-difference/',    icon: '\uD83D\uDCC5', label: 'Date Diff' },
    { href: '/birthday-countdown/', icon: '\u23F3',       label: 'Birthday' },
    { href: '/age-difference/',     icon: '\uD83D\uDC6B', label: 'Age Diff' },
    { href: '/pregnancy-due-date/', icon: '\uD83E\uDD30', label: 'Due Date' },
    { href: '/dog-age/',            icon: '\uD83D\uDC15', label: 'Dog Age' },
    { href: '/born-in-year/',       icon: '\uD83D\uDCC6', label: 'By Year' },
  ];

  var current = window.location.pathname.replace(/\/?$/, '/');

  var navHTML = tools.map(function(t) {
    var isActive = (t.href === '/' ? current === '/' : current.startsWith(t.href));
    return '<a href="' + t.href + '"' + (isActive ? ' class="active"' : '') + '>'
      + t.icon + ' ' + t.label + '</a>';
  }).join('');

  document.body.insertAdjacentHTML('afterbegin', buildHeader(navHTML));
  document.body.insertAdjacentHTML('beforeend', buildFooter());
})();
Enter fullscreen mode Exit fullscreen mode

When I add a new tool, I update one file. All 60+ pages update instantly on next deploy.


Programmatic SEO — Generating 50 Pages with a Bash Script

The born-in pages are generated with a bash script that creates an index.html for each year:

for year in $(seq 1960 2009); do
  age=$((2026 - year))
  mkdir -p "born-pages/born-in-${year}"

  # Generate HTML with year-specific content
  cat > "born-pages/born-in-${year}/index.html" << HEREDOC
<!DOCTYPE html>
<html lang="en">
<head>
  <title>How Old Am I If Born in ${year}? | QuickAgeCalc</title>
  <meta name="description" content="If you were born in ${year}, 
    you are $((age-1)) or ${age} years old in 2026.">
  ...
HEREDOC
done
Enter fullscreen mode Exit fullscreen mode

Each page has:

  • Unique title and meta description
  • Year-specific content (generation, milestone ages, days/weeks alive)
  • FAQ with schema markup targeting "how old if born in X" keywords
  • Navigation to adjacent years (← 1984 / 1986 →) for internal linking

What's Working — 2 Weeks In

Traffic:

  • 1,500+ visits/week from 47 countries
  • US is #1 (best for future AdSense RPM)
  • Cloudflare showing consistent daily growth

Search Console (early data):

  • 171 keywords with impressions
  • Top keyword: "1961 to 2026 age" — position 8.7 already
  • 55 pages indexed out of 61

The unexpected win: The born-in pages are performing better than the main calculators in early indexing. Google seems to reward programmatic pages with specific long-tail intent.


What I'd Do Differently

1. Start with the nav.js pattern from day one

I initially hardcoded navigation in every HTML file. Updating 60+ files manually was painful. The injected nav approach should be the first thing you build.

2. Generate the programmatic pages before launch

I built the core tools first, then added the born-in pages. In retrospect, having 50+ pages ready at launch would have accelerated indexing significantly.

3. Set up Google Search Console on day one

I waited a few days. Even 48 hours of early data matters for understanding what Google is seeing.


The SEO Strategy

Programmatic SEO: 50 born-in pages, each targeting a specific year's worth of long-tail keywords. Low competition, high specificity, easy to generate at scale.

Internal linking: Every born-in page links to the previous and next year, creating a chain. The hub page /born-in-year/ links to all 50. This distributes page authority efficiently.

Schema markup: Every page has WebApplication schema. FAQ pages have FAQPage schema targeting People Also Ask results.

Core Web Vitals:

  • LCP: 400ms median (Google Fonts preconnect optimization)
  • INP: 100% Good
  • CLS: 100% Good

The Stack Summary

Layer Tool Cost
Hosting Cloudflare Workers Free
CDN Cloudflare Free
Deploy GitHub Actions Free
Analytics Cloudflare Analytics Free
Search Google Search Console Free
Domain Namecheap ~10€/year

Total monthly cost: 0€


What's Next

  • Apply to Google AdSense (after 30 days)
  • Add BMI Calculator and Zodiac Sign Calculator
  • Expand programmatic pages: born-in-MONTH-YEAR (120 pages)
  • Target Mediavine/Raptive when hitting 25K sessions/month

Live Site

QuickAgeCalc.com — free age, pregnancy, and dog calculators.

Happy to answer questions about the tech stack, the Cloudflare Workers setup, or the programmatic SEO approach. Drop a comment below.


Top comments (0)