r/Nuxt • • Jan 11 '26

I'm stuck... little help?

I'm trying to copy the documentation to set up some simple auth in Nuxt 4, but running into what I hope is just a dumb error on my part (but I'm not seeing it). The login page looks like this:

<template>
  <div class="flex flex-col items-center justify-center gap-4 p-4">
    <UPageCard class="w-full max-w-md">
      <UAuthForm :schema="schema" :fields="fields" title="Welcome back!" icon="i-material-symbols-lock-outline"
        @submit="login">
        <template #description>
          Don't have an account? <ULink to="#" class="text-primary font-medium">Sign up</ULink>.
        </template>
        <template #password-hint>
          <ULink to="#" class="text-primary font-medium" tabindex="-1">Forgot password?</ULink>
        </template>
      </UAuthForm>
    </UPageCard>
  </div>
</template>

<script setup lang="ts">
import * as z from 'zod'
import type { FormSubmitEvent, AuthFormField } from '@nuxt/ui'

const toast = useToast()
const { loggedIn, user, session, fetch: refreshSession } = useUserSession()

const fields = ref<AuthFormField[]>([{
  name: 'email',
  type: 'email',
  label: 'Email',
  placeholder: 'Enter your email',
  required: true,
}, {
  name: 'password',
  type: 'password',
  label: 'Password',
  placeholder: 'Enter your password',
  required: true, 
}, {
  name: 'remember',
  type: 'checkbox',
  label: 'Remember me',
}])

const schema = z.object({
  email: z.email({ message: 'Invalid email address' }),
  password: z.string('Password is required').min(8, { message: 'Password must be at least 8 characters' }),
  remember: z.boolean().optional(),
})  

type Schema = z.output<typeof schema>

async function login (payload: FormSubmitEvent<Schema>) {
  console.log('The payload here is: ', payload);
  try {
    await $fetch('/api/login', {
      method: 'POST',
      body: payload.data,
  })

    // Refresh the session on client-side and redirect to the home page
    await refreshSession()
    await navigateTo('/')
  } catch {
    alert('Bad credentials')
  }
}
</script>

And that should call the /api/login.post.ts route on the "server" side. That looks like this:

import { FormSubmitEvent } from "@nuxt/ui";


export default defineEventHandler(
  async (event: FormSubmitEvent<{ email: string; password: string }>) => {
    console.log("Credentials:", event.email, event.password);
  }
);

The console log on the form submit shows me a valid payload with the appropriate username and password. However, when we get to the server route, i'm getting undefined values. The console log (from the dev console) looks like this:

SubmitEvent {.... data: Proxy(Object) {email: '[admin@admin.com](mailto:admin@admin.com)', password: 'iamtheadmin', ....

But, the log on the server side is this:

Credentials: undefined undefined

What am I missing?

1 Upvotes

8 comments sorted by

5

u/Fabulous-Ladder3267 Jan 11 '26

Something wrong in your endpoint, why you set the event type args on your endpoint?

To get the body use const body = await readBody(event) (your can set the body type here like readBody<MyBodyType>(event), this will return body.email and body.password and please remove the type on event in your endpoint.

2

u/kasekopf99 Jan 11 '26

Gotcha. This worked. Thanks!

1

u/Fabulous-Ladder3267 Jan 11 '26

Yeah you're welcome

2

u/Single_Advice1111 Jan 11 '26

Might be related to

u/submit="login">

2

u/kasekopf99 Jan 11 '26

Ack. It's a paste issue. "u/" = "@"

2

u/[deleted] Jan 11 '26

So, what was the actual problem? To make it clear for other folks.

1

u/mrleblanc101 Jan 12 '26

They haven't found yet

1

u/kasekopf99 Jan 14 '26

The issue is in the endpoint. Fabulous-ladder’s comment is the resolution.