N
Nuxt23h ago
WiFi Plug

supabase nuxt confirm page on email confirmation

Hi i have supabase setup using the module however when the user clicks their confirm email link they get sent to my /auth/confirm page where i put this code
<script setup lang="ts">
const user = useSupabaseUser()
const redirectInfo = useSupabaseCookieRedirect()

watch(user, () => {
if (user.value) {
// Get redirect path, and clear it from the cookie
const path = redirectInfo.pluck()
// Redirect to the saved path, or fallback to home
return navigateTo(path || '/')
}
}, { immediate: true })
</script>

<template>
<div>Waiting for login...</div>
</template>
<script setup lang="ts">
const user = useSupabaseUser()
const redirectInfo = useSupabaseCookieRedirect()

watch(user, () => {
if (user.value) {
// Get redirect path, and clear it from the cookie
const path = redirectInfo.pluck()
// Redirect to the saved path, or fallback to home
return navigateTo(path || '/')
}
}, { immediate: true })
</script>

<template>
<div>Waiting for login...</div>
</template>
which i saw in the official docs however it doesn't seem to grab the required data to sign them in? the link generated is in this format
http://localhost:3000/auth/confirm#access_token=eyJhbGciOiJ&expires_at=1746025613&expires_in=3600&refresh_token=n7aokx&token_type=bearer&type=magiclink
http://localhost:3000/auth/confirm#access_token=eyJhbGciOiJ&expires_at=1746025613&expires_in=3600&refresh_token=n7aokx&token_type=bearer&type=magiclink
the only work around i've found is changing the confirm page code to something where i grab the hash from the url and then use verifyotp and changing the email templates manually to send the hash etc which works but seems overly complicated so i would prefer to use the default method with access tokens and refresh tokens in the url that i'm sent
8 Replies
kapa.ai
kapa.ai23h ago
Hi @WiFi Plug. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The behavior you're describing—where the user is sent to a /auth/confirm page with tokens in the URL hash after clicking the Supabase email confirmation link—is expected when using the Supabase Nuxt module. The code you posted is indeed from the official documentation and is intended to handle the redirect after authentication:
<script setup lang="ts">
const user = useSupabaseUser()
const redirectInfo = useSupabaseCookieRedirect()

watch(user, () => {
if (user.value) {
// Get redirect path, and clear it from the cookie
const path = redirectInfo.pluck()
// Redirect to the saved path, or fallback to home
return navigateTo(path || '/')
}
}, { immediate: true })
</script>

<template>
<div>Waiting for login...</div>
</template>
<script setup lang="ts">
const user = useSupabaseUser()
const redirectInfo = useSupabaseCookieRedirect()

watch(user, () => {
if (user.value) {
// Get redirect path, and clear it from the cookie
const path = redirectInfo.pluck()
// Redirect to the saved path, or fallback to home
return navigateTo(path || '/')
}
}, { immediate: true })
</script>

<template>
<div>Waiting for login...</div>
</template>
However, if the user is not being signed in automatically when they land on /auth/confirm with the hash parameters, it suggests that the Supabase Nuxt module is not processing the hash fragment as expected. What Should Happen - The Supabase Nuxt module should automatically detect the hash in the URL (containing access_token, refresh_token, etc.) and complete the sign-in process. - The useSupabaseUser() composable should then update, triggering your watcher and redirecting the user. Common Issues - Module Configuration: Ensure your Supabase module is correctly configured in nuxt.config.ts, especially the redirectOptions.callback property, which should match your confirm page route (e.g., /auth/confirm). - Page Exists: Make sure the /auth/confirm.vue page exists, as the module expects this route for the callback. - No Manual Hash Handling Needed: You should not need to manually parse the hash or call verifyOtp—the module should handle this for you. Reference from Knowledge Sources A similar issue was resolved by simply creating the confirm.vue page, which allowed the Supabase Nuxt module to handle the callback and sign-in automatically. No manual hash parsing or custom logic was required beyond having the correct page and configuration:
I just had to create a confirm.vue page and it worked
Supabase oauth redirectUrl not working | Nuxt 3 Troubleshooting Steps 1. Check your Supabase module config:
supabase: {
url: process.env.SUPABASE_URL,
key: process.env.SUPABASE_KEY,
redirectOptions: {
login: '/login',
callback: '/auth/confirm', // This should match your confirm page
exclude: ['/*'],
},
},

