A targeted data service for static Center Centre sites that need live Airtable content without paying the latency cost on every page load.
The service has two jobs:
- Act as a runtime cache in front of Airtable.
- Publish per-site preload files so browser clients can start with data already on hand.
That combination lets static sites keep their current hosting and deployment model while moving dynamic content closer to first render.
Center Centre course sites are mostly static, but key conversion paths depend on frequently changing Airtable data such as cohort schedules and enrollment links. Direct client-side Airtable requests kept the operational model simple, but introduced a visible delay before critical page content appeared.
This service is a localized intervention. It avoids a full SSR migration, keeps the client request format backward compatible, and improves latency in two stages:
- Runtime caching reduces repeated Airtable calls.
- Prehydrated preload files let clients skip many network calls entirely.
GET /v0/<airtable-path>?<original-query>&ref=<site-key>&refresh=true|false
Behavior:
- The route normalizes the Airtable request and resolves the site key from
reforReferer. - Cache identity ignores Airtable pagination offsets.
- Airtable pages are merged into one cached dataset before persistence.
- The response includes
X-Airtable-Cachewithhit,stale,miss, orrefresh.
Each site snapshot is stored as:
data/cache/<site-token>.jsonas the canonical on-disk recordpublic/cache-<site-token>.jsas the browser-facing preload artifact
The preload file is derived from the JSON snapshot rather than maintained separately. When a client imports it, the browser gets the same request-response inventory that the runtime cache is already maintaining for that site.
The service is designed as an enhancement, not a hard dependency.
- Clients prefer the preloaded browser cache.
- If the preload misses, clients can call this service.
- If this service is unavailable, clients can still fall back to Airtable directly.
That keeps the integration low-risk for existing sites.
app/v0/[[...path]]/route.tsandapp/zapier/route.tsare thin route adapters.lib/airtable-cache/contains request normalization, caching, persistence, and Airtable-specific behavior.lib/zapier/service.tscontains the protected Zapier forwarding flow.scripts/prepare-preloads.mjsandscripts/run-next-with-preloads.mjsrebuild preload artifacts before local startup.tests/covers route behavior, cache behavior, persistence, and regressions.
The live endpoints use the App Router. The tiny pages/ files exist only because Next.js still expects _document and 404 during production builds.
Required:
AIRTABLE_API_KEY
Optional:
CACHE_STALE_AFTER_MSCACHE_EVICT_AFTER_MSAIRTABLE_FETCH_TIMEOUT_MSCACHE_DATA_DIRCACHE_PUBLIC_DIRAIRTABLE_API_BASE_URLZAPIER_SHARED_SECRETZAPIER_ALLOWED_HOSTS
Default policy:
- Stale after 15 minutes
- Evict after 72 hours
Eviction is based on lastAccessedAt, not only updatedAt.
npm install
npm run devValidation:
npm run checkOther useful commands:
npm run lint
npm run typecheck
npm run test
npm run build- Generated files under
data/cache/andpublic/cache-*.jsshould not be committed. - Deleting a corrupted snapshot forces the next request to rebuild it from Airtable.
- Legacy preload artifacts are migrated into the JSON snapshot format on first access.
- The cache is process-local and assumes one Node process per VM.