Good day! I've been facing some issues trying to import custom fonts into a Gatsby application. I looked around the open and closed issues here and found a few different ways to import fonts, but none of them have helped me so far. Currently, I'm using the method @monsieurnebo describes in this comment.
These are the relevant files in my project's src folder:
├───fonts
│ *.otf
│ *.ttf
│ index.js
│
└───layouts
globalStyles.js
index.js
I'm importing all of my fonts in fonts/index.js, and using injectGlobal from Styled Components to add them to the stylesheet. This correctly(?) translates into CSS URLs such as http://localhost:3000/static/Futura Std - Medium-Condensed.4a67ef3b.ttf. layouts/globalStyles.js itself is being imported into layouts/index.js.
However, I don't see any of the fonts on the webpage, and the devtools don't show any network requests to those URLs. The URLs _do_ work if you manually visit them.
Here's an example font I'm using in one of my components:
fonts.js:
import FuturaStd_ExtraBold from 'fonts/Futura Std - Extra-Bold.ttf';
export {
FuturaStd_ExtraBold,
};
globalStyles.js:
import { injectGlobal } from 'styled-components';
import * as fonts from 'fonts';
export default injectGlobal`
@font-face {
font-family: 'Futura Std Web';
font-style: normal;
font-weight: 900;
src: url(${fonts.FuturaStd_ExtraBold});
}
`;
Layout -> Component -> styledComponent:
styled.header`
span {
text-transform: uppercase;
font-family: 'Futura Std Web';
font-size: 3.2rem;
font-weight: 900;
color: black;
}
`;
I've tried a couple other methods of importing the fonts (pure CSS, uh, actually that's about it) and none of them have worked. I'm not really sure as to what could be wrong, and any help would be great.
package.json:
{
"scripts": {
"dev": "gatsby develop -p 3000",
"format": "prettier --write 'src/**/*.js'",
"build": "gatsby build"
},
"dependencies": {
"babel-plugin-styled-components": "^1.5.1",
"gatsby": "^1.9.241",
"gatsby-link": "^1.6.39",
"gatsby-plugin-react-helmet": "^2.0.8",
"gatsby-plugin-styled-components": "^2.0.11",
"react-helmet": "^5.2.0",
"react-particles-js": "^2.1.1",
"styled-components": "^3.2.3",
"styled-normalize": "^4.0.0",
"three": "^0.91.0"
},
"devDependencies": {
"prettier": "^1.11.1"
}
}
gatsby-config.js (+ Styled Components support):
module.exports = {
siteMetadata: {
title: 'intrnt-dolphin/mannielikes.design',
},
plugins: [
'gatsby-plugin-react-helmet',
'gatsby-plugin-styled-components',
],
};
gatsby-node.js (resolving src for absolute component reference, would adding .ttf and .otf help here? I tried a moment ago but it didn't seem to change anything):
const path = require('path');
exports.modifyWebpackConfig = ({ config, env }) => {
config.merge({
resolve: {
root: path.resolve(__dirname, './src'),
extensions: [ '', '.js', '.json' ],
},
});
return config;
};
npm list gatsby): 1.9.241gatsby --version): 1.1.498.10.0Windows 10 (x64)What does the injected @fontface styles in your HTML look like?
Hah. You did it. I switched from what I previously had in injectGlobals.js to this:
@font-face {
font-family: 'Futura Std Web';
font-style: normal;
font-weight: 900;
src: url('${fonts.FuturaStd_ExtraBold}');
}
Webpack was spitting out font URLs with spaces in them. I distinctly remember checking the styles injected into the HTML for the correct path, but not whether they had spaces or quotes around them.
Thank you very much. Closing the issue.
I'm still pretty confused with this @KyleAMathews -- sorry if i pinged another message with you in it earlier this AM. I have a simple gatsby landing page with no more than 3 components. there's two distinct .ttf i'm loading in via CSS. The fonts render correctly in chrome and safari, but the fonts do not render in desktop FF, or any browser on iOS. Been trying to figure this issue out for a few hours now. I even tried the typography.js way but the result is exactly the same.
@tetreault can you see the font files in Firefox's Network inspector? Are they being downloaded?
@m-allanson thanks for the reply! they were not being downloaded at all, it was extremely odd. in the end, thankfully these were google fonts and i was able to use the typeface node module to import them so my client worry is over. I am genuinely curious why my normal/standard CSS import wasn't working though, especially when I could view the generated files from npm run build.
Did you confirm that it wasn't the same issue I had? What are the paths the compiled CSS is looking for on the live page? Do the font files have spaces in their name? Are there quotes around the file imports?
@intrnt-dolphin the fonts were rendering in desktop chrome and desktop safari but not desktop FF nor any of the mobile browsers. they were just standard google fonts, paths correct (especially the generated ones from the build process) and no spaces in their name.
I can think of only two points of failures: your imports, and the usage. If you think the imports are clear, then it's possible that the usage is somehow off. Could you try modifying the font name when pulling into CSS to something that won't clash with any system fonts (i.e. "Helvetica" to "Helvetica Web")? I doubt that's your problem, but that's all I can think of off the top of my head.
I can't get custom fonts to work (neither with gatsby develop nor gatsby build).
Like for @tehkaiyu there is no network request being made to load the font file. Doesn't work for any browser. If the font is (pre-)installed on the system, it's getting displayed correctly.
I have the same project structure as @intrnt-dolphin
├───fonts
│ futura-light.ttf
│ index.js
│
└───layouts
globalStyles.js
index.js
The relevant files look as follows
// src/fonts/index.js
import FuturaLightTTF from "./futura-light.ttf"
export { FuturaLightTTF }
// src/layouts/globalStyles.js
import { injectGlobal } from 'styled-components'
import * as fonts from '../fonts'
console.log(fonts.FuturaLightTTF) // <-- "http://localhost:8000/static/futura-light.0595c32d.ttf"
export default injectGlobal`
@font-face {
font-family: 'Futura-Light';
font-style: normal;
font-weight: 300;
src: local('Futura Light'), local('Futura-Light'), url(${fonts.FuturaLightTTF}) format('ttf');
}
body {
font-family: 'Futura-Light';
}
// etc...
`
// src/layouts/index.js
import './globalStyles'
// etc...
When I visit http://localhost:8000/static/futura-light.0595c32d.ttf the browser automatically downloads my font, so font hosting seems ok.
Seeking for help.
This is actually the only issue that has stopped me from using gatsby on more projects that dont have purely google fonts (as absolutely crazy as that sounds). I couldn't get it working either on a separate project with fonts we purchased, but if its a google font then it works great using the node modules for them. If I don't have to worry about something as trivial as handling fonts with something like Nuxt for Vue, that matters IMO
Two suggestions. @asterikx One's a complete shot in the dark and other might have something do with Styled Component's injectGlobal.
In my case, my font's file name had spaces and surrounding ${fonts.*} in the url() call with single quotes helped. I doubt that's your issue, but still, check to make sure something funky isn't happening on that front.
Also, are the rest of your styles from injectGlobal being applied properly? I don't see anything wrong with your usage, but check to make sure there isn't some odd discrepancy -- that's the only other thing I can imagine that might be non-Gatsby-specific.
All else fails, it is most likely something wrong with Gatsby -- which feels hard to imagine as I haven't seen any other issues related to fonts crop up since my initial incident with it.
Thanks for your help @intrnt-dolphin. Unfortunately this didn't solve my issue. I already tried surrounding it by single quotes (and double quotes) without success.
Yes, the rest of my injectGlobal styles are applied correctly. If I remove everything but the font related parts, my site looks broken because of it, but the font is still not working.
// src/layouts/globalStyles.js
import { injectGlobal } from 'styled-components'
import * as fonts from '../fonts'
console.log(fonts.FuturaLightTTF) // <-- "http://localhost:8000/static/futura-light.0595c32d.ttf"
export default injectGlobal`
@font-face {
font-family: 'Futura-Light';
font-style: normal;
font-weight: 300;
src: local('Futura Light'), local('Futura-Light'), url('${fonts.FuturaLightTTF}') format('ttf');
}
body {
font-family: 'Futura-Light';
}
`
I had the same problem and for me, there was something wrong with the name of the font. I renamed the font files and removed all ()_- characters and left only alphabetic characters and the issue is gone.
Most helpful comment
This is actually the only issue that has stopped me from using gatsby on more projects that dont have purely google fonts (as absolutely crazy as that sounds). I couldn't get it working either on a separate project with fonts we purchased, but if its a google font then it works great using the node modules for them. If I don't have to worry about something as trivial as handling fonts with something like Nuxt for Vue, that matters IMO