Skip to content

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. #2589

Description

@lokinderchauhan

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions