5

I want to set custom fonts in Webview. I have implemented the below code:

@font-face {
    font-family: 'Poppins-Bold'; 
    src:url('file:///android_asset/fonts/Poppins-Bold.ttf') format('truetype')
}
body{
    font-family: Poppins-Bold
    margin: 0;
    padding: 0;
    color: red;
}

It works fine in android, but it does not working in iOS. Let me know if anybody has a solution for this.

Note: I don't want to use google's CSS font

immodi
  • 607
  • 1
  • 6
  • 21

2 Answers2

2
  1. Set the following font URL based on platform:
    const fontUrl = Platform.select({
        ios: "Poppins-Bold.ttf",
        android: "file:///android_asset/fonts/Poppins-Bold.ttf",
    });
    
  2. Update your CSS styles to the following:
     const css = `
         @font-face {
            font-family: 'Poppins-Bold'; 
            src: local('Poppins-Bold') url('${fontUrl}') format('truetype')
         }
         body {
            font-family: Poppins-Bold
            margin: 0;
            padding: 0;
            color: red;
         }`
    
    • Note that format('truetype') is used since your font extension is ttf. If you're using an eot font you'll need to use format('opentype').
  3. Once you do that, update your WebView component with the following props:
    <WebView 
        source={{ html, baseUrl: '' }}
        originWhitelist={["*"]}
    />
    
    • Setting baseUrl to blank will ensure fonts are loaded. Reference this post.
    • Without setting originWhitelist, you'll get errors on iOS that the URL cannot be found.

This worked for me on both Android & iOS and I happen to be using Poppins as well

German
  • 270
  • 2
  • 9
1

I tried the solution outlined by German but this didn't work for me.

The only thing that got it working for me was by base64 encoding the font (you can use the service here), and injecting it that way, which is really annoying but it works across iOS and Android:

const pageHtml = `
      <!DOCTYPE html>
        <html lang="en">
          <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <style>
              @font-face {
                font-family: 'Canela'; 
                src: url('data:font/woff2;charset=utf-8;base64,${CANELA_BASE_64}') format('woff');
              }
h1, h2, h3, html, body { font-family: Canela; }
</style>
          </head>
          <body>
          ${props.html}
          </body>
        </html>
      `;

Then you can set up the WebView like this:

const webViewSource = { html: pageHtml, baseUrl: '' };
return (
   <WebView
      source={webViewSource}
      originWhitelist={['*']}
   />
);
Willster
  • 2,526
  • 1
  • 32
  • 32