feat: Add thoughts on html mails post
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				ci/woodpecker/push/woodpecker Pipeline was successful
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	ci/woodpecker/push/woodpecker Pipeline was successful
				
			This commit is contained in:
		
							
								
								
									
										125
									
								
								content/post/about-html-mails/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								content/post/about-html-mails/index.md
									
									
									
									
									
										Normal file
									
								
							@@ -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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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 %}
 | 
				
			||||||
 | 
					    <p>Moin,</p>
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					        es wurde ein neuer Useraccount erstellt.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					        Details findest du hier
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					    <p>
 | 
				
			||||||
 | 
					        <a href="{{ notification.user_related.get_full_url }}" class="cta-button">{% translate 'User anzeigen' %}</a>
 | 
				
			||||||
 | 
					    </p>
 | 
				
			||||||
 | 
					{% 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. 
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								content/post/about-html-mails/mail_screenshot.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								content/post/about-html-mails/mail_screenshot.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 51 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								static/uploads/html-e-mails.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/uploads/html-e-mails.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 197 KiB  | 
		Reference in New Issue
	
	Block a user