v3.3.1
Playground
Guides

Browser and Nuxt

Share Zod schemas across client and server code and validate create requests without requiring a generated ID.

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.

schemas/user.ts
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.

server/api/users.post.ts
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.