Sent Verification email Instead of having configured HTML template file, the email body contains the HTML returned by the application URL configured in GOTRUE_SITE_URL.

Open
#2,589 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
go

Research direction

Start by reproducing the issue with the self-hosted GoTrue Docker setup, the GOTRUE_MAILER_TEMPLATES_CONFIRMATION path, and GOTRUE_SITE_URL configuration described here; inspect the confirmation email in Mailpit. Compare the configured file-based template with the generated message and verify whether the signup flow using emailRedirectTo selects the URL response instead. Done means the configured template is rendered with variables such as ConfirmationURL, while SITE_URL only affects links and redirects.

Written by the indexing model from the issue text.

Description

bug

Bug report

  • I confirm this is a bug with Supabase, not with my own application.
  • I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

When self-hosting Supabase Auth (GoTrue) and configuring custom email templates via the GOTRUE_MAILER_TEMPLATES_* environment variables, the configured template files appear to be ignored.

Instead of rendering the contents of the configured HTML template file, the email body contains the HTML returned by the application URL configured in GOTRUE_SITE_URL.

In our case:

GOTRUE_SITE_URL=https://app.ometasystems.com
GOTRUE_MAILER_TEMPLATES_CONFIRMATION=/etc/gotrue/templates/signup_confirmation.html

The confirmation email body contains the HTML source of:

https://app.ometasystems.com

(which is a React/Vite SPA index page), rather than the contents of:

/etc/gotrue/templates/signup_confirmation.html

The behavior is reproducible with Mailpit and appears to originate from GoTrue rather than the SMTP server.

To Reproduce

Environment

Self-hosted Supabase Auth:

image: supabase/gotrue:v2.189.0
Configure custom template

Mount template directory:

auth:
  volumes:
    - ./volumes/auth/templates:/etc/gotrue/templates

Configure environment variables:

GOTRUE_SITE_URL=https://app.ometasystems.com

GOTRUE_MAILER_TEMPLATES_CONFIRMATION=/etc/gotrue/templates/signup_confirmation.html
GOTRUE_MAILER_TEMPLATES_INVITE=/etc/gotrue/templates/invite.html
GOTRUE_MAILER_TEMPLATES_RECOVERY=/etc/gotrue/templates/reset_password.html
GOTRUE_MAILER_TEMPLATES_MAGIC_LINK=/etc/gotrue/templates/magic_link.html
GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGE=/etc/gotrue/templates/email_change.html

GOTRUE_MAILER_URLPATHS_CONFIRMATION=/auth/v1/verify
GOTRUE_MAILER_URLPATHS_INVITE=/auth/v1/verify
GOTRUE_MAILER_URLPATHS_RECOVERY=/auth/v1/verify
GOTRUE_MAILER_URLPATHS_EMAIL_CHANGE=/auth/v1/verify

Template file example:

<html>
  <body>
    <h1>Confirm Your Account</h1>

    <a href="{{ .ConfirmationURL }}">
      Confirm Email
    </a>
  </body>
</html>

Verify template exists inside container:

docker exec -it supabase-auth cat /etc/gotrue/templates/signup_confirmation.html

Output matches the expected template file.

Sign up a user
await supabase.auth.signUp({
  email,
  password,
  options: {
    emailRedirectTo: "https://app.ometasystems.com/auth"
  }
})
Observe email

Using Mailpit, the received email body contains the HTML source of:

https://app.ometasystems.com

Example excerpt:

<!doctype html>
<html lang="en">
<head>
  <script type="module" src="/@vite/client"></script>
  <title>Lovable App</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>

instead of the configured template content.

Expected behavior

GoTrue should render the email using the configured file:

GOTRUE_MAILER_TEMPLATES_CONFIRMATION=/etc/gotrue/templates/signup_confirmation.html

The resulting email body should contain the HTML from the template file with variables substituted (e.g. {{ .ConfirmationURL }}).

The contents of GOTRUE_SITE_URL should only influence generated URLs and redirects, not replace the email template body.

System information

  • OS: Ubuntu Server 24.04 LTS
  • Deployment: Self-hosted Supabase via Docker Compose
  • Auth Image: supabase/gotrue:v2.189.0
  • SMTP: Mailpit
  • Browser: Chrome
  • Frontend: React + Vite
  • Version of supabase-js: latest v2.x (can provide exact version if needed)
  • Node.js: 22.x

Additional context

Runtime environment confirms the template variables are correctly set:

GOTRUE_MAILER_TEMPLATES_CONFIRMATION=/etc/gotrue/templates/signup_confirmation.html
GOTRUE_MAILER_TEMPLATES_INVITE=/etc/gotrue/templates/invite.html
GOTRUE_MAILER_TEMPLATES_RECOVERY=/etc/gotrue/templates/reset_password.html
GOTRUE_MAILER_TEMPLATES_MAGIC_LINK=/etc/gotrue/templates/magic_link.html
GOTRUE_MAILER_TEMPLATES_EMAIL_CHANGE=/etc/gotrue/templates/email_change.html

The template files are present inside the running container:

docker exec -it supabase-auth ls -R /etc/gotrue/templates

Output:

email_change.html
invite.html
magic_link.html
reset_password.html
signup_confirmation.html

This appears either to be:

  1. A regression in supabase/gotrue:v2.189.0
  2. An undocumented interaction between GOTRUE_SITE_URL, emailRedirectTo, and GOTRUE_MAILER_TEMPLATES_*
  3. File-based templates being ignored in favor of a URL-based template source
Dominant language
Go
Stars
2.6k
Forks
764
Avg merge
5d 3h
Merged PRs (30d)
39

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from supabase/auth

All issues in supabase/auth

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.