supabase: {
url: process.env.SUPABASE_URL,
key: process.env.SUPABASE_KEY,
redirectOptions: {
login: '/login',
callback: '/auth/confirm', // This should match your confirm page
exclude: ['/*'],
},
},

2. Ensure the /auth/confirm.vue page exists and contains the watcher code you posted. 3. Do not manually parse the hash—let the module handle it. 4. If it still doesn't work, make sure you are using a recent version of the Supabase Nuxt module, as older versions may not handle the callback as expected. If after these checks it still doesn't work, there may be an issue with the module version or a conflict with other middleware. But based on the knowledge sources, the default method should work without manual hash handling if the page and config are correct. If you need more detailed debugging, please provide your nuxt.config.ts and confirm the version of @nuxtjs/supabase you are using. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai23h ago
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
WiFi Plug
WiFi PlugOP23h ago
@kapa.ai so my email template is set to the default {{ .confirmationemail }} my site url in supabase dashboard is set to http://localhost:3000 and my redirect urls is set to http://localhost:3000/auth/confirm my nuxt.config.ts is set to
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: [
'@nuxt/eslint',
'@nuxt/ui-pro',
'@nuxt/image',
'@nuxtjs/supabase',
'@pinia/nuxt',
'pinia-plugin-persistedstate/nuxt',
],

imports: {
dirs: ['shared/**'],
},
devtools: { enabled: true },

css: ['~/assets/css/main.css'],

future: {
compatibilityVersion: 4,
},
compatibilityDate: '2024-11-01',

nitro: {
imports: {
dirs: ['shared/**'],
},
},

eslint: {
config: {
stylistic: true,
},
},

supabase: {
redirectOptions: {
login: '/',
callback: '/auth/confirm', // This should match your confirm page
exclude: ['/*'],
},
},
})
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: [
'@nuxt/eslint',
'@nuxt/ui-pro',
'@nuxt/image',
'@nuxtjs/supabase',
'@pinia/nuxt',
'pinia-plugin-persistedstate/nuxt',
],

imports: {
dirs: ['shared/**'],
},
devtools: { enabled: true },

css: ['~/assets/css/main.css'],

future: {
compatibilityVersion: 4,
},
compatibilityDate: '2024-11-01',

nitro: {
imports: {
dirs: ['shared/**'],
},
},

eslint: {
config: {
stylistic: true,
},
},

supabase: {
redirectOptions: {
login: '/',
callback: '/auth/confirm', // This should match your confirm page
exclude: ['/*'],
},
},
})
and i have a page created at pages/auth/confirm.vue with
<script setup lang="ts">
const user = useSupabaseUser()
const redirectInfo = useSupabaseCookieRedirect()

watch(
user,
() => {
if (user.value) {
// Get redirect path, and clear it from the cookie
const path = redirectInfo.pluck()
// Redirect to the saved path, or fallback to home
return navigateTo(path || '/')
}
},
{ immediate: true }
)
</script>

<template>
<div>Waiting for login...</div>
</template>
<script setup lang="ts">
const user = useSupabaseUser()
const redirectInfo = useSupabaseCookieRedirect()

watch(
user,
() => {
if (user.value) {
// Get redirect path, and clear it from the cookie
const path = redirectInfo.pluck()
// Redirect to the saved path, or fallback to home
return navigateTo(path || '/')
}
},
{ immediate: true }
)
</script>

