Email and Universal Login Templates with Liquid on Auth0
• 7 minute read
auth0, liquid, ruby, sinatra
Table of contents
One thing that annoys me is how complex a software development life cycle can be if you're coding a project that depends on the platform to test and run in some sense. You can see similar circumstances if you're building something that relies on a Liquid template engine and Auth0. It has great guides about Customize Email Templates and Customize New Universal Login Pages, but they're insufficient. That's why I'm sharing the project Auth0 Liquid Tester so you can save time when creating your custom template 🚀.
How it works
You can issue the following command:
docker-compose up
Then you can check all the templates at http://localhost:9292/
. Because of this volume, if you update any template in the views folder, it will reflect immediately after a refresh in the browser. You can also test more complicated scenarios by changing what Liquid receives through the controllers:
All email templates come with some configuration about i18n. Look at this example from welcome_email.liquid
:
{% assign language = user.user_metadata.preferredLanguage %}
{% if language %}
{% assign language = user.user_metadata.preferredLanguage | slice: 0,2 %}
{% endif%}
{% assign company_name = "Rave of Phonetics" %}
{% capture company_image %}
<img alt="Rave of Phonetics" height="auto" src="https://avatars.githubusercontent.com/u/83559025?s=200&v=4" style="border: 0; display: block; outline: none; text-decoration: none; height: auto; width: 100%; font-size: 13px" width="150" />
{% endcapture %}
{% if language == 'pt' %}
{% capture action_image %}
<img alt="Símbolo que representa verificação" height="auto" src="http://cdn.auth0.com/website/emails/product/top-verify.png" style="border: 0; display: block; outline: none; text-decoration: none; height: auto; width: 100%; font-size: 13px" width="80" />
{% endcapture %}
{% capture highlighted_title %}
Cadastro validado.<br /> Seja bem-vindo!
{% endcapture %}
{% capture bottom_text %}
Você recebeu este e-mail porque você tem uma conta no {{ company_name }}. Se você não sabe o porquê está recebendo esta mensagem, por favor entre em <a href="{{ support_url }}" style="color: #0a84ae; text-decoration: none">contato conosco</a>.
{% endcapture %}
{% else %}
{% capture action_image %}
<img alt="Symbol that represents verify" height="auto" src="http://cdn.auth0.com/website/emails/product/top-verify.png" style="border: 0; display: block; outline: none; text-decoration: none; height: auto; width: 100%; font-size: 13px" width="80" />
{% endcapture %}
{% capture highlighted_title %}
Your account has been verified.<br /> Seja bem-vindo!
{% endcapture %}
{% assign highlighted_title = "You have been verified. Welcome!" %}
{% capture bottom_text %}
You’re receiving this email because you have an account in {{ company_name }}. If you are not sure why you’re receiving this, please contact us through our <a href="{{ support_url }}" style="color: #0a84ae; text-decoration: none">Support Center</a>.
{% endcapture %}
{% endif %}
The project also includes basic tests. In theory, you can create a test for each email template to guarantee that Liquid can render it correctly, including any required param that must be present, like {{ code }}
or {{ url }}
. Check out this sample where we assert that the verification email is rendered properly:
RSpec.describe(EmailController) do
context "verification email link" do
it 'should render properly' do
get '/verification-email-link'
expected_values = [
"jafar@willianantunes.com",
"https://www.willianantunes.com/",
"https://github.com/willianantunes/tutorials"
]
expect(last_response.status).to(be(200))
expected_values.each do |name|
expect(last_response.body).to(include(name))
end
end
end
end
Email templates available
Here's a list of what is available and a brief description of each one followed by its image. I took the definitions from Auth0 😁.
Verification Email (using Link)
This email will be sent whenever a user signs up or logs in for the first time.
Verification Email (using Code)
This email will be sent in scenarios where the user needs to prove they have access to the email on file for an account:
- You have enabled the code-based email verification flow, and a user signs up or logs into the account for the first time.
- You have enabled the Adaptive MFA policy, and there is a low-confidence transaction for which account ownership must be verified.
Welcome Email
This email will be sent once the user verifies their email address. If the Verification Email is turned off, it will be sent when the user signs up or logs in for the first time.
Enroll in Multifactor Authentication
This email will be sent when an admin sends a guardian enrollment email.
Change Password
This email will be sent whenever a user requests a password change. The password will not be changed until the user follows the verification link in the email.
Blocked Account Email
This email will be sent whenever a user is blocked due to suspicious login attempts.
Password Breach Alert
This email will be sent whenever Auth0 detects that the user is trying to access the application using a password that a third party has leaked.
Verification Code for Email MFA
Will provide the MFA verification code to a user using an MFA email verifier.
User Invitation
This email will be sent whenever a user is invited to an organization or application.
Passwordless Email
Will provide a code that the user can use to log in.
New Universal Login templates available
Again I took the templates from Auth0, excluding the one with a modal for terms of use. You can implement the terms of use with Redirect with Actions, but it's a lot more complicated as it requires an external service. All explained, let's see the templates.
Basic
The most straightforward template. It shows what happens if you just use the widget without anything else.
Login box + image
The following template will show the login box to the left and an image to the right only for the login/signup pages. The rest of the pages will look like the default ones. Use the query string to change how it behaves.
Page footers
The template adds a gray footer with links to Privacy Policy and Terms of Services.
Terms of use acceptance
This would happen only during the sign-up flow. The user would have to accept before going on.
Conclusion
At first glance, Auth0 seems to have all the sample projects you need to create yours, but that's only partly correct. Most sample projects are not production-ready, which is understandable from a certain point of view. Nevertheless, Auth0 offers a great development experience, and I can assure you it's on a whole different level when you compare it with its competitors. Excellent docs, various sample projects, great articles, easy integration process, diversity of libraries and SDKs, and many more. However, it's not flawless, and that's totally fine 🙂.
See everything we did here on GitHub.
Posted listening to Made of Tears, Joe Satriani 🎶.