```html

Dynamic Artist Celebration Sections: Injecting Daily Content into Static Event Pages via Google Apps Script

What Was Done

We implemented a system to dynamically inject artist celebration content into Queen of San Diego's Rady Shell event pages. The solution combines static HTML site generation with a Google Apps Script backend that refreshes artist spotlight sections three times daily until each concert date. This hybrid approach honors the site's static architecture while enabling dynamic, personalized content without requiring a full CMS migration.

The Problem & Design Philosophy

The challenge: event pages are statically generated and deployed to S3/CloudFront, but we needed daily-updating artist celebration sections that evolve as concert dates approach. A full database-driven site would be overkill; instead, we chose to inject content client-side or via a lightweight API endpoint.

The inspiration came from a principle Steve Jobs articulated about Nike's marketing—rather than showcasing products, Nike celebrates the athletes. Similarly, we wanted to shift focus from venue details to celebrating the artists themselves, building emotional connection through curated spotlights that refresh frequently.

Technical Architecture

Frontend: Injected HTML Structure

We created a new artist celebration section in the event page templates. The section is rendered by the Python site generator at build time with a placeholder structure:

<section id="artist-spotlight" class="artist-celebration">
  <h2>Celebrating the Artist</h2>
  <div id="spotlight-content">
    <!-- Injected dynamically via GAS -->
  </div>
</section>

The key file managing this is /Users/cb/Documents/repos/sites/queenofsandiego.com/rady-shell-events/tools/render_event_sites.py. This Python renderer processes the Jinja2 templates and injects the artist section structure into every event HTML file before they're uploaded to S3.

Backend: Google Apps Script Service

We created ArtistCelebrationsService.gs, a new Google Apps Script module that:

  • Exposes a public HTTP endpoint via Apps Script deployment
  • Queries a Google Sheet containing artist metadata and celebration content
  • Calls the Anthropic API to generate dynamic, contextual spotlight text based on the artist, venue, and days-until-concert
  • Returns formatted HTML ready to inject into the page
  • Implements caching to avoid excessive API calls within the 8-hour update window

The service is deployed as a new Apps Script web app with a unique deployment ID. We updated Code.gs to route requests to this service via a dedicated endpoint pattern.

Orchestration: Multiple Deployment Pipeline

The deployment process involved several steps:

# 1. Push GAS project with ArtistCelebrationsService
clasp push

# 2. Create new GAS deployment for the artist celebration endpoint
gapps deploy --description "Artist Celebration Service"

# 3. Verify live deployment URL from GAS console
# Deployments are tagged with unique exec IDs for production

# 4. Inject artist spotlight into all event HTML files
python tools/inject_artist_spotlight.py

# 5. Upload updated HTML to all S3 event buckets
aws s3 sync ./build/events s3://qos-event-santa-cruz/ --region us-west-2
aws s3 sync ./build/events s3://qos-event-hollywood-bowl/ --region us-west-2
# ... (repeat for all event subdomains)

# 6. Invalidate CloudFront caches
aws cloudfront create-invalidation --distribution-id E2ABC123XYZ --paths "/*"
# ... (repeat for all event distribution IDs)

Infrastructure Details

S3 Buckets & CloudFront Distributions

Each event maintains its own S3 bucket and CloudFront distribution following this pattern:

  • S3 Bucket: qos-event-{venue-slug} (e.g., qos-event-santa-cruz, qos-event-hollywood-bowl)
  • CloudFront Distribution: Configured with Origin pointing to each bucket's static website endpoint
  • Route53 Record: Event subdomain (e.g., {event-slug}.queenofsandiego.com) aliases to the CloudFront distribution

We discovered during deployment that not all event subdomains were previously cataloged. We enumerated them by listing all CloudFront distributions with filtering for those serving queenofsandiego.com event subdomains, then invalidated each one to clear cached content.

Google Apps Script Deployment

Apps Script deployments create immutable versions with unique execution IDs. The live production deployment serves requests at:

https://script.google.com/macros/d/{DEPLOYMENT_ID}/usercontent

We created a new deployment specifically for the artist celebration endpoint to isolate this feature from other GAS functionality and enable independent version management.

Key Technical Decisions

Why Client-Side Injection Over Server-Side Rendering

We chose an architecture where the HTML structure is static but content is fetched and injected client-side. This preserves the benefits of static site generation (CDN caching, fast delivery, low attack surface) while enabling daily updates without rebuilding and redeploying every event page three times daily.

Why Google Apps Script Over a Dedicated API

The project already uses GAS for other automation. Leveraging the existing deployment infrastructure avoided introducing a new service to maintain. GAS web apps scale automatically, require no container orchestration, and integrate seamlessly with Google Sheets for data management.

Why Anthropic API for Content Generation

Rather than hardcoding celebration text, we use Claude to generate contextual, personalized spotlights. The model receives the artist name, venue, and days-until-concert, allowing it to craft content that feels fresh and timely. This scales to dozens of artists without manual content curation.

Caching Strategy

Each spotlight result is cached in Apps Script's Properties service with an 8-hour TTL. This ensures we don't hammer the Anthropic API while still refreshing content three times daily (midnight, 8 AM, 4 PM). On the CloudFront side, we set the Cache-Control header to a short duration (1 hour) to balance freshness with CDN efficiency.

Deployment Verification

After uploading HTML files and invalidating CloudFront caches, we verified the artist spotlight sections rendered correctly by sampling several event pages. The verification process included:

  • Checking that the placeholder section loaded without JavaScript errors
  • Confirming the GAS endpoint returned properly formatted HTML
  • Validating that content updated on subsequent requests (cache behavior)
  • Testing across multiple event subdomains to ensure the injection was comprehensive

What's Next

The system is now live and updating artist spotlights three times daily across all Queen of San Diego event pages. Potential enhancements include:

  • Adding user engagement tracking (which spotlights drive the most page views/ticket sales)
  • Integrating social media feeds or news about each artist
  • Implementing A/B testing on spotlight messaging
  • Extending the