Skip to content

perf, a11y & SEO: accessible names, meta descriptions, FA subset, asset pipeline#50

Merged
HeyItsGilbert merged 8 commits into
mainfrom
fix/a11y-seo-metadata
Jun 28, 2026
Merged

perf, a11y & SEO: accessible names, meta descriptions, FA subset, asset pipeline#50
HeyItsGilbert merged 8 commits into
mainfrom
fix/a11y-seo-metadata

Conversation

@HeyItsGilbert

Copy link
Copy Markdown
Member

Addresses the most widespread issues from the Unlighthouse audit of the live site, in four focused commits.

Accessibility (button-name, link-name scored 0 on every crawled page)

  • Icon-only controls now have accessible names: header Discord link, mobile-menu toggle, dropdown chevron; footer social links and back-to-top button. Decorative <i> glyphs marked aria-hidden.

SEO (meta-description scored 0 on 65 list/taxonomy/author/pagination pages)

  • baseof.html now falls back from .Description → summary → a title-based description, so every page emits a non-empty meta description. Verified 0 published pages missing one.

Performance — render-blocking & cache

  • Non-critical CSS (Prism, alerts, code-copy, Algolia) loads via the media="print" swap with a <noscript> fallback; only the critical Tailwind bundle blocks first paint.
  • netlify.toml: Cache-Control for fonts (immutable 1y, content-hashed) and images (30d).

