Building a Dynamic Artist Celebration System for Concert Event Pages
We recently implemented a system to inject dynamic, daily-updating artist celebration content into Rady Shell event pages on queenofsandiego.com. This technical post covers the architecture, infrastructure changes, and implementation details of this feature.
The Philosophy Behind the Feature
The inspiration came from Nike's marketing approach: rather than focusing on product commodities, they celebrate the athletes themselves. Similarly, we wanted to shift focus from simply listing concert details to celebrating the artists performing at each event. The content needed to update automatically three times daily until the concert date, keeping the spotlight fresh and engaging.
Architecture Overview
The system comprises three main components:
- Google Apps Script (GAS) Backend: Generates dynamic artist content via API integration
- Static Site Renderer: Injects the spotlight section into event HTML templates
- Content Distribution: S3 + CloudFront deployment pipeline with cache invalidation
Technical Implementation Details
Google Apps Script Service Creation
We created a new file ArtistCelebrationsService.gs in the apps-script-replacement directory. This service:
- Accepts event identifiers and artist names as parameters
- Calls the Anthropic API to generate compelling artist celebration content
- Returns formatted HTML sections ready for injection into event pages
- Caches responses appropriately to minimize API calls while respecting the three-times-daily update requirement
The GAS deployment was configured as an executable endpoint, allowing HTTP requests from the static site renderer and CloudFront. We updated Code.gs to include a new routing handler that directs requests to /artist-celebration to the ArtistCelebrationsService.
Command to deploy and verify:
clasp push # Deploy the updated GAS project
clasp deployments list # Retrieve the live exec URL ID
Static Site Rendering Pipeline
Modified tools/render_event_sites.py to:
- Parse the events.json configuration file for artist details
- Call the GAS ArtistCelebrationsService endpoint for each event
- Inject the returned HTML into a new
<section class="artist-spotlight">element within event page templates - Position the spotlight section prominently—typically after the header and before technical event details
We also created a new utility script tools/inject_artist_spotlight.py to retroactively inject the spotlight section into all existing event HTML files. This script:
- Reads compiled event HTML from S3 buckets
- Identifies insertion points in the DOM based on CSS selectors
- Injects the artist celebration section without disrupting existing page structure
- Handles edge cases where pages may have been customized
Infrastructure and Deployment
S3 Bucket Structure
Event content is distributed across multiple S3 buckets following the pattern:
qos-event-subdomain-[eventname]-us-west-2
Each bucket contains the static HTML files for that specific event. We identified all event subdomains by querying the Route53 hosted zone and cross-referencing with CloudFront distributions.
CloudFront Cache Strategy
Because artist celebration content updates three times daily, we needed aggressive cache invalidation. After uploading updated event HTML to each S3 bucket, we triggered CloudFront invalidations:
aws cloudfront create-invalidation \
--distribution-id [DISTRIBUTION_ID] \
--paths "/*"
This ensures users see the latest artist celebration content within minutes of updates, rather than waiting for the default TTL to expire. We applied this invalidation across all event distribution IDs identified in CloudFront.
Deployment Sequence
- Push updated GAS code with ArtistCelebrationsService to Google Apps Script
- Create or update GAS deployment to expose the artist celebration endpoint
- Run render_event_sites.py to generate fresh event HTML with artist spotlights
- Run inject_artist_spotlight.py for retroactive injection into existing compiled pages
- Upload updated HTML files to each event S3 bucket
- Invalidate CloudFront cache for all event distributions
- Verify injection in sample pages by examining DOM structure and content
Key Decisions and Trade-offs
Why Google Apps Script?
GAS provides:
- Native integration with Google Sheets (our event data source)
- Built-in Anthropic API client support
- Time-based trigger capabilities for the three-times-daily update schedule
- No infrastructure to manage—scaling handled by Google
Why Inject Rather Than Server-Render?
We chose HTML injection over server-side rendering because:
- Event pages are static, globally distributed via CloudFront
- Injection happens at build time, avoiding runtime dependencies
- Content updates don't require rebuilding entire pages—only the spotlight section
- Maintains separation between event metadata and dynamic content
Cache Invalidation Trade-offs
While CloudFront invalidation costs per invalidation, the business requirement for fresh content three times daily justifies this cost. We prioritized user experience over CDN expenses, ensuring the celebration content feels current and engaging.
Monitoring and Verification
Post-deployment, we verified the implementation by:
- Sampling event pages across different subdomains
- Confirming the artist-spotlight section renders in the correct DOM position
- Verifying content updates by checking timestamps and comparing cached vs. fresh requests
- Monitoring GAS deployment logs for API errors or quota issues
What's Next
Future enhancements could include:
- Personalization based on user location or browsing history
- A/B testing different celebration styles to optimize engagement
- Integration with social media feeds to showcase artist performances
- Scheduled content variations based on time-to-event countdown
The artist celebration system is now live across all Rady Shell event pages, updating dynamically and celebrating the artists who make these performances possible.
```