How to set default font family in React Native?

React Native

React Native Problem Overview


Is there an equivalent to this CSS in React Native, so that the app uses the same font everywhere ?

body {
  font-family: 'Open Sans';
}

Applying it manually on every Text node seems overly complicated.

React Native Solutions


Solution 1 - React Native

The recommended way is to create your own component, such as MyAppText. MyAppText would be a simple component that renders a Text component using your universal style and can pass through other props, etc.

https://reactnative.dev/docs/text#limited-style-inheritance

Solution 2 - React Native

There was recently a node module that was made that solves this problem so you don't have to create another component.

https://github.com/Ajackster/react-native-global-props

https://www.npmjs.com/package/react-native-global-props

The documentation states that in your highest order component, import the setCustomText function like so.

import { setCustomText } from 'react-native-global-props';

Then, create the custom styling/props you want for the react-native Text component. In your case, you'd like fontFamily to work on every Text component.

const customTextProps = { 
  style: { 
    fontFamily: yourFont
  }
}

Call the setCustomText function and pass your props/styles into the function.

setCustomText(customTextProps);

And then all react-native Text components will have your declared fontFamily along with any other props/styles you provide.

Solution 3 - React Native

For React Native 0.56.0+ check if defaultProps is defined first:

Text.defaultProps = Text.defaultProps || {}

Then add:

Text.defaultProps.style =  { fontFamily: 'some_font' }

Add the above in the constructor of the App.js file (or any root component you have).

In order to override the style you can create a style object and spread it then add your additional style (e.g { ...baseStyle, fontSize: 16 })

Solution 4 - React Native

You can override Text behaviour by adding this in any of your component using Text:

let oldRender = Text.prototype.render;
Text.prototype.render = function (...args) {
    let origin = oldRender.call(this, ...args);
    return React.cloneElement(origin, {
        style: [{color: 'red', fontFamily: 'Arial'}, origin.props.style]
    });
};

Edit: since React Native 0.56, Text.prototypeis not working anymore. You need to remove the .prototype :

let oldRender = Text.render;
Text.render = function (...args) {
    let origin = oldRender.call(this, ...args);
    return React.cloneElement(origin, {
        style: [{color: 'red', fontFamily: 'Arial'}, origin.props.style]
    });
};

Solution 5 - React Native

With React-Native 0.56, the above method of changing Text.prototype.render does not work anymore, so you have to use your own component, which can be done in one line!

MyText.js

export default props => <Text {...props} style={[{fontFamily: 'Helvetica'}, props.style]}>{props.children}</Text>

AnotherComponent.js

import Text from './MyText';

...
<Text>This will show in default font.</Text>
...

Solution 6 - React Native

Add this function to your root App component and then run it from your constructor after adding your font using these instructions. https://medium.com/react-native-training/react-native-custom-fonts-ccc9aacf9e5e

import {Text, TextInput} from 'react-native'

SetDefaultFontFamily = () => {
    let components = [Text, TextInput]

    const customProps = {
        style: {
            fontFamily: "Rubik"
        }
    }

    for(let i = 0; i < components.length; i++) {
        const TextRender = components[i].prototype.render;
        const initialDefaultProps = components[i].prototype.constructor.defaultProps;
        components[i].prototype.constructor.defaultProps = {
            ...initialDefaultProps,
            ...customProps,
        }
        components[i].prototype.render = function render() {
            let oldProps = this.props;
            this.props = { ...this.props, style: [customProps.style, this.props.style] };
            try {
                return TextRender.apply(this, arguments);
            } finally {
                this.props = oldProps;
            }
        };
    }
}

Solution 7 - React Native

Super late to this thread but here goes.

TLDR; Add the following block in your AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    
 ....
    // HERE: replace "Verlag" with your font
  [[UILabel appearance] setFont:[UIFont fontWithName:@"Verlag" size:17.0]];
  ....
}

Walkthrough of the whole flow.

A few ways you can do this outside of using a plugin like react-native-global-props so Ill walk you though step by step.

Adding fonts to platforms.

How to add the font to IOS project

First let's create a location for our assets. Let's make the following directory at our root.


    ios/
    static/
           fonts/

Now let's add a "React Native" NPM in our package.json

  "rnpm": {
    "static": [
   "./static/fonts/"
    ]
  }

Now we can run "react-native link" to add our assets to our native apps.

Verifying or doing manually.

