UNPKG

@stolbov.r/nuxt-font-loader

Version:

Fork of nuxt-font-loader with Nuxt 4 compatibility

132 lines (126 loc) 3.17 kB
import { useHead } from '#imports'; const parseFormat = (src, strict = false) => { let [, format] = src.split(/\.(?=[^.]+$)/); if (strict) { if (format === "ttf") format = "truetype"; else if (format === "otf") format = "opentype"; } return format; }; const generateStyles = (fonts) => { let fontFace = ""; let classes = ""; let root = ""; let variables = ""; for (const font of fonts) { const options = { weight: "400", display: "optional", style: "normal", ...font }; const { src, family, fallback, weight, style, display } = options; const { class: _class, variable } = options; const { unicode } = options; let unicodes = ""; const format = parseFormat(src, true); const fb = fallback ? `,${fallback}` : ""; const faceRules = [ `font-family:"${family}";`, `font-weight:${weight};`, `font-style:${style};`, `font-display:${display};`, `src:url('${src}') format('${format}');` ].join(""); if (unicode) unicodes = `unicode-range:${unicode};`; if (_class) classes += `.${_class}{font-family:"${family}"${fb};}`; if (variable) variables += `--${variable}:"${family}"${fb};`; fontFace += `@font-face{${faceRules}${unicodes}}`; } if (variables) root += `:root{${variables}}`; return { fontFace, classes, root }; }; const useExternalFont = (external) => { const { classes, root } = generateStyles(external); const styles = `${classes}${root}`; const links = []; let google = false; let typekit = false; for (const font of external) { const { src } = font; if (src.includes("google") && !google) { google = true; links.push( { rel: "preconnect", href: "https://fonts.googleapis.com" }, { rel: "preconnect", crossorigin: "anonymous", href: "https://fonts.gstatic.com" } ); } if (src.includes("typekit") && !typekit) { typekit = true; links.push({ rel: "preconnect", crossorigin: "anonymous", href: "https://use.typekit.net" }); } links.push( { rel: "preload", as: "style", href: src }, { rel: "stylesheet", href: src } ); } useHead({ link: links }); if (styles) return useHead({ style: [styles] }); }; const useLocalFont = (local) => { const { fontFace, classes, root } = generateStyles(local); const styles = `${fontFace}${classes}${root}`; const links = []; for (const font of local) { const options = { preload: true, ...font }; const { src } = options; if (options.preload) { const format = parseFormat(src); if (!links.some((v) => v.href === src)) { links.push({ rel: "preload", as: "font", type: `font/${format}`, crossorigin: "anonymous", href: src }); } } } if (links.length) useHead({ link: links }); return useHead({ style: [styles] }); }; export { useExternalFont, useLocalFont };