Skip to content

Self-hosted stylesheet assets 404 in static builds: url() points at /myst_assets_folder, which myst build --html never creates #138

Description

@mmcky

Self-hosted stylesheet assets are referenced with an absolute /myst_assets_folder/… URL, which does not exist in myst build --html output. Every KaTeX font file 404s on statically built sites — the deployment mode the lectures actually use.

What happens

Remix rewrites url() in a bundled stylesheet to ${publicPath}_assets/<file>, and publicPath is /myst_assets_folder/ (remix.config.prod.js:8). So the KaTeX stylesheet self-hosted in #125 ships with 60 absolute references:

url(/myst_assets_folder/_assets/KaTeX_AMS-Regular-U6PRYMIZ.woff2)

Under myst start that resolves, because template/server.js:21 mounts express.static('public/build') at exactly that path. A static build has no such route, and mystmd's asset rewriter only rewrites .html, .js and .json — never .css — so the path inside the stylesheet is left pointing at a directory the output does not contain.

Reproduction

myst build --html of the repo's own visual fixture against a current make build-theme:

check result
<link> to the KaTeX stylesheet in the HTML rewritten to /build/_assets/katex.min-STXY5V2I.css — loads
url() inside that stylesheet still /myst_assets_folder/_assets/KaTeX_AMS-Regular-U6PRYMIZ.woff2
myst_assets_folder/ in the output tree absent
where the fonts actually landed build/_assets/ — 20 woff2 files

So the stylesheet loads and every font it asks for 404s. KaTeX then falls back to system fonts for maths glyphs, which is the degraded rendering #125 set out to prevent — now on every static site rather than only where jsdelivr is blocked.

Scope

Only the KaTeX stylesheet is affected today: app.css and thebe-core.css emit no url() references (checked — 0 matches each). The exposure arrived with #125; before that, KaTeX came from jsdelivr with absolute CDN font URLs that resolved everywhere jsdelivr was reachable.

This also blocks #131: self-hosting Source Sans 3 through the same app/links.ts route would put body text on the same broken path, and it would fail silently in exactly the same way.

Suggested direction

Make the emitted URLs relative to the stylesheet (url(./KaTeX_AMS-Regular-U6PRYMIZ.woff2)). The CSS and its font files are emitted into the same _assets/ directory in both layouts, so a relative reference resolves in myst start (/myst_assets_folder/_assets/…), in a static build (/build/_assets/…), and under a baseurl — where today's absolute path is wrong as well. publicPath itself cannot be made relative, since Remix also uses it to load JS chunks, so a post-build rewrite of the emitted CSS is the smallest change that covers every mode.

Worth proposing upstream separately that mystmd's static rewriter should treat .css like .html/.js/.json — but that only helps once consumers upgrade the CLI, so the theme should not depend on it.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions