'Can't seem to load custom fonts with Expo's Font.loadAsync
I'm using React Native with Expo, and it is all going well except for this one issue with custom fonts. I have my font Lobster-Regular.ttf
in ./assets/fonts, and I have been trying to load it as seen in the official docs:
componentDidMount() {
Font.loadAsync({
'Lobster': require('./assets/fonts/Lobster-Regular.ttf'),
});
}
I then style my header as such:
headerText: {
color: 'white',
fontSize: 30,
fontFamily: 'Lobster'
},
All I get is
fontFamily 'Lobster' is not a system font and has not been loaded through Font.loadAsync.
If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system.
If this is a custom font, be sure to load it with Font.loadAsync.
Am I missing something?
Solution 1:[1]
Yes. You are missing that the call is Font.loadAsync()
. This means that it loads asynchronously. As in: It takes a while. You can't render the UI until the font has loaded. You need to do something along these lines:
import { AppLoading, Font } from 'expo'
state = {
fontsLoaded: false,
...
}
componentWillMount() {
Font.loadAsync( {
'Lobster': require('./assets/fonts/Lobster-Regular.ttf')
}
).then( () => this.setState( { fontsLoaded: true } ) )
}
render() {
if( !this.state.fontsLoaded ) {
return <AppLoading/>
}
return (
...
)
}
Solution 2:[2]
Font.loadAsync is old and proved to have unpredictable problems. now expo have rolled out new solutions here
so the correct code is now:
import {useFonts} from 'expo-font';
import AppLoading from "expo-app-loading";
let [fontsLoaded] = useFonts({
'Lobster': require('./assets/fonts/Lobster-Regular.ttf'),
});
if (!fontsLoaded) {
return <AppLoading/>;
}
...
Solution 3:[3]
install expo-font package from expo CLI because sometime expo-font version is not compatible with your expo version so,
step 1:
expo install expo-font
step 2:
class App extends React.Component {
state = {
fontLoaded: false,
};
componentDidMount() {
this.loadAssetsAsync();
}
async loadAssetsAsync() {
await Font.loadAsync({
// Load a font `Montserrat` from a static resource
MuseoSans500: require("./assets/fonts/museosans_500-webfont.ttf"),
MuseoSans700: require("./assets/fonts/museosans_700-webfont.ttf"),
});
this.setState({ fontLoaded: true });
}
render() {
if (!this.state.fontLoaded) {
return null; // render some progress indicator
}
return <AnyComponent />;
}
}
Solution 4:[4]
** react-native font in stateless function **
**step:1 import font from expo **
import * as Font from 'expo-font';
import { AppLoading } from 'expo';
*step2: require font from files *
// fetchFonts from local files type ttf
const fetchFonts = () => {
return Font.loadAsync({
'PacificoRegular': require('../assets/Pacifico/Pacifico-Regular.ttf'),
});
};
*****step3:use state *****
// state font fetch control
const [fontloaded,setfontloaded]=useState(false);
**step4: use app loaded **
if(!fontloaded){
return(
<AppLoading
startAsync={fetchFonts}
onFinish={()=>{setfontloaded(true)}}
onError={console.warn}/>
)
}
**step5:style font **
txt:{
padding:5,
fontSize:18,
fontFamily: 'PacificoRegular',
}
Solution 5:[5]
useEffect(()=>{
async function loadFonts(){
await Font.loadAsync({
'Montserrat': require("./assets/fonts/Montserrat/Montserrat-Regular.ttf"),
'Montserrat-SemiBold': require('./assets/fonts/Montserrat/Montserrat-SemiBold.ttf'),
'Montserrat-Bold': require('./assets/fonts/Montserrat/Montserrat-Bold.ttf'),
'Fascinate': require('./assets/fonts/Fascinate/Fascinate-Regular.ttf')
}).then(res=>{
console.log("FONTS LOADED!");
setLoaded(true)
}).catch(Err=>{
setLoaded(true);
console.log(Err);
});
}
loadFonts();
},[])
Load using this useEffect in your App.js file, once loaded the fonts can be used anywhere in your expo or react-native project
const Heading = (color) => {
return({fontSize:45*fontScale, fontFamily: "Montserrat-SemiBold", color, marginTop: -10, marginLeft: InitialMargin, letterSpacing: 4})
}
Make sure you are not using the style fontWeight, as it will override the fontStyle and will not apply the fontFamily to your Text.
Solution 6:[6]
Because 'startAsync' is depreacted from the component AppLoading,
we can use coustom fonts as bellow,
This code works fine.
I think <Apploading> causes no further instructions to be
performed until the font is loaded
===============================================
import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import React ,{useState}from 'react';
export default function App() {
const [fontLoading,setFontLoading]=useState(false);
Font.loadAsync( {
yekan:require("./myapp/fonts/byekan.ttf"),
ih:require("./myapp/fonts/ih.ttf")
}
).then( () => setFontLoading('true') )
if (!fontLoading){
return(
<AppLoading/>);
} else{
return(
do someting.....
............
)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Ken |
Solution 3 | |
Solution 4 | |
Solution 5 | |
Solution 6 |