<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Aymeric M</title>
    <description>The latest articles on Forem by Aymeric M (@aymericmartinache).</description>
    <link>https://forem.com/aymericmartinache</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2904335%2Fd06fd310-4c67-48e2-9c78-33a5f7920dfc.jpeg</url>
      <title>Forem: Aymeric M</title>
      <link>https://forem.com/aymericmartinache</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/aymericmartinache"/>
    <language>en</language>
    <item>
      <title>The Mystery of Fonts on iOS: Why Was My App Not Displaying Custom Fonts?</title>
      <dc:creator>Aymeric M</dc:creator>
      <pubDate>Fri, 28 Feb 2025 17:51:51 +0000</pubDate>
      <link>https://forem.com/aymericmartinache/the-mystery-of-fonts-on-ios-why-was-my-app-not-displaying-custom-fonts-3h8j</link>
      <guid>https://forem.com/aymericmartinache/the-mystery-of-fonts-on-ios-why-was-my-app-not-displaying-custom-fonts-3h8j</guid>
      <description>&lt;h3&gt;
  
  
  A Frustrating Bug on iOS
&lt;/h3&gt;

&lt;p&gt;Recently, while working on a mobile application with &lt;strong&gt;React Native&lt;/strong&gt; and &lt;strong&gt;Expo&lt;/strong&gt;, I encountered an unexpected issue: &lt;strong&gt;my custom fonts were not displaying on iOS&lt;/strong&gt;. Yet, everything worked perfectly on Android.&lt;/p&gt;

&lt;p&gt;After hours of debugging and investigation, I discovered that &lt;strong&gt;iOS does not recognize fonts by their file name but rather by their "Full Name"&lt;/strong&gt;, a subtlety that does not exist on Android.&lt;/p&gt;

&lt;p&gt;In this article, I'll explain the cause of this issue, how to identify it, and most importantly, how to fix it.&lt;/p&gt;




&lt;h3&gt;
  
  
  Understanding Font Behavior on iOS
&lt;/h3&gt;

&lt;p&gt;On Android, using a custom font is relatively straightforward. You define the font in &lt;code&gt;expo-font&lt;/code&gt; using the file path, and it can be referenced directly by its filename:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useFonts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expo-font&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fontsLoaded&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFonts&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BasierCircle-Regular&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./assets/fonts/BasierCircle-Regular.ttf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;fontsLoaded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BasierCircle-Regular&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello, world!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; This code does not always work on iOS. The reason is that iOS does not identify fonts by their file name (&lt;code&gt;BasierCircle-Regular.ttf&lt;/code&gt;), but rather by their &lt;strong&gt;internal font name&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Identifying the Issue
&lt;/h3&gt;

&lt;p&gt;To check which fonts were actually loaded by iOS, I added a simple &lt;code&gt;console.log()&lt;/code&gt; in my code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Fonts loaded on iOS:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ExpoFont&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLoadedFonts&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result was surprising:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fonts loaded on iOS: [
  "BasierCircle-Regular",
  "font000000002d6f7cbc",
  "BasierCircle-SemiBold",
  "SwearDisplay-Bold"
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some font names appeared as hexadecimal identifiers (&lt;code&gt;font000000002d6f7cbc&lt;/code&gt;) instead of the expected names!&lt;/p&gt;

&lt;p&gt;What was happening was that iOS was not using the correct font name but instead generating an identifier.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Solution: Editing the "Full Name" of the Font
&lt;/h3&gt;

&lt;p&gt;To fix this, I used &lt;strong&gt;FontForge&lt;/strong&gt;, an open-source software that allows you to edit font metadata.&lt;/p&gt;

&lt;h4&gt;
  
  
  Steps to follow:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open FontForge&lt;/strong&gt; and load the font (&lt;code&gt;.ttf&lt;/code&gt; or &lt;code&gt;.otf&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Element → Font Info&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Modify the &lt;strong&gt;"Full Name"&lt;/strong&gt; field to match the exact desired name (e.g., &lt;code&gt;BasierCircle-Regular&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Save the font and re-import it into the application.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Proper Integration in Expo
&lt;/h3&gt;

&lt;p&gt;Once the name was corrected, I declared my fonts in &lt;code&gt;app.config.ts&lt;/code&gt; (instead of using &lt;code&gt;require()&lt;/code&gt; in my code):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expo-font&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;fonts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./assets/fonts/BasierCircle-Regular.ttf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./assets/fonts/BasierCircle-Medium.ttf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./assets/fonts/BasierCircle-SemiBold.ttf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./assets/fonts/BasierCircle-Bold.ttf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This avoids issues related to manually loading fonts and ensures cleaner management via &lt;strong&gt;expo-font&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This bug highlights a crucial difference between iOS and Android in handling custom fonts. To avoid this type of issue, here are some best practices to keep in mind:&lt;/p&gt;

&lt;p&gt;✅ Always check a font's "Full Name" on iOS using &lt;strong&gt;FontForge&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
✅ Declare fonts in &lt;code&gt;app.config.ts&lt;/code&gt; rather than loading them with &lt;code&gt;require()&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
✅ Use &lt;code&gt;ExpoFont.getLoadedFonts()&lt;/code&gt; to quickly debug font loading.  &lt;/p&gt;

&lt;p&gt;🚀 With these adjustments, my app now displays fonts correctly on &lt;strong&gt;all platforms&lt;/strong&gt;!&lt;/p&gt;




&lt;h3&gt;
  
  
  Useful Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.expo.dev/guides/using-custom-fonts/" rel="noopener noreferrer"&gt;Expo Font Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://fontforge.org/en-US/" rel="noopener noreferrer"&gt;FontForge - Edit Font Metadata&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.expo.dev/versions/latest/config-plugins/" rel="noopener noreferrer"&gt;Expo Config Plugin for Fonts&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've encountered a similar issue, share your experience in the comments!&lt;/p&gt;

</description>
      <category>expofont</category>
      <category>reactnative</category>
      <category>ios</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
