19

I am trying to use Font Awesome icons with my JSF application. I have had some success by following the getting started instructions and adding the following to my view's <h:head> section:

<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css"
      rel="stylesheet" />

This gives me a nice home icon when I use the icon-home class:

enter image description here

However, I don't want to be dependent on the bootstrap server to provide the Font Awesome resources, so I am trying to bundle these with my war, and configure my views to use the bundled resources.

I am using the pre-made JAR created by the webjars project. My pom has the following dependency:

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>font-awesome</artifactId>
    <version>3.2.1</version>
</dependency>

This places the JAR in my WAR's WEB-INF/lib directory. The relevent parts of the JAR's structure are:

META-INF
  - MANIFEST.MF
  + maven
  - resources
    - webjars
      - font-awesome
        - 3.2.1
          - css
            - font-awesome.css
            - *other css files*
          - font
            - *font files*

I have tried the following to include the icons in my project:

<h:outputStylesheet library="webjars" 
                    name="font-awesome/3.2.1/css/font-awesome.css"  />

However, this renders the previously working home icon as:

enter image description here

And my browser (Chrome) shows the following errors in the console (domain/port/context-root changed to protect the innocent ;):

GET http://DOMAIN:PORT/CONTEXT-ROOT/javax.faces.resource/font-awesome/3.2.1/font/fontawesome-webfont.woff?v=3.2.1 404 (Not Found) 
GET http://DOMAIN:PORT/CONTEXT-ROOT/javax.faces.resource/font-awesome/3.2.1/font/fontawesome-webfont.ttf?v=3.2.1 404 (Not Found) 
GET http://DOMAIN:PORT/CONTEXT-ROOT/javax.faces.resource/font-awesome/3.2.1/font/fontawesome-webfont.svg 404 (Not Found)

So it looks like although the css file is resolved properly, the files which contain the fonts that the css file refers to cannot be found. I have checked those references in the css file and they are:

src: url('../font/fontawesome-webfont.eot?v=3.2.1');
src: url('../font/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'), url('../font/fontawesome-webfont.woff?v=3.2.1') format('woff'), url('../font/fontawesome-webfont.ttf?v=3.2.1') format('truetype'), url('../font/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg');

Those paths are relative to the css resource, so I thought JSF should have no problem finding it. Now I'm not sure what to do.

Any pointers would be great! Cheers.

Kukeltje
  • 11,924
  • 4
  • 19
  • 44
Ryan Bennetts
  • 1,064
  • 1
  • 13
  • 27

5 Answers5

29

The JSF mapping and library name is missing in those URLs. If you've mapped your FacesServlet on *.xhtml, then those URLs should actually have been:

GET http://DOMAIN:PORT/CONTEXT-ROOT/javax.faces.resource/font-awesome/3.2.1/font/fontawesome-webfont.woff.xhtml?ln=webjars&v=3.2.1
GET http://DOMAIN:PORT/CONTEXT-ROOT/javax.faces.resource/font-awesome/3.2.1/font/fontawesome-webfont.ttf.xhtml?ln=webjars&v=3.2.1
GET http://DOMAIN:PORT/CONTEXT-ROOT/javax.faces.resource/font-awesome/3.2.1/font/fontawesome-webfont.svg.xhtml?ln=webjars

Essentially, you should be using #{resource} in CSS file to print the proper JSF resource URL:

src: url("#{resource['webjars:font-awesome/3.2.1/font/fontawesome-webfont.eot']}&v=3.2.1");
src: url("#{resource['webjars:font-awesome/3.2.1/font/fontawesome-webfont.eot']}&#iefix&v=3.2.1");

