Gatsby: How to preload self-hosted fonts?

Created on 3 Apr 2019  路  9Comments  路  Source: gatsbyjs/gatsby

Hi, I want to add preload for my self-hosted fonts.

Problem: Each font is requested twice.
Question: What am I doing wrong?

Env: dev

My base.scss file:

@font-face {
  font-family: 'Comfortaa';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  unicode-range: U+000-5FF;
  src: local('Comfortaa Regular'), local('Comfortaa-Regular'),
  url('../fonts/comfortaa-v19-latin-regular.woff2') format('woff2'),
  url('../fonts/comfortaa-v19-latin-regular.woff') format('woff');
}

@font-face {
  font-family: "Mont Demo";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  unicode-range: U+000-5FF;
  src: local('Mont-HeavyDEMO'),
  url('../fonts/montheavydemo.woff2') format('woff2'),
  url('../fonts/montheavydemo.woff') format('woff');
}

My seo.js file:

    <Helmet
      ...default options from gatsby
    >
      <link rel="preload"
            as="font"
            href="../fonts/comfortaa-v19-latin-regular.woff2"
            type="font/woff2"
            crossOrigin="anonymous" />
      <link rel="preload"
            as="font"
            href="../fonts/montheavydemo.woff2"
            type="font/woff2"
            crossOrigin="anonymous" />
    </Helmet>

Selection_048
Selection_049

question or discussion

Most helpful comment

Ok try this:

+ // in import section (might need to adjust path to match your directory structure)
+ import FontUrl1 from "../fonts/comfortaa-v19-latin-regular.woff2"
+ import FontUrl2 from "../fonts/montheavydemo.woff2"

// in your component
 <Helmet
      ...default options from gatsby
    >
      <link rel="preload"
            as="font"
-           href="../fonts/comfortaa-v19-latin-regular.woff2"
+           href={FontUrl1}
            type="font/woff2"
            crossOrigin="anonymous" />
      <link rel="preload"
            as="font"
-           href="../fonts/montheavydemo.woff2"
+           href={FontUrl2}
            type="font/woff2"
            crossOrigin="anonymous" />
    </Helmet>

All 9 comments

Internal Gatsby webpack configuration is adding hashes to files (that's why preload href link is not matching one for actual font file). I'm not sure yet how to solve this problem

@pieh Thanks for the answer!

Do you think it is possible to solve this with the help of a preload-webpack-plugin or something like that?

@yaroslav-perec the other thing is I think you _are_ loading the fonts twice? Once with your font-family declaration, which will perform a network request ,and again with your links? Please correct me if I鈥檓 wrong.

@merelinguist

Now this is because the Internal Gatsby webpack configuration is adding hashes to files, as mentioned earlier. If the links are the same, the fonts are downloaded once.
Good article about font optimization

I'm not sure if the preload-webpack-plugin will work because we manually contruct html file (not using any webpack plugins for that). I'm trying to figure out if we can get final url that can be used to properly construct preload href

Understood, thanks

Ok try this:

+ // in import section (might need to adjust path to match your directory structure)
+ import FontUrl1 from "../fonts/comfortaa-v19-latin-regular.woff2"
+ import FontUrl2 from "../fonts/montheavydemo.woff2"

// in your component
 <Helmet
      ...default options from gatsby
    >
      <link rel="preload"
            as="font"
-           href="../fonts/comfortaa-v19-latin-regular.woff2"
+           href={FontUrl1}
            type="font/woff2"
            crossOrigin="anonymous" />
      <link rel="preload"
            as="font"
-           href="../fonts/montheavydemo.woff2"
+           href={FontUrl2}
            type="font/woff2"
            crossOrigin="anonymous" />
    </Helmet>

@pieh

Works! Great thanks

You might be interested in my proposal here: #14281

Was this page helpful?
0 / 5 - 0 ratings