Reputation: 7314
I can't load fonts in my Rails 4 app in production, it works normally in development.
Assets are precompiled on the server while deploying.
I have my fonts in
app/assets/fonts
My app.css:
@font-face {
font-family: 'WalkwayBoldRegular';
src: url('Walkway_Bold-webfont.eot');
src: url('Walkway_Bold-webfont.eot?#iefix') format('embedded-opentype'),
url('Walkway_Bold-webfont.woff') format('woff'),
url('Walkway_Bold-webfont.ttf') format('truetype'),
url('Walkway_Bold-webfont.svg#WalkwayBoldRegular') format('svg');
font-weight: normal;
font-style: normal;
}
In my production.rb I have:
config.assets.precompile << Proc.new { |path|
if path =~ /\.(eot|svg|ttf|woff)\z/
true
end
}
Upvotes: 20
Views: 15955
Reputation: 1241
1:- Keep all your fonts on app/assets/fonts folder.
2:- After rake asset:precompile RAILS_ENV=production all your fonts will get precompiled to public/assets folder with a digest.
3:- Instead of using src: url('fontname.eot')
use src: font_url('fontname.eot')
in scss files.
Upvotes: 1
Reputation: 1089
Works with Rails >= 5 && sprockets >= 4:
src: url('Walkway_Bold-webfont.eot');
Works only in development because in development rails serves all app/assets
folder directly without pre-compilation (but not in production that's why rails can't find the fonts), so you can access what's inside app/assets
folder with just the url url
.
In production you need the pre-compiled version of these files. Rails precompile these files to public/assets
. To access these files, you need to
use sprockets helpers: font-url
or the more generic helper asset-url
.
src: font-url('Walkway_Bold-webfont.eot');
In addition, all folders under app/assets
will be pre-compiled automatically, you don't need to add fonts
folder to sprockets search path.
You can check search path with: Rails.application.config.assets.paths
in rails console.
Upvotes: 1
Reputation: 35
Rails come with a prebuild helper for this. You need to use asset-url() instead of using url().
Upvotes: 0
Reputation: 21815
Here is a generic way how to troubleshoot this problem for any library.
Run rails server on production
rake assets:precompile
This on config/environments/production.rb
# Rails 4 production
# config.serve_static_files = true
# Rails 5, Uncomment to run production on local
# config.log_level = :debug
config.public_file_server.enabled = true
RAILS_ENV=production rails s
application.css
needs to be renamed to application.scss
since asset-url
will be usedAdd fonts to precompile on file config/initializers/assets.rb
:
Rails.application.config.assets.precompile << /\.(?:svg|eot|woff|ttf)$/
Look for font face definition inside your CSS library and copy that to application.scss
. It should be something like:
@font-face {
font-family: 'my-library';
src: url('../fonts/my-library.eot');
src:
url('../fonts/my-library.eot?#iefix') format('embedded-opentype'),
url('../fonts/my-library.woff2') format('woff2'),
url('../fonts/my-library.ttf') format('truetype'),
url('../fonts/my-library.woff') format('woff'),
url('../fonts/my-library.svg?#my-library') format('svg');
font-weight: normal;
font-style: normal;
}
Change to:
@font-face {
font-family: 'my-library';
src: asset-url('my-library/fonts/my-library.eot');
src:
asset-url('my-library/fonts/my-library.eot?#iefix') format('embedded-opentype'),
asset-url('my-library/fonts/my-library.woff2') format('woff2'),
asset-url('my-library/fonts/my-library.ttf') format('truetype'),
asset-url('my-library/fonts/my-library.woff') format('woff'),
asset-url('my-library/fonts/my-library.svg?#my-library') format('svg');
font-weight: normal;
font-style: normal;
}
asset-url
instead of url
../fonts
or similar to a path that asset-url
understands.To know which path asset-url
understands, go to rails console and enter Rails.application.assets.paths
. You will get something like:
[
'/path/1',
'/path/2',
'/path/3',
]
If your fonts are on /path/2/my-library/fonts/
then use
asset-url('my-library/fonts/my-library.eot')
.
i.e. You remove the path that part that you found on Rails.application.assets.paths
.
On Rails console on development:
helper.asset_url('my-library/fonts/my-library.eot')
Should return:
"/assets/my-library/fonts/my-library-2517b97e2c0e1e6c8ceb9dd007015f897926bc504154137281eec4c1a9f9bdc9.eot"
Note the trailing /assets/
and the digest in the last part.
Upvotes: 14
Reputation: 76774
We had this problem last week - the problem is that your assets will be compiled to have MD5 hashes on them, whilst your standard CSS will still be looking for their "standard" names. This is a problem with images & fonts.
@font-face {
font-family: 'akagi';
src: asset_url('fonts/akagi-th-webfont.eot');
src: asset_url('fonts/akagi-th-webfont.eot?#iefix') format('embedded-opentype'),
asset_url('fonts/akagi-th-webfont.woff') format('woff'),
asset_url('fonts/akagi-th-webfont.ttf') format('truetype'),
asset_url('fonts/akagi-th-webfont.svg#akagithin') format('svg');
font-weight: 300;
font-style: normal;
}
This is an example of how you should use scss files to load assets dynamically. These files are compiled (either before push or during init) into your .css files, all with their assets correctly synced.
We had a similar problem to you with Heroku, and managed to get it working by putting our files into /stylesheets/layout/fonts.css.scss and then calling
@import '/layout/fonts';
We also called our application.css -> application.css.scss to support the @import function
Upvotes: 25