A Swagger UI plugin that displays custom badges for API operations based on OpenAPI extension fields.
- π·οΈ Custom badges for any OpenAPI extension field
- π¨ Configurable styling with custom icons, colors, and backgrounds
- π§ Flexible parsing support for strings, arrays, and objects
- π Multiple badge types per operation
- π Framework agnostic - works with any Swagger UI implementation
- β‘ Zero dependencies (peer dependency on swagger-ui-dist only)
npm install swagger-custom-badgesyarn add swagger-custom-badgespnpm add swagger-custom-badgesimport { CustomBadgePlugin } from 'swagger-custom-badges';
// Configure Swagger UI with the plugin
SwaggerUIBundle({
url: './openapi.json',
dom_id: '#swagger-ui',
plugins: [
CustomBadgePlugin({
fields: [
{
fieldName: 'x-roles',
badge: {
icon: 'π€',
background: '#007bff',
color: 'white'
}
}
]
})
]
});Add extension fields to your OpenAPI operations:
paths:
/users:
get:
summary: Get users
x-roles: "admin"
responses:
'200':
description: Successinterface PluginConfig {
fields: FieldConfig[]; // Array of field configurations
defaultIcon?: string; // Default icon for all badges
defaultColor?: string; // Default text color
defaultBackground?: string; // Default background color
}interface SingleBadgeField {
fieldName: string; // OpenAPI extension field name (e.g., 'x-roles')
badge: BadgeConfig; // Badge styling configuration
parser?: BadgeParser; // Optional custom parser function
}
interface BadgeConfig {
icon?: string; // Emoji or text icon
color?: string; // Text color (CSS color value)
background?: string; // Background color (CSS color value)
}interface MultiBadgeField {
fieldName: string; // OpenAPI extension field name
badges: { [key: string]: BadgeConfig }; // Mapping of badge keys to configurations
parser?: BadgeParser; // Optional custom parser function
}Create custom parsing logic for complex field values:
interface BadgeParser {
(value: any): Array<{ key: string; value: any }>;
}
// Example: Custom parser for deprecated fields
const deprecatedParser = (value: { reason: string; since: string; until: string }) => [
{
key: 'deprecated',
value: `${value.reason} (${value.since} - ${value.until})`
}
];import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { CustomBadgePlugin } from 'swagger-custom-badges';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('API Documentation')
.setDescription('API with custom badges')
.setVersion('1.0')
.build();
const documentFactory = () => SwaggerModule.createDocument(app, config);
SwaggerModule.setup('docs', app, documentFactory, {
swaggerOptions: {
plugins: [
CustomBadgePlugin({
fields: [
{
fieldName: 'x-roles',
badges: {
admin: { icon: 'π', background: '#dc3545' },
user: { icon: 'π€', background: '#28a745' },
guest: { icon: 'π', background: '#6c757d' }
}
},
{
fieldName: 'x-deprecated',
badge: {
icon: 'β οΈ',
background: '#ffc107',
color: '#000'
}
}
],
defaultIcon: 'π·οΈ',
defaultColor: 'white',
defaultBackground: '#6f42c1'
})
]
}
});
await app.listen(3000);
}
bootstrap();import { Controller, Get } from '@nestjs/common';
import { ApiExtension, ApiOperation } from '@nestjs/swagger';
@Controller('users')
export class UsersController {
@Get()
@ApiOperation({ summary: 'Get all users' })
@ApiExtension('x-roles', ['admin', 'user'])
getUsers() {
return [];
}
@Get('profile')
@ApiOperation({ summary: 'Get user profile' })
@ApiExtension('x-roles', { admin: true, user: true })
getProfile() {
return {};
}
@Get('legacy')
@ApiOperation({ summary: 'Legacy endpoint' })
@ApiExtension('x-deprecated', {
reason: 'Use /users instead',
since: '1.0.0',
until: '2.0.0'
})
getLegacy() {
return {};
}
}const express = require('express');
const swaggerUi = require('swagger-ui-express');
const { CustomBadgePlugin } = require('swagger-custom-badges');
const swaggerDocument = require('./openapi.json');
const app = express();
app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument, {
swaggerOptions: {
plugins: [
CustomBadgePlugin({
fields: [
{
fieldName: 'x-security-level',
badges: {
high: { icon: 'π', background: '#dc3545' },
medium: { icon: 'π‘', background: '#ffc107' },
low: { icon: 'π’', background: '#28a745' }
}
}
]
})
]
}
}));<!DOCTYPE html>
<html>
<head>
<title>API Documentation</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui-bundle.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js"></script>
<script src="./swagger-custom-badges.js"></script>
<script>
SwaggerUIBundle({
url: './openapi.json',
dom_id: '#swagger-ui',
plugins: [
SwaggerUIBundle.plugins.DownloadUrl,
CustomBadgePlugin({
fields: [
{
fieldName: 'x-team',
badge: {
icon: 'π₯',
background: '#17a2b8'
}
}
]
})
]
});
</script>
</body>
</html>CustomBadgePlugin({
fields: [
{
fieldName: 'x-auth',
badges: {
admin: { icon: 'π', background: '#dc3545' },
moderator: { icon: 'π‘οΈ', background: '#fd7e14' },
user: { icon: 'π€', background: '#28a745' },
guest: { icon: 'π', background: '#6c757d' }
}
}
]
})OpenAPI specification:
paths:
/admin/users:
get:
x-auth: ["admin"]
/posts:
get:
x-auth: ["admin", "moderator", "user"]
post:
x-auth: { admin: true, user: true }CustomBadgePlugin({
fields: [
{
fieldName: 'x-deprecated',
badge: {
icon: 'β οΈ',
background: '#ffc107',
color: '#000'
},
parser: (value) => [
{
key: 'deprecated',
value: `Deprecated since ${value.since}`
}
]
}
]
})CustomBadgePlugin({
fields: [
{
fieldName: 'x-environment',
badges: {
production: { icon: 'π', background: '#dc3545' },
staging: { icon: 'π§ͺ', background: '#ffc107' },
development: { icon: 'π§', background: '#28a745' }
}
}
]
})CustomBadgePlugin({
fields: [
{
fieldName: 'x-rate-limit',
badge: {
icon: 'β±οΈ',
background: '#6f42c1'
},
parser: (value) => [
{
key: 'rate-limit',
value: `${value.requests}/${value.window}`
}
]
}
]
})The plugin automatically parses different data formats:
x-roles: "admin,user,guest" # Comma-separated valuesx-roles: ["admin", "user", "guest"]x-roles:
admin: true
user: false
guest: truex-metadata:
team: "backend"
priority: "high"
version: "v2"The plugin automatically injects CSS styles, but you can override them:
.operation-with-badges {
/* Container for operations with badges */
}
.badges {
/* Container for badge row */
}
.swagger-custom-badge {
/* Individual badge styling */
display: inline-block;
padding: 2px 6px;
margin: 2px 4px 2px 0;
font-size: 11px;
font-weight: bold;
border-radius: 3px;
color: white;
}Creates a new instance of the custom badge plugin.
Parameters:
config- Plugin configuration object
Returns: Swagger UI plugin object
const defaultConfig = {
fields: [],
defaultIcon: 'π·οΈ',
defaultColor: 'white',
defaultBackground: '#50e3c2'
};- Swagger UI: 5.21.0+ (peer dependency)
- Node.js: 16+
- TypeScript: 5.0+ (optional)
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
# Clone the repository
git clone https://github.com/Dexsper/swagger-custom-badges.git
cd swagger-custom-badges
# Install dependencies
npm install
# Build the project
npm run build
# Run the example
cd examples/nestjs
npm install
npm run start:devThis project is licensed under the MIT License - see the LICENSE file for details.
- π Issues
- π¬ Discussions
- Initial release
- Support for custom badges on Swagger UI operations
- Configurable styling options
- Multiple data format support
- NestJS example
Made with β€οΈ by Dexsper
