nuxt-yup

Yup integration for Nuxt 4 with a simple composable.

Nuxt Yup

npm version npm downloads License Nuxt

A Nuxt module that brings Yup into your app with first-class Nuxt integration, global access, and typed extension support.

Features

  • 🔌  Use Yup anywhere with the auto-imported useYup() composable
  • 🌍  Configure global validation messages through app.config.ts
  • 📦  Add custom methods from yup.methods.ts
  • 🏷️  Automatically generate TypeScript types for custom Yup methods

Why use nuxt-yup?

nuxt-yup gives you a Nuxt-native Yup workflow with minimal setup.

  • Auto-imported useYup() composable
  • Global configuration through app.config.ts
  • Typed custom Yup extensions
  • Seamless Nuxt runtime integration
  • Better DX with less boilerplate

Quick Example

const yup = useYup()

const userSchema = yup.object({
  name: yup.string().required(),
  email: yup.string().email().required(),
  document: yup.string().cnpj(), // custom method from yup.methods.ts
})

const sampleUser = {
  name: 'Ada Lovelace',
  email: 'ada@example.com',
  document: '12345678901234',
}

await userSchema.validate(sampleUser)

Quick Setup

Install the module in your Nuxt project:

npx nuxi@latest module add nuxt-yup

Yup is now available globally in your app.

Usage

Access Yup anywhere with useYup() or the $yup plugin.

<template>
  <div>
    <input v-model="value" placeholder="Enter a value" />
    <p>Is valid: {{ isValid }}</p>
  </div>
</template>

<script setup>
const yup = useYup()
// or: const { $yup } = useNuxtApp()

const value = ref('')
const isValid = ref(false)

const schema = yup.string().min(3).required()

watch(value, async (newValue) => {
  isValid.value = await schema.isValid(newValue)
})
</script>

Comparison

FeatureYupnuxt-yup
Auto-import composableManual import and wiringuseYup() available automatically
Global configManual setup in app bootstrapConfigure with app.config.ts
Typed extensionsManual declaration mergingTyped descriptors + generated augmentation
Nuxt developer experienceGeneric library usageNuxt-first integration and DX

Configuration

Customizing error messages (setLocale)

Override Yup default messages globally with yup.setLocale in app.config.ts.

// app.config.ts
export default defineAppConfig({
  yup: {
    setLocale: {
      mixed: {
        required: 'This field is required',
      },
      string: {
        min: 'Must be at least ${min} characters',
        email: 'Must be a valid email address',
      },
      number: {
        min: 'Must be at least ${min}',
        max: 'Must be at most ${max}',
      },
    },
  },
})

See the full list of keys in the Yup locale documentation.


Module options (nuxt.config.ts)

Use methodsDir when your methods file is outside the Nuxt root.

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-yup'],
  yup: {
    methodsDir: './shared/validation',
  },
})
  • The module searches this directory for yup.methods.*.
  • If no file is found, it logs an error and continues without custom methods.

yup.methods.ts

Create a yup.methods.ts file in your project root to register custom methods. The module auto-detects it and supports two modes.

Export an array of descriptors with defineYupExtension. Type augmentations are generated automatically.

// yup.methods.ts
import { defineYupExtension } from 'nuxt-yup'

export default defineYupExtension([
  {
    name: 'cnpj',
    type: 'string',
    message: 'Invalid CNPJ',
    validate(value: string) {
      return /^\d{14}$/.test(value)
    },
  },
  {
    name: 'isEven',
    type: 'number',
    message: 'Must be an even number',
    async validate(value: number) {
      return value % 2 === 0
    },
  },
])

Each descriptor accepts:

PropertyTypeDescription
namestringMethod name to add to the schema
typeYupExtensionTypeYup schema type to extend
messagestring (optional)Default error message
validate(value) => boolean | Promise<boolean>Validation logic (sync or async)

Yup types are automatically augmented, so you get full autocomplete:

// ✅ TypeScript knows about .cnpj() and .isEven()
useYup().string().cnpj()
useYup().number().isEven()

Compat Mode — function export

For full control (for example, migrations from an existing setup), export a function that receives the yup instance directly. Type augmentations are not generated in this mode.

// yup.methods.ts
import type * as Yup from 'yup'

export default function extendYup(yup: typeof Yup) {
  yup.addMethod(yup.StringSchema, 'documentId', function (message = 'Invalid document') {
    return this.test('document-id', message, (value) => {
      if (value == null) return true
      return typeof value === 'string' && value.length >= 6
    })
  })
}

Supported file extensions

The yup.methods file is resolved in this order from your project root (or from methodsDir):

.ts.mts.cts.js.mjs.cjs


Works well with

  • Nuxt 3 / Nuxt 4
  • TypeScript
  • vee-validate
  • Nuxt server routes (server/api/*)

Contributing

Contributions are welcome. Open an issue for bugs or feature ideas, and submit a PR when you're ready.

For local development and test commands, see package.json.


License

MIT — Made with ❤️ by Darlan Prado