react-native-vector-icons icon indicating copy to clipboard operation
react-native-vector-icons copied to clipboard

Fonts "downloadable font: rejected by sanitizer" or "Failed to decode downloaded font"

Open jlounds opened this issue 2 years ago • 1 comments

  • [ X ] Review the documentation: https://github.com/oblador/react-native-vector-icons
  • [ X ] Search for existing issues (including closed ones): https://github.com/oblador/react-native-vector-icons/issues

Environment

  • Mac OS, web platform, using Expo
  • Excerpts from package.json:
"@expo/webpack-config": "~19.0.1",
"expo": "~50.0.6",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.73.4",
"react-native-paper": "^5.12.3",
"react-native-web": "~0.19.6",
"url-loader": "^4.1.1"

Description

Web fonts for the icons are not being downloaded / interpreted by Firefox, Chrome, or Safari and only show the dreaded square box. (Firefox shows a Unicode number as well)

Firefox error message in developer tools console:

downloadable font: rejected by sanitizer (font-family: "MaterialCommunityIcons" style:normal weight:400 stretch:100 src index:0) source: http://localhost:19006/static/media/MaterialCommunityIcons.7527ec3ffabe608ca630.ttf

Chrome:

Failed to decode downloaded font: http://localhost:19006/static/media/MaterialCommunityIcons.7527ec3ffabe608ca630.ttf
OTS parsing error: invalid sfntVersion: 1702391919

I confirmed that the file in /static/media is being downloaded. In fact, I tried uploading it to https://transfonter.org/ to see if I could convert it to a different format and manually add it, but even that failed saying the "Font file is corrupted."

Code

I tried following the instructions in the readme, but I think Expo and/or the version of webpack is complicating things. But since I am new to all of this, I don't know how to narrow it down.

  • webpack.config.js
const createExpoWebpackConfigAsync = require('@expo/webpack-config');
const path = require('path');

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);
  config.module.rules.push(
    {
      test: /\.ttf$/,
      loader: "url-loader",
      include: path.resolve(__dirname, "node_modules/react-native-vector-icons"),
    }
  );
  return config;
};
  • Excerpt from App.web.js
import materialCommunityIconFont from 'react-native-vector-icons/Fonts/MaterialCommunityIcons.ttf';
const moreFonts = `@font-face {
  src: url(${materialCommunityIconFont});
  font-family: "MaterialCommunityIcons";
}`;

const moreFontsStyle = document.createElement('style');
moreFontsStyle.type = 'text/css';

if (moreFontsStyle.styleSheet) {
  moreFontsStyle.styleSheet.cssText = moreFonts;
} else {
  moreFontsStyle.appendChild(document.createTextNode(moreFonts));
}
document.head.appendChild(moreFontsStyle);

jlounds avatar Feb 10 '24 22:02 jlounds

This stack-overflow answer led me to the solution that fixed it for me. In your webpack-config change this:

{
  test: /\.ttf$/,
  loader: "url-loader", // or directly file-loader
  include: path.resolve(__dirname, "node_modules/react-native-vector-icons"),
}

to this:

{
  test: /\.ttf$/,
  type: 'asset/resource',
  include: path.resolve(__dirname, "node_modules/react-native-vector-icons"),
}

This should probably also be updated in the readme.

c-goettert avatar Mar 13 '24 13:03 c-goettert