tldr: You can scroll to the Solution section if you want the final code.
Sometimes you need to let your users preview some emails, like transactional emails customized by them with some content or style.
I have to built a preview system like this for Superdocu, and I thought it’ll be an easy task thanks to ActionMailer::Preview. But it wasn’t : there’s no officiel documentation for embedding this feature in production.
Finally, the default preview system used by
ActionMailer::Preview is not a
valid solution, because it can’t be easily integrated ou customized in the
I tried to call the mailer directly and render its html part (decoded) like this:
But it didn’t work, because of inline attachments which aren’t correctly decoded 😕
So I have to understand how rails emails previewing system works and how to use it in order to implement my previewing system, and avoid to rewrite in html my mailers’ views (it uses the mjml framework, so mjml templates and not html templates).
Investigating how to extract the email previewing system
I started by investigating rails logs to find the name of the controller which
handles the preview action :
It has multiple actions, but it’s the
preview action which is interesting for us :
it handles both the entire page and the iframe part.
Here is the
preview action code 👇
The first condition handles when there’s no action in the path. For example if you have an
actionmail preview for
UserMailer, it will renders available preview methods.
The second part (in the first else) handles both the view with iframe and the mailer content part inside iframe ( the content part action is called here ).
Now I have to understand how the final render works on this preview system: there’s a class which handles this magic, which is ActionMailer::InlinePreviewInterceptor.
This class replace converts image tag src attributes that use inline
cid: style URLs
data: style URLs so that they are visible when previewing an HTML email in a web browser.
preview action, this class is called here:
call method from
ActionMailer::Preview class calls a private method
), which calls the
which does the trick on images 🪄
Thanks to this investigation, I managed to fix the original implementation like this:
Have a nice day 🙃