@Mail Domain Check

Supabase Auth | signUp | GitHub Pages path

Supabase Signup emailRedirectTo Loses the Repository Path

If a confirmation email sends successfully but redirects from /repository/ to the GitHub Pages root, do not change SMTP. Prove the actual /signup?redirect_to= request, the path-stripped cross-origin Referer, the Auth allow-list decision, the confirmation template, and the final verification redirect separately.

Fastest request check

@supabase/auth-js 2.110.7 puts emailRedirectTo in the URL query as redirect_to. A JSON field named email_redirect_to is not the same handoff.

Keep four redirect decisions separate

Client request
The supported SDK sends redirect_to on the actual signup URL. An options object or JSON body alone does not prove Auth received it.
Auth selection
Current Auth prefers an accepted explicit redirect_to, then a valid Referer, then configured SiteURL. A cross-origin Referer can contain only the origin and silently lose /repository/.
Email template
{{ .ConfirmationURL }} includes the selected redirect. A template based on {{ .SiteURL }} or a hand-built link can discard it.
Final navigation
The verify endpoint, any link rewriter, application callback, router base, and GitHub Pages hosting behavior can still change the destination after the email is rendered.

Browser-local redirect planner

Locate the first lost path

No email address, project reference, confirmation link, token, OTP, API key, cookie, authorization header, or full network capture is requested or transmitted.

What the 2.110.7 client and Auth source prove

In signUp() in auth-js 2.110.7, options.emailRedirectTo is passed to the request helper as redirectTo. The request helper serializes it as the redirect_to query parameter.

In reviewed Auth commit 67c55c0, GetReferrer first checks redirect_to from the request header or query/form data. If that is absent or invalid, it accepts a valid HTTP Referer before falling back to SiteURL. A body field named email_redirect_to is not read by that signup path.

For a cross-origin browser POST, a policy such as strict-origin-when-cross-origin commonly sends only https://user.github.io/ as the Referer. Because that origin can still pass redirect validation, current Auth may select it before a configured SiteURL containing /repository/. Open PR 2629 proposes preferring the path-bearing Site URL in that case and accepting signup JSON body fields, but it was not merged as of this review and must not be treated as deployed behavior.

The confirmation mailer places that selected referrer in both ConfirmationURL and RedirectTo. That lets one private message inspection distinguish an Auth fallback from a later template or browser problem.

Password recovery reaching the correct path does not prove signup used the same request URL, template, or fresh link. Compare the two flows at each boundary instead of treating one as a control for the whole chain.

Run one bounded correction

  1. Record the exact @supabase/auth-js package version used by the browser bundle.
  2. Inspect the actual signup request URL and decode only the redirect_to host and path. Record the request Referer as only origin versus full path. Do not rely on the JavaScript options object or request body view.
  3. Use an exact production Redirect URL entry when possible. With patterns, * does not cross /; ** does.
  4. Create one fresh controlled signup. In the newest private confirmation link, classify whether decoded redirect_to has the repository path, the origin-only Referer, or Site URL fallback.
  5. Check whether the button uses unmodified {{ .ConfirmationURL }}. If a custom endpoint is required, carry and revalidate {{ .RedirectTo }}.
  6. Open the newest link once and compare the verification response Location path with the final browser route.

Direct HTTP requests use a different field boundary

For a direct request, send the target on the URL:

POST /auth/v1/signup?redirect_to=https%3A%2F%2Fexample.github.io%2Frepository%2F
Content-Type: application/json

{"email":"controlled-address","password":"controlled-password"}

The example shows placement, not values to post publicly. Do not add email_redirect_to to the JSON and assume the Auth referrer was set.

Regression contract

  1. Assert the outgoing signup URL contains the complete encoded redirect_to path.
  2. Assert the generated ConfirmationURL decodes to the same path.
  3. Assert the delivered button preserves that value without provider link rewriting.
  4. Assert one fresh verification succeeds and its Location retains the repository path.
  5. Assert an unlisted origin, wrong scheme, wrong port, and an unmatched path fall back or fail safely.
  6. Assert replay and expired links remain rejected without changing redirect policy.
Also diagnosing missing Supabase Auth mail?

Keep redirect correctness separate from message generation, provider processing, receiver visibility, and one-time token completion.

Open Supabase Auth path

Primary references