Skip to content

Remove font loading from the library; let apps load their own fonts #855

Description

@ravisuhag

Summary

The library loads fonts itself. packages/raystack/styles/typography.css starts with four Google Fonts @import calls:

@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Lora:wght@400;500&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Josefin+Sans:wght@400;500&display=swap");
@import url("https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital@0;1&display=swap");

A component library should not decide how or where fonts load. That belongs to the app. We should remove these imports and keep only the --rs-font-* variables (the font-family names), then let each app load the fonts it needs.

Why this is a problem

  • Consumers download fonts they never use. Any app that pulls in Apsara fetches Inter, Lora, Josefin Sans, and JetBrains Mono — even if it only uses Inter. Lora and Josefin Sans only apply under [data-style="traditional"], so most apps pay for them for nothing.
  • @import blocks render. Fonts inside a CSS @import are found late by the browser, which delays paint and causes a flash of unstyled text (FOUT).
  • Extra connections. Each @import needs DNS + TLS to Google's domains before the font even downloads.
  • No control for the app. The app can't preload the font, can't set font-display, and can't self-host. All of that is decided inside the library.
  • Blocks other improvements. We can't cleanly add a 600 weight or use Inter's optical-sizing (opsz) axis, because the library pins the exact Google Fonts URL and weights.

Proposal

  1. Remove the four @import lines from packages/raystack/styles/typography.css.
  2. Keep the --rs-font-* variables (Inter, Lora, Josefin Sans, JetBrains Mono, Menlo) so component styles stay unchanged.
  3. Document how consuming apps load the fonts, for example:
    • Self-host with Fontsource — @fontsource-variable/inter (variable font, all weights from one file).
    • next/font for Next.js apps.
    • A plain @font-face or Google Fonts <link> for apps that want it.
  4. Note the optional families (Lora, Josefin Sans) are only needed for the traditional style.

Breaking change

This is a breaking change. Apps that rely on Apsara loading fonts will render in a fallback font until they load the fonts themselves. The migration is small — install the fonts and import them once at the app entry — but it must be called out in release notes with a clear before/after.

Acceptance criteria

  • No @import of font files in the library CSS.
  • --rs-font-* variables still present; components render identically once the app loads Inter.
  • Docs / README show how to load fonts in a plain Vite app and a Next.js app.
  • Migration note added to the changelog / release notes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BREAKING CHANGEenhancementNew feature or requestglobalCross-cutting issue affecting multiple components

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions