There's nothing wrong with Android's native sytem fonts, they're perfectly readable and people are used to their look, but in order to give your App some unique character, you probably want to include custom fonts.
It'll take a short while until these fonts are available and ready, so in the meantime, you can use Expo's <AppLoading />
component:
๐ฑ Expo AppLoading
Expo AppLoading is a component that keeps the splash screen until all assets are loaded. In its simplest usage, your top level App component would conditionally render either <AppLoading />
or the actual App components.
To install:
expo install expo-app-loading
To import:
import AppLoading from 'expo-app-loading';
See examples for usage below.
๐ฑ Using Expo Google Fonts
Expo supports an easy way to include Google Fonts with their expo-google-fonts package. You can import them directly by specifying the font family (check the Full list of supported Google fonts to see which exact name to use). For this example, I'm using the Lobster font (Lobster_400Regular).
First step is to install it:
expo install @expo-google-fonts/lobster
In App.js, you can import it and use the useFonts
hook to detect when it's loaded:
import AppLoading from 'expo-app-loading';
import { StyleSheet, View, Text } from 'react-native';
import { useFonts, Lobster_400Regular } from '@expo-google-fonts/lobster';
export default function App(){
let [fontsLoaded] = useFonts({ Lobster_400Regular })
if (!fontsLoaded) {
return (
<AppLoading />
);
}
return (
<View>
<Text style={{ fontFamily: 'Lobster_400Regular' }}>I am the Lobster Font</Text>
</View>
)
}
๐ฑ Loading a custom font (with useFonts hook)
To load your own font file (supported formats are .otf
and .ttf
), put them into a folder inside your project (for example, /assets/fonts).
First, install expo-font:
expo install expo-font
Then in App.js, use the useFonts
hook to require the file. I've given it a name lobster-reg
, which is the name that's used to refer to it in the StyleSheet.
import AppLoading from 'expo-app-loading';
import { StyleSheet, View, Text } from 'react-native';
import { useFonts } from 'expo-font';
export default function App(){
let [fontsLoaded] = useFonts({ 'lobster-reg': require('./assets/fonts/Lobster-Regular.ttf') })
if (!fontsLoaded) {
return (
<AppLoading />
);
}
return (
<View>
<Text style={{ fontFamily: 'lobster-reg' }}>I am the Lobster Font</Text>
</View>
)
}
๐ฑ Loading a custom font (with Font.loadAsync)
useFonts
is a quick-and-uncomplicated way to load fonts, but Font.loadAsync
gives a little more control. You'll also need it if you're still into Class components.
To load the font, write a small function fetchFonts and pass it as startAsync
prop to the <AppLoading />
component. The onFinish
prop can then set the state of fontsLoaded
.
import AppLoading from 'expo-app-loading';
import { useState } from 'react';
import * as Font from 'expo-font';
// function to load the font(s)
const fetchFonts = () => {
return Font.loadAsync({
'lobster-reg': require('./assets/fonts/Lobster-Regular.ttf')
});
};
export default function App(){
// keep the value of fontsLoaded in state
const [ fontsLoaded, setFontsLoaded ] = useState(false);
if (!fontsLoaded) {
return (
<AppLoading
startAsync={fetchFonts}
onError={console.warn}
onFinish={() => setFontsLoaded(true)}
/>
);
}
return (
<View>
<Text style={{ fontFamily: 'lobser-reg' }}>I am the Lobster Font</Text>
</View>
)
}
Those were three (slightly different) ways to include a custom font. I can't say which way I prefer, the differences are subtle. The only sure thing is that you always want to include them in the app bundle assets, instead of downloading them from the web.
๐ฑ Thanks for reading!
If you find any errors or have additions, questions or just want to say hi, please leave a comment below, or get in touch via my website jsdisco.dev or Twitter.
Keep calm & code ๐