That should add your font names into the projects .plist (for VS code users run code ios/*/Info.plist to confirm)

Here let's assume Verlag is the font you added, it should look something like this:

     <dict>
   <plist>
      .....
      <key>UIAppFonts</key>
      <array>
         <string>Verlag Bold Italic.otf</string>
         <string>Verlag Book Italic.otf</string>
         <string>Verlag Light.otf</string>
         <string>Verlag XLight Italic.otf</string>
         <string>Verlag XLight.otf</string>
         <string>Verlag-Black.otf</string>
         <string>Verlag-BlackItalic.otf</string>
         <string>Verlag-Bold.otf</string>
         <string>Verlag-Book.otf</string>
         <string>Verlag-LightItalic.otf</string>
      </array>
      ....    
</dict>
</plist>

Now that you mapped them, now let's make sure they are actually there and being loaded (this is also how you'd do it manually).

Go to "Build Phase" > "Copy Bundler Resource", If it didn't work you'll a manually add under them here.

1_uuz0__3kx2vvguz37bhvya

Get Font Names (recognized by XCode)

First open your XCode logs, like:

XXXX

Then you can add the following block in your AppDelegate.m to log the names of the Fonts and the Font Family.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    .....
    
    
  for (NSString* family in [UIFont familyNames])
  {
    NSLog(@"%@", family);
    for (NSString* name in [UIFont fontNamesForFamilyName: family])
    {
      NSLog(@" %@", name);
    }
  }
  
  ...
}
  

Once you run you should find your fonts if loaded correctly, here we found ours in logs like this:

2018-05-07 10:57:04.194127-0700 MyApp[84024:1486266] Verlag
2018-05-07 10:57:04.194266-0700 MyApp[84024:1486266]  Verlag-Book
2018-05-07 10:57:04.194401-0700 MyApp[84024:1486266]  Verlag-BlackItalic
2018-05-07 10:57:04.194516-0700 MyApp[84024:1486266]  Verlag-BoldItalic
2018-05-07 10:57:04.194616-0700 MyApp[84024:1486266]  Verlag-XLight
2018-05-07 10:57:04.194737-0700 MyApp[84024:1486266]  Verlag-Bold
2018-05-07 10:57:04.194833-0700 MyApp[84024:1486266]  Verlag-Black
2018-05-07 10:57:04.194942-0700 MyApp[84024:1486266]  Verlag-XLightItalic
2018-05-07 10:57:04.195170-0700 MyApp[84024:1486266]  Verlag-LightItalic
2018-05-07 10:57:04.195327-0700 MyApp[84024:1486266]  Verlag-BookItalic
2018-05-07 10:57:04.195510-0700 MyApp[84024:1486266]  Verlag-Light

So now we know it loaded the Verlag family and are the fonts inside that family

  • Verlag-Book

  • Verlag-BlackItalic

  • Verlag-BoldItalic

  • Verlag-XLight

  • Verlag-Bold

  • Verlag-Black

  • Verlag-XLightItalic

  • Verlag-LightItalic

  • Verlag-BookItalic

  • Verlag-Light

These are now the case sensitive names we can use in our font family we can use in our react native app.

Got -'em now set default font.

Then to set a default font to add your font family name in your AppDelegate.m with this line

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    
 ....
    // ADD THIS LINE (replace "Verlag" with your font)

  [[UILabel appearance] setFont:[UIFont fontWithName:@"Verlag" size:17.0]];
  ....
}

Done.

Solution 8 - React Native

For android, this is works for me.

Create a folder called font inside > android\app\src\main\res\

Insert your font.ttf/.otf inside the font folder, Make sure the font name is lower case letters and underscore only. > eg:- rubik_regular.ttf

Add below line in > android\app\src\main\res\values\styles.xml

<item name="android:fontFamily">@font/font_name</item>

for example,

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="android:fontFamily">@font/rubik_regular</item>
    </style>

    ...

</resources>

Make sure to re-run your app.

Also, we can add font size and font colors like this

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="android:textSize">20sp</item>
        <item name="android:textColor">#008</item>
        <item name="android:fontFamily">@font/rubik_regular</item>
    </style>

    ...

</resources>

Solution 9 - React Native

This answer used to work for me when I was using v0.63. But after upgrading react-native to v0.66.4 it broke.

I think the implementation of Text component has changed.

I came up with this solution:

    const oldTextRender = Text.render;

    Text.render = function(...args) {
        const origin = oldTextRender.call(this, ...args);
        const children = origin.props.children;

        if (typeof children === 'object') {
            return React.cloneElement(origin, {
                children: React.cloneElement(children, {
                    style: [ { fontFamily: 'CustomFontFamily' }, children.props.style ]
                })
            });
        }

        return React.cloneElement(origin, {
            style: [ { fontFamily: 'CustomFontFamily' }, origin.props.style ]
        });
    };

Notice that children prop may be an object, for example it might be a LogBoxMessage component. But the type of children prop of normal texts that are rendered on the screen are as type of string.

You may want to use a recursive function to apply the fontFamily to children

Solution 10 - React Native

That works for me: Add Custom Font in React Native

download your fonts and place them in assets/fonts folder, add this line in package.json

 "rnpm": {
"assets": ["assets/fonts/Sarpanch"]}

then open terminal and run this command: react-native link

Now your are good to go. For more detailed step. visit the link above mentioned

Solution 11 - React Native

For React Native version ≥ 0.60, in your root file create a file called react-native.config.js and put the followings, then just run react-native link

module.exports = {
  assets: ["./assets/fonts"]
}

Solution 12 - React Native

Add

"rnpm": {
  "assets": [
 "./assets/fonts/"
  ]
}

in package.json then run react-native link

Solution 13 - React Native

Set in package.json

"rnpm": {
  "assets": [
     "./assets/fonts/"
  ]
}

And link react-native link

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDagobert RenoufView Question on Stackoverflow
Solution 1 - React NativeDavid E. ChenView Answer on Stackoverflow
Solution 2 - React NativeAjacksterView Answer on Stackoverflow
Solution 3 - React NativeA-J-AView Answer on Stackoverflow
Solution 4 - React NativeFloris MView Answer on Stackoverflow
Solution 5 - React NativeanniView Answer on Stackoverflow
Solution 6 - React NativeRobView Answer on Stackoverflow
Solution 7 - React NativegarrettmacView Answer on Stackoverflow
Solution 8 - React Nativesanka sanjeewaView Answer on Stackoverflow
Solution 9 - React Nativec0m1tView Answer on Stackoverflow
Solution 10 - React NativeKhushboo TahirView Answer on Stackoverflow
Solution 11 - React NativeenestatliView Answer on Stackoverflow
Solution 12 - React NativeSanjib SunaView Answer on Stackoverflow
Solution 13 - React Nativeuser14031841View Answer on Stackoverflow