fonts icon indicating copy to clipboard operation
fonts copied to clipboard

Question: How to fetch only woff2 format?

Open lttr opened this issue 1 year ago • 7 comments

Since woff2 format is often enough, I would like to have woff2 and only woff2 format of a font downloaded. I have not found a way how to configure a provider like Google in order to force only this format.

Details

I have tried the Fonts module both without any configuration and with configuration like this one:

  fonts: {
    families: [
      {
        name: "Poppins",
        weights: [400],
        styles: ["normal"],
        subsets: ["latin-ext", "latin"],
        provider: "google",
      },
    ],
  },

In both cases the behavior is following:

  • on dev server both woff and woff2 formats are downloaded (woff first)
  • on preview (nuxi preview) of a prod build (node preset) only the woff format is downloaded

I was unable to create a reproduction on Stackblitz since fonts are not at all downloaded there with Google provider.

lttr avatar Jul 09 '24 14:07 lttr

Hey @lttr! I'm here to assist you with any bugs, questions, or contributions you have. Let's tackle this font format issue together!

To configure the Fonts module to download only the woff2 format when using a provider like Google, you can specify the font data directly with the src property in the families array. Here is an example configuration:

export default {
  fonts: {
    families: [
      {
        name: 'Poppins',
        provider: 'google',
        src: 'url(https://example.com/font.woff2)'
      }
    ]
  }
}

This configuration ensures that only the woff2 format is downloaded for the specified font family from the Google provider. Additionally, you can use a custom provider setup to ensure only woff2 fonts are resolved:

import type { FontProvider } from '@nuxt/fonts'

const resolvableFonts = new Set<string>()
export default {
  async setup() {
    // Do some stuff
    resolvableFonts.add('Poppins')
  },
  async resolveFontFaces(fontFamily) {
    if (!resolvableFonts.has(fontFamily)) {
      return
    }
    return {
      fonts: {
        src: 'url(https://example.com/font.woff2)',
      },
    }
  },
} satisfies FontProvider

This custom provider setup ensures that only the woff2 format is resolved for the specified font family [1][2].

To continue talking to Dosu, mention @dosu.

dosubot[bot] avatar Jul 09 '24 14:07 dosubot[bot]

While the bot might be right with the answer above, it misses the point. If I want I can use the URL directly or I might download the fonts manually. The advantage here is that this module could do it automatically.

lttr avatar Jul 09 '24 14:07 lttr

To configure the Fonts module to download only the woff2 format when using a provider like Google, you can specify the font data directly with the src property in the families array.

It does not work since I need 2 different subsets as mentioned in a code snippet in the original description. @dosu

lttr avatar Jul 09 '24 14:07 lttr

To configure the Fonts module to download only the woff2 format while supporting multiple subsets for a font from a provider like Google, you need to modify the userAgents object to include only the woff2 format and ensure that the subsets are supported in the query parameters when fetching the font details.

Here is the relevant code snippet with the necessary modifications:

const userAgents = {
  woff2: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
}

async function getFontDetails(family: string, variants: ResolveFontFacesOptions) {
  const font = fonts.find(font => font.family === family)!
  const styles = [...new Set(variants.styles.map(i => styleMap[i]))].sort()
  const variableWeight = font.axes.find(a => a.tag === 'wght')
  const weights = variableWeight
    ? [`${variableWeight.min}..${variableWeight.max}`]
    : variants.weights.filter(weight => weight in font.fonts)

  if (weights.length === 0 || styles.length === 0) return []

  const resolvedVariants = weights.flatMap(w => [...styles].map(s => `${s},${w}`)).sort()

  let css = ''

  for (const extension in userAgents) {
    css += await $fetch<string>('/css2', {
      baseURL: 'https://fonts.googleapis.com',
      headers: { 'user-agent': userAgents[extension as keyof typeof userAgents] },
      query: {
        family: family + ':' + 'ital,wght@' + resolvedVariants.join(';'),
        subset: variants.subsets.join(','), // Ensure subsets are included in the query
      },
    })
  }

  return addLocalFallbacks(family, extractFontFaceData(css))
}

In this code:

  1. The userAgents object is modified to include only the woff2 format.
  2. The getFontDetails function is updated to include the subset parameter in the query to support multiple subsets.

Additionally, you can configure the Fonts module options in your Nuxt configuration to specify the Google provider and other relevant settings:

export default {
  fonts: {
    providers: {
      google: true,
    },
    defaults: {
      subsets: ['latin', 'latin-ext'], // Specify the subsets you need
    },
  },
}

This configuration ensures that the Fonts module uses the Google provider and includes the specified subsets by default [1][2].

To continue talking to Dosu, mention @dosu.

dosubot[bot] avatar Jul 09 '24 14:07 dosubot[bot]

@lttr I checked with Nuxt Devtools, For woff2 there is a unicode-range, but for woff there is no unicode-range.

In this case, the browser seems to be downloading woff.

neobutter avatar Jul 11 '24 10:07 neobutter

@lttr I checked with Nuxt Devtools, For woff2 there is a unicode-range, but for woff there is no unicode-range.

In this case, the browser seems to be downloading woff.

@neobutter Can you elaborate on this? I don't really understand how to workaround this.

I'm not interested in woff at all, browsers support woff2 just fine. I would even welcome a switch in the nuxt/fonts module to completely disable all formats other than woff2.

lttr avatar Jul 12 '24 12:07 lttr

@lttr You've created a new issue.

neobutter avatar Jul 22 '24 14:07 neobutter

let's track in https://github.com/nuxt/fonts/issues/204.

danielroe avatar Sep 23 '24 12:09 danielroe