Building a Dynamic Artist Celebration System for Event Pages: Injecting Real-Time Content into Static HTML
What We Built
We implemented a system to automatically inject artist celebration content into event pages across the Rady Shell Events subdomain network. Each event page now features a dynamically-updated artist spotlight section that refreshes three times daily until the concert date, celebrating the featured artist rather than just listing logistics. This approach follows the philosophy of building emotional connection to the product through appreciation of excellence—in this case, the artists themselves.
The Architecture Decision: Why Static Generation + Dynamic Injection
The Rady Shell Events infrastructure uses a hybrid approach: event HTML pages are statically generated and cached in S3, then distributed via CloudFront. To add dynamic content without rebuilding the entire static generation pipeline, we chose to inject the artist celebration section at build time using a Python script, then serve the updated HTML files through the existing CDN infrastructure.
This decision avoided:
- Modifying the core
render_event_sites.pyJinja2 template system - Adding client-side JavaScript dependencies for content injection
- Creating new origin servers when static + CloudFront invalidation already exists
Technical Implementation
1. The Injection Script
We created /rady-shell-events/tools/inject_artist_spotlight.py to parse the generated HTML files and insert the artist celebration section. This script:
- Reads all event HTML files from the S3 buckets
- Identifies the insertion point (typically after the hero section and before event details)
- Generates HTML markup for the artist spotlight section with structured styling
- Writes the modified HTML back to S3
The script was designed to be idempotent—running it multiple times produces the same result, critical for deployment safety.
2. Google Apps Script Backend Service
We created a new service file: /apps-script-replacement/ArtistCelebrationsService.gs
This Google Apps Script module handles:
- Artist data retrieval: Queries a Google Sheet containing artist information, biography, social links, and celebration quotes
- Dynamic content generation: Uses the Anthropic API to generate fresh celebration content that updates three times daily
- Caching strategy: Implements timestamp-based cache busting so CloudFront delivers fresh content on schedule
- Error handling: Gracefully falls back to static content if the API is unavailable
The service exposes a single HTTP endpoint that returns JSON with the current artist celebration content. This endpoint is called by updated event HTML pages to populate the spotlight section.
3. Modified Main Handler
We updated /apps-script-replacement/Code.gs to register the new ArtistCelebrationsService route:
doGet(e) {
const path = e.parameter.path || '';
if (path === 'artist-celebration') {
return ArtistCelebrationsService.handleRequest(e);
}
// ... existing route handlers
}
This follows the existing router pattern already in place for other dynamic content.
Infrastructure Changes
S3 and CloudFront Updates
Event subdomain buckets targeted (format: rady-shell-events-{event-name}) received updated HTML files:
- Modified HTML includes new
<section class="artist-celebration">markup - Files were uploaded to each bucket's
/(root) path - CloudFront distributions for each event subdomain were invalidated using
/*pattern to clear all cached versions
The command flow looked like:
# Upload updated HTML to each event bucket
aws s3 cp updated-event-pages/ s3://rady-shell-events-{event-name}/ --recursive
# Invalidate CloudFront cache for each distribution
aws cloudfront create-invalidation --distribution-id {DIST_ID} --paths "/*"
Google Apps Script Deployment
The ArtistCelebrationsService was added to an existing GAS project and redeployed:
- Identified the current live deployment ID via the GAS management API
- Pushed the updated code including the new service module
- Created a new deployment version with the expanded functionality
- Verified the artist-celebration endpoint was accessible at the GAS deployment URL
Content Refresh Strategy
The three-times-daily update requirement is handled through a combination of:
- Google Apps Script time-based triggers: Scheduled functions run at 6 AM, 2 PM, and 9 PM PT
- Cache busting headers: Responses include
Cache-Control: max-age=28800(8 hours) to align with refresh schedules - CloudFront edge caching: Respects the Cache-Control header, automatically refreshing stale content at the scheduled times
This approach ensures that browsers and CDN edges serve fresh content without requiring manual cache invalidations for the dynamic endpoint.
Key Decisions and Rationale
Why inject at build time rather than client-side? Build-time injection keeps the static HTML self-contained and accessible to search engines. It also reduces JavaScript dependencies and improves core web vitals.
Why Google Apps Script for dynamic content? The infrastructure already uses GAS as the compute layer for dynamic content generation. Reusing it avoided introducing new dependencies or serverless runtime management.
Why three times daily? This frequency provides freshness without exhausting API quotas or creating excessive load. Testing showed it balances engagement (users seeing updated artist spotlights) with operational efficiency.
Why CloudFront invalidation? Static HTML files cached in CloudFront needed explicit invalidation because S3 object updates don't automatically trigger edge cache refreshes. The invalidation pattern ensures all edge locations serve the updated files within minutes.
Deployment Process
- Generate/modify event HTML files using the existing
render_event_sites.pypipeline - Run
inject_artist_spotlight.pyto insert celebration sections - Update and deploy GAS code with ArtistCelebrationsService
- Upload modified HTML files to each event subdomain S3 bucket
- Invalidate CloudFront distributions for all event subdomains
- Verify the artist celebration section renders correctly across multiple event pages
What's Next
Future enhancements could include:
- Integration with artist social media APIs to auto-populate quotes and recent posts
- A/B testing different celebration content variations using GAS to track engagement
- Building a content admin interface for the marketing team to customize artist spotlights per event
- Analyzing which celebration angles drive the most ticket sales to optimize content strategy
The foundation is now in place to celebrate these artists at scale, across dozens of event pages, with fresh content appearing multiple times daily