Skip to content

Instantly share code, notes, and snippets.

Last active April 4, 2023 15:02
  • Star 30 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Inline CSS or JS in Rails
config.assets.precompile += [
# precompile any CSS or JS file that doesn't start with _
def read_file_contents(stylesheet)
if %w(test development).include?(Rails.env.to_s)
# if we're running the full asset pipeline,
# just grab the body of the final output
# in a production-like environment, read the
# fingerprinted and compiled file, 'public', 'assets', stylesheet.digest_path))
def inline_file(asset_path)
file = Rails.application.assets.find_asset(asset_path)
file.nil? ? '' : read_file_contents(file)
def inline_js(asset_path)
"<script>#{inline_file asset_path}</script>"
def inline_css(asset_path)
"<style>#{inline_file asset_path}</style>"
# use a method like this to automatically load CSS that
# follows the current controller/action name structure
# example: assets/stylesheets/views/users/show.sass
def current_view_stylesheet
inline_css("views/#{params[:controller]}/#{params[:action]}") +
Copy link

wafiq commented Oct 27, 2015

Should stylesheet.body be stylesheet.source instead?


Copy link

Dagnan commented Jan 25, 2017

.source works for Rails 5.

Copy link

Dagnan commented Jan 25, 2017

Copy link

dignoe commented Mar 3, 2017

FYI - I couldn't get this to work in Rails 3.2 with Sprockets 2.2.3. Here's what I did (created independently of this code, but posting here for anyone who needs some help):

module StylesheetsHelper


  def include_inline_stylesheet(file)
    content_for :stylesheets do
      content_tag("style", inline_stylesheet_source(file).html_safe, type: "text/css")

  def inline_stylesheet_source(file)
    path = file.pathmap("%-1d")
    filename = File.basename(file, ".html.erb").titleize.parameterize

    if Rails.env.development? || Rails.env.test?
      asset_path = ActionController::Base.helpers.asset_path("responsive/inline/#{path}/#{filename}.css")"#{Rails.root}/public#{asset_path}")


And then in my views I add <%= include_inline_stylesheet(__FILE__) %> and I have a <%= yield :stylesheets %> in my <head>.
CSS files are in the format of responsive/inline/orders/index.css.scss (Note that this code replaces underscores with dashes in the filename, so my_file.html.erb becomes my-file.css).

Copy link

This is genius. Thank you a lot, @averyvery and @Dagnan!

Copy link

wagoid commented Sep 25, 2017

@averyvery you could also leverage Rails cache when reading the file contents, replacing this:, 'public', 'assets', stylesheet.digest_path))
by this:
render file: File.join(Rails.root, 'public', 'assets', stylesheet.digest_path)

render here will return the actual string with the file contents, because it's being called from a view template 😃
That will avoid a lot of I/O operations and make your users happier!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment