T
TanStack2w ago
foreign-sapphire

Is the `.inputValidator` on server functions only meant to be used for type validation?

I am trying to use the .inputValidator with zod to validate my input but when the input is invalid it throw and when I catch this inside of my component code the entire zod array of errors are serialized instead of showing up as an array. Is this the normal behavior and also why is there nothing in the documentation mentioning this if it is?
import { createFileRoute, Link } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { FormEvent } from 'react'
import { z, ZodError } from 'zod'

const AuthUserSchema = z.object({
email: z.email(`Email is not valid`).min(1, `Email is required`),
password: z.string().min(1, `Password is required`)
.min(5, `Password must be at least 5 characters`),
});

const submitForm = createServerFn({ method: 'POST' })
.inputValidator(AuthUserSchema)
.handler(async({ data }) => {
const email = data.email
const password = data.password

console.log({ email, password })

// Process the form...
return { success: true }
})

export const Route = createFileRoute('/auth/signin')({
component: RouteComponent,
})

function RouteComponent() {
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)

const email = formData.get("email") as string;
const password = formData.get("password") as string;

try {
await submitForm({ data: { email, password }})
} catch (error) {
// Handle Zod validation errors
console.log('Error caught:', error) // Debug log
console.log('Error type:', error?.message) // Debug log
console.log('Error data:', error?.data) // Debug log
}
}

return (
<div className="w-11/12 p-12 px-6 py-10 rounded-lg sm:w-8/12 md:w-6/12 lg:w-5/12 2xl:w-3/12 sm:px-10 sm:py-6">
<h2 className="font-semibold text-4xl mb-4">Sign in</h2>
... Form code would be here
</div>
)
}
import { createFileRoute, Link } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { FormEvent } from 'react'
import { z, ZodError } from 'zod'

const AuthUserSchema = z.object({
email: z.email(`Email is not valid`).min(1, `Email is required`),
password: z.string().min(1, `Password is required`)
.min(5, `Password must be at least 5 characters`),
});

const submitForm = createServerFn({ method: 'POST' })
.inputValidator(AuthUserSchema)
.handler(async({ data }) => {
const email = data.email
const password = data.password

console.log({ email, password })

// Process the form...
return { success: true }
})

export const Route = createFileRoute('/auth/signin')({
component: RouteComponent,
})

function RouteComponent() {
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)

const email = formData.get("email") as string;
const password = formData.get("password") as string;

try {
await submitForm({ data: { email, password }})
} catch (error) {
// Handle Zod validation errors
console.log('Error caught:', error) // Debug log
console.log('Error type:', error?.message) // Debug log
console.log('Error data:', error?.data) // Debug log
}
}

return (
<div className="w-11/12 p-12 px-6 py-10 rounded-lg sm:w-8/12 md:w-6/12 lg:w-5/12 2xl:w-3/12 sm:px-10 sm:py-6">
<h2 className="font-semibold text-4xl mb-4">Sign in</h2>
... Form code would be here
</div>
)
}
3 Replies
flat-fuchsia
flat-fuchsia2w ago
you need a custom error seralizer. its just not documented yet the default error serializer will just serialize the message. here is an example on how to set this up: https://github.com/TanStack/router/blob/main/e2e/react-start/serialization-adapters/src/CustomError.ts#L18 https://github.com/TanStack/router/blob/main/e2e/react-start/serialization-adapters/src/start.tsx#L8
foreign-sapphire
foreign-sapphireOP2w ago
Ok I will give this a try and respond here with my results. It would be good if this was documented as there are mentions of using zod in the docs and without this it's kinda not that useful.
flat-fuchsia
flat-fuchsia2w ago
yeah of course this will be documented

Did you find this page helpful?