Files

3.9 KiB

name, description, version, author, license, metadata
name description version author license metadata
static-site-development Use when adding data-driven pages to a static site. 1.0.0 Hermes Agent MIT
hermes
tags related_skills
static-site
vanilla-js
html
nginx
tailwind
audio-player
gitea
proxmox-lxc-deployment

static-site-development — Add Data-Driven Pages to Static Sites

Use when building or extending a self-hosted static website with data-driven content (music libraries, download galleries, resource lists) where the content changes independently of the page markup.

Core Pattern

  1. JSON manifest (library.json or similar) — single source of truth for all content
  2. Vanilla JS rendering — fetch the manifest, build DOM from it, no frameworks
  3. Folder-based assets — organize by category/genre/type in subdirectories
  4. Match existing theme — reuse the site's CSS framework, color tokens, nav, footer, dark/light toggle

When to Use

  • Adding a new content section to an existing static site
  • Content that changes frequently (add/remove items without editing HTML)
  • Filterable lists (by genre, category, tag)
  • Media players (audio, video) with play + download actions
  • Any page where a hand-maintained HTML list would be painful

When NOT to Use

  • Single static page with content that never changes — just write HTML
  • Sites that already use a framework (React, Vue, etc.) — use the framework's patterns
  • Pages requiring server-side rendering or auth — this is static-only

Implementation Checklist

  1. Read the existing site's index.html to extract: CSS framework, color tokens, nav structure, footer, theme toggle JS
  2. Create the page shell: same <head>, same nav, same footer, same theme toggle
  3. Design the manifest schema — minimal fields, only what the UI needs
  4. Build the JS: fetch manifest → build filters → render list → bind interactions
  5. Add the nav link to index.html
  6. Verify: curl the page, check 200, check JS renders

Common Patterns

Genre/Category Filters

  • Filter buttons built dynamically from unique values in the manifest
  • "All" button always present, active by default
  • Click handler: set active genre, re-render visible items
  • Empty state when no items match

Single Shared Media Player

  • One hidden <audio> or <video> element
  • Each row's play button sets src and calls play()
  • Track activeId — if same track clicked, toggle play/pause; if different, switch
  • Sync UI on play, pause, ended events
  • Playing row gets visual highlight (border, ring, background)
  • Plain <a href="..." download> — no JS needed
  • download attribute suggests filename; server sets Content-Disposition for forced download

Theme Matching

  • Copy the site's <head> (Tailwind CDN config, font imports, custom CSS classes)
  • Copy the nav and footer verbatim, update the active nav link
  • Reuse the same dark/light toggle script
  • Use the same glass/gradient/color utility classes

Pitfalls

  • Browser can't list directories — a static site can't readdir server folders. Always use a manifest file; never try to discover files by scanning paths from JS.
  • Caching the manifest — append ?t= + Date.now() to the fetch URL during development. Switch to a versioned URL or short cache in production.
  • Autoplay policy — browsers block play() without user gesture. The play button click satisfies this; setting src then play() in the same click handler works.
  • Multiple audio elements — avoid per-row <audio> tags. One shared element is lighter and prevents accidental multi-play.
  • nginx byte ranges — for seeking in audio/video, nginx must serve Accept-Ranges: bytes. It does by default for static files; don't disable it.

Reference Files

  • references/music-page-pattern.md — full implementation of a music library page with genre folders, library.json, single audio player, and Tailwind theme matching