locomotivecms / steam

The rendering stack used by both Wagon and Station (new name of the engine). It includes the rack stack and the liquid drops/filters/tags.
MIT License
38 stars 59 forks source link

{{ base_url }} doesn't work in email templates #217

Open greyskin opened 1 year ago

greyskin commented 1 year ago

On a number of sites we manage, we have set up various email templates to be delivered to our clients' customers when they perform certain actions on the site, e.g. register for an account, place an order, etc.

We have been using {{ base_url }} in conjunction with the {% path_to 'page-handle' %} tag in our email templates and we have realised that this doesn't work as we expected. Specifically, it only renders the relative page link.

Example:

I've done some testing and have removed {{ base_url }} entirely and the result is the same. I expect our email client (Gmail) is adding the URL protocol (http://) automatically, which would indicate that {{ base_url }} isn't being rendered at all.

Obviously, we can hard-code the URL protocol and site domain for every site, but this is far from ideal. Is this expected behaviour?

did commented 1 year ago

@greyskin thanks for bringing this topic up.

First of all,{{ base_url }} is an alias pointing to the base_url method of the rack HTTP request. Here is the current implementation:

def base_url
  "#{scheme}://#{host_with_port}"
end

We do have an "issue" with base_url in the context of email sending. When we send an email which is going to use a page liquid template, we use a different rendering mechanism, different from the classical HTTP one. And we don't pass the rack HTTP request since email can be delivered asynchronously. So, the result is that {{ base_url }} will return indeed an empty string.

My recommendation is to write something like this in email page templates:

<a href="{{ site.domains | first }}{% path_to 'contact' %}">Contact us</a>

Regarding assets, I declare my css like this:

<link href="{{ 'email.css' | stylesheet_url | absolute_url }}" media="screen" rel="stylesheet" type="text/css">
greyskin commented 1 year ago

Thanks @did,

That's very useful information. I've implemented your suggestion and it works as expected.


For others who might stumble across this, one thing to note is that {{ site.domains }} will render nothing if the email is triggered from a staging domain (e.g. station.locomotive.works). To ensure complete working functionality for our customers during the sign-off phase of a project, I would implement something like:

{% if site.domains == empty %}
    {% assign baseURL = 'https://station.locomotive.works' %}
{% else %}
    {% assign baseURL = site.domains | first | prepend: 'https://' %}
{% endif %}

Then:

<a href="{{ baseURL }}{% path_to 'contact' %}">Contact us</a>