nuxt / fonts

Plug-and-play web font optimization and configuration for Nuxt apps.
https://fonts.nuxt.com
MIT License
449 stars 7 forks source link

Question: How to fetch only woff2 format? #195

Closed lttr closed 1 month ago

lttr commented 4 months ago

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:

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

dosubot[bot] commented 4 months ago

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.

lttr commented 4 months ago

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 commented 4 months ago

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

dosubot[bot] commented 4 months ago

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.

neobutter commented 4 months ago

@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.

lttr commented 4 months ago

@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.

neobutter commented 3 months ago

@lttr You've created a new issue.

danielroe commented 1 month ago

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