'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.ttfin ./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