diff --git a/content/post/about-html-mails/index.md b/content/post/about-html-mails/index.md new file mode 100644 index 0000000..994602e --- /dev/null +++ b/content/post/about-html-mails/index.md @@ -0,0 +1,125 @@ +--- +title: "Thoughts on HTML mails" +date: 2025-07-12T12:05:10+02:00 +draft: false +image: "uploads/html-e-mails.png" +categories: ['English'] +tags: ['email', 'html', 'plaintext', 'django', 'notfellchen'] +--- + +Lately I worked on notification e-mails for [notfellchen.org](https://notfellchen.org). Initially I just sent text +notifications without links to the site. Terrible idea! An E-Mail notification I send always has Call-to-Action or at +minimum a link to more information. + +I left the system like this for half a year because it kinda worked for me (didn't suck enough for me to care), and I was the main receiver of these notifications. +However, as the platform is developed further and more users join I need to think about more user-centric notifications. + +So what do I imagine is important to a user? +* +* **Information benefit**: An e-mail has the purpose to inform a user. This information should be immediately visible & understandable. +* **Actionables**: Users should be able to act on the information received. This is the bright red button "DO SOMETHING NOW!" you see so often. +* **Unsubscribing**: Informing e-mails stop is not only a legal requirement and morally the right thing to do but it also gives users agency and - I hope - increases the User Experience + +With these I naturally came to the next question: Plaintext or HTML? + +Some people would say [Plaintext is inherently better](https://useplaintext.email/) than HTML e-mails. Many of these reasons resonate with me including: +* Privacy invasion and tracking +* HTML emails are less accessible +* Some clients can't display HTML emails at all +* Mail client vulnerabilities + +These are all valid points and are a reason I generally enjoy plaintext e-mails when I receive them. +But this is not about me but users. And there are some real benefits of HTML e-mails: +* Visually appealing: This is subjective but generally most users seem to agree on that +* User guidance: Rich text provides a real benefit when searching for the relevant information + +Be honest: Do you read automated e-mails you receive completely? Or do you just skim for important information? + +And here HTML-mails shine: **Information can easily be highlighted** and big button can lead the user to do the right action. +Some might argue that you can also a highlight a link in plaintext but that nearly always will worsen accessibility for screen-reader user. + +# The result + +In the end, I decided that providing plaintext-only e-mails was not enough. I set up html mails, mostly using +[djangos send_mail](https://docs.djangoproject.com/en/5.2/topics/email/#send-mail) function where I can pass the html message and attattching it correctly is done for me. + +![A screenshot of an e-mail in thunderbird. The e-mail is structured in header, body and footer. The header says "Notfellchen.org", the body shows a message that a new user was registered and a bright green button to show the user. The footer offers a link to unsubscribe](mail_screenshot.png) + + +For anyone that is interested, here is how most my notifications are sent +```python +def send_notification_email(notification_pk): + notification = Notification.objects.get(pk=notification_pk) + + subject = f"{notification.title}" + context = {"notification": notification, } + if notification.notification_type == NotificationTypeChoices.NEW_REPORT_COMMENT or notification.notification_type == NotificationTypeChoices.NEW_REPORT_AN: + html_message = render_to_string('fellchensammlung/mail/notifications/report.html', context) + plain_message = render_to_string('fellchensammlung/mail/notifications/report.txt', context) + [...] + elif notification.notification_type == NotificationTypeChoices.NEW_COMMENT: + html_message = render_to_string('fellchensammlung/mail/notifications/new-comment.html', context) + plain_message = render_to_string('fellchensammlung/mail/notifications/new-comment.txt', context) + else: + raise NotImplementedError("Unknown notification type") + + if "plain_message" not in locals(): + plain_message = strip_tags(html_message) + mail.send_mail(subject, plain_message, settings.DEFAULT_FROM_EMAIL, + [notification.user_to_notify.email], + html_message=html_message) +``` + +Yes this could be made more efficient - for now it works. I made the notification framework too complicated initially, so I'm still tyring out what works and what doesn't. + +Here is the html template +```html +{% extends "fellchensammlung/mail/base.html" %} +{% load i18n %} +{% block title %} + {% translate 'Neuer User' %} +{% endblock %} + +{% block content %} +

Moin,

+

+ es wurde ein neuer Useraccount erstellt. + +

+

+ Details findest du hier +

+

+ {% translate 'User anzeigen' %} +

+{% endblock %} +``` + +and here the plaintext +``` +{% extends "fellchensammlung/mail/base.txt" %} +{% load i18n %} +{% block content %}{% blocktranslate %}Moin, + +es wurde ein neuer Useraccount erstellt. + +User anzeigen: {{ new_user_url }} +{% endblocktranslate %}{% endblock %} +``` + + + +Works pretty well for now. People that prefer plaintext will get these and most users will have skimmable html e-mail where the +styling will help them recognize where it's from and what to do. Accessibility-wise this seems like the best option. + +And while adding a new notification will force me to create +* a new notification type, +* two new e-mail templates and +* a proper rendering on the website + +this seems okay. Notifications are useful, but I don't want to shove them everywhere. I'm not running facebook or linkedin after all. + +So for now I'm pretty happy with the new shiny e-mails and will roll out the changes soon (if I don't find any more wired bugs). + +PS: I wrote this post after reading [blog & website in the age of containerized socials](https://blog.avas.space/blog-website-eval/) by ava. +Maybe this "Thoughts on" format will stay and I will post these in addition to more structured deep dives. \ No newline at end of file diff --git a/content/post/about-html-mails/mail_screenshot.png b/content/post/about-html-mails/mail_screenshot.png new file mode 100644 index 0000000..3f049aa Binary files /dev/null and b/content/post/about-html-mails/mail_screenshot.png differ diff --git a/static/uploads/html-e-mails.png b/static/uploads/html-e-mails.png new file mode 100644 index 0000000..0cccc95 Binary files /dev/null and b/static/uploads/html-e-mails.png differ