Trying to get the Supabase authentication template/project to work

Currently trying to get a Next.js / Supabase project fully functional where users can signup, login/logout and get a page protected.

I used the instructions from here: Supabase Starter
… and I already have a functional Supabase project, complete with my own SMTP server config’d.

Locally everything runs ok, no errors in the logs, clean…

The site runs on localhost:3000 where I can signup, and I receive the email confirming my address, but the link in the email ultimately resolves to http://localhost:3000/auth/confirm?token_hash=pkce_36b0d0905bd8f1cdb4d597440428a0a5cb8e2d843a9daf086fa7c811&type=email

…which doesn’t exist and naturally 404s.

It would seem that I need to change that link in the body of the email, and while I know where to change it, I don’t know what to change it to.

Has anyone had success deploying their Nextjs app using Supabase via this setup method? What do I change my link to?

Thanks in advance,
Rich

Here’s my package.json file, hope it helps:

{
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "@radix-ui/react-checkbox": "^1.1.1",
    "@radix-ui/react-dropdown-menu": "^2.1.1",
    "@radix-ui/react-label": "^2.1.0",
    "@radix-ui/react-slot": "^1.1.0",
    "@supabase/ssr": "latest",
    "@supabase/supabase-js": "latest",
    "autoprefixer": "10.4.20",
    "class-variance-authority": "^0.7.0",
    "clsx": "^2.1.1",
    "lucide-react": "^0.468.0",
    "next": "latest",
    "next-themes": "^0.4.3",
    "prettier": "^3.3.3",
    "react": "19.0.0",
    "react-dom": "19.0.0"
  },
  "devDependencies": {
    "@types/node": "22.10.2",
    "@types/react": "^19.0.2",
    "@types/react-dom": "19.0.2",
    "postcss": "8.4.49",
    "tailwind-merge": "^2.5.2",
    "tailwindcss": "3.4.17",
    "tailwindcss-animate": "^1.0.7",
    "typescript": "5.7.2"
  }
}

Here’s the email template from my Supabase project:

<h2>Confirm your signup</h2>

<p>Follow this link to confirm your user:</p>

<p><a href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email">Confirm your mail</a></p>

Hi @richleach, welcome to the Vercel Community!

Thanks for explaining your issue in detail.

If you deploy your project on Vercel, you’ll get a unique .vercel.app domain, which will be constant for your project’s production deployment. So, you can replace the localhost:3000 with that in the production environment. In a similar way, you can also use a custom domain for your project.

For this you can also use the VERCEL_PROJECT_PRODUCTION_URL environment variable.

So sorry Anshuman, I should have noted that all of this is being run on my localhost:3000 , I haven’t yet deployed it to Vercel. In my .env file I have the following:
NEXT_PUBLIC_BASE_URL=http://localhost:3000

I’m guessing I have to change something in the email template? But I can’t find any docs to support my case, which is where I’m still hung up.

Thanks so much for your input.

Rich

:point_up: This is what you need to change.

1 Like

… but the problem Pauline is that I’ve not even made this to production yet, I can’t get the current configuration to work in my dev environment. It has to pass testing in dev before I can promote to prod.
That’s why I’m confused as to what to do to make the links in the email work. Any ideas?
Thanks,
Rich

k, here’s what I found after debugging:

User goes to localhost:3000/sign-up, fills out form to sign up, hits submit.
User receives email with link to confirm user. User clicks link and…
User is redirected to localhost:3000/auth/confirm which does not exist in this code. 404 message.
After I created /auth/confirm/route.ts with the following code, it works as expected and user gets confirmed in Supabase db and the Next.js app forwards user to localhost:3000/protected as expected.

// /auth/confirm/route.ts
import { type EmailOtpType } from '@supabase/supabase-js'
import { type NextRequest } from 'next/server'

import { createClient } from "@/utils/supabase/server";
import { redirect } from 'next/navigation'

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url)
  const token_hash = searchParams.get('token_hash')
  const type = searchParams.get('type') as EmailOtpType | null
  const next = searchParams.get('next') ?? '/'

  if (token_hash && type) {
    const supabase = await createClient()

    const { error } = await supabase.auth.verifyOtp({
      type,
      token_hash,
    })
    if (!error) {
      // redirect user to specified redirect URL or root of app
      redirect(next)
    }
  }

  // redirect the user to an error page with some instructions
  redirect('/error')
}

Like I said after I made the above changes (and added the missing route handler) the app functions as expected.

So I guess my question is now

How do I submit a bug report against this template? It’s broken without the added route handler.

Thanks,

Rich

1 Like

Hi @richleach, glad that you figured it out. Also, thanks for sharing your solution here.

I tried cloning the project locally to verify your solution but the project worked for me out of the box. Then after comparing the code this is what my Supabase Sign up email template looks like:

From the code, I see that in the actions.ts file, the signUpAction action sets the emailRedirectTo URL to /auth/callback which exists in the application. So, everything worked fine for me.

Can you confirm you didn’t change these presets?

Anshuman I also have the same content in my /app/actions.ts file.

That doesn’t appear to be the issue, the issue is that /app/auth/confirm/route.ts is missing from the project. Once I added it (as I described above) the issue was resolved.

/app/auth/confirm/route.ts is missing and needs to be added.

Thanks,

Rich

1 Like

OR…

…is the problem in the Supabase sign up email template? Your is different from mine, why is that? I did not make any changes to my sign up email template but it’s different from yours, at least as posted…

1 Like

Hi @richleach, that is my guess as well. When did you create this project?

The template I shared is what I got by default and it works out of the box with the repository for me. So, I’m not sure either.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.