Yup! Even more schemas validation examples for Yup… featured image

Yup! Even more schemas validation examples for Yup…

May 01, 2021 · 6 min read

1. Basic User Profile Schema

This schema is great for a user profile or signup form that requires a name, email, and phone number.

import * as yup from 'yup';

const userProfileSchema = yup.object().shape({
  name: yup
    .string()
    .min(2, 'Name must be at least 2 characters long')
    .max(50, 'Name must be less than 50 characters')
    .required('Name is required'),
  email: yup
    .string()
    .email('Invalid email format')
    .required('Email is required'),
  phone: yup
    .string()
    .matches(
      /^[0-9]{10,15}$/,
      'Phone number must contain only digits (10-15 characters)'
    )
    .required('Phone number is required'),
});

const userProfileData = {
  name: 'Jane Doe',
  email: 'jane.doe@example.com',
  phone: '1234567890',
};

userProfileSchema
  .validate(userProfileData)
  .then(valid => console.log('Valid user profile data:', valid))
  .catch(err => console.log('Validation error:', err.errors));

Key Points:

  • min and max help keep string inputs within a certain length.
  • matches ensures phone number follows a digit-only format.
  • required guarantees a field is present and not empty.

2. Blog Post Schema

If you’re working with a blogging platform or content management system, this schema can help validate a new blog post’s title, content, and tags.

import * as yup from 'yup';

const blogPostSchema = yup.object().shape({
  title: yup
    .string()
    .min(5, 'Title must be at least 5 characters')
    .required('Title is required'),
  content: yup
    .string()
    .min(20, 'Content must be at least 20 characters')
    .required('Content is required'),
  tags: yup
    .array()
    .of(yup.string().min(2, 'Each tag must have at least 2 characters'))
    .max(10, 'You can only have up to 10 tags')
    .required('Please include at least one tag'),
});

const blogPostData = {
  title: 'How to Master JavaScript',
  content: 'JavaScript is a versatile language used in web development...',
  tags: ['javascript', 'web', 'dev'],
};

blogPostSchema
  .validate(blogPostData)
  .then(valid => console.log('Valid blog post data:', valid))
  .catch(err => console.log('Validation error:', err.errors));

Key Points:

  • array().of(...) ensures each item in the tags array meets a certain rule.
  • You can limit how many items an array may have using max.
  • Good for ensuring a certain minimum length for text-based content.

3. Product or E-Commerce Schema

Perfect for an online store, this schema ensures a product has a title, price, and optional stock quantity.

import * as yup from 'yup';

const productSchema = yup.object().shape({
  title: yup
    .string()
    .required('Product title is required')
    .max(100, 'Product title cannot exceed 100 characters'),
  price: yup
    .number()
    .typeError('Price must be a number')
    .positive('Price must be greater than zero')
    .required('Price is required'),
  inStock: yup
    .number()
    .typeError('Stock quantity must be a number')
    .integer('Stock quantity must be an integer')
    .min(0, 'Stock quantity cannot be negative')
    .default(0),
  description: yup
    .string()
    .max(500, 'Description cannot exceed 500 characters')
    .nullable(true), // Allows the field to be null or omitted
});

const newProduct = {
  title: 'Super Comfy Chair',
  price: 79.99,
  inStock: 15,
  description: 'A very comfortable chair for your living room.',
};

productSchema
  .validate(newProduct)
  .then(valid => console.log('Valid product data:', valid))
  .catch(err => console.log('Validation error:', err.errors));

Key Points:

  • number().typeError(...) helps ensure the value is actually numeric.
  • positive() and integer() are great for numeric constraints.
  • .default(0) sets a default value if inStock is omitted.
  • .nullable(true) allows description to be null or absent if needed.

4. Nested Objects & Date Ranges

If you’re working with bookings, reservations, or any time-based system, you might want to ensure a check-in date is before a check-out date. This example also shows how to use nested objects in Yup.

import * as yup from 'yup';

const dateRangeSchema = yup.object().shape({
  user: yup.object().shape({
    userId: yup.string().required('User ID is required'),
    name: yup.string().required('User name is required'),
  }),
  startDate: yup.date().required('Check-in date is required'),
  endDate: yup
    .date()
    .required('Check-out date is required')
    .min(yup.ref('startDate'), 'Check-out date cannot be before check-in date'),
});

const reservationData = {
  user: {
    userId: '12345',
    name: 'John Wick',
  },
  startDate: '2025-05-10',
  endDate: '2025-05-15',
};

dateRangeSchema
  .validate(reservationData)
  .then(valid => console.log('Valid reservation:', valid))
  .catch(err => console.log('Date range error:', err.errors));

Key Points:

  • yup.object().shape({...}) can be nested, allowing you to validate deeply structured data.
  • .min(yup.ref('startDate')) ensures endDate is the same or after startDate.
  • Useful for flight bookings, hotel reservations, or event scheduling.

