Browser and Nuxt
Browser and Nuxt
You can define a Zod schema in code shared by the browser and server. Import helpers from @nullix/zod-mongoose; bundlers that honor package exports select the browser-safe implementation for client code. Call toMongooseSchema() only on the server.
Share read and create schemas
The read schema includes the ID Mongoose adds. The create schema omits it, so a request body only needs name.
import {z} from 'zod/v4';
import {zObjectId} from '@nullix/zod-mongoose';
export const UserReadSchema = z.object({
_id: zObjectId(),
name: z.string().min(2),
});
export const CreateUserSchema = UserReadSchema.omit({_id: true});
In the browser, zObjectId() uses a string representation. On the server, it accepts Mongoose ObjectIds and valid 24-character hex strings. Shared schema definition does not require Mongoose in a client bundle.
Validate a Nuxt create request
This server route assumes your app has connected Mongoose to MongoDB. Model reuse avoids recompiling it during development reloads.
import mongoose from 'mongoose';
import {toMongooseSchema} from '@nullix/zod-mongoose';
import {CreateUserSchema, UserReadSchema} from '~/schemas/user';
const UserModel = mongoose.models.User ||
mongoose.model('User', toMongooseSchema(UserReadSchema));
export default defineEventHandler(async (event) => {
const body = await readValidatedBody(event, (input) => CreateUserSchema.parse(input));
const user = await UserModel.create(body);
return UserReadSchema.parse(user.toObject());
});
For a browser-only form, call CreateUserSchema.safeParse(formData) before sending the request. setFrontendMode() is deprecated; the package's conditional exports handle the environment. See Migration if you still call it.