Skip to content

Public website

The pool UI is a plain HTML, CSS, and JavaScript site in public/, deployed to Azure Static Web Apps. It does not have a Node server, login flow, or linked Function API. GitLab Pages hosts the documentation only.

What visitors see

FeatureBehavior
Current-week cardMatchup, selected player’s squares, winnings, and available winners
Player selectorUses the saved browser choice, then the snapshot’s default player
List viewSchedule and the selected player’s numbers, with available result rows
Board viewScrollable 10×10 board with sticky score digits and highlighted squares
Game selectorChooses the board week, including BYE handling
WinnersHalftime/final labels and a brief celebration for selected winners
About dialogBackground and contact links

Player selection is stored under the browser key ravens-pool-player. If browser storage is blocked, selection still works for the current visit. This preference is local to that browser and does not change the summary recipient or Azure settings.

The board uses Ravens digits across the top and opponent digits down the side, matching the printed sheet. Gold outlines mark the selected player’s squares; green labels identify winners. The scroll region remains keyboard-focusable. Reduced-motion preferences disable the confetti celebration and CSS transitions.

Search, sharing, and bookmarks

The preferred public URL is https://football-pool.bobclingan.work/. public/index.html includes a search description, canonical URL, Open Graph metadata, Twitter summary card metadata, theme color, and bookmark/touch icons. The existing 400×400 cardinal PNG supplies the preview image and icons. These tags are in the initial HTML so crawlers do not need to run JavaScript.

If the public domain changes, update the canonical link, og:url, og:image, and twitter:image together. Preview image URLs must remain absolute and publicly accessible. Descriptions describe the pool generally; live scores and player selections are not embedded in metadata. Social services may cache old previews after a deployment.

References: Open Graph protocol and Google’s supported metadata.

Results URL and CORS

The current RESULTS_PATH in public/app.js is:

const RESULTS_PATH =
"https://poolweb9173.blob.core.windows.net/$web/results.json";

For another storage account, change that constant and redeploy the website. The Function’s RESULTS_STORAGE_CONNECTION_STRING must publish to the same account.

sequenceDiagram
    participant Browser as Visitor browser
    participant SWA as Azure Static Web Apps
    participant Blob as Blob service endpoint
    Browser->>SWA: Request HTML, CSS, and JavaScript
    SWA-->>Browser: Static UI
    Browser->>Blob: GET results.json with cache bypass
    Blob-->>Browser: JSON and allowed-origin response
    Browser->>Browser: Render player, list, board, and winners

Configure the Blob service CORS rule to allow the exact origins used by the website, including the Azure hostname, any custom domain, and local development origins when needed. Use GET and HEAD, with headers appropriate to the request. An origin includes scheme and port but has no path.

Examples:

https://<app>.azurestaticapps.net
https://<custom-domain>
http://localhost:8080

CORS is a browser permission check; it does not grant anonymous access to a private blob. The current public feed also needs anonymous blob-read access. Do not put a storage connection string or expiring private credential in frontend code. The *.web.core.windows.net static website endpoint does not support Storage CORS. See Azure’s Storage website documentation.

Refresh and current-week rules

fetchJson() runs during page load and adds a timestamp query parameter with cache: "no-store". The publisher also sets Cache-Control: no-store, must-revalidate.

The page does not poll for new JSON. Its one-minute interval only recalculates the featured week using data already loaded. Reload the page to fetch newly published scores or roster changes.

The effective week advances at midnight Tuesday in America/New_York, keeping each game featured through the following Monday. This also handles the configured BYE entry. Browser date formatting preserves game calendar dates rather than shifting them according to the viewer’s timezone.

Browser error reporting

The public site reports JavaScript errors to Sentry: uncaught exceptions, unhandled promise rejections, and failures while loading or rendering results. Caught results-loading errors carry the tag operation: load-results; visitors still see the existing reload message.

index.html loads the configuration, Sentry browser SDK, and initialization script before app.js. The SDK is pinned to version 10.42.0 with an integrity hash. If the SDK is blocked or unavailable, the application can still load results.

The project’s public DSN is already configured. GitLab deployment labels events as production and uses the commit SHA as the release. Local previews use development and send errors to the same project by default. See configuration for overrides and operations for a delivery check.

Session replay and performance tracing are not enabled. Default PII collection and breadcrumbs are disabled, and the application does not attach player identities or pool data to events. This integration covers the public site; Function failures remain in Azure monitoring.

Assets and cache versions

FileRole
index.htmlSemantic page structure and dependency references
app.jsFetching and rendering logic
sentry-config.jsPublic DSN and environment; regenerated during deployment
sentry.jsInitializes browser error reporting when a DSN and SDK are available
styles.cssLayout, board, responsive rules, and reduced motion
football-ball-rugby-field.webp2400×1642 background, about 301 KiB
cardinal.pngHeader emblem

The background was reduced from approximately 8.2 MiB to 301 KiB. Preserve the full composition when recompressing it; avoid replacing it with a multi-megabyte source photo. The stylesheet and script references in index.html use version query strings; update the appropriate value when shipping asset changes.

The page loads [email protected] from jsDelivr and uses ESPN-hosted team logos. The Sentry SDK loads from browser.sentry-cdn.com. These external assets are separate from the Python SBOMs. A missing confetti script should leave the results usable; application logic treats it as optional.

Local preview

Terminal window
python3 -m http.server 8080 --directory public

Open http://localhost:8080. With the current absolute Blob URL, the Blob CORS rule must permit that origin. For an isolated preview, temporarily use a relative results.json and a synthetic local feed; do not commit private state or credentials as sample data. Restore the intended production URL before committing.

Run the same lint check as CI:

Terminal window
npm ci --prefix ci/biome
ci/biome/node_modules/.bin/biome lint public --max-diagnostics=none