Importing fonts with SDK 32

Hello,

As always, thanks for all the work with Expo. It is a great tool and has helped me a lot.

I recently upgraded to SDK 32 and I received an error report from Sentry for my app, saying:

Error: Font.loadAsync unexpected exception: Font not found

I believe it has something to do with the changes in your post on SDK 32:

Similarly, in the expo-font module we’ve deprecated the import { Font } from 'expo-font'; syntax in favor of individually named exports ( import * as Font from 'expo-font'; ). Upgrade @expo/vector-icons if you get a warning about this.

I currently use this in App.js:

import { AppLoading, Font } from 'expo';

Should I replace it with this?

import { AppLoading } from 'expo';
import * as Font from 'expo-font';

And is it literally an asterisk I should put, or replace it with the font name(s)?

Also, your post says:

We’ve also removed deprecated support for passing an array into Font.loadAsync. This feature displayed a deprecation warning for several SDK versions so if you didn’t see it, this change shouldn’t affect you.

In my App.js I load an object (not an array) with my icons, so is that still OK?

export default class App extends React.Component {
  state = {
    fontLoaded: false
  };
  async UNSAFE_componentWillMount() {
    try {
      // Bugfix: We include 'Material Icons' as well so that icons show when viewed through Expo (when in development)
      // See here: https://github.com/react-native-training/react-native-elements/issues/1005#issuecomment-373689090
      // See here: https://javascriptrambling.blogspot.com/2018/03/expo-icon-fonts-with-react-native-and.html
      await Font.loadAsync({
        'Material Icons': require('@expo/vector-icons/fonts/MaterialIcons.ttf'),
        MaterialIcons,
        FontAwesome,
        Ionicons
      });
      this.setState({ fontLoaded: true });
    } catch (error) {
      // console.log('error loading icon fonts', error);
    }
  }
  render() {
    if (!this.state.fontLoaded) {
      return <AppLoading />;
    }
    return <Root store={store} persistor={persistor} />;
  }
}

Thanks in advance for any help you can provide.

Ran into this yesterday. Yes, it’s an actual * and an object should work fine. Here’s what my component looks like (removed a bunch of the redux-y stuff).

import React, { Component } from 'react';
import { AppLoading } from 'expo';
import * as Font from 'expo-font';
import _ from 'lodash';

export class AuthLoading extends Component {
  constructor(props) {
    super(props);

    this.cacheResourcesAsync = this.cacheResourcesAsync.bind(this);
  }

  async cacheResourcesAsync() {
    await Font.loadAsync({
      'parisienne-regular': require('../assets/fonts/parisienne/Parisienne-Regular.ttf'),
      'poppins-regular': require('../assets/fonts/poppins/Poppins-Regular.ttf'),
      'poppins-medium': require('../assets/fonts/poppins/Poppins-Medium.ttf'),
      'poppins-bold': require('../assets/fonts/poppins/Poppins-Bold.ttf'),
      'poppins-light': require('../assets/fonts/poppins/Poppins-Light.ttf')
    });

    // After fonts loaded actions
  }

  render() {
    return (
      <AppLoading
        startAsync={this.cacheResourcesAsync}
        onFinish={() => console.log('finished')}
        onError={console.warn}
      />
    );
  }
}

Thanks very much @mwood23 for the detailed reply. I’ve updated my app as suggested, and hopefully I won’t be seeing that error anymore in my logs (I personally never saw it in my testing so will need to rely on Sentry).

Thanks again.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.