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:
- expo-font
- 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
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
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";
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"),
});
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}
/>
);
}
}
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:
- startAsync
- onFinish
- 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",
},
});
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",
},
});
With this little tutorial, I hope you are able to load a font properly in your react-native app. Go forth and be great!!
Top comments (3)
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.
You're welcome and thank you for the font options. I will definitely look into it.
Note: (Apploading from "expo-app-loading";) is deprecated kindly use the below command to install Apploading,
npm i expo-app-loading