5. Web3 Wallet Address Example

If you’re building a dApp or dealing with cryptocurrencies, you may want to validate an Ethereum address or other blockchain wallets.

import * as yup from 'yup';

const ethWalletSchema = yup.string()
  .matches(/^0x[a-fA-F0-9]{40}$/, 'Must be a valid Ethereum wallet address')
  .required('Wallet address is required');

const userWalletData = {
  walletAddress: '0xabcd1234fFfbbb0000CCC9999aaaeee111111111',
};

ethWalletSchema
  .validate(userWalletData.walletAddress)
  .then(valid => console.log('Valid ETH wallet address:', valid))
  .catch(err => console.log('Wallet validation error:', err.errors));

Key Points:

  • The schema enforces addresses to start with 0x and follow a 40-character hex format.
  • This approach can be adapted for other chain addresses if you know the expected pattern.

6. Strictly Enumerated Roles (e.g., Admin, Editor, Viewer)

Sometimes, you want a field to only allow certain string values (like user roles).

import * as yup from 'yup';

const roleSchema = yup.string()
  .oneOf(['admin', 'editor', 'viewer'], 'Role must be either admin, editor, or viewer')
  .required('User role is required');

roleSchema
  .validate('editor')
  .then(valid => console.log('Valid role:', valid))
  .catch(err => console.log('Role validation error:', err.errors));

Key Points:

  • .oneOf([...]) restricts the value to a specific set of valid options.
  • Perfect for user permissions or any scenario with a limited set of allowable values.

7. Array of Objects Example (e.g., Items in a Shopping Cart)

Validating arrays of objects? No problem. Here’s an example of items in a cart, each with a product ID, quantity, and price.

import * as yup from 'yup';

const cartItemSchema = yup.object().shape({
  productId: yup.string().required('Product ID is required'),
  quantity: yup
    .number()
    .integer('Quantity must be an integer')
    .positive('Quantity must be greater than zero')
    .required('Quantity is required'),
  price: yup
    .number()
    .positive('Price must be positive')
    .required('Price is required'),
});

const shoppingCartSchema = yup.array().of(cartItemSchema);

const myCartData = [
  {
    productId: 'ABC123',
    quantity: 2,
    price: 19.99,
  },
  {
    productId: 'XYZ456',
    quantity: 1,
    price: 59.99,
  },
];

shoppingCartSchema
  .validate(myCartData)
  .then(valid => console.log('Valid cart items:', valid))
  .catch(err => console.log('Cart validation error:', err.errors));

Key Points:

  • yup.array().of(...) allows you to define the schema for each item in an array.
  • Each item must adhere to the shape defined by cartItemSchema.
  • Handy for validating any “list of objects” scenario (e.g., cart items, tasks, etc.).

8. Credit Card and Expiration Date

Finally, a common use case for e-commerce sites is validating credit card information. Below is a simple pattern example (note that real credit card validation can be more nuanced).

import * as yup from 'yup';

const paymentSchema = yup.object().shape({
  cardNumber: yup.string()
    .matches(/^[0-9]{16}$/, 'Card number must be 16 digits')
    .required('Card number is required'),
  expiryMonth: yup.number()
    .min(1, 'Month cannot be less than 1')
    .max(12, 'Month cannot exceed 12')
    .required('Expiry month is required'),
  expiryYear: yup.number()
    .min(new Date().getFullYear(), 'Year must be this year or greater')
    .required('Expiry year is required'),
  cvc: yup.string()
    .matches(/^[0-9]{3,4}$/, 'CVC must be 3 or 4 digits')
    .required('CVC is required'),
});

const paymentData = {
  cardNumber: '1234567812345678',
  expiryMonth: 12,
  expiryYear: 2030,
  cvc: '123',
};

paymentSchema
  .validate(paymentData)
  .then(valid => console.log('Valid payment data:', valid))
  .catch(err => console.log('Payment validation error:', err.errors));

Key Points:

  • This uses simple numeric constraints for month and year.
  • CVC can be 3 or 4 digits depending on the card type.
  • Real-world credit card checks might involve using a Luhn algorithm or further checks.

Tips for Structuring Yup Schemas

  1. Combine Schemas: You can define multiple smaller schemas and combine them if your data is spread across different sections (for example, user details, address, and payment).
  2. Custom Methods and Validation: If your logic is more complex, Yup allows for custom tests using .test(...).
  3. Error Messaging: Provide user-friendly error messages. This makes the validation feedback more meaningful.
Griffen Fargo headshot

Griffen Fargo

Published

Share
Keep Reading

Discussion

Have thoughts? Drop them in.

Comments are powered by Disqus. Sign in once, comment anywhere.

Loading comments…
Fin.

griffen.codes

made with 💖 and

© 2026all rights reservedupdated 12 seconds ago