question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support for Nuxt 3

See original GitHub issue
  1. Installed a fresh Nuxt 3 app.
  2. Installed google fonts module.
  3. Error

ERROR Cannot start nuxt: Cannot find module 'tslib'

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:14
  • Comments:14 (1 by maintainers)

github_iconTop GitHub Comments

6reactions
Teranodecommented, Feb 1, 2022

Here’s one with download support (Note: this was tested on Nuxt3 not bridge):

/modules/google-fonts/index.ts

import { resolve } from 'path'
import { GoogleFontsHelper, DownloadOptions, GoogleFonts } from 'google-fonts-helper'
import { defineNuxtModule } from '@nuxt/kit'

export interface ModuleOptions extends Partial<DownloadOptions & GoogleFonts> {
  prefetch?: boolean;
  preconnect?: boolean;
  preload?: boolean;
  useStylesheet?: boolean;
  download?: boolean;
  inject?: boolean;
}

const CONFIG_KEY = 'googleFonts'

declare module '@nuxt/types' {
  interface NuxtConfig { [CONFIG_KEY]?: ModuleOptions } // Nuxt 2.14+
  interface Configuration { [CONFIG_KEY]?: ModuleOptions } // Nuxt 2.9 - 2.13
}

export default defineNuxtModule({
    meta: {
        name: '@nuxtjs/google-fonts',
        configKey: CONFIG_KEY,
        compatibility: {
            nuxt: '^3.0.0'
        }
    },
    async setup(moduleOptions, nuxt) {

        const DEFAULTS: ModuleOptions = {
            families: {},
            display: null,
            subsets: [],
            text: null,
            prefetch: true,
            preconnect: true,
            preload: true,
            useStylesheet: false,
            download: false,
            base64: false,
            inject: true,
            overwriting: false,
            outputDir: nuxt.options.dir.assets,
            stylePath: 'css/fonts.css',
            fontsDir: 'fonts',
            fontsPath: '~assets/fonts'
        }

        const options: ModuleOptions = {
            ...DEFAULTS,
            ...moduleOptions,
            ...nuxt.options['google-fonts'],
            ...nuxt.options[CONFIG_KEY],
        }

        const googleFontsHelper = new GoogleFontsHelper({
            families: options.families,
            display: options.display,
            subsets: options.subsets,
            text: options.text
        })

        // merge fonts from valid head link
        // @ts-ignore
        const fontsParsed = (nuxt.options.meta.link || []).filter(link => GoogleFontsHelper.isValidURL(link.href)).map(link => GoogleFontsHelper.parse(link.href))

        if (fontsParsed.length) {
            googleFontsHelper.merge(...fontsParsed)
        }
        
        // construct google fonts url
        const url = googleFontsHelper.constructURL()
    
        if (!url) {
            console.warn('No provided fonts.')
    
            return
        }

        // remove fonts
        // @ts-ignore
        nuxt.options.meta.link = (nuxt.options.meta.link || []).filter(link => !GoogleFontsHelper.isValidURL(link.href))

        // download
        if (options.download) {
            const outputDir = nuxt.resolver ? nuxt.resolver.resolveAlias(options.outputDir) : nuxt.options.alias[options.outputDir] || 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) {
                    nuxt.options.css.push(resolve(outputDir, options.stylePath))
                }
            
            } catch (e) { /* istanbul ignore next */
                console.error(e)
            }
    
            return
        }

        // https://developer.mozilla.org/en-US/docs/Web/Performance/dns-prefetch
        if (options.prefetch) {
            // @ts-ignore
            nuxt.options.meta.link.push({
                hid: 'gf-prefetch',
                rel: 'dns-prefetch',
                href: 'https://fonts.gstatic.com/'
            })
        }
    
        // https://developer.mozilla.org/en-US/docs/Web/Performance/dns-prefetch#Best_practices
        // connect to domain of font files
        if (options.preconnect) {
            // @ts-ignore
            nuxt.options.meta.link.push({
                hid: 'gf-preconnect',
                rel: 'preconnect',
                href: 'https://fonts.gstatic.com/',
                crossorigin: ''
            })
        }

        // https://developer.mozilla.org/pt-BR/docs/Web/HTML/Preloading_content
        // optionally increase loading priority
        if (options.preload) {
            // @ts-ignore
            nuxt.options.meta.link.push({
                hid: 'gf-preload',
                rel: 'preload',
                as: 'style',
                href: url
            })
        }

        // append CSS
        if (options.useStylesheet) {
            // @ts-ignore
            nuxt.options.meta.link.push({
                hid: 'gf-style',
                rel: 'stylesheet',
                href: url
            })

            return
        }

        // JS to inject CSS
        // @ts-ignore
        nuxt.options.meta.script = nuxt.options.meta.script || []
        // @ts-ignore
        nuxt.options.meta.script.push({
            hid: 'gf-script',
            innerHTML: `(function(){var l=document.createElement('link');l.rel="stylesheet";l.href="${url}";document.querySelector("head").appendChild(l);})();`
        })

        // no-JS fallback
        // @ts-ignore
        nuxt.options.meta.noscript = nuxt.options.meta.noscript || []
        // @ts-ignore
        nuxt.options.meta.noscript.push({
            hid: 'gf-noscript',
            innerHTML: `<link rel="stylesheet" href="${url}">`
        })

        // Disable sanitazions
        // @ts-ignore
        nuxt.options.meta.__dangerouslyDisableSanitizersByTagID = nuxt.options.meta.__dangerouslyDisableSanitizersByTagID || {}
        // @ts-ignore
        nuxt.options.meta.__dangerouslyDisableSanitizersByTagID['gf-script'] = ['innerHTML']
        // @ts-ignore
        nuxt.options.meta.__dangerouslyDisableSanitizersByTagID['gf-noscript'] = ['innerHTML']
    }
})

nuxt.config.ts

import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
    buildModules: [
        '~/modules/google-fonts',
    ],
    googleFonts: {
        display: 'swap',
        useStylesheet: true,
        inject: true,
        download: true,
        families: {
            'Inter': [300, 400, 500, 600, 700],
            'Open Sans': [300, 400, 500, 600, 700]
        }
    }
})
5reactions
ricardogobbosouzacommented, Jul 22, 2022

Support Nuxt 3 v3.0.0-0

Read more comments on GitHub >

github_iconTop Results From Across the Web

Announcing Nuxt 3.0 stable
The browser and Node.js support. Nuxt 3 officially supports evergreen browsers only. The "core browser set" is what we (And web.dev team) ...
Read more >
Announcing Nuxt 3 Release Candidate
Nuxt 3 beta was announced on October 12, 2021 after 16 months of work, ... This means Nuxt 3 officially supports both Vite...
Read more >
Modules support status · Discussion #751 · nuxt/framework
This discussion is to keep track of the module's compatibility with Nuxt 3. If you spot a module that is not working with...
Read more >
Nuxt 3 support : WEB-54200 - YouTrack
To support Nuxt 3 we need: WEB-53890 - index d.ts files in .nuxt folder; WEB-54199 - recognize GlobalComponents Vue 3 interface; remove special...
Read more >
Nuxt 3 is here! What does that mean for you? | Vue Mastery
Nuxt 3 also comes with Vite support, which is backwards compatible with Nuxt 2. Vite is a build tool that aims to provide...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found