Can't access images and fonts on production Rails - ruby-on-rails

I access some static images (favicon, etc) through /assets/image.jpg.
It works as expected on localhost but when I push in production, I can't access fonts and images.
Css and js are compiled and working fine.
I've added this to my production.rb file but it still doesn't work :
config.serve_static_files = true
config.serve_static_assets = true
config.assets.compile = true
What do I have to write to access them and where ?

Ok, I figured, it was dumb :
In production we have to use rails link helpers to provide assets, for example, you can't access favicon with :
<link rel="shortcut icon" type="image/gif" href="/assets/images/favicon.gif"/>
we have to use
<%= favicon_link_tag 'favicon.gif' %>
because a sha is generated and produces the following link for example
/assets/favicon-02168c53f101e2059920863c64a71d6abc53b4fbec334f2e0b002f7866e63b69.gif

Related

Search robots can't index because of assets present rails heroku

On these websites https://staging.blockbutler.io and https://blockbutler.io (RoR on heroku both)
Google and Yandex search bots can't index with reason: 'robots.txt blocks'
but robots.txt is fine. And if you will remove
javascript_include_tag and stylesheet_link_tag it perfectly indexed the page. I spent 3 days of trying different tests - nothing helps:
if there are only javascript_include_tag with empty
application.js or only stylesheet_link_tag with empty
application.scss - no indexing
add gem 'rails_12factor' - no
indexing
rake assets:precompile RAILS_ENV=production and push static files from public/assets to server - no indexing
put assets in footer - no indexing
wrap assets in <noindex> and rel: "nofollow" - no indexing
I really don't know what da magic is going on and be really happy for any ideas
Logs when run google search console live test:
production.rb:
config.assets.js_compressor = :uglifier
config.assets.enabled = true
config.assets.version = '1.0'
config.assets.compile = true
robots.txt:
User-agent: *
Allow: /
User-agent: Yandex
Allow: /
User-agent: Google
Allow: /
Sitemap: https://blockbutler.io/sitemap.xml
p.s. sorry for bad english - will appreciate editing my language (:
Some freaking magic over here.
Change <%= javascript_include_tag 'application', rel: "nofollow" %> to <script src="/assets/application.js" rel="nofollow"></script>
And now google indexer works just fine. GooGLe InDExER DoesN'T LiKE BIg fiLe NamES. Will think about how to prevent cache assets file.
p.s. ok. Now every time Im updating assets - Im changing assets name, like applicationv0.js and etc. Still have no idea, why google wasn't ok with default application-hash.js filename

Rails webpacker.yml, extract_css option

According to rails/webpacker documentation, extract_css is default to true in production environment and false in development. From what I observed:
With extract_css true, webpacker will emit a css file from each stylesheet_pack_tag in application.html.erb.
And, with extract_css false, stylesheet_pack_tag return nil & stylesheet that gets imported in js files will get extracted and bundle into blobs and send to browser. Hence, link tags to blob url exist.
So, I assume that using extract_css true yield the same result as using inline styles in header since styles get downloaded to browser with the website document file. If what I understand is true then setting extract_css to true on production should be ok.
Is what I understand about extract_css option correct?
You mostly correct, you can read more about extract_css in css.md or v4-upgrade.md
With extract_css: true, webpacker will emit a single css <link rel="stylesheet"... from each stylesheet_pack_tag.
With extract_css: false, stylesheet_pack_tag return nil & stylesheet that gets imported in js files will get extracted and bundle into blobs and injected into as an inline .
In the end extract_css: false is the one that yields the same result as using inline styles.
I don't have anything to add other than "extract_css" in webpacker.yml has been a source of confusion for me as well. When it is "extract_css: false" in development and production, a stylesheet IS included in the document head (shouldn't this be "extract_css: true"?). And when I use "extract_css: true", styles are not included in the document.

How to load a marker png from within leaflet that is held in assets/images of a production site

