premailer-rails
premailer-rails copied to clipboard
Webpacker Support
Hello!
I'm using Webpacker on a new Rails project and I would like to use Premailer on my outbound emails.
Is there any current plan to support Webpacker? Would you be open to PR's with a webpack strategy?
Hey @waltz!
Is there any current plan to support Webpacker?
Not really. What would be needed for that? Are you processing your CSS with Webpacker? How would that be different? premailer-rails, at least in production, just loads a CSS file. So I assume you're talking specifically about development, aren't you?
You're spot on, I'm processing my CSS with Webpacker and I'd like to use mailer previews in development to take a peek at things before I deploy.
I hacked on it for a little bit and managed to get it working. I built an adapter that looks for a running webpack dev server and asks it for the CSS. If you're interested I could make a PR.
I'm not too familiar with the Webpack integration in Rails. As I understand, at least in development, it's completely orthogonal to the asset pipeline, isn't it?
I hacked on it for a little bit and managed to get it working. I built an adapter that looks for a running webpack dev server and asks it for the CSS. If you're interested I could make a PR.
Sure, that would be a great starting point to discuss this further.
Hey guys - thanks for the great work. I have tried all solutions from this post and finally settled with premailer-rails.
I also got this error
could not be loaded by any strategy. (for /packs/mailer-3243232.css)
But I could solve it with this kinda hacky solution. Maybe it helps the next person as well until webpacker support gets included. I threw this into the mailer layout. Works with preview and emails.
<link href="<%= Rails.application.routes.default_url_options[:host]%><%= Webpacker.manifest.lookup("mailer.css") %>" media="screen" rel="stylesheet" type="text/css" />
My current project uses webpacker and I was able to get premailer-rails to work by copying the stylesheet_pack_tag from the head of our application layout into the head of the mailer layout.
!!!
%html
%head
%meta(content="text/html; charset=utf-8" http-equiv="Content-Type")
= stylesheet_pack_tag 'application', media: 'all'
%body
= yield
Hope that helps.
Both solutions only work if CSS is extracted into separate files, e.g. by setting extract_css
to true
in webpacker.yml
. (By default it is only true
for production) Otherwise Webpacker.manifest.lookup
and stylesheet_pack_tag
just return nil
.
It would be nice if premailer-rails supported javascript_pack_tag
, at least in development mode. But that would require processing script
tags and running Javascript before processing the document...
With Webpacker 4 and extract_css
set to true
I needed to use the following:
= stylesheet_link_tag "#{root_url.chomp('/')}#{asset_pack_path('email.css')}"
@full-of-foo did you try using stylesheet_pack_tag
instead of stylesheet_link_tag
?
@mhanberg yes, apologies, I see now that the following works:
# in development.rb
config.action_controller.asset_host = 'http://localhost:3000'
# in mailer
= stylesheet_pack_tag "email"
@full-of-foo @mhanberg Trying to get this to work now... Do I need to import the mailer SCSS file I want to use into my application.js
file? Or does the import statement belong in application.scss
instead?
@fphilipe Support for Webpacker really should be standard now that it will be bundled by default in Rails 6. Easier said than done, of course, but I imagine this is going to be a frequently asked question until support is added.
@mcmaddox I have a app/javascript/packs/mailer.js
that imports a app/javascript/css/mailer.css
.
In my app/views/layouts/mailer.html.haml
file, i have the following in the head
tag.
%head
%meta(content="text/html; charset=utf-8" http-equiv="Content-Type")
= stylesheet_pack_tag 'mailer', media: 'all'
I would consider this library to already have Webpacker support.
Strange... I followed the steps you outlined and I'm still not able to get premailer-rails to apply the stylesheet_pack_tag
from the layout to the HEAD
of my mailer in the iframe when I preview it on http://localhost:3000/rails/mailers.
Manifest.json shows both mailer.js and mailer.scss are being compiled in Webpacker, but only inline styles and adding CSS to a <style>
tag in the mailer itself (not the layout) are working right now.
Am I missing a configuration for premailer-rails? I only added the line from the instructions:
Premailer::Rails.config.merge!(preserve_styles: true, remove_ids: true)
I'm also using ERB, not HAML.
@mcmaddox
These are the only config that I have set for mail related things I think
# development.rb
config.action_mailer.default_url_options = { :host => "localhost:3000" }
config.action_mailer.asset_host = "http://localhost:3000"
@mhanberg I figured it out: my SCSS file was in the wrong file path & didn't include the stylesheet_pack_tag
helper. My mailer also didn't include the layout
call (DUH).
Everything is working now as you described. Thanks for your help.
@fphilipe Sorry for wasting your time. Thanks for the truly helpful gem.
@mcmaddox I'm glad you got it working.
For the record, I don't think you're wasting anyone's time 😄.
@mcmaddox no worries 😊 As I'm not using this gem at the moment and haven't really used webpacker, I can't help much.
We are running into this issue as well. Is it fair to say that - as @daniel-rikowski alluded to - if one has extract_css
set to false
, there is no good workaround for using premailer with webpacker?
There are 2 things you need to do to get this to work correctly, first, you need to have something like this in your mailer layout (when not extracting css, it comes as javascript). This will get that javascript tag into the layout, but then premailer strips it out:
- if Rails.env.production?
= stylesheet_pack_tag 'mailer'
- else
= javascript_pack_tag 'mailer'
So after you have that, if you set a message header like this:
headers[:skip_premailer] = true if Rails.env.development?
You should be able to see your styles. I'm going to work on a PR that will not strip the javascript tag if it has a special class.
I know that there's a better way to detect if extract_css is true or false, rather than depending on the Rails.env. Will add that when I find it.
Also, instead of adding that skip_premailer to the headers in the mailer action, you could also setup a before_action in the mailer or set the default headers in your development.rb config like this:
config.action_mailer.default_options = {
skip_premailer: true
}
Of course, all of this just disables premailer in development, so it's not going to at this point show you exactly what is produced in production vs dev enviroments, but at least allows you to use hmr/inline styles AND preview emails.
Looks like premailer also accepts this option, which could be put in an initializer:
Premailer::Rails.config.merge!(remove_scripts: false)
I think the right way forward @fphilipe would be to add another "strategy" that works with webpacker .js files, to get the CSS out of what's generated there.
@niedfelj, happy to accept a PR for this! 😊 👍
@mcmaddox
These are the only config that I have set for mail related things I think
# development.rb config.action_mailer.default_url_options = { :host => "localhost:3000" } config.action_mailer.asset_host = "http://localhost:3000"
I've made it working including the asset_host
config, thanks!
@fphilipe hey, someone else already wrote the code.
Take a look:
https://github.com/leslie-clutter/premailer-rails/commit/27c3d82b12272404614004eedcb039b1534228aa
What do you think? I can help with that.
@niedfelj I could not move forward with this PR, could you give some help here?
Hi there, any plans to merge the pull request? Webpacker has been bundled with rails for quite some time now. Cheers
Just checking in here to see what the best practice is to use premailer with webpacker. I can't get it working for the life of me, no matter what I try from any comment above.
Thank you!
We have been able to keep premailer active in development since today on our app, in mailer preview.
Webpacker 6 (Webpacker 5) on Rails 6.1
Thought I'd post what worked for me, it's basically a mix of the methods gathered from here. I'm on:
- Rails
6.1
- Webpacker
5.3.0
- Premailer Rails
1.11
Steps:
- Create a file for the mailer css:
app/javascript/stylesheets/mailer.scss
// Entirety of your css here
* {
margin: 0;
padding: 0;
}
- Import that mailer css in a javascript pack file:
app/javascript/packs/mailer.js
import "../stylesheets/mailer";
- Set
extract_css
option totrue
in yourwebpacker.yml
so webpacker builds a separate css file to hook into:config/webpacker.yml
...
extract_css: true
...
- Added
stylesheet_pack_tag
to mailer layout file<head>
tag to load the css file:app/views/layouts/mailer.html.erb
<!DOCTYPE>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Title</title>
<%= stylesheet_pack_tag 'mailer' , media: 'all' %>
</head>
- Setup action mailer config:
config/environments/development.rb
:
Rails.application.configure do
# ...
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
config.action_mailer.asset_host = "http://localhost:3000"
# ...
end
- And of course make sure you've installed the
premailer-rails
gem (with initializer) following its documentation
Hope this can help others!
Thought I'd post what worked for me, it's basically a mix of the methods gathered from here. I'm on Rails 6.1 Hope this can help others!
Exactly what I was looking for! :+1: Thank you so much for sharing! <3
It is still not working for me. I'm not sure what I'm doing incorrectly.
I've:
- Created an initializer (don't think that's necessary)
- Created a
mailer.css
file underjavascript/stylesheets
- Created a
mailer.js
pack underjavascript/packs
- Set
extract_css: true
onconfig/webpacker.yml
- Set up the
config/environment/development.rb
- In my mailer layout, I've either used
stylesheet_pack_tag
orjavascript_pack_tag
with no results. - Made sure I had
premailer-rails
installed, haha
My Rails version is 5.2.8 with Webpacker 5.2.1
It is still not working for me. I'm not sure what I'm doing incorrectly.
I've:
1. Created an initializer (don't think that's necessary) 2. Created a `mailer.css` file under `javascript/stylesheets` 3. Created a `mailer.js` pack under `javascript/packs` 4. Set `extract_css: true` on `config/webpacker.yml` 5. Set up the `config/environment/development.rb` 6. In my mailer layout, I've either used `stylesheet_pack_tag` or `javascript_pack_tag` with no results. 7. Made sure I had `premailer-rails` installed, haha
My Rails version is 5.2.8 with Webpacker 5.2.1
I'm on Rails 6 and I haven't tried on Rails 5 so there might be some fundamental difference there potentially (I've updated my original post with all my version specs). Here's a few things to try though:
For the extract_css
parameter make sure it's being set for the environments you need it to be, and if you put it under default
so that it works in all environments make sure you aren't overwriting it later in the file in the environment specific sections.
When running the server is Webpack compiling everything correctly? Do you see it creating a separate mailer.css
file? Something like:
css/mailer.css 3.16 KiB mailer [emitted] [immutable] mailer
And are your styles being imported correctly into that file?
Are there any differences between your mailer.js
and mine?
I think(?) it has to be a stylesheet_pack_tag
because the gem looks for linked stylesheets
I believe you do need the initializer from the gem documentation so it will run automatically on outgoing emails