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.
Thereās plenty of topics on StackOverflow, but none of them explains how to extract or use the rails preview system used in development.
Thereās also a few gems (Maily or Rails Email Preview for example), but they use rails engines, which is not really end-user friendly.
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
application.
I tried to call the mailer directly and render its html part (decoded) like this:
Controller
View
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 : Rails::MailersController
I searched in the rails basecode, with the controller named, which can be find here, in the railties folder.
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
to data:
style URLs so that they are visible when previewing an HTML email in a web browser.
In our preview
action, this class is called here:
The call
method from ActionMailer::Preview
class calls a private method
inform_preview_interceptors
(
source
), which calls the
ActionMailer::InlinePreviewInterceptor
ās transform
method
(
source
),
which does the trick on images šŖ
Solution
Thanks to this investigation, I managed to fix the original implementation like this:
Controller
View
Have a nice day š