My rails site is using the leaflet gem. I have no trouble loading the png in development, but when I switch to my production site the path now start under leaflet.
I want my path to by MY_WEB_SITE/assets/images/ but in production it becomes MY_WEB_SITE/assets/leaflet/dist/images/
I've attached .erb to my coffeescript. And the following code:
digested_icon = L.icon({
iconUrl: "<%= asset_path 'marker-icon.png' %>"
iconRetinaUrl: "<%= asset_path 'marker-icon-2x.png' %>"
shadowUrl: "<%= asset_path 'marker-shadow.png' %>"
})
sgMarker = L.marker(sgLatLng, {icon: digested_icon})
I've also tried asset_url, but it has the same effect.
Configure asset pipeline to compile .png files (particularly in vendor/ as it's not done by default):
# In config/initializers/assets.rb
Rails.application.config.assets.precompile += ["*.png"]
This will allow your .png images to be compiled to public/assets/leaflet/dist/images/ then they will show up in production.

asset_path returns wrong path for folder

I have .swf files under vendor/assets/images/swf/. I need the asset path of that folder.
But this (.js.coffee.erb)
#= soundmanager2
$ ->
soundManager.setup
url: '<%= asset_path "swf/" %>'
is rendering this (.js):
(function() {
var $ = jQuery;
$(function() {
return soundManager.setup({
url: '/swf/'
});
});
}).call(this);
I am using rails 4.0.0.rc1. I am on development mode. The path /assets/swf/soundmanager2.swf returns 200, while /swf/soundmanager2.swf returns 404. The helper image_path returns /images/swf/, but /images/swf/soundmanager2.swf also returns 404.
It is not worth the trouble, because you would have to disable digest to get the name of the files right. So the solution is to fix the library. In the case of Sound Manager 2, I did this:
Some CoffeeScript that I require:
#= require soundmanager2
jQuery ->
soundManager.swfNames =
"/soundmanager2.swf": "<%= asset_path('swf/soundmanager2.swf') %>"
"/soundmanager2_debug.swf": "<%= asset_path('swf/soundmanager2_debug.swf') %>"
"/soundmanager2_flash9.swf": "<%= asset_path('swf/soundmanager2_flash9.swf') %>"
"/soundmanager2_flash9_debug.swf": "<%= asset_path('swf/soundmanager2_flash9_debug.swf') %>"
soundManager.setup
debugMode: <% if Rails.env.development? %>true<% else %>false<% end %>
url: '/'
In my copy of soundmanager2.js (V2.97a.20130512), inside the definition of normalizeMovieURL:
url = ... // After url is set
url = sm2.swfNames[url]; // Workaround
on rails 4 all the asset helpers (image_path, asset_path and the likes) appear to only return a config.assets.prefix-prefixed path if the asset you're accessing is actually resolvable by sprockets.
put simply: it must exist in you asset path on the disk after precompilation.
therefore, asset_path('swf/') will not work since it is a directory and not a file.
also, i experienced the following: rails < 4 (sprockets, rather) copied original images (and thus swf files) and created a digested version of that same file. because of this soundmanager was still able to find the non-digested swf files even though i have config.assets.digest = true.
with rails 4, these original images are not copied anymore because they changed some precompile internals which leads soundmanager to throw up if it wants to fallback to flash.
to properly fix this soundmanager needs to be patched, like michelpm proposes.
for soundmanager-rails i started working on a fix including a proper patch for soundmanager which you can find over on github.

Conditional javascript require in the asset pipeline

I'm struggling with the asset pipeline. I'm loading dojo from Google CDN putting this in my template:
= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js', :'data-dojo-config' => %Q(dojoBlankHtmlUrl:'/blank.html', baseUrl: 'assets/', modulePaths: {custom: 'javascripts/modules'})
I just want a fallback to a local version if running locally or if the CDN is down. I thought of doing this:
script typeof(dojo) === "undefined" && document.write(unescape('%3Cscript src="js/libs/dojo-1.6.1.min.js"%3E%3C/script%3E'));
But I don't like it as it works out of the asset pipeline. I want to keep dojo in vendors/assets/javascripts/dojo. How can I get the fallback to be served by the asset pipeline.
Is there a way do declare conditional require in the asset pipeline. What I want is to run some javascript tests, and depending on the result serve a file.
Thanks
I suggest you use yepnope, a lightweight library for loading libraries like this in parallel (for speed) and it gives you the option to run some other code to test if the library is loaded. For example:
yepnope([{
load: 'http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js',
complete: function () {
if (!window.jQuery) {
yepnope('asset_path('you_local_copy_of_dojo') ');
}
}
}])
(Note: You will need erb tags around the asset_path helper)
The local dojo file would be in the assets/javascript folder, but not included in the application manifest. You need to add the dojo file to the precompile array:
config.assets.precompile += 'your_local_file.js'
And this will make it available to the asset_path helper.
Thanks Richard!
I don't want to have yepnope to load one library. It would be overkill imo. Here is the solution I came up with, based on your help (written in slim):
1/ In vendors/assets/javascripts/, I have my dojo.js.
2/ In config/application.rb:
# Precompile these assets files
config.assets.precompile += ['dojo.js']
3/ In the template:
= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/dojo/#{Settings.dojoVersion}/dojo/dojo.xd.js", :'data-dojo-config' => %Q(dojoBlankHtmlUrl:'/blank.html', baseUrl: 'assets/', modulePaths: {custom: 'javascripts/modules'})
script = "typeof(dojo) === \"undefined\" && document.write(unescape('%3Cscript src=\"#{asset_path('dojo')}\"%3E%3C/script%3E'));".html_safe
I also posted on the Rails Google Group to request the addition of two options to the javascript_include_tag, :test and :local that would take care of all the work. We'll see.

Resources