How to apply custom fonts to whole project, Expo React Native
Asked Answered
F

7

16

I'm new to React and those languages. Trying to apply a custom google font(Ubuntu) to whole project. I managed to pull the font into the project, but I can only use it in simple texts in App.js. Like this:

import React, {useState} from 'react';
import './firebase/index';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { ThemeProvider } from 'react-native-elements';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';
import { BLUE } from './common/colors';
import Dashboard from './screens/Dashboard';
import Login from './screens/Login';
import Accounts from './screens/Accounts';
import Cards from './screens/Cards';
import Credits from './screens/Credits';
import Insurances from './screens/Insurances';
import Investments from './screens/Investments';
import MoneyTransfers from './screens/MoneyTransfers';
import OtherOperations from './screens/OtherOperations';
import Payments from './screens/Payments';

import * as Font from "expo-font";
import Apploading from "expo-app-loading";
import { StyleSheet, Text, View } from "react-native";


const Drawer = createDrawerNavigator();

const getFonts = () =>
  Font.loadAsync({
    limelight: require("./assets/fonts/Ubuntu-Regular.ttf"),
    indie: require("./assets/fonts/Ubuntu-BoldItalic.ttf"),
  });


export default function App() {

  const [fontsloaded, setFontsLoaded] = useState(false);
  if (fontsloaded){
    return (
      <View>
          <Text 
            style={{ fontFamily: "limelight" }}>
             Hello World
          </Text>
          <Text 
            style={{ fontFamily: "limelight" }}>
             Hello World
          </Text>
          <Text 
            >
             Hello World
          </Text>
          <Text 
            style={{ fontFamily: "indie" }}>
             Hello World
          </Text>
          <Text 
            style={{ fontFamily: "limelight" }}>
             Hello World
          </Text>
          <Text 
            >
             Hello World
          </Text>
          <Text 
            style={{ fontFamily: "indie" }}>
             Hello World
          </Text>
          <Text 
            style={{ fontFamily: "indie" }}>
             Hello World
          </Text>
          <Text 
            >
             Hello World
          </Text>
          <Text 
            >
             Hello World
          </Text>
          <Text 
            style={{ fontFamily: "limelight" }}>
             Hello World
          </Text>
          <Text 
            >
             Hello World
          </Text>
        </View>
    );
  }
  else {
    return (
      <Apploading
        startAsync={getFonts}
        onFinish={() => {
          setFontsLoaded(true);
        }}
        onError={console.warn}
      />
    );
  }
  
}

But I used those text just for test. In normal my code is like this and when I try to use ubuntuRegular font it is not working.

import React, {useState} from 'react';
import './firebase/index';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { ThemeProvider } from 'react-native-elements';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';
import { BLUE } from './common/colors';
import Dashboard from './screens/Dashboard';
import Login from './screens/Login';
import Accounts from './screens/Accounts';
import Cards from './screens/Cards';
import Credits from './screens/Credits';
import Insurances from './screens/Insurances';
import Investments from './screens/Investments';
import MoneyTransfers from './screens/MoneyTransfers';
import OtherOperations from './screens/OtherOperations';
import Payments from './screens/Payments';

import * as Font from "expo-font";
import Apploading from "expo-app-loading";
import { StyleSheet, Text, View } from "react-native";


const Drawer = createDrawerNavigator();

const getFonts = () =>
  Font.loadAsync({
    limelight: require("./assets/fonts/Ubuntu-Regular.ttf"),
    indie: require("./assets/fonts/Ubuntu-BoldItalic.ttf"),
  });


export default function App() {

  const [fontsloaded, setFontsLoaded] = useState(false);
  if (fontsloaded){
    return (
      <SafeAreaProvider>
        <ThemeProvider>
          <NavigationContainer>
            <Drawer.Navigator
              drawerType="slide"
              initialRouteName="Login"
              screenOptions={{
                headerShown: true,
                headerStyle: {
                  backgroundColor: BLUE,
                },
                headerTintColor: '#fff',
                headerTitleStyle: {
                  fontWeight: 'bold',
                  fontFamily: 'ubuntuRegular'
                },
              }}
            >
              {/* Dashboard a ayri header gecilebilir
              https://reactnavigation.org/docs/headers#replacing-the-title-with-a-custom-component */}
              <Drawer.Screen
                name="Login"
                component={Login}
                options={{ headerShown: false, title: 'Login' }}
              />
              <Drawer.Screen
                name="Dashboard"
                component={Dashboard}
                options={{ title: 'Anasayfa' }}
              />
              <Drawer.Screen
                name="Accounts"
                component={Accounts}
                options={{ title: 'Hesaplarım' }}
              />
              <Drawer.Screen
                name="Cards"
                component={Cards}
                options={{ title: 'Kartlarım' }}
              />
              <Drawer.Screen
                name="Money Transfers"
                component={MoneyTransfers}
                options={{ title: 'Para Transferleri' }}
              />
              <Drawer.Screen
                name="Investments"
                component={Investments}
                options={{ title: 'Yatırımlar' }}
              />
              <Drawer.Screen
                name="Payments"
                component={Payments}
                options={{ title: 'Ödemeler' }}
              />
              <Drawer.Screen
                name="Credits"
                component={Credits}
                options={{ title: 'Krediler' }}
              />
              <Drawer.Screen
                name="Insurances"
                component={Insurances}
                options={{ title: 'Sigortalar' }}
              />
              <Drawer.Screen
                name="Other Operations"
                component={OtherOperations}
                options={{ title: 'Diğer İşlemler' }}
              />
            </Drawer.Navigator>
          </NavigationContainer>
        </ThemeProvider>
      </SafeAreaProvider>
    );
  }
  else {
    return (
      <Apploading
        startAsync={getFonts}
        onFinish={() => {
          setFontsLoaded(true);
        }}
        onError={console.warn}
      />
    );
  }
  
}

