Post

React Native: use custom fonts

I love to working with mobile application. Now I start mobile development for my project, and I forgot many of React Native features as well as Expo. Many of them have been updated and deprecated. So I start again from the basic. This post is for setting up the custom fonts.

Install

Install the expo-font package on your project.

1
$ expo install expo-font

Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { useEffect, useCallback } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';

export default function App() {
  const [fontsLoaded] = useFonts({
    'Inter-Black': require('./assets/fonts/Inter-Black.otf'),
  });

  /**
   * without this block:
   * fontFamily "Inter-Black" is not a system font and
   * has not been loaded throught Font.loadAsync
  */
  if (!fontsLoaded) {
    return null;
  }

  return (
    <View style={styles.container} >
      <Text style={{ fontFamily: 'Inter-Black', fontSize: 30 }}>Inter Black</Text>
      <Text style={{ fontSize: 30 }}>Platform Default</Text>
    </View>
  );
}

const styles = StyleSheet.create({ ... });

useFonts hook returns loaded and error. With the return value loaded, we must handle the case when the fonts are not loaded. (See the comment above).

For better practice, we can also import SplashScreen to continue showing the SplashScreen, when the fonts are not loaded.

Better Solution

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import { useEffect, useCallback } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';

export default function App() {
  const [fontsLoaded] = useFonts({
    'Inter-Black': require('./assets/fonts/Inter-Black.otf'),
  });

  useEffect(() => {
    /**
     * This asynchronous function prevents SplashScreen
     * from auto hiding while the fonts are loaded.
     */
    async function prepare() {
      await SplashScreen.preventAutoHideAsync();
    }

    prepare();
  }, []);

  /**
   * After the custom fonts have loaded,
   * we can hide the splash screen and display the app screen.
  */
  const onLayoutRootView = useCallback(async () => {
    if (fontsLoaded) {
      await SplashScreen.hideAsync();
    }
  }, [fontsLoaded]);

  if (!fontsLoaded) {
    return null;
  }

  return (
    <View style={styles.container} onLayout={onLayoutRootView}>
      <Text style={{ fontFamily: 'Inter-Black', fontSize: 30 }}>Inter Black</Text>
      <Text style={{ fontSize: 30 }}>Platform Default</Text>
    </View>
  );
}

const styles = StyleSheet.create({ ... });

References:

This post is licensed under CC BY 4.0 by the author.