import { resolve } from 'path' ; import type { Module } from '@nuxt/types' ; import consola from 'consola' ; import defu from 'defu' ; import { GoogleFontsHelper , DownloadOptions , GoogleFonts } from 'google-fonts-helper' ; import { name , version } from '../package.json' ; const logger = consola . withTag ( 'nuxt:google-fonts' ) ; export interface ModuleOptions extends Partial < DownloadOptions & GoogleFonts > { prefetch ? : boolean ; preconnect ? : boolean ; preload ? : boolean ; useStylesheet ? : boolean ; download ? : boolean ; inject ? : boolean ; } const CONFIG_KEY = 'googleFonts' ; const nuxtModule = function ( moduleOptions ) { const DEFAULTS = { families : { } , display : null , subsets : [ ] , text : null , prefetch : true , preconnect : true , preload : true , useStylesheet : false , download : false , base64 : false , inject : true , overwriting : false , outputDir : this . options . dir . assets , stylePath : 'css/fonts.css' , fontsDir : 'fonts' , fontsPath : '~assets/fonts' } ; this . nuxt . hook ( 'build:before' , async ( ) => { const options = defu ( this . options [ 'google-fonts' ] , this . options [ CONFIG_KEY ] , moduleOptions , DEFAULTS ) ; const googleFontsHelper = new GoogleFontsHelper ( { families : options . families , display : options . display , subsets : options . subsets , text : options . text } ) ; const fontsParsed = ( this . options . head . link || [ ] ) . filter ( link => GoogleFontsHelper . isValidURL ( link . href ) ) . map ( link => GoogleFontsHelper . parse ( link . href ) ) ; if ( fontsParsed . length ) { googleFontsHelper . merge ( ... fontsParsed ) ; } const url = googleFontsHelper . constructURL ( ) ; if ( ! url ) { logger . warn ( 'No provided fonts.' ) ; return ; } this . options . head . link = ( this . options . head . link || [ ] ) . filter ( link => ! GoogleFontsHelper . isValidURL ( link . href ) ) ; if ( options . download ) { const outputDir = this . nuxt . resolver . resolveAlias ( options . outputDir ) ; try { await GoogleFontsHelper . download ( url , { base64 : options . base64 , overwriting : options . overwriting , outputDir , stylePath : options . stylePath , fontsDir : options . fontsDir , fontsPath : options . fontsPath } ) ; if ( options . inject ) { this . options . css . push ( resolve ( outputDir , options . stylePath ) ) ; } } catch ( e ) { logger . error ( e ) ; } return ; } if ( options . prefetch ) { this . options . head . link . push ( { hid : 'gf-prefetch' , rel : 'dns-prefetch' , href : 'https://fonts.gstatic.com/' } ) ; } if ( options . preconnect ) { this . options . head . link . push ( { hid : 'gf-preconnect' , rel : 'preconnect' , href : 'https://fonts.gstatic.com/' , crossorigin : '' } ) ; } if ( options . preload ) { this . options . head . link . push ( { hid : 'gf-preload' , rel : 'preload' , as : 'style' , href : url } ) ; } if ( options . useStylesheet ) { this . options . head . link . push ( { hid : 'gf-style' , rel : 'stylesheet' , href : url } ) ; return ; } this . options . head . script = this . options . head . script || [ ] ; this . options . head . script . push ( { hid : 'gf-script' , innerHTML : `(function(){var l=document.createElement('link');l.rel="stylesheet";l.href="${ url }";document.querySelector("head").appendChild(l);})();` } ) ; this . options . head . noscript = this . options . head . noscript || [ ] ; this . options . head . noscript . push ( { hid : 'gf-noscript' , innerHTML : `<link rel="stylesheet" href="${ url }">` } ) ; this . options . head . __dangerouslyDisableSanitizersByTagID = this . options . head . __dangerouslyDisableSanitizersByTagID || { } ; this . options . head . __dangerouslyDisableSanitizersByTagID [ 'gf-script' ] = [ 'innerHTML' ] ; this . options . head . __dangerouslyDisableSanitizersByTagID [ 'gf-noscript' ] = [ 'innerHTML' ] ; } ) ; } ; ( nuxtModule as any ) . meta = { name , version } ; declare module '@nuxt/types' { interface NuxtConfig { [ CONFIG_KEY ] ? : ModuleOptions ; } interface Configuration { [ CONFIG_KEY ] ? : ModuleOptions ; } } export default nuxtModule ;