Skip to content

fix(web): self-host fonts to resolve CSP connect-src violation#389

Merged
Doberjohn merged 1 commit into
masterfrom
fix/self-host-fonts
Jun 25, 2026
Merged

fix(web): self-host fonts to resolve CSP connect-src violation#389
Doberjohn merged 1 commit into
masterfrom
fix/self-host-fonts

Conversation

@Doberjohn

Copy link
Copy Markdown
Owner

Problem

In production the service worker logged a CSP violation on every load:

Connecting to https://fonts.googleapis.com/css2?... violates the following Content Security Policy directive: connect-src ...

Root cause: a CSP directive mismatch. The Google Fonts <link rel="stylesheet"> loads fine because a stylesheet load is governed by style-src (which listed fonts.googleapis.com). But the workbox service worker re-fetches that same URL via fetch() to cache it, and fetch() is governed by connect-src (which did not). Same URL, two different directives. The page rendered correctly, but the SW fetch was blocked: console noise plus no offline font caching.

Fix

Self-host the fonts instead of widening the CSP, removing the last external runtime fetch entirely (card images are already self-hosted).

  • Add 6 woff2 (Tinos 400/700, Plus Jakarta Sans 400/500/600/700; latin + latin-ext subsets) under apps/web/public/fonts/, declared via @font-face in index.css (font-display: swap).
  • Replace the Google <link>/preconnect with same-origin preloads of the two above-the-fold weights.
  • Drop the two google-fonts-* workbox runtime-caching rules; the existing woff2 globPattern already precaches the self-hosted files (verified: all 6 in the build's precache manifest).
  • Remove all Google Fonts hosts from the CSP: fonts are now same-origin under 'self'.
  • Update the SEO e2e test to assert the self-hosted preloads.

Verification

  • All 6 fonts serve 200 font/woff2; every weight fetches and decodes (document.fonts.load). Page renders in Plus Jakarta Sans, zero font/CSP console errors.
  • Production build green; 6 woff2 in dist/fonts/ and in the workbox precache manifest; no Google Fonts references remain in sw.js/workbox-*.js.
  • Pre-push gate passed: lint, 228 engine + 636 web unit tests, 3-browser E2E (incl. updated SEO test), CodeScene strict.

Note: design-system mirror

This changes apps/web/index.html font imports (Google <link> → self-hosted @font-face), a design-system-tracked file. The design-system project should be refreshed for the font-loading change.

The service worker fetched Google Fonts (StaleWhileRevalidate on the CSS,
CacheFirst on the woff2), and fetch() is governed by connect-src, which did
not list fonts.googleapis.com/fonts.gstatic.com. The page rendered fine (the
<link> stylesheet is governed by style-src, which did allow them), but the SW
fetch was blocked in production, spamming the console and breaking offline
font caching.

Self-host the fonts instead of widening the CSP:
- Add 6 woff2 (Tinos 400/700, Plus Jakarta Sans 400/500/600/700; latin +
  latin-ext) under public/fonts, declared via @font-face in index.css.
- Replace the Google <link>/preconnect with same-origin preloads of the two
  above-the-fold weights.
- Drop the two google-fonts workbox runtime-caching rules; the woff2
  globPattern already precaches the self-hosted files.
- Remove all Google Fonts hosts from the CSP (now same-origin under 'self').
- Update the SEO e2e test to assert the self-hosted preloads.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
inkweave Ready Ready Preview, Comment Jun 25, 2026 5:29pm

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Doberjohn, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 33 minutes and 47 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: dead6f2d-e718-4773-a4b1-25940a87130b

📥 Commits

Reviewing files that changed from the base of the PR and between d21d623 and 0b7860d.

⛔ Files ignored due to path filters (6)
  • apps/web/public/fonts/plus-jakarta-sans-400.woff2 is excluded by !**/*.woff2
  • apps/web/public/fonts/plus-jakarta-sans-500.woff2 is excluded by !**/*.woff2
  • apps/web/public/fonts/plus-jakarta-sans-600.woff2 is excluded by !**/*.woff2
  • apps/web/public/fonts/plus-jakarta-sans-700.woff2 is excluded by !**/*.woff2
  • apps/web/public/fonts/tinos-400.woff2 is excluded by !**/*.woff2
  • apps/web/public/fonts/tinos-700.woff2 is excluded by !**/*.woff2
📒 Files selected for processing (5)
  • apps/web/e2e/tests/seo.spec.ts
  • apps/web/index.html
  • apps/web/src/index.css
  • apps/web/vite.config.ts
  • vercel.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/self-host-fonts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

🎨 Design-surface change detected

This PR touches files mirrored by the Inkweave design system project.
After merge, refresh the mirror so it doesn't drift out of sync.

What changed:

  • ✏️ Font importsapps/web/index.html (flag any swap)
  • 🖼️ Imagery — playstyle or franchise covers
  • 📖 CLAUDE.md — design language sections may have shifted

To refresh: open the design system Claude project and prompt:

Refresh against the latest of Doberjohn/inkweave@master. Focus on the files this PR touched: apps/web/index.html, apps/web/public/art/franchises/monsters-inc.webp, apps/web/public/art/franchises/turning-red.webp, apps/web/public/art/franchises/up.webp, apps/web/public/art/sets/attack-of-the-vine.png, CLAUDE.md

This is a reminder, not a blocker. Configured in .github/workflows/design-system-drift.yml.

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our agent can fix these. Install it.

Gates Passed
6 Quality Gates Passed

Quality Gate Profile: Pay Down Tech Debt
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

@github-actions

Copy link
Copy Markdown

size-limit report 📦

Path Size
Total JS bundle 284.47 KB (-0.01% 🔽)
Card data JSON 321.95 KB (0%)

@github-actions

Copy link
Copy Markdown

⚡ Lighthouse Results

URL TBT LCP CLS FCP SI
/ 🟢 32ms 🔴 4824ms 🟢 0.072 🟠 2035ms 🟢 2035ms
/browse 🟢 88ms 🔴 5744ms 🟢 0.010 🔴 2405ms 🟢 2405ms
/card/957 🟢 22ms 🔴 5495ms 🟢 0.001 🟠 1928ms 🟢 1928ms
/card/957/synergies 🟢 25ms 🔴 4914ms 🟢 0.000 🟠 1937ms 🟢 1937ms
/playstyles 🟢 62ms 🔴 6640ms 🟢 0.000 🟠 2190ms 🟢 2190ms
/playstyles/lore-denial 🟢 44ms 🔴 5581ms 🟢 0.000 🔴 2391ms 🟢 2391ms
Threshold 🚫 500ms ⚠️ 3000ms 🚫 0.1 ⚠️ 2200ms ⚠️ 4000ms

Median of 3 runs. 🟢 ≤75% of limit · 🟠 within limit · 🔴 over limit · 🚫 merge-blocking · ⚠️ warning

@Doberjohn Doberjohn merged commit 873a213 into master Jun 25, 2026
23 checks passed
@Doberjohn Doberjohn deleted the fix/self-host-fonts branch June 25, 2026 17:54
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