Performance — Font Awesome subset

  • New scripts/build-icons.mjs (npm run build:icons) scans the built HTML, resolves classes via FA metadata (incl. FA5-era aliases so legacy names aren't silently dropped), and emits a self-hosted subset: ~300 KB CDN webfonts + CSS → ~11.5 KB (5.8 KB solid + 2.6 KB brands woff2, 3.1 KB inlined CSS, fingerprinted + preloaded). Mirrors the committed-artifact model of build:css.

Performance — image pipeline

  • Logo (32 KB → 3.7 KB) and CC badge (101 KB → 2.7 KB) moved into assets/ and served as Hugo-processed, display-sized WebP — ~130 KB saved on every page.
  • Podcast/author cards request YouTube hqdefault instead of maxresdefault (~100 KB → ~15 KB each); the full-width video facade keeps maxresdefault for hero quality.

Validation

  • a11y and SEO gains confirmed via a scoped local re-scan (e.g. tags page a11y 83→100, SEO 85→92).
  • All 72 fa-* tokens in the built HTML resolve to real icons (0 silent drops); subsetted woff2s are valid.
  • Cache headers, real CDN compression, and icon rendering to be confirmed on the Netlify deploy preview.

🤖 Generated with Claude Code

HeyItsGilbert and others added 4 commits June 28, 2026 08:40
Resolves the most widespread Unlighthouse findings across the site:

- link-name / button-name (scored 0 on all crawled pages): icon-only
  social links, mobile-menu toggle, dropdown chevron, and back-to-top
  button now have aria-labels; decorative icons marked aria-hidden.
- meta-description (scored 0 on 65 list/taxonomy/author/pagination
  pages): these had neither .Description nor .Summary, leaving the tag
  empty. Add a summary-then-title fallback so every page emits a
  non-empty description.
- unsized-images / image-aspect-ratio: footer CC BY-SA and Netlify
  badges get explicit width/height matching intrinsic ratio.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Targets the render-blocking and cache-lifetime Unlighthouse findings:

- baseof.html: Font Awesome, Prism, alerts, code-copy, and Algolia
  stylesheets now load via the print-media swap (media=print +
  onload) instead of blocking first paint. Only the critical
  fingerprinted Tailwind bundle remains render-blocking. A <noscript>
  block preserves the blocking links when JS is disabled.
- netlify.toml: add Cache-Control for fonts (immutable 1y, they are
  content-hashed) and images (30d, not fingerprinted).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replaces the render-blocking ~270 KB Font Awesome CDN webfonts + 30 KB
CSS with a self-hosted subset containing only the ~72 glyphs the site
actually uses (5.8 KB solid + 2.6 KB brands woff2, 3.1 KB CSS, inlined).

- scripts/build-icons.mjs (npm run build:icons): builds the site, scans
  the output HTML for fa-* classes, resolves them via Font Awesome's
  metadata (including FA5-era alias names like fa-ticket-alt so legacy
  classes are not silently dropped), subsets the woff2s, and emits a
  minimal CSS. Mirrors the build:css committed-artifact model — CI ships
  the committed files as-is.
- baseof.html: drop the FA CDN <link>; inline the subset CSS with
  fingerprinted, preloaded, font-display:swap @font-face declarations.
  Regular face is wired conditionally for future-proofing.

Verified: all 72 fa-* tokens in the built HTML resolve to real icons
(0 silent drops); no CDN font-awesome references remain in output.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cuts the largest image-delivery offenders flagged by Unlighthouse.

- Move logo.png and cc-by-sa.png into assets/images and serve Hugo-
  processed, fingerprinted WebP at display size: logo 32 KB -> 3.7 KB
  (80x80), CC badge 101 KB -> 2.7 KB (160px). Both render in the header/
  footer on every page, so this saves ~130 KB per page. Explicit
  width/height retained; the CC badge is lazy-loaded.
- schema-site/-article: reference the logo via its resource Permalink
  (absolute URL) now that it lives in assets, keeping the JSON-LD logo
  resolvable.
- Podcast/author episode cards: request YouTube hqdefault (480x360)
  instead of maxresdefault (1280x720), ~100 KB -> ~15 KB each, with
  mqdefault as the onerror fallback. The full-width video facade on
  single pages keeps maxresdefault for hero quality.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@netlify

netlify Bot commented Jun 28, 2026

Copy link
Copy Markdown

Deploy Preview for powershellorg ready!

Name Link
🔨 Latest commit c77e8ee
🔍 Latest deploy log https://app.netlify.com/projects/powershellorg/deploys/6a414ff854ace40008c0873d
😎 Deploy Preview https://deploy-preview-50--powershellorg.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

HeyItsGilbert and others added 4 commits June 28, 2026 09:34
…eight

The badges carried explicit width/height attrs alongside `w-auto`, but
`w-auto` was purged out of the committed Tailwind bundle (it appeared in
no other markup), so it was inert and the width attribute squished both
badges to full intrinsic width at 24px tall. Remove the static dimensions
and let `h-6` set the height with natural width.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The footer badges use w-auto; regenerate the purged bundle so the class
is present rather than relying on the img default. Confirms no other
introduced classes were missing from the committed bundle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Deploys ship the committed, purged CSS and subsetted webfonts as-is
(bare hugo, not the build:* scripts), so a markup/content change that
adds a Tailwind class or fa-* icon silently renders wrong until someone
regenerates them — exactly how w-auto slipped through.

Add a freshness check to the PR build: regenerate via build:css and
build:icons, then fail if assets/css/tailwind.css or
assets/css/fontawesome-subset.css differ from what is committed, with a
message telling the dev to regenerate and commit. Diffs the generated
CSS (deterministic, the source of truth for included classes/icons)
rather than the woff2 bytes, which vary across subset-font versions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- .gitattributes: force LF on the committed generated CSS so the PR
  guard (regenerated on a Linux runner) can't false-fail on line
  endings; mark woff2/ttf binary.
- ADR 0005: record the build.yml freshness guard as the mitigation for
  the PurgeCSS silent-removal failure mode, and update the asset section
  to reflect FontAwesome now shipping as a self-hosted purged subset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@HeyItsGilbert HeyItsGilbert force-pushed the fix/a11y-seo-metadata branch from cf42dd6 to c77e8ee Compare June 28, 2026 16:46
@HeyItsGilbert HeyItsGilbert merged commit 244c1bf into main Jun 28, 2026
5 checks passed
@HeyItsGilbert HeyItsGilbert deleted the fix/a11y-seo-metadata branch June 28, 2026 16:51
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