Files
2026-02-13 22:02:30 +01:00

167 lines
5.3 KiB
JavaScript

import { resolve } from 'pathe';
import { useLogger, defineNuxtModule, resolvePath, isNuxt2 } from '@nuxt/kit';
import { isValidURL, parse, constructURL, merge, download } from 'google-fonts-helper';
const name = "@nuxtjs/google-fonts";
const version = "3.2.0";
const logger = useLogger("nuxt:google-fonts");
const module = defineNuxtModule({
meta: {
name,
version,
configKey: "googleFonts"
},
defaults: {
families: {},
display: void 0,
// set to 'swap' later if no preload or user value
subsets: [],
text: void 0,
prefetch: true,
preconnect: true,
preload: false,
useStylesheet: false,
download: true,
base64: false,
inject: true,
overwriting: false,
outputDir: "node_modules/.cache/nuxt-google-fonts",
stylePath: "css/nuxt-google-fonts.css",
fontsDir: "fonts",
fontsPath: "../fonts"
},
async setup(options, nuxt) {
if (options.display === void 0 && !options.preload) {
options.display = "swap";
}
const fontsParsed = [];
const head = nuxt.options.app.head || nuxt.options.head;
if (typeof head === "function") {
logger.warn("This module does not work with `head` as function.");
return;
}
fontsParsed.push(
...head.link.filter((link) => isValidURL(String(link.href))).map((link) => parse(String(link.href)))
);
const url = constructURL(merge(options, ...fontsParsed));
if (!url) {
logger.warn("No provided fonts.");
return;
}
head.link = head.link.filter((link) => !isValidURL(String(link.href)));
if (options.download && options.outputDir) {
const outputDir = await resolvePath(options.outputDir);
try {
const downloader = download(url, {
base64: options.base64,
overwriting: options.overwriting,
outputDir,
stylePath: options.stylePath,
fontsDir: options.fontsDir,
fontsPath: options.fontsPath
});
const outputFonts = [];
downloader.hook("download:start", () => {
logger.start("Downloading fonts...");
});
downloader.hook("download:complete", () => {
logger.success("Download fonts completed.");
logger.log("");
});
downloader.hook("download-css:done", (url2) => {
logger.success(url2);
});
downloader.hook("download-font:done", (font) => {
const fontName = font.outputFont.replace(`-${font.outputFont.replace(/.*-/, "")}`, "");
if (!outputFonts.includes(fontName)) {
outputFonts.push(fontName);
logger.info(fontName);
}
});
await downloader.execute();
if (options.inject && options.stylePath) {
nuxt.options.css.push(resolve(outputDir, options.stylePath));
}
nuxt.options.nitro = nuxt.options.nitro || {};
nuxt.options.nitro.publicAssets = nuxt.options.nitro.publicAssets || [];
nuxt.options.nitro.publicAssets.push({ dir: outputDir });
} catch (e) {
logger.error(e);
}
return;
}
if (options.prefetch) {
head.link.push({
key: "gf-prefetch",
rel: "dns-prefetch",
href: "https://fonts.gstatic.com/"
});
}
if (options.preconnect) {
head.link.push(
// connect to domain of font files
{
key: "gf-preconnect",
rel: "preconnect",
href: "https://fonts.gstatic.com/",
crossorigin: "anonymous"
},
// Should also preconnect to origin of Google fonts stylesheet.
{
key: "gf-origin-preconnect",
rel: "preconnect",
href: "https://fonts.googleapis.com/"
}
);
}
if (options.preload) {
head.link.push({
key: "gf-preload",
rel: "preload",
as: "style",
href: url
});
}
if (options.useStylesheet) {
head.link.push({
key: "gf-style",
rel: "stylesheet",
href: url
});
return;
}
if (isNuxt2()) {
head.script.push({
key: "gf-script",
innerHTML: `(function(){var l=document.createElement('link');l.rel="stylesheet";l.href="${url}";document.querySelector("head").appendChild(l);})();`
});
head.noscript.push({
key: "gf-noscript",
innerHTML: `<link rel="stylesheet" href="${url}">`,
tagPosition: "bodyOpen"
});
head.__dangerouslyDisableSanitizersByTagID = head.__dangerouslyDisableSanitizersByTagID || {};
head.__dangerouslyDisableSanitizersByTagID["gf-script"] = ["innerHTML"];
head.__dangerouslyDisableSanitizersByTagID["gf-noscript"] = ["innerHTML"];
return;
}
head.script.unshift({
key: "gf-script",
children: `(function(){
var h=document.querySelector("head");
var m=h.querySelector('meta[name="head:count"]');
if(m){m.setAttribute('content',Number(m.getAttribute('content'))+1);}
else{m=document.createElement('meta');m.setAttribute('name','head:count');m.setAttribute('content','1');h.append(m);}
var l=document.createElement('link');l.rel='stylesheet';l.href='${url}';h.appendChild(l);
})();`
});
head.noscript.push({
children: `<link rel="stylesheet" href="${url}">`,
tagPosition: "bodyOpen"
});
}
});
export { module as default };