lib/util/fonts/downloadGoogleFonts.js
async function downloadGoogleFonts(
  fontProps,
  { formats = ['woff2', 'woff'], fontDisplay = 'swap', text } = {}
) {
  const sortedFormats = [];

  for (const format of formatOrder) {
    if (formats.includes(format)) {
      sortedFormats.push(format);
    }
  }

  const result = {};
  const googleFontId = getGoogleIdForFontProps(fontProps);
  let fontCssUrl = `https://fonts.googleapis.com/css?family=${googleFontId}`;

  if (text) {
    fontCssUrl += `&text=${encodeURIComponent(text)}`;
  }

  result.src = await Promise.all(
    sortedFormats.map(async format => {
      const assetGraph = new AssetGraph();
      assetGraph.teepee.headers['User-Agent'] = formatAgents[format];

      const [cssAsset] = await assetGraph.loadAssets(fontCssUrl);

      await assetGraph.populate();

      const [fontRelation] = assetGraph.findRelations({
        from: cssAsset,
        type: 'CssFontFaceSrc'
      });

      fontRelation.node.each(decl => {
        if (decl.prop !== 'src') {
          result[decl.prop] = decl.value;
        }
      });

      return [fontRelation.to, fontRelation.format];
    })
  );

  if (!('unicode-range' in result)) {
    const font = result.src[0][0];
    result['unicode-range'] = unicodeRange(
      fontkit.create(font.rawSrc).characterSet
    );
  }

  result['font-display'] = fontDisplay;

  // Output font face declaration object as CSS
  const declarationStrings = [];

  for (const [property, value] of Object.entries(result)) {
    if (property !== 'src') {
      declarationStrings.push(`  ${property}: ${value};`);
    }
  }

  const sources = result.src.map(([font, format]) => {
    return `url('${font.dataUrl}') format('${format}')`;
  });

  declarationStrings.push(`  src: \n       ${sources.join(',\n       ')};`);

  return ['@font-face {', ...declarationStrings, '}'].join('\n');
}
async function downloadGoogleFonts(
  fontProps,
  { formats = ['woff2', 'woff'], fontDisplay = 'swap', text } = {}
) {
  const sortedFormats = [];

  for (const format of formatOrder) {
    if (formats.includes(format)) {
      sortedFormats.push(format);
    }
  }

  const result = {};
  const googleFontId = getGoogleIdForFontProps(fontProps);
  let fontCssUrl = `https://fonts.googleapis.com/css?family=${googleFontId}`;

  if (text) {
    fontCssUrl += `&text=${encodeURIComponent(text)}`;
  }

  result.src = await Promise.all(
    sortedFormats.map(async format => {
      const assetGraph = new AssetGraph();
      assetGraph.teepee.headers['User-Agent'] = formatAgents[format];

      const [cssAsset] = await assetGraph.loadAssets(fontCssUrl);

      await assetGraph.populate();

      const [fontRelation] = assetGraph.findRelations({
        from: cssAsset,
        type: 'CssFontFaceSrc'
      });

      fontRelation.node.each(decl => {
        if (decl.prop !== 'src') {
          result[decl.prop] = decl.value;
        }
      });

      return [fontRelation.to, fontRelation.format];
    })
  );

  if (!('unicode-range' in result)) {
    const font = result.src[0][0];
    result['unicode-range'] = unicodeRange(
      fontkit.create(font.rawSrc).characterSet
    );
  }

  result['font-display'] = fontDisplay;

  // Output font face declaration object as CSS
  const declarationStrings = [];

  for (const [property, value] of Object.entries(result)) {
    if (property !== 'src') {
      declarationStrings.push(`  ${property}: ${value};`);
    }
  }

  const sources = result.src.map(([font, format]) => {
    return `url('${font.dataUrl}') format('${format}')`;
  });

  declarationStrings.push(`  src: \n       ${sources.join(',\n       ')};`);

  return ['@font-face {', ...declarationStrings, '}'].join('\n');
}
async function downloadGoogleFonts ( fontProps , { formats = [ 'woff2' , 'woff' ] , fontDisplay = 'swap' , text } = { } ) { const sortedFormats = [ ] ; for ( const format of formatOrder ) { if ( formats . includes ( format ) ) { sortedFormats . push ( format ) ; } } const result = { } ; const googleFontId = getGoogleIdForFontProps ( fontProps ) ; let fontCssUrl = ` ${ googleFontId } ` ; if ( text ) { fontCssUrl += ` ${ encodeURIComponent ( text ) } ` ; } result . src = await Promise . all ( sortedFormats . map ( async format => { const assetGraph = new AssetGraph ( ) ; assetGraph . teepee . headers [ 'User-Agent' ] = formatAgents [ format ] ; const [ cssAsset ] = await assetGraph . loadAssets ( fontCssUrl ) ; await assetGraph . populate ( ) ; const [ fontRelation ] = assetGraph . findRelations ( { from : cssAsset , type : 'CssFontFaceSrc' } ) ; fontRelation . node . each ( decl => { if ( decl . prop !== 'src' ) { result [ decl . prop ] = decl . value ; } } ) ; return [ fontRelation . to , fontRelation . format ] ; } ) ) ; if ( ! ( 'unicode-range' in result ) ) { const font = result . src [ 0 ] [ 0 ] ; result [ 'unicode-range' ] = unicodeRange ( fontkit . create ( font . rawSrc ) . characterSet ) ; } result [ 'font-display' ] = fontDisplay ; // Output font face declaration object as CSS const declarationStrings = [ ] ; for ( const [ property , value ] of Object . entries ( result ) ) { if ( property !== 'src' ) { declarationStrings . push ( ` ${ property } ${ value } ` ) ; } } const sources = result . src . map ( ( [ font , format ] ) => { return ` ${ font . dataUrl } ${ format } ` ; } ) ; declarationStrings . push ( ` \n ${ sources . join ( ',\n       ' ) } ` ) ; return [ '@font-face {' , ... declarationStrings , '}' ] . join ( '\n' ) ; }
Download google fonts for self-hosting

@async
@param  {FontProps} fontProps CSS font properties to get font for
@param  {Object} options
@param  {String[]} [options.formats=['woff2', 'woff']] List of formats that should be inclued in the output
@param  {String} [options.fontDisplay='swap'] CSS font-display value in returned CSS blocks
@param  {String} [options.text] Text to create a subset with
@return {String} CSS asset with inlined google fonts
Download google fonts for self - hosting