diff --git a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts index 043c09ca91b29..a3fff7d54fa99 100644 --- a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts +++ b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts @@ -106,7 +106,7 @@ export class FontStylesheetGatheringPlugin { !props.rel || props.rel !== 'stylesheet' || !props.href || - !OPTIMIZED_FONT_PROVIDERS.some((url) => + !OPTIMIZED_FONT_PROVIDERS.some(({ url }) => props.href.startsWith(url) ) ) { diff --git a/packages/next/next-server/lib/constants.ts b/packages/next/next-server/lib/constants.ts index eed0b3877ba92..8d2dc6ba86db4 100644 --- a/packages/next/next-server/lib/constants.ts +++ b/packages/next/next-server/lib/constants.ts @@ -37,8 +37,9 @@ export const TEMPORARY_REDIRECT_STATUS = 307 export const PERMANENT_REDIRECT_STATUS = 308 export const STATIC_PROPS_ID = '__N_SSG' export const SERVER_PROPS_ID = '__N_SSP' +export const GOOGLE_FONT_PROVIDER = 'https://fonts.googleapis.com/css' export const OPTIMIZED_FONT_PROVIDERS = [ - 'https://fonts.googleapis.com/css', - 'https://use.typekit.net/', + { url: GOOGLE_FONT_PROVIDER, preconnect: 'https://fonts.gstatic.com' }, + { url: 'https://use.typekit.net', preconnect: 'https://use.typekit.net' }, ] export const STATIC_STATUS_PAGES = ['/500'] diff --git a/packages/next/next-server/lib/post-process.ts b/packages/next/next-server/lib/post-process.ts index 2a448f64bab56..04c9ad8225720 100644 --- a/packages/next/next-server/lib/post-process.ts +++ b/packages/next/next-server/lib/post-process.ts @@ -82,7 +82,7 @@ class FontOptimizerMiddleware implements PostProcessMiddleware { (tag: HTMLElement) => tag.getAttribute('rel') === 'stylesheet' && tag.hasAttribute('data-href') && - OPTIMIZED_FONT_PROVIDERS.some((url) => { + OPTIMIZED_FONT_PROVIDERS.some(({ url }) => { const dataHref = tag.getAttribute('data-href') return dataHref ? dataHref.startsWith(url) : false }) @@ -104,6 +104,8 @@ class FontOptimizerMiddleware implements PostProcessMiddleware { options: renderOptions ) => { let result = markup + let preconnectUrls = new Set() + if (!options.getFontDefinition) { return markup } @@ -132,9 +134,27 @@ class FontOptimizerMiddleware implements PostProcessMiddleware { '', `` ) + + const provider = OPTIMIZED_FONT_PROVIDERS.find((p) => + url.startsWith(p.url) + ) + + if (provider) { + preconnectUrls.add(provider.preconnect) + } } }) + let preconnectTag = '' + preconnectUrls.forEach((url) => { + preconnectTag += `` + }) + + result = result.replace( + '', + preconnectTag + ) + return result } } diff --git a/packages/next/next-server/server/font-utils.ts b/packages/next/next-server/server/font-utils.ts index 4d4b25dbe9425..6e2b9cfee6a3a 100644 --- a/packages/next/next-server/server/font-utils.ts +++ b/packages/next/next-server/server/font-utils.ts @@ -1,4 +1,5 @@ import * as Log from '../../build/output/log' +import { GOOGLE_FONT_PROVIDER } from '../lib/constants' const https = require('https') const CHROME_UA = @@ -10,6 +11,10 @@ export type FontManifest = Array<{ content: string }> +function isGoogleFont(url: string): boolean { + return url.startsWith(GOOGLE_FONT_PROVIDER) +} + function getFontForUA(url: string, UA: string): Promise { return new Promise((resolve, reject) => { let rawData: any = '' @@ -45,7 +50,9 @@ export async function getFontDefinitionFromNetwork( * CSS cascading 🤷‍♂️. */ try { - result += await getFontForUA(url, IE_UA) + if (isGoogleFont(url)) { + result += await getFontForUA(url, IE_UA) + } result += await getFontForUA(url, CHROME_UA) } catch (e) { Log.warn( diff --git a/packages/next/pages/_document.tsx b/packages/next/pages/_document.tsx index d3a486a0e4de9..9faa6ebfd7414 100644 --- a/packages/next/pages/_document.tsx +++ b/packages/next/pages/_document.tsx @@ -447,7 +447,9 @@ export class Head extends Component< if ( c.type === 'link' && c.props['href'] && - OPTIMIZED_FONT_PROVIDERS.some((url) => c.props['href'].startsWith(url)) + OPTIMIZED_FONT_PROVIDERS.some(({ url }) => + c.props['href'].startsWith(url) + ) ) { const newProps = { ...(c.props || {}) } newProps['data-href'] = newProps['href'] @@ -639,6 +641,9 @@ export class Head extends Component< )} {children} + {process.env.__NEXT_OPTIMIZE_FONTS && ( + + )} {head} { /