Solution 1 :

I’m Persian and our language fonts very very look like Arabic fonts. for my project, I create a separated file, and I named it globalStyles.js:

import { createStyles } from '@material-ui/core';
import yekanRegularTtf from '../app/assets/font/iranyekanwebregular.ttf';
import yekanRegularWoff from '../app/assets/font/iranyekanwebregular.woff';
import yekanRegularWoff2 from '../app/assets/font/iranyekanwebregular.woff2';
import yekanBoldTtf from '../app/assets/font/iranyekanwebbold.ttf';
import yekanBoldWoff from '../app/assets/font/iranyekanwebbold.woff';
import yekanBoldWoff2 from '../app/assets/font/iranyekanwebbold.woff2';

const globalStyles = ({ spacing, typography, colors }) =>
  createStyles({
    '@global': {
      '@font-face': [
        {
          fontFamily: 'IRANYekan',
          fontStyle: 'normal',
          fontWeight: 400,
          src: `url(${yekanRegularWoff2}) format('woff2')`,
          fallbacks: {
            src: [
              `url(${yekanRegularWoff})`,
              `url(${yekanRegularTtf}) format('truetype')`,
            ],
          },
        },
        {
          fontFamily: 'IRANYekan',
          fontStyle: 'normal',
          fontWeight: 700,
          src: `url(${yekanBoldWoff2}) format('woff2')`,
          fallbacks: {
            src: [
              `url(${yekanBoldWoff})`,
              `url(${yekanBoldTtf}) format('truetype')`,
            ],
          },
        },
      ],
      html: {
        lineHeight: '1.5',
        WebkitTextSizeAdjust: '100%',
      },
      '*': {
        transition: 'opacity 1s cubic-bezier(0.4, 0, 0.2, 1)',
        fontFamily: "'IRANYekan', sans-serif, Arial",
        boxSizing: 'border-box',

        '&:after, &:before': {
          fontFamily: "'IRANYekan', sans-serif, Arial",
          boxSizing: 'border-box',
        },
        '&[type="checkbox"], &[type="radio"]': {
          boxSizing: 'border-box',
          padding: '0',
        },
        '&[type="number"]': {
          '&::-webkit-inner-spin-button, &::-webkit-outer-spin-button': {
            height: 'auto',
          },
        },
        '&[type="search"]': {
          WebkitAppearance: 'textfield',
          outlineOffset: -2,

          '&::-webkit-search-decoration': {
            WebkitAppearance: 'none',
          },
        },
        '&[hidden]': {
          display: 'none',
        },
        '&::-webkit-file-upload-button': {
          WebkitAppearance: 'button',
          font: 'inherit',
        },
      },
      body: {
        fontFamily: "'IRANYekan', sans-serif, Arial",
        lineHeight: '1.38',
        margin: 0,
      },
      '#react-view': {},
      'h1, h2, h3, h4, h5, h6': {
        margin: [[0, 0, spacing.margin]],
        lineHeight: '1.3',
        letterSpacing: 0,
        textTransform: 'none',
        color: colors.black,
        display: 'block',
        fontFamily: "'IRANYekan', sans-serif, Arial",
      },
      h1: {
        fontSize: typography.fontSize * 1.4,
      },
      h2: {
        fontSize: typography.fontSize * 1.2,
      },
      h3: {
        fontSize: typography.fontSize,
      },
      h4: {
        fontSize: typography.fontSize,
      },
      h5: {
        fontSize: typography.fontSize,
      },
      h6: {
        fontSize: typography.fontSize,
      },
      p: {
        display: 'block',
        margin: [[0, 0, spacing.margin]],
      },
      main: {
        display: 'block',
      },
      hr: {
        boxSizing: 'content-box',
        height: 0,
        overflow: 'visible',
      },
      pre: {
        fontSize: '1em',
      },
      a: {
        backgroundColor: 'transparent',
        textDecoration: 'none',
      },
      'b, strong': {
        fontWeight: 'bold',
      },
      small: {
        fontSize: '80%',
      },
      img: {
        borderStyle: 'none',
      },
      button: {
        WebkitAppearance: 'button',
      },
      input: {
        overflow: 'visible',
      },
      'button, input, optgroup, select, textarea': {
        fontFamily: 'inherit',
        fontSize: '100%',
        lineHeight: '1.15',
        margin: 0,
      },
      'button, input': {
        overflow: 'visible',
      },
      'button, select': {
        textTransform: 'none',
      },
      textarea: {
        overflow: 'auto',
      },
      'button, [type="button"], [type="reset"], [type="submit"]': {
        WebkitAppearance: 'button',

        '&::-moz-focus-inner': {
          borderStyle: 'none',
          padding: '0',
        },
        '&:-moz-focusring': {
          outline: [[1, 'dotted', 'ButtonText']],
        },
      },
      fieldset: {
        padding: '0.35em 0.75em 0.625em',
      },
      legend: {
        boxSizing: 'border-box',
        color: 'inherit',
        display: 'table',
        maxWidth: '100%',
        padding: '0',
        whiteSpace: 'normal',
      },
      progress: {
        verticalAlign: 'baseline',
      },
      details: {
        display: 'block',
      },
      summary: {
        display: 'list-item',
      },
      template: {
        display: 'none',
      },
    },
  });

