How do I add a custom font in React Native? - react-native

I'm running this on ios. I followed the steps here and was able to get the "Montserrat-SemiBold" font to work. I tried doing the same thing with "Source Sans Pro" but I'm getting the error "Unrecognized font family".
I've spent a couple of hours trying multiple things I found online but can't get it to work.
This is my repo => RefugeApp
p.s. I'm using VSCode

I use expo-font to use custom fonts, It's easy and straight forward.
Steps to use custom fonts with expo-font on the bare react-native project.
Install and config unimodules on iOS/Android
Configuration for iOS
Configuration for Android
Install expo-font
npm i expo-font
Setup your custom fonts on your App.js
import "react-native-gesture-handler";
import React from "react";
import { Text } from "react-native";
import * as Font from "expo-font";
class App extends React.Component {
state = {
appIsReady: false,
};
async componentDidMount() {
this.prepareResources();
}
prepareResources = async () => {
await cacheAssets();
this.setState({ appIsReady: true });
};
render() {
if (!this.state.appIsReady) {
return <Text>loading...</Text>;
}
return <Text>App</Text>;
}
}
async function cacheAssets() {
const fontAssets = cacheFonts([
{ thin: require("./assets/fonts/thin.ttf") },
{ medium: require("./assets/fonts/medium.ttf") },
{ bold: require("./assets/fonts/bold.ttf") },
]);
await Promise.all([...fontAssets]);
}
function cacheFonts(fonts) {
return fonts.map((font) => Font.loadAsync(font));
}
export default App;
Use it
<Text style={{ fontFamily: "medium" }}>App</Text>
This might be helpful if anyone using react-native-unimodules and wants to config custom fonts.

1 - download all the fonts you want (make sure its terminated in .ttf example: Arial-narrow.ttf)
2 - rename it as simple as possible eg: from piazzolla-reagular=s8.ttf to piazzolla-regular.ttf
3 - create an "assets" folder on your project (you probably already have created one)
4 - create a folder named "fonts" inside your your assets folder and paste all your downloaded (and renamed) fonts inside there
5 - create a file named "react-native.config.js" inside your project and fill the inside with this code:
module.exports = {
project: {
ios: {},
android: {}, // grouped into "project"
},
assets: ["./assets/fonts/"], // stays the same
};
6 - on your console (inside your project directory) write:
npx react-native link
this will link your project...
now, to apply your fonts on your style component use the fontFamily prop, eg:
style={{color:'#999',fontFamily:'exo2-regular'}}
hope this helps everyone whos in need of a font guide.
ps: I concat this method from various website guides around web like:
https://mehrankhandev.medium.com/ultimate-guide-to-use-custom-fonts-in-react-native-77fcdf859cf4
How do I add a custom font in React Native?
https://medium.com/#alcides.bsilvaneto/installing-custom-fonts-ttf-or-otf-on-react-native-0-60-projects-e8dafbc0dff3
No credits for me.

If you were able to do it correctly for Montserrat-SemiBold I suppose that your fonts are installed correct so I will skip this step, let's go to "Unrecognized font family" problem
You need to check font name in your system, not by name of the file, you need to open font_book in Launchpad and check font that you interested in Example image
For example the name of file IMFellEnglishSC-Regular.ttf but in the system, it could be IM_FELL_English_SC with underscores _ :)
So you need to use it like fontFamily: IM_FELL_English_SC, even if filename is different
In your case seems like fontFamily: SourceSansPro-Regular should work for you check this image
For future you could use this cool package to easy link & unlink fonts it's quite cool and simple for such things like adding custom fonts -> react-native-assets
Cheers 🤸‍♂️☀️

Related

React-native expo using custom fonts throws an error about not using font.loadAsync

I'm using custom fonts downloaded from Google (Poppins font family) and uploaded into the app as follows:
export default function App() {
const [fontsLoaded] = useFonts({
poppinsLight: require("./assets/fonts/poppins/Poppins-Light.ttf"),
});
if (!fontsLoaded) {
<AppLoading />;
}
...
};
But when I reload the app I get the following message:
ERROR fontFamily "poppinsLight" is not a system font and has not been loaded through Font.loadAsync.
If you intended to use a system font, make sure you typed the name correctly and that it is supported by your device operating system.
If this is a custom font, be sure to load it with Font.loadAsync.
And fonts are not loaded. Do you know how I can fix the above (I should just use useFonts and not Font.loadAsync following Expo docs).

