DEV Community

loading...
Cover image for How to use custom fonts in React-Native.

How to use custom fonts in React-Native.

ReenyDavidson
・4 min read

Have you tried using font-family in react-native and it didn't seem to work? It's fine, you have nothing to worry about. The pattern used to render a font in CSS for the web is quite different from the way you will render it in a react-native app. LET'S DIVE IN!

To render a custom font in a react-native app, two main libraries are needed. These libraries are:

  1. expo-font
  2. expo-app-loading

expo-font

expo-font is a library that allows one to load fonts from the web and use it in a react-native component. It does this with the help of a method called loadAsync. To use expo-font, we will need to install it with expo.

expo install expo-font
Enter fullscreen mode Exit fullscreen mode

expo-app-loading

While the font from expo-font is still loading, expo-app-loading makes sure that a loading screen component or splash screen is running or being displayed. Once the font is loaded, it automatically allows the component with the font in it to display and allows the loading screen or splash screen to unmount. It does this with the help of a component called Apploading. We can use it by installing expo-app-loading with expo

expo install expo-app-loading
Enter fullscreen mode Exit fullscreen mode

The next thing to do is to download the fonts which you would want to use in your app and store them in the assets folder of your react-native app workspace. You can download google fonts at https://fonts.google.com/ they have wonderful fonts over there.

Let's Build

Firstly, we import our libraries :

import React, { useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import * as Font from "expo-font";
import Apploading from "expo-app-loading";

Enter fullscreen mode Exit fullscreen mode

We import Apploading from expo-app-loading, which makes sure that the splash screen component or loading screen component is visible while it is mounted and we also import everything in expo-font as Font so as to load fonts.

const getFonts = () =>
  Font.loadAsync({
    limelight: require("./assets/fonts/Limelight/Limelight- 
    Regular.ttf"),
    indie: require("./assets/fonts/Indie_Flower/IndieFlower- 
    Regular.ttf"),
  });
Enter fullscreen mode Exit fullscreen mode

We use loadAsync method to asynchronously load static or remote resources that can be used in the react-native application. In this case, we are using it to asynchronously load the required font needed in the react-native app. It registers the font in a name which will be used while referring to it with fontFamily.

export default function App() {
  const [fontsloaded, setFontsLoaded] = useState(false);

  if (fontsloaded) {
    return (
     //you can return any component of your choice here
      <View style={styles.container}>
        <Text style={styles.Texts}>
          Open up App.js to start working on your app!
        </Text>
        <StatusBar style="auto" />
      </View>
    );
  } else {
    return (
      <Apploading
        startAsync={getFonts}
        onFinish={() => {
          setFontsLoaded(true);
        }}
        onError={console.warn}
      />
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

We use useState to monitor if the fonts is loaded or not and then we use the conditional statement to render a particular component depending depending on if the fonts is loaded or not. In the snippet above, if fonts is loaded(fontsloaded), then we return the component where the font is specified or else we return a component called Apploading. Apploading takes in three props which includes:

  1. startAsync
  2. onFinish
  3. onError

startAsync
startAsync returns a promise. This promise is what is being loaded or resolved while the a loading screen or splash screen is mounted or running. In the case above, the getFont function is what is being called in startAsync.

onFinish
This guy takes in a function setFontLoaded and sets it to true. In the case above, the onFinish prop waits for startAsync to load the fonts from getFont function and then it updates the state of the react-native app thereby rendering the font being loaded.

onError
onError catches every possible error that might be thrown from startAsync and handles it properly.

Now, we can use our font in any component we wish to use it in.

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  Texts: {
    fontFamily: "indie",
  },
});
Enter fullscreen mode Exit fullscreen mode

As we can see above, the name of the font family is the specified name given to the font when loading it from loadAsync. We can now use the loaded font and also specify weight and other attributes to the font loaded.

Full code:

import { StatusBar } from "expo-status-bar";
import React, { useState } from "react";
import { StyleSheet, Text, View } from "react-native";
import * as Font from "expo-font";
import Apploading from "expo-app-loading";

const getFonts = () =>
  Font.loadAsync({
    limelight: require("./assets/fonts/Limelight/Limelight-Regular.ttf"),
    indie: require("./assets/fonts/Indie_Flower/IndieFlower-Regular.ttf"),
  });

export default function App() {
  const [fontsloaded, setFontsLoaded] = useState(false);

  if (fontsloaded) {
    return (
    //you can return any component of your choice here
      <View style={styles.container}>
        <Text style={styles.Texts}>
          Open up App.js to start working on your app!
        </Text>
        <StatusBar style="auto" />
      </View>
    );
  } else {
    return (
      <Apploading
        startAsync={getFonts}
        onFinish={() => {
          setFontsLoaded(true);
        }}
        onError={console.warn}
      />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  Texts: {
    fontFamily: "indie",
  },
});
Enter fullscreen mode Exit fullscreen mode

With this little tutorial, I hope you are able to load a font properly in your react-native app. Go forth and be great!!

Discussion (2)

Collapse
finistratbob profile image
finistratbob

Thanks for the detailed guide on installing fonts. I often learn new models and ways of modifying fonts. I recently found a cool selection masterbundles.com/best-sharp-fonts/ of custom fonts on a website for designers. These are sharp-style fonts that can be useful for decorating a website for business cards or banners. I would pay attention to ready-made technical solutions of designers, because long-term self-customization may not be relevant.

Collapse
reenydavidson profile image
ReenyDavidson Author

You're welcome and thank you for the font options. I will definitely look into it.