Skip to content

fix: generate favicon set (was 5 dead refs → 404 on every site) - #3

Merged
ProfessorManhattan merged 3 commits into
mainfrom
feat/generate-favicons
Jun 24, 2026
Merged

fix: generate favicon set (was 5 dead refs → 404 on every site)#3
ProfessorManhattan merged 3 commits into
mainfrom
feat/generate-favicons

Conversation

@ProfessorManhattan

Copy link
Copy Markdown
Contributor

Bug (caught by validate-assets in #1)

index.html referenced 5 favicons (favicon.ico, favicon-16/32.png, apple-touch-icon.png, safari-pinned-tab.svg) that don't exist in public/ → every cloned site shipped 404'd favicons (checklist #23 violation).

Fix (zero deps, verified)

scripts/generate-favicons.mjs generates the full set, brand-colored from _brand.json (brandHue → HSL→RGB), using only node:zlib — real RGBA PNGs (rounded square) + a PNG-in-ICO + SVG (brand bg + business initial) + safari mask. Wired into prebuild (regenerates per brand; vite copies public/dist/). Added an SVG-favicon <link> for modern browsers.

Verified on a clean build: all 6 favicons land in dist/, 0 dead refs, valid PNG/ICO magic bytes. validate-assets (#1) now passes the favicon gate. Brand-default placeholders committed so the repo is clean even pre-rebuild.

🤖 Generated with Claude Code

Brian Zalewski and others added 3 commits June 20, 2026 23:52
index.html referenced favicon.ico, favicon-16/32.png, apple-touch-icon.png, safari-pinned-
tab.svg — none existed in public/ (caught by validate-assets, PR #1). Every cloned site
shipped 404'd favicons (violates checklist #23).

scripts/generate-favicons.mjs generates the full set brand-colored from _brand.json (brandHue
→ HSL→RGB) with ZERO external deps — pure node:zlib for valid RGBA PNGs (rounded square),
a BMP/PNG-in-ICO writer, and SVG (rich, brand bg + business initial) + safari mask. Wired
into prebuild so it regenerates per brand and vite copies public/ → dist/. Also added an
SVG-favicon <link> (modern browsers). Committed brand-default placeholders so the repo is
clean even before a per-brand rebuild.

Verified on a clean build: all 6 favicons land in dist/, 0 dead refs, valid PNG/ICO magic
bytes. validate-assets (PR #1) now passes the favicon gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ProfessorManhattan
ProfessorManhattan merged commit 1d938f0 into main Jun 24, 2026
ProfessorManhattan pushed a commit that referenced this pull request Jun 25, 2026
* origin/main:
  fix: generate the favicon set (was 5 dead refs → 404 on every site) (#3)
  feat: build-gate validators (enforce the completeness checklist + caught a favicon bug) (#1)

# Conflicts:
#	package.json
ProfessorManhattan added a commit that referenced this pull request Aug 23, 2026
…n't blank the page

Add <SafeSection>, a section-scoped error boundary, and wrap every top-level
section of Home in it. Root-cause fix for the iteration-1 failure that scored a
generated site 3.2/10: a render-crashing TypeError ("Cannot read properties of
undefined (reading 'primary')") blanked the ENTIRE page below the hero.

Why the existing top-level ErrorBoundary wasn't enough: it wraps the whole app,
so a throw in ANY section unwinds the entire tree and swaps in the error card —
header, footer, hero, NAP, every sibling section, and every SEO landmark vanish
with it. SafeSection contains the blast radius to one section: the crash is
caught locally, that section fails soft (renders null in prod, a compact notice
in dev), and every sibling section + the header/footer landmarks + the
pre-rendered SEO head keep painting. This turns a whole-page blank into a single
missing section — the difference between a 3/10 and a shippable page.

Directly addresses all three iter-1 weaknesses:
- #1 render-crash blanking everything below the hero — isolated per section.
- #2 SEO head + header/main/footer landmarks depended on the same crashing
  render — they now survive any section throw.
- #3 services / NAP / booking / CTA never rendered — a crash in one no longer
  takes down the others.

- src/components/SafeSection.tsx — the fail-soft primitive (telemetry to
  gtag/posthog, dev-only inline notice, optional custom fallback).
- src/pages/Home.tsx — each section wrapped; flag-gating preserved.
- src/pages/AGENTS.md — hard rule so future generations keep the wrappers.
- tests/unit/SafeSection.test.tsx — 4 tests (createRoot + act, no new deps):
  healthy passthrough, sibling-survives isolation, custom fallback, telemetry.

Gate: npm install --legacy-peer-deps && npm run build → exit 0, dist/ produced;
vitest 96 passed (92 baseline + 4 new). Additive, zero new deps.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant