Self-Hosting

Custom Email Templates

Configure custom email templates with self-hosted Supabase instance


When running a self-hosted Supabase instance, you can fully customize emails sent by Supabase Auth.

Overview#

Supabase Auth does not read email templates from mounted Docker volumes. Instead, it expects each template to be available at a URL that returns a valid HTML template.

This URL:

  • Does not need to be public
  • Must be reachable from auth service
  • Must return a valid Golang HTML template

To provide templates to Supabase Auth, you need a service that serves static HTML files. This can be any server of your choice. You can even use kong service which is included with the default Supabase docker configuration. The only requirement is that the auth service must be able to reach it via a HTTP GET request.

This guide uses Caddy for serving templates.

Authentication email templates#

Authentication email templates can be configured using the following environment variables:

  • GOTRUE_MAILER_TEMPLATES_<AUTH_FLOW>: Provide a custom template URL. Falls back to the default template if not set.
  • GOTRUE_MAILER_SUBJECTS_<AUTH_FLOW>: Customize the email subject. Falls back to the default subject if not set.
Auth flowSent
CONFIRMATIONWhen a user signs up and needs to verify their email address
RECOVERYWhen a user requests a password reset
MAGIC_LINKWhen a user requests a magic link for password-less authentication
INVITEWhen a user is invited to join your application via email invitation
EMAIL_CHANGEWhen a user requests to change their email address
REAUTHENTICATIONWhen a user needs to re-authenticate for sensitive operations

For example:

1
GOTRUE_MAILER_TEMPLATES_MAGIC_LINK='<template_url>'
2
GOTRUE_MAILER_SUBJECTS_MAGIC_LINK='<custom_subject>'

Example#

Below is an example configuration for setting up a custom invite template.

Step 1: Create a templates directory#

Create a templates directory inside the existing volumes directory and add your email templates to it.

Your directory structure should look like this:

1
volumes/
2
templates/
3
invite.html

Step 2: Update docker-compose.yml#

Update the auth service to depend on templates-server, and pass the email template environment variables. Then add a templates-server service to serve the templates from ./volumes/templates.

1
services:
2
auth:
3
depends_on:
4
db:
5
condition: service_healthy
6
templates-server: # 👈 new dependency
7
condition: service_started
8
environment:
9
GOTRUE_MAILER_TEMPLATES_INVITE: 'http://templates-server/invite.html'
10
GOTRUE_MAILER_SUBJECTS_INVITE: 'You have been invited'
11
12
templates-server:
13
image: caddy:2-alpine
14
command: ['caddy', 'file-server', '-r', '/templates', '--listen', ':80']
15
volumes:
16
- ./volumes/templates:/templates

What this configuration does#

  • Adds a templates-serverservice that runs alongside the Supabase services in the same docker network.
  • Serves your custom email template files from the ./volumes/templates directory.
  • Keeps the templates-server private to the Docker network (no published ports), so it is not accessible from outside.
  • Allows the auth service to fetch templates via http://templates-server/<template>.html.

Step 3: Restart containers#

1
docker compose up -d --force-recreate --no-deps auth templates-server

Notification email templates#

Notification email templates can be configured using the following environment variables:

  • GOTRUE_MAILER_NOTIFICATIONS_<NOTIFICATION_TYPE>_ENABLED: Enable the notification email
  • GOTRUE_MAILER_TEMPLATES_<NOTIFICATION_TYPE>_NOTIFICATION: Provide a custom template URL. Falls back to the default template if not set.
  • GOTRUE_MAILER_SUBJECTS_<NOTIFICATION_TYPE>_NOTIFICATION: Customize the email subject. Falls back to the default subject if not set.
Notification TypeSent
PASSWORD_CHANGEDWhen a user's password is changed
EMAIL_CHANGEDWhen a user's email address is changed
PHONE_CHANGEDWhen a user's phone number is changed
MFA_FACTOR_ENROLLEDWhen a new MFA factor is added to the user's account
MFA_FACTOR_UNENROLLEDWhen an MFA factor is removed from the user's account
IDENTITY_LINKEDWhen a new identity is linked to the account
IDENTITY_UNLINKEDWhen an identity is unlinked from the account

For example:

1
GOTRUE_MAILER_NOTIFICATIONS_EMAIL_CHANGED_ENABLED='true'
2
GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGED_NOTIFICATION='<template_url>'
3
GOTRUE_MAILER_SUBJECTS_EMAIL_CHANGED_NOTIFICATION='<custom_subject>'

Example#

Below is an example configuration for setting up a custom password changed notification template.

Step 1: Create the templates directory#

This example reuses the directory created in Auth Email Templates – Step 1 (volumes/templates). Add your notification email templates to this directory.

Your directory structure should look like this:

1
volumes/
2
templates/
3
invite.html
4
password_changed_notification.html

Step 2: Update docker-compose.yml#

Update the auth service in docker-compose.yml to enable password changed notification

1
services:
2
auth:
3
depends_on:
4
db:
5
condition: service_healthy
6
templates-server:
7
condition: service_started
8
environment:
9
GOTRUE_MAILER_NOTIFICATIONS_PASSWORD_CHANGED_ENABLED: 'true' # 👈 enabling the notification is required
10
GOTRUE_MAILER_TEMPLATES_PASSWORD_CHANGED_NOTIFICATION: 'http://templates-server/password_changed_notification.html'
11
GOTRUE_MAILER_SUBJECTS_PASSWORD_CHANGED_NOTIFICATION: 'Your password has been changed'
12
13
templates-server:
14
image: caddy:2-alpine
15
command: ['caddy', 'file-server', '-r', '/templates', '--listen', ':80']
16
volumes:
17
- ./volumes/templates:/templates

Step 3: Restart containers#

1
docker compose up -d --force-recreate --no-deps auth templates-server