Celebrate
Celebrate is a robust Express.js middleware designed for integrating Joi validation seamlessly into web applications. It allows developers to define validation schemas for various parts of an incoming request, including `req.params`, `req.headers`, `req.query`, `req.body`, `req.cookies`, and `req.signedCookies`. The library is currently stable at version 15.0.3 and undergoes regular maintenance with notable major version updates introducing breaking changes (e.g., v15, v14, v13, v8, v4, v3, v2). A key differentiator is its formal dependency on `joi`, ensuring a consistent and up-to-date Joi version is always used and also exported for consumer compatibility. It aims to simplify input validation in Express routes, providing a consistent error handling mechanism before any route handler is executed.
Common errors
-
TypeError: celebrate is not a function
cause Incorrect import statement or mixing CommonJS `require` with ES Modules `import` syntax without proper configuration.fixFor ES Modules and TypeScript: `import { celebrate } from 'celebrate';`. For CommonJS: `const { celebrate } = require('celebrate');`. Ensure `package.json` has `"type": "module"` for ESM. -
ValidationError: "someField" is required
cause A Joi schema marked a field as `required()` but it was missing from the incoming request payload.fixEnsure the client is sending all required fields as defined in your Joi schema. Double-check field names and casing. -
Cannot read properties of undefined (reading 'json')
cause You are attempting to validate `req.body` with `celebrate`, but a body-parsing middleware like `body-parser` (or Express's built-in `express.json()`) has not been applied before `celebrate`.fixAdd `app.use(bodyParser.json());` or `app.use(express.json());` before your `celebrate` middleware. Ensure it's active for the routes where `req.body` validation occurs. -
Error [ERR_REQUIRE_ESM]: require() of ES Module ... celebrated.js not supported.
cause You are attempting to `require()` an ES Module in a CommonJS context, often when `celebrate` (or its dependencies) have transitioned to ESM-only.fixTransition your project to ES Modules by adding `"type": "module"` to your `package.json` and updating all `require()` statements to `import` statements. Alternatively, investigate if a CommonJS-compatible version or wrapper is available.
Warnings
- breaking `Joi` is now a named export. If you were previously importing `Joi` as a default export or through `require('celebrate').Joi`, you must update your import statement.
- breaking The default validation `Modes` changed from `FULL` to `PARTIAL`. This means validation will now stop on the first error encountered, rather than collecting all errors across all segments.
- breaking Celebrate now requires Joi v17 or newer. Additionally, `req.params` validation logic and general error handling mechanisms were significantly updated. The `celebrator` API was also deprecated.
- breaking The `Joi` export from `celebrate` was renamed from `Joi` to `@hapi/joi` to reflect the package name change in the Joi ecosystem at the time.
- breaking Celebrate dropped support for Node.js versions older than 10.x. This impacts deployment environments and local development setups.
- gotcha Celebrate mutates the request object (`req.body`, `req.query`, etc.) when Joi schemas apply default values, coercions, or transformations. This means the request object passed to subsequent middleware or route handlers might differ from the original incoming request.
- gotcha Celebrate (and Joi) will not validate `req.body` for HTTP GET requests by default, as the HTTP specification states GET requests should not contain a body.
Install
-
npm install celebrate -
yarn add celebrate -
pnpm add celebrate
Imports
- celebrate
const celebrate = require('celebrate');import { celebrate } from 'celebrate'; - Joi
import Joi from 'joi';
import { Joi } from 'celebrate'; - errors
const errors = require('celebrate').errors;import { errors } from 'celebrate'; - Segments
const { Segments } = require('celebrate').Segments;import { Segments } from 'celebrate';
Quickstart
import express from 'express';
import bodyParser from 'body-parser';
import { celebrate, Joi, errors, Segments } from 'celebrate';
const app = express();
app.use(bodyParser.json());
app.post('/signup', celebrate({
[Segments.BODY]: Joi.object().keys({
name: Joi.string().required().min(3).max(50),
email: Joi.string().email().required(),
age: Joi.number().integer().min(18).max(120),
role: Joi.string().valid('user', 'admin').default('user')
}),
[Segments.HEADERS]: Joi.object({
authorization: Joi.string().required()
}).unknown(true) // Allow other headers
}), (req, res) => {
// At this point, req.body and req.headers have been validated and
// req.body.role is set to 'user' if not provided.
console.log('Validated body:', req.body);
console.log('Validated headers:', req.headers.authorization);
res.status(200).send('Signup successful!');
});
// Error handling middleware from celebrate
app.use(errors());
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
// Example of accessing the exported Joi instance directly
const myCustomSchema = Joi.object({
customField: Joi.string().alphanum().min(3).required()
});
// To test, send a POST request to http://localhost:3000/signup
// with a JSON body like:
// {"name": "Test User", "email": "test@example.com", "age": 30}
// and an 'Authorization' header. A missing 'name' or 'email' will fail validation.