Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using custom fonts in react-native project #1167

Closed
samuelcouch opened this issue May 6, 2015 · 74 comments

Comments

@samuelcouch
Copy link

commented May 6, 2015

Looking to add custom fonts to my react-native app -- can't seem to find any documentation on this.

@brentvatne

This comment has been minimized.

Copy link
Collaborator

commented May 6, 2015

@samuelcouch - same as how you would in a regular iOS app 😄

Follow steps 1-4 here: http://codewithchris.com/common-mistakes-with-adding-custom-fonts-to-your-ios-app/

Then you can use that font family inside of your styles

@brentvatne brentvatne closed this May 6, 2015

@mixophrygian

This comment has been minimized.

Copy link

commented Jun 12, 2015

Does RN support .woff fonts?

@jaygarcia

This comment has been minimized.

Copy link
Contributor

commented Jun 13, 2015

I think it's restricted to what IOS allows.

I've used free TTF's in my react native project.

@satya164

This comment has been minimized.

Copy link
Collaborator

commented Sep 16, 2015

Any tips on how to use custom fonts in Android?

@ccheever

This comment has been minimized.

Copy link
Contributor

commented Sep 17, 2015

@satya164 what have you tried? were you able to get anything working?

@satya164

This comment has been minimized.

Copy link
Collaborator

commented Sep 17, 2015

@ccheever All examples on the web suggest to extend the default Android TextView. There is also one using reflection which changes the font for the whole app (this worked). Though this is acceptable, I would also prefer is to be able to declare font families and use them in styles, so that I can use icon fonts etc.

Here is the link if you you just want to change font family for entire app - http://stackoverflow.com/questions/2711858/is-it-possible-to-set-font-for-entire-application

NOTE: I used sans instead of monospace.

@marcshilling

This comment has been minimized.

Copy link

commented Sep 17, 2015

I had custom fonts working in a native Android app. Trying to port it over to RN now and they aren't loading inside of <Text> components :(

@ccheever

This comment has been minimized.

Copy link
Contributor

commented Sep 17, 2015

@marcshilling can you describe in more detail what you tried? Do you still have .ttf files or similar in an assets/ folder? And how are you trying to use the custom fonts inside of RN? Just using the fontFamily style property on text nodes and referencing the fonts you are including?

@marcshilling

This comment has been minimized.

Copy link

commented Sep 17, 2015

@ccheever yes, exactly. I've tried putting the .ttf (and .otf) files in both /assets and /assets/fonts (I had to the do the latter on native). And then I declare text like so:

<Text style={{fontFamily: 'FuturaStd-ExtraBold'}}>Hello World</Text>

And just for the record - I'm using the same exact font files and declaring <Text> the exact same way in an iOS React Native project and they are working.

@geolivero

This comment has been minimized.

Copy link

commented Sep 20, 2015

@marcshilling what do you mean with "I had to the do the latter on native", did you write "Typeface font = Typeface.createFromAsset" in the main activity?

@satya164

This comment has been minimized.

Copy link
Collaborator

commented Sep 20, 2015

This is how I got custom font working,

  1. Put your font files under assets/fonts
  2. Add the following files

FontsOverride.java

import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Typeface;

public final class FontsOverride {
    public static void setDefaultFont(Context context,
                                      String staticTypefaceFieldName, String fontAssetName) {
        final Typeface regular = Typeface.createFromAsset(context.getAssets(),
                fontAssetName);
        replaceFont(staticTypefaceFieldName, regular);
    }

    protected static void replaceFont(String staticTypefaceFieldName,
                                      final Typeface newTypeface) {
        try {
            final Field staticField = Typeface.class
                    .getDeclaredField(staticTypefaceFieldName);
            staticField.setAccessible(true);
            staticField.set(null, newTypeface);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

MyApplication.java

import android.app.Application;

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/Custom-Font-Regular.ttf");
        FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/Custom-Font-Regular.ttf");

        // You can also use "MONOSPACE" and "SERIF", but "DEFAULT" and "SANS_SERIF" is all you need
        FontsOverride.setDefaultFont(this, "MONOSPACE", "fonts/Custom-Font-Monospace.ttf");
        FontsOverride.setDefaultFont(this, "SERIF", "fonts/Custom-Font-Serif.ttf");
    }
}

res/values/styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        ...
        <item name="android:typeface">sans</item>
    </style>

</resources>

Finally, in the <application> field of your AndroidManifest.xml, add the android:theme and android:name properties,

    <application
      ...
      android:name=".MyApplication"
      android:theme="@style/AppTheme"
      ...
      >
@geolivero

This comment has been minimized.

Copy link

commented Sep 20, 2015

@satya164, you saved my day, i'm going going to try this tonight.
Thanks!
Geo

On Sun, Sep 20, 2015 at 4:36 AM, Satyajit Sahoo notifications@github.com
wrote:

This is how I got custom font working,

