Adding Custom-Variable Fonts in React Native — Part II
This is the continuation of my previous blog:
Previously in that blog, we would have seen how to slice different font weights from a variable font (e.g. InterV.var.ttf) and add them to Expo App.
Let us look at how to add them in a Bare React Native workflow.
Creating a react native application through the React Native Command Line Interface.
npx react-native init FontExampleApp
Once the app has been created we can run our application like this.
Let us go ahead and run our application on iOS.
If your app has been successfully launched you can see this screen on your simulator.
We will be using the expo-font package to link our fonts here too.
If you look at the package documentation it will provide installation steps for both projects
- Expo Managed
- Bare React Native
So before using Expo modules in our React Native project we will have to install and configure the expo package.
Expo has install-expo-modules
a command for getting it done.
npx install-expo-modules@latest
Let us go ahead and run this command in our project.
This command will prompt a question like this:
Expo module's minimum iOS requirement is 13.0. This tool will change your iOS deployment target to 13.0.
I think it's okay. Because it changes the min deployment target. As far as the app runs, I guess.
After the installation is successfully complete, you will have to go ahead and rebuild your iOS App.
Once the rebuild is successful, we can go ahead and add our expo-font
package.
expo install expo-font
Additional configuration is required for iOS (and none for Android), you will have to run
npx pod-install
After successfully running the above command let's go ahead and rebuild our app again.
Once the app is built and launched. We will have to load our fonts in a similar fashion we did for the expo app.
Go ahead and create a folder structure like src/assets/fonts
.
Add all our previously sliced fonts to this folder.
Let us copy the code we used in the expo snack, and paste it in our App.js
file.
At first, this code will break for two reasons:
- We would have used the
expo-splash-screen
package.
We will install this package now.
npx expo install expo-splash-screen
This package also needs a separate configuration for iOS. Let us run npx-pod-install
and rebuild our project.
2. The path for the font file will be different from the code we copied.
const [fontsLoaded] = useFonts({
'Inter-400-14': require('./src/assets/fonts/Inter-400-14.ttf'),
'Inter-440-14': require('./src/assets/fonts/Inter-440-14.ttf'),
'Inter-460-14': require('./src/assets/fonts/Inter-460-14.ttf'),
'Inter-520-24': require('./src/assets/fonts/Inter-520-24.ttf'),
'Inter-600-30': require('./src/assets/fonts/Inter-600-30.ttf'),
});
As the App.js file resides at the top of our app and our assets are inside the src
folder. We have to include them in the path as above.
After that, we can see the output in our iOS Simulator.
That’s all for iOS. 🎉
Let us try to build in android and see if the fonts are working fine.
Initially, my build failed saying I was using an outdated version of Java.
So I straight up headed to the React Native docs to check what is the updated way of running the app on Android Simulator on Mac.
The recommended way of installing the OpenJDK is called Azul Zulu using Homebrew.
Had to run these commands in the terminal to get the latest Azul Zulu JDK.
brew tap homebrew/cask-versions
brew install --cask zulu11
The great thing about Zulu is that
The Zulu OpenJDK distribution offers JDKs for both Intel and M1 Macs. This will make sure your builds are faster on M1 Macs compared to using an Intel-based JDK.
Glad. I am on an M1 Chip Mac. 🎉
Next up we will have to set up our Android Development Environment, install Android Studio, and install Android Studio SDK.
But we don't need the whole development environment, we just need the Emulator to be running while we execute the react native command to run our app.
Thanks to Google.
We have an Android Emulator(still in pre-release, but WORKS!).
If you have it downloaded. And you give the permission to Open the app through settings.
You will have your Android Emulator up and running.
Now let's run the command to start our application
npx react-native run-android
As everything is set up correctly, you should see our new app running in your Android emulator now.
Let us see the Android and iOS app screenshots side by side now, as we have our all fonts loaded now.
That's it. 🙌
The final code in App.js is
import {useEffect, useCallback} from 'react';
import {Text, View, StyleSheet} from 'react-native';
import {useFonts} from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import React from 'react';
export default function App() {
const [fontsLoaded] = useFonts({
'Inter-400-14': require('./src/assets/fonts/Inter-400-14.ttf'),
'Inter-440-14': require('./src/assets/fonts/Inter-440-14.ttf'),
'Inter-460-14': require('./src/assets/fonts/Inter-460-14.ttf'),
'Inter-520-24': require('./src/assets/fonts/Inter-520-24.ttf'),
'Inter-600-30': require('./src/assets/fonts/Inter-600-30.ttf'),
});
useEffect(() => {
async function prepare() {
await SplashScreen.preventAutoHideAsync();
}
prepare();
}, []);
const onLayoutRootView = useCallback(async () => {
if (fontsLoaded) {
await SplashScreen.hideAsync();
}
}, [fontsLoaded]);
if (!fontsLoaded) {
return null;
}
return (
<View style={styles.container} onLayout={onLayoutRootView}>
<Text style={styles.Inter_400_14}>Font Weight 400 with opsz 14</Text>
<Text style={styles.Inter_440_14}>Font Weight 440 with opsz 14</Text>
<Text style={styles.Inter_460_14}>Font Weight 460 with opsz 14</Text>
<Text style={styles.Inter_520_24}>Font Weight 520 with opsz 24</Text>
<Text style={styles.Inter_600_30}>Font Weight 600 with opsz 30</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingHorizontal: 16,
},
Inter_400_14: {
textAlign: 'center',
fontFamily: 'Inter-400-14',
fontSize: 30,
color: 'black',
},
Inter_440_14: {
textAlign: 'center',
fontFamily: 'Inter-440-14',
fontSize: 30,
color: 'black',
},
Inter_460_14: {
textAlign: 'center',
fontFamily: 'Inter-460-14',
fontSize: 30,
color: 'black',
},
Inter_520_24: {
textAlign: 'center',
fontFamily: 'Inter-520-24',
fontSize: 30,
color: 'black',
},
Inter_600_30: {
textAlign: 'center',
fontFamily: 'Inter-600-30',
fontSize: 30,
color: 'black',
},
});
In the Two-Part Blog series, we successfully sliced different font weights and optical sizing using Slice App and loaded them up in React Native in both workflows, Expo and Bare React Native.
Hope these blogs ease your development process in some way.
Thanks :)
If you find this blog post helpful, tell me in the comments, would love to know your views. Thank you :)
If you find any difficulties or see anything which could be done better, please feel free to add your comments (I really like to read them, maybe something on what my next blog should be? You know. Whatev! ). … :)