<template>
<div>Waiting for login...</div>
</template>
so why might it not be working?
kapa.ai
kapa.ai23h ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the information in your question and the knowledge sources, your setup appears correct: - Your Supabase dashboard redirect URL is set to <http://localhost:3000/auth/confirm.> - Your Nuxt config uses the Supabase module with redirectOptions.callback set to /auth/confirm. - You have a pages/auth/confirm.vue file with the recommended watcher code. - Your email template uses the default {{ .ConfirmationURL }} (assuming you meant this, as {{ .confirmationemail }} is not a standard Supabase variable). What should happen:
When a user clicks the confirmation link, the Supabase Nuxt module should automatically process the hash in the URL (containing access_token, etc.), sign the user in, and update useSupabaseUser(), which triggers your watcher and redirects the user. Why might it not be working? From the knowledge sources, the most common reasons for this not working are: 1. Supabase Nuxt module version:
If you are using an older version of @nuxtjs/supabase, the callback handling may not work as expected. The knowledge sources do not specify a required version, but one user resolved their issue simply by ensuring the confirm page existed and the config matched the route, with no extra code needed beyond what you have Supabase oauth redirectUrl not working | Nuxt 3. 2. Email template variable:
The knowledge sources do not mention {{ .confirmationemail }} as a valid variable. The standard is {{ .ConfirmationURL }}. If your email template is not using the correct variable, the confirmation link may not be generated properly, which could prevent the module from handling the callback as expected. 3. No manual hash handling required:
The module should handle the hash automatically. If you find yourself needing to manually parse the hash or call verifyOtp, it suggests the module is not intercepting the callback as it should, possibly due to a misconfiguration or version issue. Summary:
- Double-check that your email template uses {{ .ConfirmationURL }}. - Ensure you are using a recent version of @nuxtjs/supabase. - Your config and page setup match the working examples in the knowledge sources. - No additional manual hash handling should be necessary. If all of the above are correct and it still does not work, the knowledge sources do not provide further troubleshooting steps. In that case, you may need to check for issues specific to your environment or consult the Supabase Nuxt module documentation for updates.
I just had to create a confirm.vue page and it worked
Supabase oauth redirectUrl not working | Nuxt 3 If you have confirmed all of the above and the issue persists, the knowledge sources do not contain enough information to provide a more specific solution. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai23h ago
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
WiFi Plug
WiFi PlugOP23h ago
@kapa.ai yeah that still didn't work, so the link i get sent to when clicking the confirmation email link in my email is my root page localhost:3000 rather than the redirect so could that be a part of it? but why does it send me to my root page and not the confirm page?
kapa.ai
kapa.ai23h ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Yes, the fact that the confirmation link in your email sends you to the root page (localhost:3000) instead of /auth/confirm is likely the cause of your issue. According to the knowledge sources, the Supabase Nuxt module expects the callback URL (where the user is redirected after confirming their email) to match the route specified in your Nuxt config's redirectOptions.callback (e.g., /auth/confirm). This is also the URL you should set in your Supabase dashboard as the redirect URL for email confirmations. If the link in your email is pointing to the root (/) instead of /auth/confirm, the module's automatic handling will not be triggered, and the user will not be signed in as expected. This matches the behavior described in the knowledge sources, where simply creating the correct confirm page and ensuring the callback URL matches resolved the issue:
I just had to create a confirm.vue page and it worked
Supabase oauth redirectUrl not working | Nuxt 3 Why is this happening? - If your email template is not using the correct variable (it should be {{ .ConfirmationURL }}), or if your Supabase dashboard's redirect URL is not set to /auth/confirm, the generated link will not point to the correct page. What to check: 1. In your Supabase dashboard, ensure the redirect URL for email confirmations is set to <http://localhost:3000/auth/confirm.> 2. In your email template, use {{ .ConfirmationURL }} to generate the confirmation link. 3. Your Nuxt config should have callback: '/auth/confirm' under redirectOptions. If after these changes the link still points to the root, double-check the Supabase dashboard settings and the email template variable. The knowledge sources do not provide further troubleshooting steps if these are already correct, but the redirect URL in the email must match your confirm page for the module to work as intended. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai23h ago
<@679734274840330384> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?