Middleware
Intercept and modify handler execution with the middleware chain.
Middleware runs before every command, context menu, and event handler. Use it for logging, permission checks, rate limiting, or any cross-cutting concern. Middleware files live in src/middleware/.
File structure
Handler signature
The default export receives a MiddlewareData object and can return a MiddlewareResult to abort or modify execution:
import type { MiddlewareData } from '@robojs/discordjs'
export default (data: MiddlewareData) => {
console.log(`Handler: ${data.record.key} (${data.record.type})`)
}export default (data) => {
console.log(`Handler: ${data.record.key} (${data.record.type})`)
}MiddlewareData
The data argument contains:
Prop
Type
Aborting execution
Return { abort: true } to prevent the handler from running:
The
MiddlewareResulttype also includes apayloadfield, but it is reserved for future use and is not currently consumed by the runtime. Onlyabortis checked.
Error behavior: If any middleware throws an error, the entire handler execution is aborted. Ensure middleware functions handle their own errors gracefully if you want execution to continue.
import type { MiddlewareData, MiddlewareResult } from '@robojs/discordjs'
import type { ChatInputCommandInteraction } from 'discord.js'
export default (data: MiddlewareData): MiddlewareResult | void => {
const interaction = data.payload[0] as ChatInputCommandInteraction
if (interaction?.user && interaction.user.id !== 'YOUR_ADMIN_ID') {
interaction.reply({ content: 'Admin only!', ephemeral: true })
return { abort: true }
}
}export default (data) => {
const interaction = data.payload[0]
if (interaction?.user && interaction.user.id !== 'YOUR_ADMIN_ID') {
interaction.reply({ content: 'Admin only!', ephemeral: true })
return { abort: true }
}
}Middleware config
Export a config object to control execution order and enablement.
Prop
Type
import type { MiddlewareConfig } from '@robojs/discordjs'
export const config: MiddlewareConfig = {
order: -10 // appears first in middleware.chain()
}
export default (data) => {
// Rate limiting logic
}Execution order
The order field is accepted in middleware config and controls runtime execution order. Lower values run first. The middleware.chain() namespace controller returns the same ordered chain programmatically:
order: -10 -> first
order: 0 -> default
order: 10 -> last