  1. Put your font files under assets/fonts
  2. Add the following files

FontsOverride.java*

import java.lang.reflect.Field;import android.content.Context;import android.graphics.Typeface;
public final class FontsOverride {
public static void setDefaultFont(Context context,
String staticTypefaceFieldName, String fontAssetName) {
final Typeface regular = Typeface.createFromAsset(context.getAssets(),
fontAssetName);
replaceFont(staticTypefaceFieldName, regular);
}

protected static void replaceFont(String staticTypefaceFieldName,
                                  final Typeface newTypeface) {
    try {
        final Field staticField = Typeface.class
                .getDeclaredField(staticTypefaceFieldName);
        staticField.setAccessible(true);
        staticField.set(null, newTypeface);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

}

MyApplication.java

import android.app.Application;

public class MyApplication extends Application {
@override
public void onCreate() {
super.onCreate();

    FontsOverride.setDefaultFont(this, "DEFAULT", "fonts/Custom-Font.ttf");
    FontsOverride.setDefaultFont(this, "SANS_SERIF", "fonts/Custom-Font.ttf");
}

}

res/values/styles.xml

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
    <item name="android:typeface">sans</item>
</style>


Reply to this email directly or view it on GitHub
#1167 (comment)
.

Met vriendelijk groet,
Gerald Olivero
+31634771782
geolivero.com

@satya164

This comment has been minimized.

Copy link
Collaborator

commented Sep 20, 2015

@geolivero No problem, I had left out the part where you have to change the AndroidManifest.xml, added it to the post now.

@marcshilling

This comment has been minimized.

Copy link

commented Sep 21, 2015

@satya164 what if I need multiple, different custom fonts in my app? You approach seems to simply replace the default font with a single custom font.

@satya164

This comment has been minimized.

Copy link
Collaborator

commented Sep 21, 2015

@marcshilling Yeah, that will be immensely useful, e.g. - icon fonts. But I've not managed to figure that out yet.

@corymsmith

This comment has been minimized.

Copy link

commented Sep 29, 2015

@satya164 I've just added Android support to react-native-icons so you can use icon fonts.

As for custom fonts in general, CustomStyleSpan.java is where typefaces are currently set in React Native Android. For fontFamily to properly work with a custom font, RN would need some way to register a custom font family name with a font file in /assets when setting up the ReactInstanceManager.

Something like:

 mReactInstanceManager = ReactInstanceManager.builder()
  .setApplication(getApplication())
  .setBundleAssetName("index.android.bundle")
  .setJSMainModuleName("index.android")
  .addPackage(new MainReactPackage())

  // Add a font family name associated to a font file in /assets
  .addTypeFace("CustomFont", "Custom-Font.ttf")  

  .setUseDeveloperSupport(BuildConfig.DEBUG)
  .setInitialLifecycleState(LifecycleState.RESUMED)
  .build();
@satya164

This comment has been minimized.

Copy link
Collaborator

commented Sep 29, 2015

@corymsmith Awesome man. Thanks a ton.

@vovaguguiev

This comment has been minimized.

Copy link

commented Oct 9, 2015

// Add a font family name associated to a font file in /assets .addTypeFace("CustomFont", "Custom-Font.ttf")

Does it work with 0.11.4? For me compiler cannot find this method on Builder instance

@satya164

This comment has been minimized.

Copy link
Collaborator

commented Oct 9, 2015

@wizardzloy It's just a concept.

@corymsmith

This comment has been minimized.

Copy link

commented Oct 9, 2015

@wizardzloy I was merely proposing a way to handle that but it hasn't been implemented

@vovaguguiev

This comment has been minimized.

Copy link

commented Oct 9, 2015

@corymsmith @satya164 Oh, I see. So there is no working solution for multiple custom fonts so far?

@vovaguguiev

This comment has been minimized.

Copy link

commented Nov 4, 2015

There is an open PR that aims to solve this problem. Hope it will be merged soon
#3800

@tgoldenberg

This comment has been minimized.

Copy link
Contributor

commented Nov 10, 2015

Has anyone else had difficulty using the custom fonts on their device? I'm using a font 'GOUDIAC' for Sanskrit transliteration and while it works fine in the Simulator it doesn't load in the actual device

@fxhereng

This comment has been minimized.

Copy link

commented Nov 26, 2015

I just tried a new font using the @satya164 method and some words magically disappeared in my app, it seems that views doesn't calculate the sufficient space to display them. Does anyone have encountered the same problem?

@satya164

This comment has been minimized.

Copy link
Collaborator

commented Nov 26, 2015

@fxhereng Custom font support has been added in React Native - bfeaa6a

You can try 0.16.0-rc to use it.

@ericchris

This comment has been minimized.

Copy link

commented Nov 27, 2015

@satya164 I still have a problem using that code..
when I change the font setting on the device, my font got changed too.
Any idea?

@corymsmith

This comment has been minimized.

Copy link

commented May 31, 2016

@PierBover

If you have a peek at this:

* Class responsible to load and cache Typeface objects. It will first try to load typefaces inside

For each font family the bold, italic and bold_italic variants are supported. Given a "family" font family the files in the assets/fonts folder need to be family.ttf(.otf) family_bold.ttf(.otf) family_italic.ttf(.otf) and family_bold_italic.ttf(.otf).

So if you need other weights then it would seem like you should include the different font file for that weight and then name the file / use the font name that matches the file name for that weight.

@PierBover

This comment has been minimized.

Copy link

commented May 31, 2016

So in the styles I'd use:

fontFamily: ‘myfont_light_italic’

?

I guess that should work.

If I have time I will try to fix this so that you can also specify the weight in the .ttf file like myfont_300_italic.ttf. This makes more sense than using classic names like light,black, etc. Plus, @ericvicenti said here they want to support CSS like font weights instead.

@sibelius

This comment has been minimized.

Copy link

commented May 31, 2016

@PierBover thanks for all this links, I hope one of them works

@tje3d

This comment has been minimized.

Copy link

commented Jun 26, 2016

Here is how i get custom font working in four step:
1- Copy TTF file to /projectdir/android/app/src/main/assets/fonts ( thanks to: #1167 (comment) )
2- Delete these folders: projectfolder/android/.gradle + projectfolder/android/app/build ( thanks to: #1167 (comment) )
3- Apply fontFamily to elements ( if your ttf file is yekan.ttf, your font family should be: fontFamily: 'yekan' )
4- react-native run-android

@kunsachdeva

This comment has been minimized.

Copy link

commented Jun 28, 2016

@tje3d so you didn't have to write any Java code for this?

@tje3d

This comment has been minimized.

Copy link

commented Jun 28, 2016

@kunal95 yes

@kunsachdeva

This comment has been minimized.

Copy link

commented Jun 28, 2016

@tje3d It worked! 😀 Thanks

@krokofant

This comment has been minimized.

Copy link

commented Jul 5, 2016

I used rnpm to fix this. It basically does what @tje3d described.

Im specifying this in my package.json file

"rnpm": {
    "assets": ["Fonts"]
}

I've placed my fonts in the Fonts directory and then just run rnpm link

@PierBover

This comment has been minimized.

Copy link

commented Jul 6, 2016

Thanks @krokofant for your method!

I'm going to describe a bit what happens for the rest.

First it copies the fonts correctly for Android:

image

They also appear in Xcode in the Resources folder

image

Finally you use them like this in your StyleSheet:

fontFamily: 'opensans',
fontWeight:'bold'

Success

image

@IkeLutra

This comment has been minimized.

Copy link

commented Sep 20, 2016

From looking at the code https://github.com/facebook/react-native/blob/0.34-stable/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactFontManager.java

It doesn't look like react native supports light variants of fonts yet. If I get time I may add a PR for support

@JulianKingman

This comment has been minimized.

Copy link

commented Jan 4, 2017

Anyone know how to detect when the fonts are fully loaded? I noticed (at least in iOS simulator) that the font changes don't take effect for a few hundred milliseconds.

@sibelius

This comment has been minimized.

Copy link

commented Jan 4, 2017

@JulianKingman u can use this https://gist.github.com/sibelius/e1db241ab225aba2adb84dbd8ae6525b to check if the font name was loaded

@JulianKingman

This comment has been minimized.

Copy link

commented Jan 4, 2017

@sibelius so then would you recommend just having a setTimeout that refreshes every 10ms or so to check again, in order to update the component?

@sibelius

This comment has been minimized.

Copy link

commented Jan 4, 2017

I think all the fonts are loaded when react starts

everytime u change the font u need to recompile the native code

@HernanAA

This comment has been minimized.

Copy link

commented Feb 24, 2017

As @tje3d said before, I made those 4 steps and also I ran:
cd android
gradlew clean

One thing more: my font file is called "Lato-Bold.ttf" so I had to use {fontFamily: 'Lato-Bold'} to make it works instead of {fontFamily: 'lato-bold'} as I read in some pages. So I had to use the fontFamily as it called.
Thank @tje3d !

@petermikitsh

This comment has been minimized.

Copy link

commented Feb 26, 2017

I'm having some issues getting custom fonts working on Android (however, it works fine on iOS).

  • I've installed my fonts in ./android/app/src/main/assets/fonts:

screen shot 2017-02-25 at 6 39 35 pm

  • My project uses an abstract CustomText wrapper component, to ensure the custom font is applied everywhere. When applying the fontFamily, I follow the <filename>.ttf pattern mentioned by folks above. E.g., since my font file is named opensans.ttf, my fontFamily is opensans for the Android platform.

screen shot 2017-02-25 at 6 40 56 pm

  • I ran this (from root of react native project, to clear cached android stuff):
rm -rf ./android/.gradle
rm -rf ./android/app/build
cd android && ./gradlew clean && cd ..

Then ran:

react-native run-android

However, my fonts still don't line up. I have it custom fonts functional on iOS, and you can see the comparison here:

screen shot 2017-02-25 at 6 43 24 pm

Any ideas as to what could be going wrong? I made sure I killed the packager before deleting the cached android files and re-starting the android simulator.

@johnmurphy01

This comment has been minimized.

Copy link

commented Mar 15, 2017

Same issue as @petermikitsh.

React Native v 0.35
Font I'm trying to load is Gotham Ultra.ttf. I renamed to gotham_ultra.ttf and moved to ./android/app/src/main/assets/fonts

I tried deleting the .gradle folder and re-running the packager and react-native run-android.

I've tried every suggestion on this issue but nothing appears to work.

If it helps, I'm using a fork of https://github.com/start-react/native-starter-kit

@johnmurphy01

This comment has been minimized.

Copy link

commented Mar 15, 2017

Mine works now! I was adding the style to a single Input component, expecting the placeholder text to have the new font. However, it did not affect the placeholder text but did affect the actual typed text.

@aroth

This comment has been minimized.

Copy link
Contributor

commented May 17, 2017

From https://blog.bam.tech/developper-news/add-a-custom-font-to-your-react-native-app

4 - Format the Android font files

In the android/app/src/main/assets/fonts folder where your font was copied, rename the files so that:

  • the prefix matches your .ttf files names
  • the suffix is snake_case

In my case:

Intelligent Design - Averta-Bold.otf had to be renamed to Averta_bold.otf (along with 15 other variations).

@kesha-antonov

This comment has been minimized.

Copy link
Contributor

commented May 31, 2017

In my case in Android it worked after setting fontWight: '400' . fontWeight: 'bold' caused fallback to System font.

@aminebenkeroum

This comment has been minimized.

Copy link

commented Jun 16, 2017

I'm getting it working after removing fontWeight! Apparently, I have only 400 weight font.

@PolGuixe

This comment has been minimized.

Copy link

commented Jul 26, 2017

Is there a way that android can provide a list of available fonts and its font name?

@a3diti

This comment has been minimized.

Copy link

commented Sep 11, 2017

I was using OTF file font and having errors like font not found, for the fontFamily i was mistaken to use the Full name attribute at the font book, the correct one was PostScript name

@brunocascio

This comment has been minimized.

Copy link

commented Sep 22, 2017

I don't understand why iOS uses FONTNAME-some instead of FONT-NAME-some whether the file is FONT-NAME-some.ttf

I've implemented a function in order to use fonts on both platforms.

// utils.js

import { Platform } from 'react-native'

/**
 * Add fonts compatibility across iOS & Android.
 *
 * Examples:
 * + SF-UI-Display-Medium.ttf will:
 *    Android: SF-UI-Display-Medium
 *    iOS: SFUIDisplay-Medium
 * + Roboto-Medium.ttf will:
 *    Android: Roboto-Medium
 *    iOS: Roboto-Medium
 */
export default fontCompat = (fontFamily) => {

  if (Platform.OS === 'ios') {
    return fontFamily.replace(/(.*)-/, (x) => x.replace(/-/g,'')+'-');
  }

  return fontFamily;
}
import { fontCompat } from './utils.js'

const myStyles = {
   one: {
       fontFamily: fontCompat('SF-UI-Display-Medium')
   },
   two: {
       fontFamily: fontCompat('Roboto-Medium')
   },
}
@JulianKingman

This comment has been minimized.

Copy link

commented Sep 25, 2017

@brunobar79 I think because it uses the font's name, not the font's filename (PostScript name, as @a3diti pointed out)

@brunobar79

This comment has been minimized.

Copy link
Contributor

commented Sep 25, 2017

(@JulianKingman I think you wanted to reply to @brunocascio instead)

@brunocascio

This comment has been minimized.

Copy link

commented Sep 25, 2017

@JulianKingman I got it. Good catch, thanks!

@facebook facebook locked as resolved and limited conversation to collaborators May 29, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
You can’t perform that action at this time.