Also how can I use this font outside of the App.js like I have a MenuTitle component:

import React, {useState} from 'react';
import { StyleSheet, Text } from 'react-native';
import * as Font from "expo-font";
import Apploading from "expo-app-loading";

const getFonts = () =>
  Font.loadAsync({
    limelight: require("../assets/fonts/Ubuntu-Regular.ttf"),
    indie: require("../assets/fonts/Ubuntu-BoldItalic.ttf"),
  });

const MenuTitle = ({ text, textStyles = {} }) => {
  
  return <Text style={[styles.title, textStyles]}>{text}</Text>;
};

export default MenuTitle;

const styles = StyleSheet.create({
  title: {
    fontSize: 20,
    fontWeight: 'bold',
    paddingHorizontal: 20,
    fontFamily: 'ubuntuRegular'
  },
});

Also this is not working. I will be glad if you can help.

Frankpledge answered 4/8, 2021 at 6:45 Comment(0)
L
6

Create a folder called hooks where your App.js is located. Then inside hooks folder create a file called useFonts.js

Inside useFonts.js write like this

import * as Font from 'expo-font';

export default useFonts = async () =>
  await Font.loadAsync({
    limelight: require('../assets/fonts/Ubuntu-Regular.ttf'),
    indie: require('../assets/fonts/Ubuntu-BoldItalic.ttf'),
  });

Now in your App.js write like this

import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import React, { useState } from 'react';

import useFonts from './hooks/useFonts';

export default function App() {
  const [IsReady, SetIsReady] = useState(false);

  const LoadFonts = async () => {
    await useFonts();
  };

  if (!IsReady) {
    return (
      <AppLoading
        startAsync={LoadFonts}
        onFinish={() => SetIsReady(true)}
        onError={() => {}}
      />
    );
  }

  return <View styles={styles.container}>{/* Rest of the Code Here */}</View>;
}
Loblolly answered 21/9, 2021 at 20:42 Comment(1)
AppLoading is deprecated, and when I tried implementing this solution, I couldn't get it to work. The async function loadAsync never ran when putting it in AppLoading. Also, that's not a hook 😅 that's just a regular functionChinquapin
E
5
  1. Add font resource to project folder exp assets/fonts
  2. create variable fonts exp customFonts
  3. Import on App.js like this
import AppLoading from 'expo-app-loading';
import { useFonts } from 'expo-font';
let customFonts = {
  'Poppins-Black': require('./assets/fonts/Poppins-Black.ttf')
};

const App = () => {
  const [isLoaded] = useFonts(customFonts);
  if (!isLoaded) {
    return <AppLoading />;
  }
    return <RootApp />;
}
Encephalograph answered 11/6, 2022 at 16:26 Comment(0)
E
2

App.js

export default class App extends React.Component{
  constructor(props) {
      super(props)

      this.state = {
          fontsLoaded: false,
      }
  }
  async loadFont(){
      await Font.loadAsync({
          'ABeeZee-Italic' : require('./assets/fonts/ABeeZee-Italic.ttf'),
          'ABeeZee-Regular' : require('./assets/fonts/ABeeZee-Regular.ttf'),
      });
      this.setState({fontsLoaded:true});
  }