However, as the source code is actually outside your control (you can't edit it), then there's no other way to manage the resource handling yourself. The JSF utility library OmniFaces provides the UnmappedResourceHandler out the box for the exact purpose. With the following steps your problem should be solved:

  1. Install OmniFaces, it's available on Maven as well.

    <dependency>
        <groupId>org.omnifaces</groupId>
        <artifactId>omnifaces</artifactId>
        <version><!-- Check omnifaces.org for current version. --></version>
    </dependency>
    
  2. Register UnmappedResourceHandler in faces-config.xml as follows:

    <application>
        <resource-handler>org.omnifaces.resourcehandler.UnmappedResourceHandler</resource-handler>
    </application>
    
  3. Add /javax.faces.resource/* to FacesServlet mapping, assuming that the servlet name is facesServlet and you've already a mapping on *.xhtml:

    <servlet-mapping>
        <servlet-name>facesServlet</servlet-name>
        <url-pattern>/javax.faces.resource/*</url-pattern>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    
  4. Move the <h:outputStylesheet> library name to into the resource name.

    <h:outputStylesheet name="webjars/font-awesome/3.2.1/css/font-awesome.css" />
    
  5. Profit.

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Not sure if its appropriate to put this here but, this solution works fine but ends up breaking (which, I assume, would also break . I'm guessing because these rely on unmapped resources to export files for download? I'm getting stuff like this in the logs: Warning: JSF1091: No mime type could be found for file s01a3dc15-c480-4769-a71a-bc08f191416f. – wsaxton Feb 20 '15 at 20:30
  • @wsaxton: Which OmniFaces version? There's since 1.8 a hack in place to recognize PF dynamic resources so it could delegate accordingly. – BalusC Feb 20 '15 at 20:54
  • I'm using 1.8. Is there another way to do this then? (BTW, I did ask this question in another post if you want to reply there: http://stackoverflow.com/questions/28637732/how-can-i-integrate-font-awesome-with-jsf-difficulties-with-omnifaces-solution) – wsaxton Feb 21 '15 at 22:07
  • @balusc: Answer could be simplified see my answer below. Maybe you can edit this one – Kukeltje Feb 22 '15 at 00:13
  • If you wonder, why this does not work with 5.8.1 version of font awesome I tell you: the path inside the jar is different now. You have to use "webjars/font-awesome/5.8.1/css/fontawesome.css" as path. @BalusC - you answered almost all questions I ask myself about JSF :) Thanks a lot. – Gábor Lipták Apr 25 '19 at 08:14
  • hmm. Actually I have a problem with 5.8.1 version. If I try to include "webjars/font-awesome/5.8.1/css/all.min.css", then the fonts cannot be found. So for example I get this error: "GET http://xxxx/yyy/webfonts/fa-solid-900.woff net::ERR_ABORTED 404". @BalusC do you have any idea, how to fix this without changing the css inside the jar? – Gábor Lipták Apr 25 '19 at 08:35
  • @BalusC I figured out. I have to include "webjars/font-awesome/5.8.1/css/all-jsf.css" then it works. Cool that the font awesome developer think on JSF people :) – Gábor Lipták Apr 25 '19 at 08:41
17

The answer above is kind of made obsolete. Since some releases ago, the webjar version of font-awesome includes a specific jsf-ified version of the css so there is nothing to configure. Add the jar to your project, either via maven

<dependency>
   <groupId>org.webjars</groupId>
   <artifactId>font-awesome</artifactId>
   <version>4.6.3</version>
</dependency>

or directly and it just works. Just make sure you include the correct css

<h:outputStylesheet library="webjars" name="font-awesome/4.6.3/css/font-awesome-jsf.css" />

Note the -jsf in the name!!! This way you can always have the latest version in your application and do not depend on PF releasing something new

Kukeltje
  • 11,924
  • 4
  • 19
  • 44
7

In addition to BalusC answer, it's a good idea to add the following mime-mappings to the web.xml

<!-- web fonts -->
<mime-mapping>
    <extension>eot</extension>
    <mime-type>application/vnd.ms-fontobject</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>otf</extension>
    <mime-type>font/opentype</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>ttf</extension>
    <mime-type>application/x-font-ttf</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>woff</extension>
    <mime-type>application/x-font-woff</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>woff2</extension>
    <mime-type>application/x-font-woff2</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>svg</extension>
    <mime-type>image/svg+xml</mime-type>
</mime-mapping>
<mime-mapping>
    <extension>ico</extension>
    <mime-type>image/x-icon</mime-type>
</mime-mapping>
MathiasJ
  • 1,631
  • 1
  • 14
  • 20
Hatem Alimam
  • 9,589
  • 4
  • 39
  • 55
3

In addition to BalusC and Hatem Alimam answers, this could be useful too by adding:

<context-param>
   <param-name>primefaces.FONT_AWESOME</param-name>
   <param-value>true</param-value>
</context-param>

According to this link

Danny P
  • 73
  • 2
  • 12
  • yes, primefaces [now supports fontawesome](http://www.primefaces.org/showcase/ui/misc/fa.xhtml) out of the box since version 5.2. This is the approach I now use. – Ryan Bennetts May 14 '15 at 03:59
  • But in this approach you'll always behind the most recent font-awesome versions. Adding your own and using it in my answer guarantees the latest – Kukeltje Feb 25 '16 at 18:48
2

For primefaces 6.2 also this worked fine for me

    <dependency>
        <groupId>org.webjars</groupId>
        <artifactId>font-awesome</artifactId>
        <version>5.5.0</version>
    </dependency>

and in xhtml file:

<h:outputScript library="webjars" name="font-awesome/5.5.0/js/all.js"/>

be aware, that you have to change the usage from 4 to 5, for example fa fa-plus to fas fa-plus, based on web page - https://fontawesome.com/icons/plus?style=solid

Betlista
  • 9,561
  • 10
  • 62
  • 99