I'm trying to include Fontawesome with a Rails 4 app however the assets aren't making it into the asset pipeline. However, the fonts aren't making it out in production and I can't figure out why.
File structure organisation
All my assets are stored in /assets/components so that Fontawesome appears in: /assets/components/font-awesome (they're in a different directory because I'm using Bower).
CSS manifest file:
# application.css.scss /* ... *= require bootstrap/dist/css/bootstrap *= require font-awesome/css/font-awesome *= require_self *= require_tree . */
Asset pipeline is set to precompile fonts
# Version of your assets, change this if you want to expire all your assets config.assets.version = '1.0' config.assets.paths << Rails.root.join('vendor', 'assets', 'components') # Adding Webfonts to the Asset Pipeline config.assets.precompile << Proc.new { |path| if path =~ /\.(eot|svg|ttf|woff|otf)\z/ true end }
I added the precompile instructions so that the fonts would all be precompiled as per this question
Heroku 12 Factor gem is included
#gemfile group :production do gem "rails_12factor" end
So what's the problem?
When I push to Heroku, it shows that the application is requesting the files but that they're not loading:
And looking at the logs it seems to be a routing issue - I would have expected the font to be served from /assets/fonts but it is apparently looking in /fonts
app[web.1]: Started GET "/fonts/fontawesome-webfont.ttf?v=4.0.1" for 86.161.231.181 at 2013-10-29 15:53:01 +0000 app[web.1]: Started GET "/fonts/fontawesome-webfont.ttf?v=4.0.1" for 86.161.231.181 at 2013-10-29 15:53:01 +0000 app[web.1]: app[web.1]: ActionController::RoutingError (No route matches [GET] "/fonts/fontawesome-webfont.ttf"):
Why aren't the assets getting served
I'm a bit confused with all of this. Why aren't these fonts being served?
This problem maybe caused by a reason that Rails assets can't precompile url() function in CSS file.
Because your fonts files are precompiled by assets, all urls point to these files must be rewritten to MD5-digested file name. Unfortunately Rails can't precompile url() automatically, at least I think so because I tested some cases and got this conclusion :) In Rails guide, Rails provides these functions using ERB and Sass. see here .
I think there are two ways to solve your problem.
The first, set directory in .bowerrc to public/components and use them manually, don't require them in your assets.
The second, I suggest to use font-url() instead of url() in Font-Awesome, so your application.css.scss will be looked like:
/* ... *= require bootstrap/dist/css/bootstrap *= require font-awesome/css/font-awesome *= require_self *= require_tree . */ @font-face { font-family: 'FontAwesome'; src: font-url('font-awesome/fonts/fontawesome-webfont.eot?v=4.0.3'); src: font-url('font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'), font-url('font-awesome/fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'), font-url('font-awesome/fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'), font-url('font-awesome/fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg'); font-weight: normal; font-style: normal; }
Redefine the font-path with your actual font path and font-face with font-url() , this function is provided by sass-rails. After precompile, you will see your url has been rewritten to /assets/font-awesome/fonts/fontawesome-webfont-50b448f878a6489819d7dbc0f7dbfba0.eot?v=4.0.3 or something like in public/assets/application-xxxxxx.css.
You can find the same approach in various gems which include assets for example bootstrap-sass, it's a very popular gem. read this file: _glyphicons.scss. You will see:
@font-face { font-family: 'Glyphicons Halflings'; src: font-url('#{$icon-font-path}#{$icon-font-name}.eot'); src: font-url('#{$icon-font-path}#{$icon-font-name}.eot?#iefix') format('embedded-opentype'), font-url('#{$icon-font-path}#{$icon-font-name}.woff') format('woff'), font-url('#{$icon-font-path}#{$icon-font-name}.ttf') format('truetype'), font-url('#{$icon-font-path}#{$icon-font-name}.svg#glyphicons_halflingsregular') format('svg'); }
url() has been replaced. So I think rewrite @font-face in application.css.scss is the simplest way :)
By the way, bootstrap and font-awesome both have @font-face. I don't know whether font-awesome is necessary.
When you access the page, it shows the correct log. So you don't need change any code in bower repositories. Hope it helps.