expo: Unhandled Rejection (Error): Expected font asset of type `string | FontResource | Asset` (number is not supported on web) instead got: null

šŸ› Bug Report

Summary of Issue

Unable to load any fonts using Font.loadAsync or useFonts

Environment - output of expo diagnostics & the platform(s) you’re targeting

Expo CLI 3.22.0 environment info:
    System:
      OS: Windows 10 10.0.18363
    Binaries:
      Node: 12.16.1 - C:\Program Files\nodejs\node.EXE
      Yarn: 1.22.4 - C:\Program Files\nodejs\yarn.CMD
      npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD
    IDEs:
      Android Studio: Version  3.5.0.0 AI-191.8026.42.35.6010548
    npmPackages:
      expo: ~38.0.8 => 38.0.8
      react: ~16.11.0 => 16.11.0
      react-dom: ~16.11.0 => 16.11.0
      react-native: https://github.com/expo/react-native/archive/sdk-38.0.1.tar.gz => 0.62.2
      react-native-web: ~0.11.7 => 0.11.7

Reproducible Demo

Font.loadAsync({
                // This is the font that we are using for our tab bar
                //...Icon.Ionicons.font,
                // We include SpaceMono because we use it in HomeScreen.js. Feel free
                // to remove this if you are not using it in your app
                'CenturyGothic': require('./assets/fonts/CenturyGothic.ttf'),
                'CenturyGothicRegular': require('./assets/fonts/CenturyGothic-Regular.ttf'),
                'Roboto': require('native-base/Fonts/Roboto.ttf'),
                'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
                ...Ionicons.font,
            }).then((result) => {
                console.log("Fonts Loaded");
                this.setState({fontLoaded: true});

            })

Steps to Reproduce

Expected Behavior vs Actual Behavior

Expecting the fonts to load in the web expo, currently does not. Using latest Expo SDK 38.0.8

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 22 (7 by maintainers)

Most upvoted comments

I seemed to have created a fix for it. Seems to fix it.

if you import like so. Then it runs.

import Roboto from '../node_modules/native-base/Fonts/Roboto.ttf';
import Roboto_medium from '../node_modules/native-base/Fonts/Roboto_medium.ttf';
import Ionicons from '../node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Ionicons.ttf';

class App extends React.Component {
  constructor() {
    super();
    this.state = { loading: true };
  }

  async componentDidMount() {
    await Font.loadAsync({
      Roboto: {
        uri: Roboto,
        fontDisplay: FontDisplay.SWAP,
      },
      Roboto_medium: {
        uri: Roboto_medium,
        fontDisplay: FontDisplay.SWAP,
      },
      Ionicons: {
        uri: Ionicons,
        fontDisplay: FontDisplay.SWAP,
      },
    });

    this.setState({ loading: false });
  }

Can’t explain why, but this pattern seems to satisfy the requirements for the Expo Web build. Although this is not what the docs say to load it as. Maybe its worth noting this in the docs.

has anyone been able to find a solution to this? it is still happening, and the solution proposed is not working for me

If you’re using expo-vector-icons, FontAwesome5 triggers it

thanks to @JUDOKICK reply I was able to get this to work on the web.

I’ve created the following custom hook for loading the resources.

useResources.ts

import * as Font from 'expo-font';
import { useEffect, useState } from 'react';

import YOUR_FONT_FILE_HERE from '/path/to/fonts/FONT_NAME.ttf';

export const useResources = () => {
  const [isFontReady, setIsFontReady] = useState(false);

  const loadFontAsync = async () => {
    try {
      await Font.loadAsync({
        HindRegular: {
          uri: YOUR_FONT_FILE_HERE as any,
          display: Font.FontDisplay.SWAP,
        }
      });
    } catch (error) {
      console.log('Font Load Error:', error)
    } finally {
      setIsFontReady(true);
    }
  }

  useEffect(() => {
    loadFontAsync();
  }, []);

  return {
    isFontReady
  }
};

Usage

export default function App() {
  const { isFontReady } = useResources();

  if (!isFontReady) {
    return (
      <View>
        <Text>Resources are loading...</Text>
      </View>
    )
  }
  
  return (
    <View style={styles.container}>
      <Text style={styles.text}>Welcome to Expo + Next.js šŸ‘‹</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  text: {
    fontSize: 16,
    fontFamily: 'YOUR_FONT_NAME_HERE' <----- HERE
  },
});

issue is still happening on FontAwesome5

I am building a Next.js expo integrated project. Ionicons or Fontawesome work fine, only Fontawesome5 breaks.

I’ve also created a barebones app demonstrating the issue.

https://github.com/JUDOKICK/expo-font-loadasync

It recreates no problem. Seems to be consistent now. When you run expo start:web It gives the unhandled rejection error.

Hmm, if we can’t reproduce this it’s not really possible for us to find the issue here. You can try debugging this yourself by removing all fonts and render a placeholder. After that, you can add the fonts back 1 by 1 to see from when this issue occurs. But again, without being able to reproduce this we can’t help that much.

This has been fixed in https://github.com/expo/expo-cli/pull/2346 we will publish the fix promptly.

I too had this problem. Thanks for the fix @JUDOKICK.

I then found the problem is in require.

Not related I think, but I realized that my images stopped loading. I then replaced where I’m using require with import in the top, and now its working. Very weird…

Awesome, thanks for digging into this. I think I might know why this is happening, inline require might be handled as dynamic import in Webpack. If this happens, the require method returns a promise instead of the icon resource itself. This is something we can investigate and work on, thanks! The workaround looks great, it shouldn’t behave differently on native as well so good find!

Let’s keep this open until it’s resolved.

Here’s a flat boilerplate that demonstrates the issue perfectly. Its completely unable to open in Web due to the fonts not loading.

https://github.com/mcnamee/react-native-expo-starter-kit