Shrink an icon font to the icons a built site actually uses: the stylesheet keeps only those rules and the font keeps only those glyphs.
Tabler Icons 3 ships 5,000+ glyphs (a ~490 KB woff2 and ~5,200 CSS rules). A site using 100 of them needs a few KB. Works with any font whose CSS maps .<prefix>-<name>:before { content: "\XXXX" } (Tabler ti, Bootstrap Icons bi, …).
// astro.config.mjs
import iconSubset from '@arraypress/icon-subset/astro';
export default defineConfig({
integrations: [iconSubset({ prefix: 'ti' }), /* security-headers after */],
});Runs at astro:build:done on the static output, so an icon named anywhere (components, config, MDX, client scripts) is found as long as its full class appears in the shipped HTML/JS. Classes built at runtime from parts ('ti-' + name) can't be seen: list them in keep.
Nothing changes in astro dev.
import { subsetIconFont } from '@arraypress/icon-subset';
const r = await subsetIconFont('dist', { prefix: 'ti', keep: ['loader'] });
// { used, total, fontBefore, fontAfter, cssBefore, cssAfter, files }Files are rewritten in place (names kept, so hashed URLs still resolve). The woff/ttf/eot fallbacks are dropped from @font-face and deleted, since every browser in use reads woff2 (removeFallbacks: false to keep them, unsubset).
Subsetting is harfbuzz (hb-subset, via subset-font).
MIT © ArrayPress Limited