[fix] Load InterDisplay on production (headings were silently falling back to Inter) - #2836
Conversation
📝 WalkthroughWalkthroughThe website now loads Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
@claude review |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
Greptile SummaryThis PR ensures Inter Display is included in production builds and consistently applied to marketing headings.
Confidence Score: 5/5The PR appears safe to merge, with no concrete regressions identified in the changed font-loading or heading-style paths. The application-level font registration reaches every page layout, the removed font weight has no current Inter Display consumers, and the four class replacements preserve their prior computed styles apart from the intended font-family change.
|
| Filename | Overview |
|---|---|
| apps/website/src/pages/_app.tsx | Adds Inter Display to the Pages Router application graph and applies its variable class to the wrapper around every layout path. |
| apps/website/src/lib/fonts.ts | Removes the currently unused 700-weight Inter Display source and makes swaps fall through to the existing Inter face. |
| apps/website/src/components/homepage/CourseValueProps.tsx | Adopts bluedot-h2 while preserving the heading’s prior computed utility styles. |
| apps/website/src/components/homepage/EventsSection.tsx | Adopts bluedot-h2 without changing the heading’s existing size, weight, spacing, color, or width behavior. |
| apps/website/src/components/homepage/MergedLadder.tsx | Adopts bluedot-h2 while retaining the existing medium-weight and tighter-tracking overrides. |
| apps/website/src/components/lander/TestimonialCarousel.tsx | Adds bluedot-h2 to the homepage heading while preserving its responsive sizing and explicit typography overrides. |
Reviews (1): Last reviewed commit: "[chore] Remove PR screenshots (SHA-pinne..." | Re-trigger Greptile
There was a problem hiding this comment.
🧹 Nitpick comments (1)
apps/website/src/pages/_app.tsx (1)
18-18: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winVerify the global font preload cost before release.
Importing
interDisplayfrom_app.tsxmakes all configured font weights available to every route. The PR reports a 327 kB increase in preloaded fonts per page. Measure representative production-like routes and reduce the preload scope if pages that do not use these headings still preload all three assets.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/website/src/pages/_app.tsx` at line 18, Verify the global font preload behavior caused by importing interDisplay in _app.tsx by measuring representative production-like routes and their loaded font assets. If routes without heading usage preload all configured interDisplay weights, narrow the import or font configuration scope so only pages that use those headings preload them, while preserving inter and required heading rendering.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@apps/website/src/pages/_app.tsx`:
- Line 18: Verify the global font preload behavior caused by importing
interDisplay in _app.tsx by measuring representative production-like routes and
their loaded font assets. If routes without heading usage preload all configured
interDisplay weights, narrow the import or font configuration scope so only
pages that use those headings preload them, while preserving inter and required
heading rendering.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 2d716d98-898f-4acb-9c00-93f5e22eb086
📒 Files selected for processing (6)
apps/website/src/components/homepage/CourseValueProps.tsxapps/website/src/components/homepage/EventsSection.tsxapps/website/src/components/homepage/MergedLadder.tsxapps/website/src/components/lander/TestimonialCarousel.tsxapps/website/src/lib/fonts.tsapps/website/src/pages/_app.tsx
Takes each weight from ~106kB to ~42kB, cutting this PR's added preload from 327kB to 130kB. Subsetted in place, so the other apps loading these over HTTPS from bluedot.org get the smaller files too; glyphs outside the range fall back to Inter, which is full-coverage and already in the chain. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Added font subsetting: InterDisplay latin + latin-ext, 106kB → ~42kB per weight, cutting this PR's added preload from 327kB to 130kB. Subsetted in place so the other apps loading these from Verified by pixel-diffing rendered headings before/after subsetting: 0 differing pixels, so @claude review |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Description
interDisplay(next/font,src/lib/fonts.ts) was imported only from_document.tsx. The pages router emitsnext/fontCSS only for fonts reachable from_app, so--font-inter-displaywas never defined in production builds, only referenced. That made the.bluedot-h1/.bluedot-h2rule inglobals.cssinvalid at computed-value time, so every heading inherited--font-sansand silently rendered Inter. Local dev was unaffected, which is why it went unnoticed. Confirmed pre-fix: prod and staging both served CSS89631b6d…with the variable referenced once and defined zero times.Changes
_app.tsximportsinterDisplayand appliesinterDisplay.variable, making the module reachable from the_appgraph so its CSS ships._document.tsxstill puts both variable classes on<Html>— that's what lands the custom properties on:root, whichglobals.cssneeds for--font-sans. Both are load-bearing.next/fontcall: nothing renders.bluedot-h1/.bluedot-h2at bold, and next/font preloads every declared weight. Ships 400/500/600.adjustFontFallback: false, so the swap falls through to already-preloaded Inter instead of next/font's generated Arial-metric face. Inter and InterDisplay are the same typeface at two optical sizes, so that swap is far less visible..bluedot-h2's styling on a raw<h2>without the font-family, so they'd have stayed Inter while<H2>flipped everywhere else. Addedbluedot-h2and removed the classes that merely restated its defaults, keeping the realfont-medium/tracking-tighteroverrides.variant === 'homepage'branch stepped up totext-size-2xlabovebd-md, rendering it at 56 px against 48 px for every other H2..bluedot-h2already suppliestext-size-xl, so the size classes went entirely. Pre-existing, surfaced while auditing heading consistency for this change.Font subsetting
Subsetted in place in
public/fonts/, so the other apps that load these over HTTPS frombluedot.org/fonts(8@font-facerules inlibraries/ui/src/default-config/tailwind.css) get the smaller files too. That's deliberate: the library's.bluedot-h1resolves toInterDisplay, var(--font-sans)and its--font-sansleads with full-coverageInter, so any glyph outside the subset degrades to Inter — the same typeface at a different optical size, not a system font.All four weights subsetted, including 700, which the website no longer references but the library still declares; leaving it full-coverage would make glyph support vary by weight.
The subset range, the exact regeneration command and the
ss04caveat are documented inapps/website/README.mdunder Font Inventory. Pre-subset originals are recoverable from28b8c9fd9if the range ever needs widening — re-run against those, not against already-subsetted files.Two things worth knowing if you touch this:
--layout-features+=is required. I first wrote--layout-features='+ss04,…'and it silently emptied GSUB —ss04gone, no error, no warning. Four of these headings setfontFeatureSettings: "'ss04' on", so that would have shipped as an invisible typography regression. The README documents a one-liner to verifyss04survived.Testing
Verified against a local production build, with
origin/masterbuilt and served alongside it so before/after differ by this change alone.--font-inter-display:"interDisplay"now defined, with no"interDisplay Fallback"companion (confirmsadjustFontFallback: false).@font-faceat 400/500/600; 7 font preloads on/about(4 Inter + 3 InterDisplay), totalling 573 kB vs 443 kB on master.CSS.getPlatformFontsForNode— what actually painted, not what was requested:/about,/our-community,/programs/advising/programs/advising//ss04enabled, over the real heading copy plus latin-ext andss04-sensitive glyphs: 0 differing pixels out of 6.72M. And re-running the rendered-font check against the served build with requests tobluedot.orgblocked, so nothing could be served by production's still-full copy: 0 blocked requests, weights 400/500/600 all resolving to Inter Display faces. All four subsetted files confirmed to carryss04andss02.bd-md, 48 px above). The 66 px horizontal overflow at 1024 px is pre-existing header behaviour — staging onmastershows the identical overflow from the samenav-cta/dropdown elements.No regression test added — nothing stops a future
_appcleanup or Next upgrade from silently reverting this, and the failure mode is invisible in dev.Deployment
website/vX.Y.Zrelease will carry a sitewide visual change, so please don't cut one before design sign-off.Note the subsetted fonts reach the other apps on the website's production release, not on their own deploys, since they fetch from
bluedot.org/fontsat runtime.Two things this makes visible for the first time, both worth a designer's eye:
prosesets no heading font-family and<H1>/<H2>carrynot-prose, so blog and markdown course-content headings stay Inter while chrome/marketing headings become InterDisplay.HomeHeroContent.tsx), making it the only Inter hero on the site.Latent before, live now: the
globals.cssheading rule falls back to Tailwind's stock serif stack, so headings would render Times if both webfonts failed. Left alone to keep this diff minimal.Inter itself is still unsubsetted (443 kB across 4 weights). Subsetting it is the bigger win but carries real glyph risk — it renders user-generated names and its fallback is a system font, not a sibling cut — so it belongs in its own PR.
Issue
Fixes #2832
Developer checklist
Screenshot
Zoomed crops first, since at full-page scale the difference reads as slightly tighter letterforms rather than anything obvious.
/aboutH1 (weight 400)The logo carousel differs between the homepage shots only because it's an infinite-scroll animation caught at a different frame.