How to host Google fonts in WordPress theme locally?

Download CSS with info about embedded fonts from Googleapis.com. Example link:

https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700;1,300;1,400;1,600;1,700&display=swap

Save the file right into your child theme directory so it’s now:

https://www.example.com/wp-content/themes/theme-child/fonts.css

When you open this fonts.css file, there is content which looks like this:

/* latin-ext */
 @font-face {
   font-family: 'Montserrat';
   font-style: normal;
   font-weight: 400;
   font-display: swap;
   src: url(https://fonts.gstatic.com/s/montserrat/v15/JTUSjIg1_i6t8kCHKm459Wdhyzbi.woff2) format('woff2');
   unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
 }
...

Save font from url in newly created folder fonts in your child theme and replace path in fonts.css so it’s:

src: url(wp-content/themes/theme-child/fonts/JTUSjIg1_i6t8kCHKm459Wdhyzbi.woff2) format('woff2');

In my case, there were 60+ fonts to download. Therefore, I wrote simple PHP Downloader which I will be glad to open-source if somebody asks.

Add fonts.css to your child theme

/**
 * Add local fonts 
 */
 function jasom_add_local_fonts() {
 wp_enqueue_style( 'local-fonts', get_stylesheet_directory_uri() . '/fonts.css', array(), filemtime( dirname( FILE ) . '/fonts.css' ) ); 
 }
 add_action( 'wp_print_styles', 'jasom_add_local_fonts' );

Flush all caches and check the source code for the presence of the following line:

<link rel="stylesheet" id="local-fonts-css" href="https://www.example.com/wp-content/themes/theme-child/fonts.css?ver=1607598699" type="text/css" media="all">

How to deregister existing Google Fonts out of your theme and more in the source.