  componentDidMount(){
      this.loadFont();
  }
  render(){
         if(this.state.fontsLoaded)
             return Your_Component;
         else
             return AppLoading_Component;
          }

add the code as shown above then you can use the font on any page like below.

<Text style={{fontFamily: 'ABeeZee-Regular'}}> This is ABeeZee Regular Font</Text>
Extravagant answered 21/9, 2021 at 13:28 Comment(0)
L
2

With Expo, you generally have two distinct ways of applying custom fonts to your project:

The first is using the @expo-google-fonts/* package. Simply install the package like so:

yarn add @expo-google-fonts/Montserrat (to install Montserrat font)

Then in your code,

import React from "react";
import { View, Text } from "react-native";
import {
    useFonts,
    Montserrat_400Regular,
    Montserrat_400Regular_Italic,
    Montserrat_900Black,
} from "@expo-google-fonts/montserrat";
import AppLoading from "expo-app-loading";

export default function App() {
    const [loadedFonts] = useFonts({
        Regular: Montserrat_400Regular,
        Italic: Montserrat_400Regular_Italic,
        Black: Montserrat_900Black,
    });

    if (!loadedFonts) {
        return <AppLoading />;
    }

    return (
        <View style={{ flex: 1, justifyContent: "center" }}>
            <Text style={{ fontFamily: "Regular", fontSize: 32 }}>Hello</Text>
        </View>
    );
}

Use this directory for more assistance: https://directory.vercel.app/

The useFont hook handles the Font.loadAsync logic as displayed in other answer(s).

The second way involves importing the fonts locally. Like so,

import React from "react";
import { View, Text } from "react-native";
import { useFonts } from "expo-font";
import AppLoading from "expo-app-loading";

export default function App() {
    const [loadedFonts] = useFonts({
        Regular: require("./assets/fonts/Montserrat-Regular.ttf"),
    });

    if (!loadedFonts) {
        return <AppLoading />;
    }

    return (
        <View style={{ flex: 1, justifyContent: "center" }}>
            <Text style={{ fontSize: 32, fontFamily: "Regular" }}>Hello</Text>
        </View>
    );
}

Slight note:

If you're using the latest SDK 45, expo-app-loading is deprecated and should be replaced with expo-splash-screen. The Expo docs will help you there.

Leveridge answered 13/6, 2022 at 18:35 Comment(0)
B
1

Have you tried following those steps after adding .ttf to assets/font :

  • Create a configuration file react-native.config.js in the root project directory and add the code below:

     module.exports = {
         project: {
             ios: {},
             android: {},
         },
         assets: ['./App/assets/fonts'],
     };
    
  • Link the newly added asset by running the command:

    yarn react-native link 
    

or

react-native link

If everything is right, you can see the new font assets in android/app/src/main/assets/fonts in the case of android and changes in the Info.plist in case of iOS.

Finally, Re-run your app

After this you can put your font style in a style file and then use them in all your project:

bold11: {
    color: Colors.black,
    fontSize: 11,
    fontFamily: 'Roboto-Bold',
},
regular14: {
    color: Colors.black,
    fontFamily: 'Roboto-Regular',
    fontSize: 14,
},
Batik answered 4/8, 2021 at 8:21 Comment(2)
not sure this is a solution for expo, because already I don't have separate android and iOS folders in my project.Zoila
oh sorry didn't saw it was for expo, maybe here : docs.expo.dev/guides/using-custom-fonts/…Batik
D
0

Using Font.loadAsync instead of the useFonts hook If you don't want to use the useFonts hook.

(for example, maybe you prefer class components), you can use Font.loadAsync directly. Under the hood, the hook uses Font.loadAsync from the expo-font library. You can use it directly if you prefer, or if you want to have more fine-grained control over when your fonts are loaded before rendering.

import React from 'react';
    import { Text, View, StyleSheet } from 'react-native';
    import * as Font from 'expo-font';
    
    let customFonts = {
      'Inter-Black': require('./assets/fonts/Inter-Black.otf'),
      'Inter-SemiBoldItalic': 'https://rsms.me/inter/font-files/Inter-SemiBoldItalic.otf?v=3.12',
    };
    
    export default class App extends React.Component {
      state = {
        fontsLoaded: false,
      };
    
      async _loadFontsAsync() {
        await Font.loadAsync(customFonts);
        this.setState({ fontsLoaded: true });
      }
    
      componentDidMount() {
        this._loadFontsAsync();
      }
    
      render() {
        if (!this.state.fontsLoaded) {
          return null;
        }
    
        return (
          <View style={styles.container}>
            <Text style={{ fontFamily: 'Inter-Black', fontSize: 30 }}>Inter Black</Text>
            <Text style={{ fontFamily: 'Inter-SemiBoldItalic', fontSize: 30 }}>
              Inter SemiBoldItalic
            </Text>
            <Text style={{ fontSize: 30 }}>Platform Default</Text>
          </View>
        );
      }
    }
    
    const styles = StyleSheet.create({ ... }); 
Duran answered 1/9, 2022 at 12:11 Comment(0)
C
0

with expo you can use Google Font directly by using 'expo-google-fonts' liabrary.

Command to install npx expo install expo-font @expo-google-fonts/inter

Using Google Fonts

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useFonts, Inter_900Black } from '@expo-google-fonts/inter';

export default function App() {
  let [fontsLoaded] = useFonts({
    Inter_900Black,
  });

  if (!fontsLoaded) {
    return null;
  }

  return (
    <View style={styles.container}>
      <Text style={{ fontFamily: 'Inter_900Black', fontSize: 40 }}>Inter Black</Text>
    </View>
  );
}

for more help Visit Expo Docs Expo google fonts

Capitoline answered 21/1, 2023 at 7:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.