sofarsophie
sofarsophie

Reputation: 239

Ruby on Rails CSS/JS error with Turbolinks

I'm building a web app on ROR5 and the layout/design is all done, with the CSS/JS files finalized. But when I open the app, click on one link, and navigate through the website, the CSS fails to load. More specifically, the CSS is all messed up. For example, say I go from 'Home' -> 'Page A', then if I backspace to 'Home' again (or click the logo to navigate to 'Home'), the 'Home' page will be messed up. Only when I refresh the page, I would get the correct display.

At first I thought it was a cache problem, but soon discovered that this line is causing the issue:

<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> 

When I delete this line, the display issue is no longer present. However, all JS effects/JS-based plugins would not work. I have a text editor, a few jQuery animations and tab navigations, which all don't work when I delete that line. + of course, instead of just deleting the line, I also tried to simply disable turbolinks by doing: <%= javascript_include_tag 'application' %> and removing turbolinks from my Gemfile. This also didn't work.

My Gemfile includes: gem 'turbolinks', '~> 5' gem 'coffee-rails', '~> 4.2' gem 'jquery-rails'

And the remaining GEMs are all standard gems for my frontend side (bootstrap, SASS, font awesome etc).

My application.js looks like this:

//= require rails-ujs
//= require jquery
//= require jquery_ujs
//= require tinymce
//= require turbolinks
//= require bootstrap-sprockets
//= require_tree .

And for reference, my application.html.erb contains a like the following:

<head>
    <title>..</title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag 'application', media: 'all' %>
    <%= stylesheet_link_tag params[:controller] %>

    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> 
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Adobe Typekit Scripts -->
    <script src="https://use.typekit.net/ovy4zfg.js"></script>
    <script>try{Typekit.load({ async: true });}catch(e){}</script>
</head>

What could be the problem? Thanks.

Upvotes: 1

Views: 3146

Answers (3)

Yinka
Yinka

Reputation: 11

Tried the same thing, reinstall Webpacker and still for the error

Webpacker can't find application in C:/Users/Admin/friends/public/packs/manifest.json. Possible causes:

  1. You want to set webpacker.yml value of compile to true for your environment unless you are using the webpack -w or the webpack-dev-server.
  2. webpack has not yet re-run to reflect updates.
  3. You have misconfigured Webpacker's config/webpacker.yml file.
  4. Your webpack configuration is not creating a manifest. Your manifest contains: { }

Upvotes: 1

Michael Trojanek
Michael Trojanek

Reputation: 1943

For people who came here with a slightly different problem:

When using different CSS files for different areas of your application (e.g. application.css for your regular app and admin.css for your admin area), Turbolinks fails to handle them properly when they do not live on separate (sub)domains.

So when /admin uses a different CSS file than the rest of the application, clicking a link to, say, /admin/posts and then using the back button to navigate back to /, the wrong CSS file will be used.

In this case, you need to set a root location for Turbolinks.

From the docs:

By default, Turbolinks only loads URLs with the same origin — i.e. the same protocol, domain name, and port — as the current document. A visit to any other URL falls back to a full page load.

In some cases, you may want to further scope Turbolinks to a path on the same origin. For example, if your Turbolinks application lives at /app, and the non-Turbolinks help site lives at /help, links from the app to the help site shouldn’t use Turbolinks.

Include a <meta name="turbolinks-root"> element in your pages’ <head> to scope Turbolinks to a particular root location. Turbolinks will only load same-origin URLs that are prefixed with this path.

To make the admin area under /admin from my example display the CSS correctly, include <meta name="turbolinks-root" content="/admin"> in the layout's <head>.

Upvotes: 3

Dom Christie
Dom Christie

Reputation: 4240

I think the issue here is that you're loading in controller-specific stylesheets (<%= stylesheet_link_tag params[:controller] %>). Turbolinks will append new stylesheets, but will not remove those that are absent in subsequent page loads. So here is the flow:

  1. User visits Home
  2. Stylesheet for Home's controller loaded
  3. User visits Page A
  4. Stylesheet for Page A's controller loaded after the Home CSS
  5. Home CSS and Page A CSS will remain in the head

If possible, include all your CSS in the application.css manifest file. If you have some controller-specific styles, try adding a class to the body, e.g.:

<body class="<%= controller_name %>">

Then you can scope your styles, e.g. for a pages_controller:

body.pages {
  …
}

Alternatively you could add data-turbolinks-track="reload" to your CSS link tag:

<%= stylesheet_link_tag params[:controller], 'data-turbolinks-track': 'reload' %>

However, this will mean that you will only get the benefits of Turbolinks when navigating between pages that use the same controller. When navigating between pages that use a different controller, you will get a full page load. This is because Turbolinks will track the presence or absence of the CSS and reload if it has changed.

One last thing: it is generally a good idea to add 'data-turbolinks-track': 'reload' to your application.css so that if you release a new version of your CSS, the users on the site will be up-to-date when the change goes live.

Hope that helps

Upvotes: 2

Related Questions