Self-Host Google Fonts Used by Your Theme and Plugins
Detects Google Fonts stylesheets loaded on your site, lets you download them to your own server from Tools > Local Google Fonts, and then serves the local copies so visitors' browsers never contact Google.
Opens WPIDE on
Code
add_filter( 'style_loader_src', function ( $src ) {
if ( ! is_string( $src ) || false === strpos( $src, 'fonts.googleapis.com' ) ) {
return $src;
}
$key = md5( html_entity_decode( $src ) );
$local = (array) get_option( 'wpide_local_gfonts', array() );
if ( ! empty( $local[ $key ] ) ) {
$uploads = wp_get_upload_dir();
return $uploads['baseurl'] . '/wpide-fonts/' . $key . '.css';
}
$found = (array) get_option( 'wpide_found_gfonts', array() );
if ( ! isset( $found[ $key ] ) && count( $found ) < 20 ) {
$found[ $key ] = html_entity_decode( $src );
update_option( 'wpide_found_gfonts', $found, false );
}
return $src;
}, 99 );
add_filter( 'wp_resource_hints', function ( $urls ) {
if ( ! get_option( 'wpide_local_gfonts' ) ) {
return $urls;
}
return array_filter( $urls, function ( $url ) {
$href = is_array( $url ) ? ( isset( $url['href'] ) ? $url['href'] : '' ) : $url;
return false === strpos( $href, 'fonts.gstatic.com' ) && false === strpos( $href, 'fonts.googleapis.com' );
} );
}, 99 );
add_action( 'admin_menu', function () {
add_management_page( 'Local Google Fonts', 'Local Google Fonts', 'manage_options', 'wpide-local-fonts', function () {
$found = (array) get_option( 'wpide_found_gfonts', array() );
$local = (array) get_option( 'wpide_local_gfonts', array() );
$uploads = wp_get_upload_dir();
$dir = trailingslashit( $uploads['basedir'] ) . 'wpide-fonts';
if ( isset( $_POST['wpide_font_key'] ) && check_admin_referer( 'wpide_local_fonts' ) && current_user_can( 'manage_options' ) ) {
$key = sanitize_key( wp_unslash( $_POST['wpide_font_key'] ) );
if ( isset( $found[ $key ] ) && wp_mkdir_p( $dir ) ) {
$agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36';
$response = wp_safe_remote_get( set_url_scheme( $found[ $key ], 'https' ), array( 'timeout' => 15, 'user-agent' => $agent ) );
$css = wp_remote_retrieve_body( $response );
$ok = 200 === wp_remote_retrieve_response_code( $response ) && false !== strpos( $css, '@font-face' );
if ( $ok && preg_match_all( '#url\((https://fonts\.gstatic\.com/[^)]+)\)#', $css, $m ) ) {
foreach ( array_unique( $m[1] ) as $font_url ) {
$file = $key . '-' . md5( $font_url ) . '.' . pathinfo( wp_parse_url( $font_url, PHP_URL_PATH ), PATHINFO_EXTENSION );
$get = wp_safe_remote_get( $font_url, array( 'timeout' => 15, 'stream' => true, 'filename' => $dir . '/' . $file ) );
if ( is_wp_error( $get ) || 200 !== wp_remote_retrieve_response_code( $get ) ) {
$ok = false;
break;
}
$css = str_replace( $font_url, $uploads['baseurl'] . '/wpide-fonts/' . $file, $css );
}
}
if ( $ok && false !== file_put_contents( $dir . '/' . $key . '.css', $css ) ) {
$local[ $key ] = time();
update_option( 'wpide_local_gfonts', $local, false );
echo '<div class="notice notice-success"><p>Fonts downloaded. Your site now serves them locally.</p></div>';
} else {
echo '<div class="notice notice-error"><p>The fonts could not be downloaded. Check that your server can reach fonts.googleapis.com.</p></div>';
}
}
}
echo '<div class="wrap"><h1>Local Google Fonts</h1>';
if ( ! $found ) {
echo '<p>No Google Fonts detected yet. Visit some pages of your site, then come back.</p></div>';
return;
}
echo '<table class="widefat striped"><thead><tr><th>Stylesheet</th><th>Status</th><th></th></tr></thead><tbody>';
foreach ( $found as $key => $url ) {
echo '<tr><td><code>' . esc_html( $url ) . '</code></td><td>' . ( isset( $local[ $key ] ) ? 'Served locally' : 'Loaded from Google' ) . '</td><td>';
echo '<form method="post">';
wp_nonce_field( 'wpide_local_fonts' );
echo '<input type="hidden" name="wpide_font_key" value="' . esc_attr( $key ) . '">';
submit_button( isset( $local[ $key ] ) ? 'Download again' : 'Download and serve locally', 'secondary small', 'submit', false );
echo '</form></td></tr>';
}
echo '</tbody></table></div>';
} );
} );
Notes
Visit a few front-end pages first so the fonts are detected; fonts loaded with @import inside a theme stylesheet are not detected.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.