React Native Google Fonts - Pass the custom font to the WHOLE app

After a lot of error messages, especially the following one
If this is a custom font, be sure to load it with Font.loadAsync.
I managed to add Google font to a react native app with the following code:
import AppLoading from "expo-app-loading";
import {
useFonts,
Quicksand_300Light,
Quicksand_400Regular,
Quicksand_500Medium,
Quicksand_600SemiBold,
Quicksand_700Bold,
} from "#expo-google-fonts/quicksand";
const screen = () => {
let [fontLoaded] = useFonts({
Quicksand_300Light,
Quicksand_400Regular,
Quicksand_500Medium,
Quicksand_600SemiBold,
Quicksand_700Bold,
});
if (!fontLoaded) {
return <AppLoading />;
} else {
return (
I use react-navigation and at the moment, I need to add this code to every screen.
I tried to add it to app and receive again the same Font.loadAsync message.
a - How can I import the font once for the whole app?
b - How can I have all the Text in the app use that font without adding it to each Text style?

Is there a bundler/tool that does not bundle by default, just do specified transforms like compiling SCSS modules?

I want to create a UI library and publish it to NPM. I don't like however the idea of bundling the code into single file and adding bundler code around my code, which is what all bundlers do by default (well, bundler must bundle I guess).
I'm using TypeScript and I build my non-ui packages with tsc. I want to keep that and let bundler or other tool just run through the result and change few things.
For example let's take this file:
import React from "react";
import styles from "./b.module.scss";
const B = () => {
return (
<div className={styles.index}>index</div>
);
};
export { B };
It's getting compiled into this ESM code:
import React from "react";
import styles from "./b.module.scss";
const B = () => {
return (React.createElement("div", { className: styles.index }, "index"));
};
export { B };
//# sourceMappingURL=b.js.map
Not much changes, but this is what I want at this step.
Now I want the tool to:
see the module.scss import
build b.css file, replacing class names with mangled ones
replace import styles from "./b.module.scss"; with import "./b.css";
replace { className: styles.index } with something like: { className: "b_index_f9cb22" } (that reflect new class name in b.css)
and that's basically all
I guess those are the steps normally taken by webpack plugins, but webpack does more than that, like I said - adding its own code, bundling things together, minimizing the code, etc. Some of these things I seem to be able to skip, but still the output is far from my original one.
Is there a tool that allows me to do what I want?

Custom Font not loading React-Native

I'm trying to load a custom font from my assets folder within my project. I've looked up online and so far after doing all the steps, I'm still faced with the same issue.
I've added the source of the fonts into my package.json file like this:
"rnpm": {
"assets": [
"./assets/fonts/"
]
}
I've imported expo-font into my project as well, and I'm simply calling the fontFamily like this:
<Text style={{ textAlign: 'center', fontFamily: 'Montserrat-Regular', fontSize: 20 }}>Home</Text>
am I missing something?
EDIT: I forgot to mention that I'm using a custom font in another screen, the exact same way...yet this screen is giving me issues.
The files I am using are Montserrat-Regular.tff, Montserrat-Bold.tff, and Montserrate-Light.tff
The path for these files are MyProject/assets/fonts/MyFonts.ttf
You don't have an Android folder, so it looks like you're using Expo, not React Native.
So I'll show you how to do Expo.
Take the Open Sans zipfile that you downloaded, extract it and copy
Montserrat-Regular.ttf into the assets directory in your
project. The location we recommend is your-project/assets/fonts.
and you can run expo install expo-font
Add the following import in your application code in App.js: import * as Font from 'expo-font';
The expo library provides an API to access native functionality of
the device from your JavaScript code. Font is the module that deals
with font-related tasks. First, we must load the font from our
assets directory using Font.loadAsync(). We can do this in the
componentDidMount() lifecycle method of the App component. Add the
following method in App: Now that we have the font files saved to
disk and the Font SDK imported, let's add this code:
export default class App extends React.Component {
componentDidMount() {
Font.loadAsync({
'Montserrat-Regular': require('./assets/fonts/Montserrat-Regular.ttf'),
});
}
// ...
}
This loads Open Sans Bold and associates it with the name 'Montserrat-Regular' in Expo's font map. Now we just have to refer to this font in our Text component.
Note: Fonts loaded through Expo don't currently support the fontWeight or fontStyle properties -- you will need to load those
variations of the font and specify them by name, as we have done here
with bold.
Check your Info.plist file from the iOS folder and looking for a UIAppFonts key, you should see something similar to:
<key>UIAppFonts</key>
<array>
<string>Montserrat Regular.ttf</string>
</array>
Also, your style will be like this;
fontFamily: "Montserrat", instead fontFamily: "Montserrat-Regular".
I managed to fix the issue I was having. It seems I needed to give the app a moment to load the font, still not sure why this was giving me the issue, but here is what my working code looks like now in case anybody else is having the same problem
This is the code I added into the screen in which I was trying to load my custom font.
constructor(props) {
super(props);
this.state = {
fontLoaded: false
}
}
async componentDidMount(){
await Font.loadAsync({
'Montserrat': require('../assets/fonts/Montserrat.ttf'),
}).then(() => {
this.setState({fontLoaded: true})
})
}
<View>
{ this.state.fontLoaded == true ? (
<Text style={{ fontSize: 40, fontFamily: 'Montserrat', color:'white', marginLeft: 10}}>Home</Text>
) : (<Text> Loading...</Text>)
}
</View>

How To Use both 'adjustPan' and 'adjustResize' for 'windowSoftInputMode' in React Native Android app

How can I use both 'adjustPan' and 'adjustResize' in AndroidManifest.xml react native app.
Use Case
My navigation is made upon ReactNavigation with StackNavigator and TabNavigator. I have a text box where the user can type any data. While performing this, the tab bar is displaying on the top of Keyboard. In order to block this i used 'adjustPan' and it worked fine.
On another screen, I have a registration with multiple text boxes. Here I cant scroll the entire screen unless and clicking 'tick' on the keyboard or manually click system back button. To solve this issue I found 'KeyboardAvoidingView' which is working fine. but to activate this need to change 'windowSoftInputMode' to 'adjustResize'.
In documentation, found that these two have entirely different property and I can't both together. could someone help me on this?
References:https://medium.freecodecamp.org/how-to-make-your-react-native-app-respond-gracefully-when-the-keyboard-pops-up-7442c1535580
I found an npm package called react-native-android-keyboard-adjust, which allows us to switch the windowSoftInputMode on demand, this should be able to cater for your use case. However, the library seems to be not actively maintained and the installation documentation is a little bit out of date but for the most part, you can follow the instructions given by the README.md.
For the Update MainActivity.java in your project part, the recent versions of React Native should be able to auto-link the dependencies and there is no need to do this modification manually.
After the above steps, you can try to start your app. If you encountered an error related to something like The number of method references in a .dex file cannot exceed 64k, you can add the followings to your android/app/build.gradle file
android {
...
defaultConfig {
...
multiDexEnabled true
}
...
}
After installing the package, you can call the methods provided by the library to change the windowSoftInputMode as you need.
For example, assuming you have a default windowSoftInputMode of adjustResize, and you want to use adjustPan within ScreenA, you can call AndroidKeyboardAdjust.setAdjustPan() when ScreenA mount, and reset the windowSoftInputMode to adjustResize on unmount by calling AndroidKeyboardAdjust.setAdjustResize()
As of 2023, the best choice is react-native-avoid-softinput. react-native-android-keyboard-adjust isn't supported anymore.
You can use AvoidSoftInput.setAdjustPan and AvoidSoftInput.setAdjustResize.
I use custom hook to disable my default behavior on some screens.
import { useCallback } from 'react'
import { AvoidSoftInput } from 'react-native-avoid-softinput'
import { useFocusEffect } from '#react-navigation/native'
import { Platform } from 'react-native'
function useAndroidKeyboardAdjustNothing() {
useFocusEffect(
useCallback(() => {
if (Platform.OS === 'android') {
AvoidSoftInput.setAdjustNothing()
AvoidSoftInput.setEnabled(true)
}
return () => {
if (Platform.OS === 'android') {
AvoidSoftInput.setEnabled(false)
AvoidSoftInput.setAdjustResize()
}
}
}, []),
)
}