Bundler Setup
Tegaki’s font bundles use the ESM import-attributes syntax to load their assets:
Most bundlers handle this transparently. The note below covers Vite, where two optimizeDeps settings are needed for development to behave like production.
In dev mode on Vite 7 and earlier, the esbuild pre-bundler copies Tegaki’s font bundle modules into /node_modules/.vite/deps/ but leaves the .ttf files behind, so the bundle’s relative font URL now points to a file that isn’t there. The dev server answers that request with your index.html, and the browser rejects it as a font. Excluding tegaki from pre-bundling sends the imports through Vite’s normal asset pipeline, where the URLs resolve correctly. Vite 8’s Rolldown-based pre-bundler rewrites these URLs itself, so it doesn’t need this setting (though adding it does no harm).
Add to vite.config.ts:
After changing this, fully restart the dev server (and consider deleting node_modules/.vite/deps/ once) so Vite re-runs its pre-bundling pass against the new config.
Production builds (Rollup) need no setting; this only affects vite dev and vite preview.
Symptoms this fixes
Section titled “Symptoms this fixes”| Symptom in the browser | What’s happening | Fix |
|---|---|---|
Text is invisible but can be selected, or only appears with showOverlay. Console shows Failed to decode downloaded font: …/node_modules/.vite/deps/<family>.ttf / OTS parsing error: invalid sfntVersion, a NetworkError: A network error occurred or a [tegaki] Failed to load font warning. |
The .ttf URL broke during pre-bundling, so the dev server returns HTML instead of the font. Older tegaki versions stop drawing at this point; newer ones keep drawing with the fallback font’s spacing. |
optimizeDeps.exclude: ['tegaki'] |
Vite turns a bundle’s font URLs into public asset URLs only in client code. On the server it leaves new URL('./font.ttf', import.meta.url) as it stands, and that evaluates to a file:// path on the build machine. The tegaki/astro component renders on the server and passes that bundle to the browser, which refuses to load a local file: the handwriting still draws, but in a fallback font’s widths. The Tegaki integration makes Vite emit the fonts and resolve their URLs on the server as well:
| Symptom | What’s happening | Fix |
|---|---|---|
The build logs [tegaki] The font of "…" resolved to a local file, and the browser console shows Not allowed to load local resource: file:///…/.prerender/chunks/<family>.ttf. The text draws with the wrong letter spacing. |
The server evaluated the bundle’s font URL as a path on disk. | Add tegaki() to integrations |
Other bundlers
Section titled “Other bundlers”Webpack, Rollup, Parcel, and esbuild’s standalone build mode all handle with { type: 'url' } natively in the configurations Tegaki has been tested with. If one breaks, open an issue and its notes can go here.