Schema processors are functions that transform your OpenAPI schemas before they are used in the
documentation. They are defined in your zudoku.build.ts file and can be used to modify schemas in
various ways.
For information on how to configure processors in your project, see the
Build Configuration guide.
Built-in Processors
Zudoku provides several built-in processors that you can use to transform your schemas:
removeExtensions
Removes OpenAPI extensions (x- prefixed properties) from your schema:
Code
import { removeExtensions } from "zudoku/processors/removeExtensions";import type { ZudokuBuildConfig } from "zudoku";const buildConfig: ZudokuBuildConfig = { processors: [ // Remove all x- prefixed properties removeExtensions(), // Remove specific extensions removeExtensions({ keys: ["x-internal", "x-deprecated"], }), // Remove extensions based on a custom filter removeExtensions({ shouldRemove: (key) => key.startsWith("x-zuplo"), }), ],};export default buildConfig;
removeParameters
Removes parameters from your schema:
Code
import { removeParameters } from "zudoku/processors/removeParameters";import type { ZudokuBuildConfig } from "zudoku";const buildConfig: ZudokuBuildConfig = { processors: [ // Remove parameters by name removeParameters({ names: ["apiKey", "secret"], }), // Remove parameters by location removeParameters({ in: ["header", "query"], }), // Remove parameters based on a custom filter removeParameters({ shouldRemove: ({ parameter }) => parameter["x-internal"], }), ],};export default buildConfig;
removePaths
Removes paths or operations from your schema:
Code
import { removePaths } from "zudoku/processors/removePaths";import type { ZudokuBuildConfig } from "zudoku";const buildConfig: ZudokuBuildConfig = { processors: [ // Remove entire paths removePaths({ paths: { "/internal": true, "/admin": ["get", "post"], }, }), // Remove paths based on a custom filter removePaths({ shouldRemove: ({ path, method, operation }) => operation["x-internal"], }), ],};export default buildConfig;
If you are missing a processor that you think should be built-in, please don't hesitate to
open an issue on GitHub.
Custom Processors
You can also create your own processors. Here's a simple example that adds a description to all
operations:
Code
import type { ZudokuBuildConfig } from "zudoku";async function addDescriptionProcessor({ schema }) { if (!schema.paths) return schema; // Add a description to all operations Object.values(schema.paths).forEach((path) => { Object.values(path).forEach((operation) => { if (typeof operation === "object") { operation.description = "This is a public API endpoint"; } }); }); return schema;}const buildConfig: ZudokuBuildConfig = { processors: [addDescriptionProcessor],};export default buildConfig;
Adding Server URLs
Code
import type { ZudokuBuildConfig } from "zudoku";async function addServerUrl({ schema }) { return { ...schema, servers: [{ url: "https://api.example.com" }], };}const buildConfig: ZudokuBuildConfig = { processors: [addServerUrl],};export default buildConfig;
Using Query Parameters to Split Schemas
You can use the same OpenAPI file multiple times with different processing by appending query
parameters to the file input string. These parameters are passed to your processors via the params
argument, allowing you to filter or transform the schema differently for each variant.
This is useful when you have a single schema containing multiple API versions or groups that you
want to split into separate pages.
Plain strings work out of the box. Version paths and dropdown labels are auto-generated from the
query parameter values. For more control, use the object form with explicit path and label.
Each version tab will show only the endpoints matching that prefix. The query parameters are
arbitrary key-value pairs that you define and consume in your processors.
When schema download is enabled, param variants serve the processed (filtered) schema rather than
the original file.
Best Practices
Handle missing properties: Check for the existence of properties before accessing them
Return the schema: Always return the transformed schema, even if no changes were made
Use async/await: Processors can be async functions, which is useful for more complex
transformations
Chain processors: Processors are executed in order, so you can chain multiple transformations