Skip to main content

CMS Environment & Caching Guide

Overviewโ€‹

Our CMS architecture uses Builder.io with three separate "spaces" that map to different environments:

SpacePurposeShopify StoreWebhooks
ProductionLive customer-facing contentbirdygrace.myshopify.comEnabled (sends)
StagingContent testing with production-like cachingbirdy-grey-test-store.myshopify.comReceives from Production
HomepageBilling separation for homepage pagesbirdygrace.myshopify.comReceives from Production

Content Sync Flowโ€‹

When content is published, unpublished, archived, or deleted in the Production Builder space, a webhook automatically syncs that content to Staging and Homepage spaces.

What Syncs to Homepage Spaceโ€‹

Only specific pages sync to the Homepage space:

  • / (homepage)
  • /suits
  • /hp-promo-banner-test

Shopify Product Translationโ€‹

When content syncs from Production to Staging, Shopify product references are automatically translated:

  • Production GIDs โ†’ Staging GIDs (matched by product handle)
  • If a product doesn't exist in the staging Shopify store, that product reference is removed from the synced content

Caching by Environmentโ€‹

EnvironmentCachingContent Visibility After Publish
ProductionEnabledVaries by content type (see below)
QADisabledImmediate
StagingEnabledVaries by content type (see below)
Builder PreviewDisabledImmediate

Cache TTL by Content Typeโ€‹

Content TypeCache LevelFresh (maxAge)Stale Revalidate
Recommendation traysfaster1 second9 seconds
Homepage, announcements, headerfast/medium1 minute4-14 minutes
PDP content, PLP navigationmedium1 minute14 minutes
Footer, PDP breadcrumbs, settingsslow5 minutes55 minutes
PLPs, empty cartslower15 minutes4 hours

Liquid Proxy Pagesโ€‹

Full proxy pages (pages served entirely via the Liquid proxy) have different caching. Note that hybrid proxy pages still use Builder content for header and footer.

SettingValue
Fresh (max-age)1 hour
Stale Revalidate24 hours

This is an HTTP Cache-Control header that affects browser caching. This means:

  • Users may see stale content for up to 1 hour even after updates
  • Browser cache persists across sessions until max-age expires
  • Hard refresh (Cmd+Shift+R) bypasses browser cache
  • Header and announcements on proxy pages will reflect the cached version from when the page was first loaded, not real-time Builder content

When Will Content Updates Appear?โ€‹

Scenario: Update content in Production Builderโ€‹

EnvironmentTimeline
ProductionVaries by content type (see Cache TTL by Content Type)
QAImmediate (reads Production space directly, no cache)
StagingVaries by content type (webhook syncs content, then cache expires)

Scenario: Testing content changes before going liveโ€‹

Step 1: Test in Stagingโ€‹

  1. Edit content in Staging Builder space
  2. Use Builder Preview mode to verify changes immediately
  3. Confirm content looks correct before proceeding

Step 2: Publish to Productionโ€‹

  1. Recreate the same changes in Production Builder space
  2. Preview on QA site - changes appear immediately (no caching)
  3. Verify content on QA before cache expires on Production
  4. Production site - changes appear after cache expires (timing varies by content type)
  5. Webhook automatically syncs content to Staging/Homepage spaces

Key Points for Web Opsโ€‹

  1. Use QA for testing content changes - no caching means immediate visibility
  2. Production and Staging have identical caching - timing depends on content type
  3. Sync is one-way: Production โ†’ Staging - edits in Staging Builder don't sync back
  4. Builder Preview mode bypasses all caching - useful for real-time editing in Builder's visual editor

Static Fallback Contentโ€‹

Every deployment generates static JSON fallbacks for critical content (header, footer, announcements, settings). These are used if the Builder API is unavailable.

Fallbacks are regenerated on each deployment to QA, Staging, and Production.

Environment Comparisonโ€‹

AspectProductionStagingQA
Builder SpaceProductionStagingProduction
Shopify Storebirdygracebirdy-grey-test-storebirdygrace
CachingEnabledEnabledDisabled
Content VisibilityVaries by content typeVaries by content typeImmediate
Receives Webhook SyncN/A (source)YesN/A (same space)
Auto-deploy TriggerManual releasePush to mainVersion tag