49

I am trying to import font files on React with TypeScript project, but it doesn't recognize it as a font file, but instead, it looks at it as a module

Folder structure:

enter image description here

In my index.tsx file, I imported the font I need, and exported Font constant:

import helveticaNeueLightWoff from './HelveticaNeueW02-45Ligh.woff';
import helveticaNeueLightWoff2 from './HelveticaNeueW02-45Ligh.woff2';
import helveticaNeueMediumWoff from './HelveticaNeueW02-67MdCn.woff';
import helveticaNeueMediumWoff2 from './HelveticaNeueW02-67MdCn.woff2';
import helveticaNeueBoldWoff from './HelveticaNeueW02-75Bold.woff';
import helveticaNeueBoldWoff2 from './HelveticaNeueW02-75Bold.woff2';
import helveticaNeueBoldCnWoff from './HelveticaNeueW02-77BdCn.woff';
import helveticaNeueBoldCnWoff2 from './HelveticaNeueW02-77BdCn.woff2';

const Fonts = {
  helveticaNeueLightWoff,
  helveticaNeueLightWoff2,
  helveticaNeueMediumWoff,
  helveticaNeueMediumWoff2,
  helveticaNeueBoldWoff,
  helveticaNeueBoldWoff2,
  helveticaNeueBoldCnWoff,
  helveticaNeueBoldCnWoff2,
};

export default Fonts;

I use url-loader(I also tried with file-loader). This is my webpack.config.ts

{
          test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
          use: {
            loader: 'url-loader',
            options: {
              // Limit at 50k. Above that it emits separate files
              limit: 50000,
              // url-loader sets mimetype if it's passed.
              // Without this it derives it from the file extension
              mimetype: 'application/font-woff',
              // Output below fonts directory
              name: './fonts/[name].[ext]',
            },
          },
        },

This is the error I get: Cannot find module './HelveticaNeueW02-45Ligh.woff'

What could be the cause of this problem?

Nemus
  • 3,879
  • 12
  • 38
  • 57

2 Answers2

127

You need to declare the font file formats as modules so that TypeScript can parse them correctly.

create a fonts.d.ts file and add the following to it

declare module '*.woff';
declare module '*.woff2';

It tells TypeScript that the font filetypes are valid import modules.

The "d.ts" file format is used to provide typescript type information about an API that's written in JavaScript, or the shape of the third party imports.

Make sure that the types file is considered in the include section in tsconfig.json. A nice approach is to have a root typings directory in your project, then append typings/**/*.d.ts on include.

michelepatrassi
  • 2,016
  • 18
  • 32
Bradly Locking
  • 1,415
  • 1
  • 11
  • 6
0

Completion of the previous answer for expo user who would face a similar issue : I faced the same issue, and declaring the module was enough to import fonts but not to actually load these. I was using expo-font, and Typescript was complaining about the type of the result. To make it work, I created the same file with the following content :

declare module "*.ttf" {
  const value: import("expo-font").FontSource;
  export default value;
}

This tells that the module imported will have the type FontSource that comes from expo-font library. I was then able to load my font :)

Maka
  • 29
  • 2