Skip to content

Google Fonts (Beta) module disables core wp_print_font_faces() and drops/overrides theme.json fonts on the front end #50180

Description

@iamtakashi

Impacted plugin

Jetpack

Quick summary

The Google Fonts module is deprecated (WP 6.5+ supports fonts natively) but still ships and, wherever it's active, removes core's native font-face printing and substitutes its own "in-use only" printer. This causes two front-end regressions for themes that register a font via theme.json:

  1. The font disappears if the font-family usage value includes a fallback stack (var(--wp--preset--font-family--slug), system-ui, …) instead of a bare var(...) — the in-use scan misses it and prints nothing for that family.
  2. Even when it "works," the wrong font paints — the module injects its own fonts.wp.com copy of the same-named family alongside the theme's bundled file: faces, so visitors get Google's hosted version instead of the file the theme ships.

Both render fine in the Site Editor; only the front end is affected, and no warning is emitted.

Steps to reproduce

  1. Block theme registers a font in theme.json with a bundled fontFace (src: ["file:./…/InterVariable.woff2"], slug inter).
  2. Reference it in styles with a fallback stack:
"styles": { 
   "typography": {
      "fontFamily": "var(--wp--preset--font-family--inter), system-ui, sans-serif"
    }
}
  1. Enable the Google Fonts module; view the front end (logged out / cache bypassed)

Expected: the @font-face prints and the bundled font loads (as core wp_print_font_faces() does when the module is off).
Actual: no @font-face prints for that family; it falls back to a system font.

Site owner impact

More than 60% of the total website/platform users

Severity

Moderate

What other impact(s) does this issue have?

No response

If a workaround is available, please outline it here.

A) Toggle the module, holding theme.json constant (compound usage as above). Isolates the module as the cause:

Google Fonts module Front-end result
ON 0 @font-face, no wp-fonts-local, font gone → system fallback Image
OFF core wp-fonts-local prints the theme's InterVariable faces, font restored Image

Same theme, same theme.json — the font's presence tracks the module exactly.

B) Hold the module ON, vary only the usage value. Isolates the compound-value trigger:

styles…fontFamily usage Front-end @font-face
var(--wp--preset--font-family--inter) (bare) 11 (9 fonts.wp.com + 2 theme faces) — works
var(--wp--preset--font-family--inter), system-ui, … (compound) 0 — system fallback

C) Font substitution (bare usage, so the font is present; toggle only the module). Even when it "works," the module changes which font paints:

Module Face that paints "Handgloves wwiill 12345" @ 60px / wt 300
OFF theme's bundled InterVariable.woff2 ~623px
ON Jetpack fonts.wp.com Inter (v13 static) ~691px
On Off
Image Image

Root cause

Jetpack_Google_Font_Face (projects/plugins/jetpack/modules/google-fonts/current/class-jetpack-google-font-face.php) removes core/Gutenberg printing on wp_loaded:

remove_action( 'wp_head', 'wp_print_font_faces', 50 );
remove_action( 'wp_head', 'gutenberg_print_font_faces', 50 );

then prints only fonts detected in use. Slug detection is anchored to a trailing ):

// get_font_slug_from_setting()
preg_match( '/font-family--(?P<slug>.+)\)$/', $font_family, $matches );

A compound value doesn't end in ), so detection fails, the family isn't in $fonts_in_use, and — with core's printer already removed — nothing prints for it. Separately, print_font_faces() emits the module's fonts.wp.com faces for detected families even when the theme already registers that family with a local file: source, so the hosted copy wins over the bundled file.

Suggested fix

Since the module is deprecated in favor of native WP fonts, it should not remove core wp_print_font_faces() on WP ≥ 6.5 — defer to native, or auto-skip when native font support is present. At minimum:

  • Make in-use detection tolerant of compound values — parse the leading var(--wp--preset--font-family--<slug>) token instead of anchoring to )$ (e.g. drop $ / split on ,).
  • Fall through to core for theme-registered file: faces the module doesn't manage, so a detection miss degrades gracefully instead of dropping a shipped font.
  • Don't inject a fonts.wp.com copy for a family the theme already registers with a local file: source.

I noticed this while I'm working on a theme in an Atomic site. Claude help me to write this.

Platform (Simple and/or Atomic)

Simple, Atomic, Self-hosted

Metadata

Metadata

Assignees

Labels

BugWhen a feature is broken and / or not performing as intendedNeeds triageTicket needs to be triaged

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions