Yup! Even more schemas validation examples for Yup…

May 01, 2021

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

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.
headshot photo

Published on

May 01, 2021

griffen.codes

made with 💖 and

2025 © all rights are reserved | updated 12 seconds ago

Footer Background Image