export default globalStyles;

And in the top level of my components, I injected to the project root component:

import React from 'react';
import { Provider as ReduxProvider } from 'react-redux';
import { CssBaseline, withStyles } from '@material-ui/core';
import { Helmet } from 'react-helmet';
import SnackBarProvider from './SnackBar';
import globalStyles from '../utils/globalStyles';
import { generalHelmet } from '../utils/helmetConfig';

type AppProviderProps = {
  children: any,
  store: any,
};

const AppProvider = ({ children, store }: AppProviderProps) => (
  <>
    <Helmet {...generalHelmet} />
    <CssBaseline />
    <ReduxProvider store={store}>
      <SnackBarProvider>{children}</SnackBarProvider>
    </ReduxProvider>
  </>
);

export default withStyles(globalStyles)(AppProvider);

Also, in the Webpack configuration file I wrote the font loader just like below:

~~~

const nodeEnv = process.env.NODE_ENV || 'development';
const isDev = nodeEnv === 'development';
const exclude = [/node_modules/, /public/];
const name = isDev ? '[name].[ext]' : '[hash:5].[ext]';
const publicPath = '/assets/';

~~~

module.exports = {

  ~~~

  module: {
    rules: [

      ~~~

      {
        test: /.(woff2?|ttf|eot|svg)$/,
        exclude,
        loader: 'url',
        options: { limit: 10240, name, publicPath },
      },

And everything works well now. I hope my configuration helps you.

Solution 2 :

You can try few things as mentioned below to check if you are compiling code properly.

  1. From the related URL which you mentioned to import the font infers that the static folder and above file directory are siblings. Make sure, the related path are same as per root folder.

  2. Also, if you’re using webpack to bundle your code, make sure you include ttf file extension and add file-loader module to handle it during compiling.

e.g.

{
  test: /.(png|jpg|gif|svg|ttf|eot|woff)$/,
  loader: 'file-loader',
  query: {
    name: '[name].[ext]?[hash]'
  }
},

Solution 3 :

There are a few possibilities but I would suggest trying loading the same font via your index.css file and check the result, Could it be the location you are referring is not correct or the font isn’t present.

Also a file-loader or plugin might be required to render fonts with webpack read: https://chriscourses.com/blog/loading-fonts-webpack

Problem :

I need to use Noto Sans Arabic font in my React material UI theme.
The theme is working well, overrides are working too.

I have tried React Material UI docs to import my fonts like in react-material documentation, but it doesn’t work:

import notoArabic from '../static/fonts/NotoSansArabic-Regular.ttf'

....


const arabic = {
  fontFamily: 'Noto Sans Arabic',
  fontStyle: 'regular',
  fontDisplay: 'swap',
  fontWeight: 400,
  src: `
    local('Noto Sans Arabic'),
    local('Noto Sans Arabic-Regular'),
    url(${notoArabic}) format('ttf')
  `,
  unicodeRange:
    'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF',
};

...

overrides: {
    MuiCssBaseline: {
      '@global': {
        '@font-face': [arabic],
      },
    },

...

I expect that the font will be imported and work.

I have any errors, and can see font-family: Noto Sans Arabic; in my browser. But it doesn’t work

Comments

Comment posted by Anis R.

What do you mean by “not work”? Do the arabic characters show at all (and not as squares)? Or only the font is not being imported?

Comment posted by Hubi

I mean that fontFamily not imported.

Comment posted by Rachel Gallen

@Hubi in the React Material docs that you have referred to, the code given creates a

Comment posted by Hubi

Yes, I’m using my own react material theme wrapper and override a lot of styles, such as buttons, theme-colors, etc.

Comment posted by Hubi

export const theme = createMuiTheme({ typography: { fontFamily: “Noto Sans Arabic, regular”, /// I have such code in my theme

Comment posted by Hubi

The question was about how to do it with Material UI, but anyway I need to import fonts. So I’ll try late. Maybe I will ask more questions, okay?

By