I really like Font Awesome, and I really like NativeScript. I’ve done some basic native app development before, and images outside of webviews are always a huge pain in the ass. You have to make 50 sizes for all the screen densities, it only png and jpg are supported, there are idiosyncrasies between iOS and Android, blah blah blah…. it is so bad, that there are tools devoted to taking a single image and creating all the variants. Yuck.
For things like Tab Navigation, I’ve typically been able to find icons I need in a web font – my go to is Font Awesome. Fonts, as you know, are vector based so there is no need to go through the rigamarole of making 1000 raster images.
Hooking up fonts to NativeScript
NativeScript has good support for Icon Fonts. The problem is, iOS and Android consume the fonts differently. Android looks at the css font-family
defined in your CSS and needs the value to equal the file name of the font. iOS looks at the font-family
css directive again, but it requires the value to equal the Family
value INSIDE the .ttf
font file.
For example, here are the .ttf
files in my src/fonts
NativeScript dir:
~: ls src/fonts/
fa-brands-400.ttf fa-regular-400.ttf fa-solid-900.ttf
I then add the following to my src/_app-common.scss
:
.far {
font-family: 'Font Awesome 5 Free', fa-regular-400;
}
.fab {
font-family: 'Font Awesome 5 Brands', fa-brands-400;
}
.fas {
font-family: 'Font Awesome 5 Free Solid', fa-solid-900;
}
This tells the native app to look up the family (works on iOS) and fall back to file name (works on Android).
The Problem
Easy enough right? Wrong. When you download Font Awesome the .ttf
files for solid
and regular
use the SAME Family
name. On macOS you can easily see this by opening the “Font Book” app, and importing the Font Awesome .ttf
files. If you click on the font name, then the ‘i’ icon, you can see the value of Family
:


It is a subtle difference, the Style
value is different, but as you will see the Family
value is exactly the same.
The CSS font-family
directive has no way to specify the style
of font.
The Solution
5/1/19 NOTE: Newer versions of Font awesome broke ability to use this fix. Check out this issue.
The solution I came up with, is to simply modify the Family
name of the Solid collection .ttf
file. All you need to do is:
- Install fontname.py command line utility
- Copy the FA
.ttf
files into yoursrc/fonts/
directory and cd to this dir - Run
python fontname.py "Font Awesome 5 Free Solid" fa-solid-900.ttf
- Copy the CSS above to your
src/_app-common.scss
file
Thats it. You can then use it like this (Solid collection – fas
):
<Label class="fa" text="\uf2bb"></Label>
Or Regular collection (far
):
<Label class="fa" text="\uf2bb"></Label>
Extra Credit
There is a great NativeScript plugin called nativescript-ngx-fonticon that will allow you to not have to mess with copying unicode sequences. It turns the above example into this
<Label class="fa" text="{{'fa-address-card' | fonticon}}"></Label>
Using on a Button
When using the Nativescript themes, it defines the font-family
for the .btn
class. As you may know know icon fonts rely on font-family
as well.
So when using a <Button>
how do you apply one font-family
to the string Test while applying another font-family
to the icon?
I could solve this by giving the icon font-family
a higher precedence (ex: button.fas {...}
) – but this would prevent me from styling the textual font on the button.
The solution is to use FormattedString. It allows you to apply a class
to each element:
<Button (tap)="onTap($event)" class="btn btn-primary">
<FormattedString>
<Span class="fas" text="{{'fa-film' | fonticon}}"></Span>
<Span text=" Test" fontAttributes="Bold"></Span>
</FormattedString>
</Button>
Hope this helps!