Importing expo fonts and assets in expo web and nextjs

1.1k views Asked by At

I am trying to use expo and nextjs for my web app, and I have tried implementing the the steps listed in the doc to enable me use fonts and images, however I keep getting this error

error - ./assets/fonts/Fontisto.ttf 1:0 Module parse failed: Unexpected character ' ' (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders (Source code omitted for this binary file)

below is my nex.config.js

const { withExpo } = require('@expo/next-adapter');
const withImages = require('next-images');
const withFonts = require('next-fonts');

// module.exports = withExpo({
//   projectRoot: __dirname,
// });
//
// module.exports = withExpo(
//   withFonts({
//     projectRoot: __dirname,
//   })
// );
//
// module.exports = withExpo(
//   withImages({
//     projectRoot: __dirname,
//   })
// );

module.exports = withExpo(
  [
    withFonts,
    withImages,
  ],
  { projectRoot: __dirname }
);

3

There are 3 answers

0
Thomas Lane On

This is what I use that works:

const { withExpo } = require('@expo/next-adapter');
const withFonts = require('next-fonts');

module.exports = withExpo(
  withFonts({
    projectRoot: __dirname,
  })
);
0
Gilson Viana On

1. Install the necessary plugins

npm install --save next-compose-plugins expo-font

or

yarn add next-compose-plugins expo-font

2. Setup

next.config.js

const { withExpo } = require('@expo/next-adapter');
const withFonts = require('next-fonts');
const withImages = require('next-optimized-images');
const withPlugins = require("next-compose-plugins");

module.exports = withPlugins([
  withFonts,
  withImages,
  [
    withExpo,
    { projectRoot: __dirname }
  ]
]);

3. Type Declaration

Create the following file to be able to use the import statement for your fonts.

declarations.d.ts

Paste the following inside the file.

declare module '*.ttf' {}

4. Load fonts

I've created the following custom hook to load the resources asynchronously.

useResources.ts

import * as Font from 'expo-font';
import { useEffect, useState } from 'react';

import YOUR_FONT_FILE_HERE from '/path/to/fonts/FONT_NAME.ttf';

export const useResources = () => {
  const [isFontReady, setIsFontReady] = useState(false);

  const loadFontAsync = async () => {
    try {
      await Font.loadAsync({
        HindRegular: {
          uri: YOUR_FONT_FILE_HERE as any,
          display: Font.FontDisplay.SWAP,
        }
      });
    } catch (error) {
      console.log('Font Load Error:', error)
    } finally {
      setIsFontReady(true);
    }
  }

  useEffect(() => {
    loadFontAsync();
  }, []);

  return {
    isFontReady
  }
};

5. Usage

Here we're making sure that the resources are available before trying to use them.

export default function App() {
  const { isFontReady } = useResources();

  if (!isFontReady) {
    return (
      <View>
        <Text>Resources are loading...</Text>
      </View>
    )
  }
  
  return (
    <View style={styles.container}>
      <Text style={styles.text}>Welcome to Expo + Next.js </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  text: {
    fontSize: 16,
    fontFamily: 'YOUR_FONT_NAME_HERE' <----- HERE
  },
});

Resources for further reading.

closed issue reply (eye openning)

Expo-Font

Expo-NextJS

1
Cheng Qing Low On

This should work.

const { withExpo } = require("@expo/next-adapter");
const withFonts = require("next-fonts");
const withImages = require("next-images");
const withPlugins = require("next-compose-plugins");

const withTM = require("next-transpile-modules")([
  "expo-next-react-navigation",
  // you can add other modules that need traspiling here
]);

module.exports = withPlugins(
  [
    withTM, 
    withFonts, 
    withImages, 
    [
      withExpo, 
      { projectRoot: __dirname }
    ]
  ], 
  {
    // ...
  }
);

Reference: This example