{"owner":"swagger-api","repo":"swagger-ui","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["CLAUDE.md"],"skills":{"CLAUDE.md":"# CLAUDE.md - Swagger UI Codebase Guide\n\n> **Last Updated:** 2026-02-24\n> **Version:** 5.32.0 (in development)\n> **Purpose:** Comprehensive guide for AI assistants working with the Swagger UI codebase\n\n---\n\n## Table of Contents\n\n1. [Repository Overview](#repository-overview)\n2. [Project Architecture](#project-architecture)\n3. [Development Setup](#development-setup)\n4. [Build System](#build-system)\n5. [Testing Infrastructure](#testing-infrastructure)\n6. [Code Style & Conventions](#code-style--conventions)\n7. [Git Workflow](#git-workflow)\n8. [Plugin Architecture](#plugin-architecture)\n9. [Key Files & Directories](#key-files--directories)\n10. [Common Workflows](#common-workflows)\n11. [Important Guidelines](#important-guidelines)\n\n---\n\n## Repository Overview\n\n### What is Swagger UI?\n\nSwagger UI is a tool that allows developers to visualize and interact with API resources without having implementation logic in place. It's automatically generated from OpenAPI (formerly Swagger) Specification documents.\n\n### Multi-Package Monorepo Structure\n\nThis repository publishes **three different npm packages**:\n\n1. **swagger-ui** (main package)\n   - Traditional npm module for single-page applications\n   - Entry: `dist/swagger-ui.js`\n   - ES Module: `dist/swagger-ui-es-bundle-core.js`\n   - Includes dependency resolution via Webpack/Browserify\n\n2. **swagger-ui-dist** (distribution package)\n   - Dependency-free module for server-side projects\n   - Published separately via GitHub workflow\n   - Template location: `swagger-ui-dist-package/`\n\n3. **swagger-ui-react** (React component)\n   - React wrapper component\n   - Location: `flavors/swagger-ui-react/`\n   - Uses React hooks\n   - Released separately via GitHub workflow\n\n### OpenAPI Specification Compatibility\n\n- **Current Support:** OpenAPI 2.0, 3.0.x, 3.1.x\n- **Latest Version:** v5.31.0 (supports up to OpenAPI 3.1.2)\n\n### License\n\nApache 2.0 - See LICENSE and NOTICE files for details.\n\n---\n\n## Project Architecture\n\n### Technology Stack\n\n**Core Framework:**\n- React 18 (>=16.8.0 <20) - UI components\n- Redux 5.0.1 - State management\n- Redux Immutable 4.0.0 - Immutable state\n- Immutable.js 3.x - Immutable data structures\n- React Redux 9.2.0 - React-Redux bindings\n\n**API & Schema Processing:**\n- swagger-client 3.36.0 - OpenAPI client\n- js-yaml 4.1.1 - YAML parsing\n- remarkable 2.0.1 - Markdown rendering\n\n**Security:**\n- DOMPurify 3.2.6 - HTML sanitization (CRITICAL for XSS prevention)\n- serialize-error 8.1.0 - Error serialization\n\n**Build Tools:**\n- Webpack 5.97.1 - Module bundling\n- Babel 7.26.x - JavaScript transpilation\n- sass-embedded 1.86.0 - SCSS compilation\n- PostCSS - CSS processing\n\n**Testing:**\n- Jest 29.7.0 - Unit testing\n- Cypress 14.2.0 - E2E testing\n- Enzyme 3.11.0 - React component testing\n\n**Development:**\n- ESLint 8.57.0 - JavaScript linting\n- Prettier 3.5.3 - Code formatting\n- Stylelint 16.19.1 - CSS linting\n- Husky 9.1.7 - Git hooks\n- lint-staged 15.5.0 - Pre-commit linting\n\n### Plugin-Based Architecture\n\nSwagger UI uses a **sophisticated plugin system** powered by Redux. The core system (`src/core/system.js`) manages:\n\n- Plugin registration and lifecycle\n- Redux store creation and middleware\n- State plugin combination\n- Action/selector binding\n- Configuration management\n\n**26 Core Plugins** (in `src/core/plugins/`):\n- `auth` - Authentication handling\n- `configs` - Configuration management\n- `deep-linking` - URL-based navigation\n- `download-url` - Spec downloading\n- `err` - Error handling and transformation\n- `filter` - API filtering\n- `icons` - Icon components\n- `json-schema-2020-12` - JSON Schema 2020-12 support\n- `json-schema-2020-12-samples` - Sample generation\n- `json-schema-5` - JSON Schema Draft 5 support\n- `json-schema-5-samples` - Sample generation for Draft 5\n- `layout` - Layout system\n- `logs` - Logging\n- `oas3` - OpenAPI 3.0.x support\n- `oas31` - OpenAPI 3.1.x support\n- `oas32` - OpenAPI 3.2.x support\n- `on-complete` - Completion callbacks\n- `request-snippets` - Code snippet generation\n- `safe-render` - Safe component rendering\n- `spec` - Specification handling\n- `swagger-client` - API client integration\n- `syntax-highlighting` - Code highlighting\n- `util` - Utilities\n- `versions` - Version detection\n- `view` - View rendering\n- `view-legacy` - Legacy view support\n\n---\n\n## Development Setup\n\n### Prerequisites\n\n- **Node.js:** >=24.19.0 (Node 24.x recommended, as defined in `.nvmrc`)\n- **npm:** >=11.17.0\n- **Git:** Any version\n- **JDK 7+:** Required for Nightwatch.js integration tests\n\n### Installation Steps\n\n```bash\n# Clone the repository\ngit clone https://github.com/swagger-api/swagger-ui.git\ncd swagger-ui\n\n# Install dependencies\nnpm install\n\n# Initialize Husky (optional, for git hooks)\nnpx husky init\n\n# Start development server\nnpm run dev\n\n# Open http://localhost:3200/\n```\n\n### Development Server\n\nThe `npm run dev` command starts a hot-reloading Webpack dev server on **port 3200**.\n\n### Using Local API Definitions\n\nEdit `dev-helpers/dev-helper-initializer.js` to change the spec URL:\n\n```javascript\n// Replace\nurl: \"https://petstore.swagger.io/v2/swagger.json\",\n\n// With\nurl: \"./examples/your-local-api-definition.yaml\",\n```\n\n**Important:** Local files must be in the `dev-helpers/` directory or subdirectory. Use `dev-helpers/examples/` (already in `.gitignore`).\n\n---\n\n## Build System\n\n### Babel Environments\n\nThree Babel environments configured in `babel.config.js`:\n\n1. **development/production** - Browser builds with `modules: \"auto\"`\n2. **commonjs** - CommonJS modules with `modules: \"commonjs\"` for Node.js\n3. **esm** - ES modules with `modules: false` for modern bundlers\n\n### Babel Aliases\n\n```javascript\n{\n  root: \".\",\n  core: \"./src/core\"\n}\n```\n\n### Browserslist Environments\n\nDefined in `.browserslistrc`:\n\n- `[browser-production]` - Production browser targets\n- `[browser-development]` - Latest Chrome, Firefox, Safari\n- `[isomorphic-production]` - Browser + Node targets\n- `[node-production]` - Maintained Node versions\n- `[node-development]` - Node 24\n\n### Build Commands\n\n```bash\n# Full build (stylesheets + all bundles)\nnpm run build\n\n# Individual builds\nnpm run build:core              # Core bundle (browser)\nnpm run build:bundle            # Isomorphic bundle\nnpm run build:standalone        # Standalone preset\nnpm run build:es:bundle         # ES module bundle\nnpm run build:es:bundle:core    # ES module core\nnpm run build-stylesheets       # CSS only\n\n# Clean build artifacts\nnpm run clean\n```\n\n### Build Output (dist/)\n\n- `swagger-ui.js` - Core bundle (CommonJS)\n- `swagger-ui.css` - Compiled styles\n- `swagger-ui-bundle.js` - Isomorphic bundle\n- `swagger-ui-standalone-preset.js` - Standalone preset\n- `swagger-ui-es-bundle.js` - ES module bundle\n- `swagger-ui-es-bundle-core.js` - ES module core\n- `oauth2-redirect.html` - OAuth2 redirect page\n\n### Webpack Configurations\n\nLocated in `webpack/` directory:\n\n- `_config-builder.js` - Base configuration\n- `core.js` - Core build\n- `bundle.js` - Bundle build\n- `standalone.js` - Standalone build\n- `es-bundle.js` - ES bundle\n- `es-bundle-core.js` - ES core bundle\n- `stylesheets.js` - CSS build\n- `dev.js` - Development server\n- `dev-e2e.js` - E2E testing server\n\n---\n\n## Testing Infrastructure\n\n### Unit Tests (Jest)\n\n**Configuration:** `config/jest/jest.unit.config.js`\n\n**Environment:** jsdom (simulates browser environment)\n\n**Location:** `test/unit/`\n\n**Command:**\n```bash\nnpm run test:unit\n```\n\n**Key Features:**\n- 37 unit test files\n- Tests for core plugins, components, system\n- XSS security tests\n- Silent mode enabled by default (set to `false` for console output)\n- Module name mapper for SVG and standalone imports\n- Transform ignore patterns for node_modules exceptions\n\n**Setup Files:**\n- `test/unit/jest-shim.js` - Polyfills and shims\n- `test/unit/setup.js` - Test environment setup\n\n### E2E Tests (Cypress)\n\n**Configuration:** `cypress.config.js`\n\n**Location:** `test/e2e-cypress/`\n\n**Base URL:** http://localhost:3230/\n\n**Commands:**\n```bash\n# Run all E2E tests\nnpm run cy:ci\n\n# Interactive Cypress runner\nnpm run cy:dev\n\n# Headless run\nnpm run cy:run\n\n# Start servers and run tests\nnpm run cy:start     # Starts webpack + mock API\n```\n\n**Structure:**\n- `test/e2e-cypress/e2e/` - Test specs (99 test files)\n- `test/e2e-cypress/static/` - Test fixtures and documents\n- `test/e2e-cypress/support/` - Test helpers and commands\n\n**Test Categories:**\n- `a11y/**/*cy.js` - Accessibility tests\n- `security/**/*cy.js` - Security tests\n- `bugs/**/*cy.js` - Bug regression tests\n- `features/**/*cy.js` - Feature tests\n\n**Mock API Server:**\n```bash\nnpm run cy:mock-api  # JSON Server on port 3204\n```\n\n### Artifact Tests\n\n**Configuration:** `config/jest/jest.artifact.config.js`\n\n**Purpose:** Verify build artifacts export correctly\n\n**Command:**\n```bash\nnpm run test:artifact\n```\n\n### Complete Test Suite\n\n```bash\nnpm test  # Runs: lint-errors + test:unit + cy:ci\n```\n\n### CI/CD Testing\n\n**GitHub Actions Workflow:** `.github/workflows/nodejs.yml`\n\n**Two Jobs:**\n1. **build** - Lint, unit tests, build, artifact tests\n2. **e2e-tests** - Cypress tests (matrix strategy with 3 containers)\n\n**Branches:** `main`, `next`\n\n---\n\n## Code Style & Conventions\n\n### ESLint Configuration\n\n**File:** `.eslintrc.js`\n\n**Parser:** `@babel/eslint-parser`\n\n**Key Rules:**\n- `semi: [2, \"never\"]` - **No semicolons**\n- `quotes: [2, \"double\"]` - **Double quotes** (allow template literals)\n- `no-unused-vars: 2` - Error on unused variables\n- `camelcase: [\"error\"]` - Enforce camelCase (with exceptions for UNSAFE_, request generators, etc.)\n- `no-console: [2, {allow: [\"warn\", \"error\"]}]` - Only `console.warn` and `console.error` allowed\n- `react/jsx-no-bind: 1` - Warning for JSX bind\n- `react/jsx-filename-extension: 2` - JSX only in `.jsx` files\n- `import/no-extraneous-dependencies: 2` - Error on extraneous dependencies\n\n**Extends:**\n- `eslint:recommended`\n- `plugin:react/recommended`\n- `plugin:prettier/recommended`\n\n### Prettier Configuration\n\n**File:** `.prettierrc.yaml`\n\n**Settings:**\n```yaml\nsemi: false              # No semicolons\ntrailingComma: es5       # ES5 trailing commas\nendOfLine: lf            # Unix line endings\nrequirePragma: true      # Require @prettier pragma\ninsertPragma: true       # Insert @prettier pragma\n```\n\n**IMPORTANT:** Prettier requires `@prettier` pragma comment at the top of files:\n```javascript\n/**\n * @prettier\n */\n```\n\n### Stylelint Configuration\n\n**File:** `stylelint.config.js`\n\n**Custom Syntax:** `postcss-scss`\n\n**Rules:**\n- Uses `stylelint-prettier` plugin\n- Prettier integration without pragma requirement\n\n### Pre-commit Hooks\n\n**Husky:** `.husky/pre-commit` runs `npx lint-staged`\n\n**Lint-staged Configuration:** `.lintstagedrc`\n```json\n{\n  \"*.{js,jsx}\": [\"eslint --max-warnings 0\"],\n  \"*.scss\": [\"stylelint '**/*.scss'\"]\n}\n```\n\n**Critical:** All staged JS/JSX/SCSS files are linted with **zero warnings tolerance**.\n\n### File Structure Conventions\n\n**Components:**\n- Location: `src/core/components/`\n- Extension: `.jsx` (React components)\n- Format: PascalCase for component names\n\n**Styles:**\n- Location: `src/style/`\n- Extension: `.scss`\n- Format: SCSS with PostCSS processing\n- Dark mode: `_dark-mode.scss`\n\n**Tests:**\n- Unit: `test/unit/` (mirrors source structure)\n- E2E: `test/e2e-cypress/e2e/`\n- Naming: `*.test.js`, `*.spec.js`, `*.cy.js` (Cypress)\n\n---\n\n## Git Workflow\n\n### Branch Strategy\n\n**Main Branches:**\n- `main` - Production releases\n- `next` - Next version development\n\n**Feature Branches:**\n- Should branch from `main` or `next`\n- Use descriptive names\n\n### Commit Conventions\n\n**Format:** Conventional Commits (enforced by commitlint)\n\n**Structure:**\n```\n<type>(<scope>): <subject>\n\n<body>\n\n<footer>\n```\n\n**Types:**\n- `feat` - New feature\n- `fix` - Bug fix\n- `docs` - Documentation changes\n- `style` - Code style changes (formatting)\n- `refactor` - Code refactoring\n- `test` - Test additions/changes\n- `chore` - Build/tooling changes\n- `perf` - Performance improvements\n\n**Example:**\n```\nfeat(oas3): add support for OpenAPI 3.1.1 callbacks\n\nImplement callback rendering for OAS 3.1.1 specifications\nwith proper schema resolution and example generation.\n\nFixes #12345\n```\n\n### Pull Request Process\n\n**Template:** `.github/pull_request_template.md`\n\n**Required Sections:**\n1. **Description** - Detailed change description\n2. **Motivation and Context** - Why the change is needed\n3. **How Has This Been Tested?** - Manual testing details\n4. **Screenshots** - If UI changes\n\n**Checklist:**\n- [ ] Code type (no code/dependencies/bug fix/improvement/feature)\n- [ ] Breaking changes identification\n- [ ] Documentation updates\n- [ ] Test coverage\n- [ ] All tests passing\n\n**CI Checks:**\n- ESLint (error-only mode)\n- Unit tests (Jest)\n- Build verification\n- Artifact tests\n- E2E tests (Cypress)\n\n### Release Process\n\n**Tool:** release-it with conventional-changelog\n\n**Command:**\n```bash\nnpm run automated-release\n```\n\n**Workflows:**\n- `.github/workflows/release-swagger-ui.yml`\n- `.github/workflows/release-swagger-ui-dist.yml`\n- `.github/workflows/release-swagger-ui-react.yml`\n- `.github/workflows/release-swagger-ui-packagist.yml`\n\n---\n\n## Plugin Architecture\n\n### Core System (`src/core/system.js`)\n\nThe plugin system is the heart of Swagger UI. It uses Redux for state management with a custom plugin registration system.\n\n### Plugin Structure\n\nEach plugin is a JavaScript object/function that returns:\n\n```javascript\n{\n  statePlugins: {\n    [pluginName]: {\n      actions: {},      // Redux actions\n      reducers: {},     // Redux reducers\n      selectors: {},    // Reselect selectors\n      wrapActions: {},  // Action middleware\n      wrapSelectors: {} // Selector middleware\n    }\n  },\n  components: {},       // React components\n  fn: {},              // Utility functions\n  rootInjects: {},     // Root-level injections\n  afterLoad: Function  // Lifecycle hook\n}\n```\n\n### Key Plugin Locations\n\n**Core Plugins:** `src/core/plugins/`\n\nEach plugin has:\n- `index.js` - Main export\n- `actions.js` - Redux actions\n- `reducers.js` - Redux reducers\n- `selectors.js` - State selectors\n- `wrap-actions.js` - Action middleware\n- `wrap-selectors.js` - Selector middleware\n- Component files (`.jsx`)\n\n### Creating a Plugin\n\nSee documentation: `docs/customization/plugin-api.md`\n\n### Cross-Plugin Import Guidelines\n\n**IMPORTANT:** Avoid cross-plugin imports to maintain plugin independence and modularity.\n\n**Pattern to Follow:**\n- Each plugin should be self-contained with its own components, utilities, and functions\n- When OAS version plugins (oas3, oas31, oas32) need similar functionality, create self-contained copies within each plugin\n- Wrap components should import from their own plugin's components, not from other plugins\n\n**Example Structure:**\n```\nsrc/core/plugins/oas32/\n├── json-schema-2020-12-extensions/\n│   ├── components/              # Self-contained components\n│   │   └── keywords/\n│   │       ├── Description.jsx\n│   │       └── Properties.jsx\n│   ├── wrap-components/         # Wrappers for components\n│   │   └── keywords/\n│   │       ├── Description.jsx  # Imports from ../../components/\n│   │       └── Properties.jsx   # Not from ../../../../oas31/\n│   └── fn.js                    # Self-contained utilities\n```\n\n**Why This Matters:**\n- Prevents tight coupling between plugins\n- Makes plugins easier to test in isolation\n- Allows independent versioning and updates\n- Reduces risk of breaking changes across plugins\n- Improves code maintainability\n\n**Exceptions:**\n- Shared core utilities in `src/core/utils/` are acceptable\n- System-level functions in `src/core/system.js` are acceptable\n- Base components in `src/core/components/` are acceptable\n\n### Preset System\n\n**Base Preset:** `src/core/presets/base.js`\n\n**Standalone Preset:** `src/standalone/presets/standalone.js`\n\nPresets are collections of plugins bundled together for specific use cases.\n\n---\n\n## Key Files & Directories\n\n### Critical Source Files\n\n```\nsrc/\n├── core/\n│   ├── system.js                 # Plugin system & Redux store\n│   ├── components/               # 59 React components\n│   ├── plugins/                  # 26 core plugins\n│   ├── presets/                  # Preset configurations\n│   ├── utils/                    # Utility functions\n│   └── config/                   # Configuration system\n├── standalone/\n│   ├── plugins/                  # TopBar, StandaloneLayout\n│   └── presets/                  # Standalone preset\n├── style/                        # SCSS stylesheets\n│   ├── _dark-mode.scss          # Dark mode styles\n│   └── main.scss                # Main stylesheet entry\n└── index.js                      # Main package entry\n```\n\n### Configuration Files\n\n```\n.\n├── package.json                  # Dependencies & scripts\n├── babel.config.js              # Babel configuration\n├── .eslintrc.js                 # ESLint rules\n├── .prettierrc.yaml             # Prettier settings\n├── stylelint.config.js          # Stylelint rules\n├── .browserslistrc              # Browser targets\n├── .nvmrc                       # Node version (24.x)\n├── .lintstagedrc                # Pre-commit linting\n└── cypress.config.js            # Cypress E2E config\n```\n\n### Build & Tooling\n\n```\nwebpack/\n├── _config-builder.js           # Base Webpack config\n├── core.js                      # Core build\n├── bundle.js                    # Bundle build\n├── standalone.js                # Standalone build\n├── es-bundle.js                 # ES bundle build\n├── es-bundle-core.js           # ES core bundle\n├── stylesheets.js              # CSS compilation\n├── dev.js                       # Dev server\n└── dev-e2e.js                  # E2E dev server\n\nconfig/jest/\n├── jest.unit.config.js          # Unit test config\n└── jest.artifact.config.js      # Artifact test config\n```\n\n### Documentation\n\n```\ndocs/\n├── usage/\n│   ├── installation.md\n│   ├── configuration.md\n│   ├── cors.md\n│   ├── oauth2.md\n│   ├── deep-linking.md\n│   ├── version-detection.md\n│   └── limitations.md\n├── customization/\n│   ├── overview.md\n│   ├── plugin-api.md\n│   └── custom-layout.md\n└── development/\n    ├── setting-up.md\n    └── scripts.md\n```\n\n### Testing\n\n```\ntest/\n├── unit/                        # Jest unit tests (37 files)\n│   ├── setup.js                # Test environment setup\n│   └── jest-shim.js           # Polyfills\n├── e2e-cypress/                 # Cypress E2E tests (99 files)\n│   ├── e2e/                    # Test specs\n│   ├── static/                 # Fixtures\n│   └── support/                # Helpers\n└── e2e-selenium/               # Legacy Selenium tests\n```\n\n### Distribution\n\n```\nflavors/\n└── swagger-ui-react/            # React component wrapper\n\nswagger-ui-dist-package/         # Template for dist package\n\ndist/                            # Build output (generated)\n├── swagger-ui.js\n├── swagger-ui.css\n├── swagger-ui-bundle.js\n├── swagger-ui-standalone-preset.js\n├── swagger-ui-es-bundle.js\n├── swagger-ui-es-bundle-core.js\n└── oauth2-redirect.html\n```\n\n---\n\n## Common Workflows\n\n### Making Code Changes\n\n1. **Read before modifying:**\n   ```bash\n   # ALWAYS read files before editing them\n   # Understand the existing code structure\n   ```\n\n2. **Follow the style guide:**\n   - Use double quotes\n   - No semicolons\n   - Add `@prettier` pragma to new files\n   - Use `.jsx` extension for React components\n\n3. **Run linters:**\n   ```bash\n   npm run lint          # Check for errors and warnings\n   npm run lint-fix      # Auto-fix JavaScript issues\n   npm run lint-styles   # Check SCSS\n   npm run lint-styles-fix  # Auto-fix SCSS\n   ```\n\n4. **Test your changes:**\n   ```bash\n   npm run test:unit     # Run unit tests\n   npm run cy:dev        # Interactive E2E testing\n   npm run build         # Verify build works\n   npm run test:artifact # Verify artifacts\n   ```\n\n### Adding a New Component\n\n1. Create component in `src/core/components/` or appropriate plugin directory\n2. Use `.jsx` extension\n3. Add `@prettier` pragma\n4. Follow React best practices (functional components, hooks)\n5. Add PropTypes validation\n6. Create corresponding test in `test/unit/`\n7. Export from plugin's `index.js` if needed\n\n### Adding a New Plugin\n\n1. Create directory in `src/core/plugins/[plugin-name]/`\n2. Create `index.js` with plugin structure\n3. Add actions, reducers, selectors as needed\n4. Register plugin in preset (e.g., `src/core/presets/base.js`)\n5. Add tests in `test/unit/core/plugins/[plugin-name]/`\n6. Document the plugin\n\n### Fixing a Bug\n\n1. **Reproduce the bug:**\n   - Add a failing test in `test/unit/` or `test/e2e-cypress/`\n   - Document reproduction steps\n\n2. **Fix the issue:**\n   - Make minimal changes to fix the bug\n   - Avoid refactoring unless necessary\n   - Ensure the test now passes\n\n3. **Verify:**\n   ```bash\n   npm run test:unit\n   npm run build\n   npm run test:artifact\n   ```\n\n4. **Create PR:**\n   - Reference the issue number\n   - Include before/after behavior\n   - Add screenshots if UI-related\n\n### Adding a Feature\n\n1. **Plan the feature:**\n   - Review existing architecture\n   - Identify affected plugins/components\n   - Consider OpenAPI spec compatibility\n\n2. **Implement:**\n   - Follow plugin architecture patterns\n   - Add configuration options if needed\n   - Update presets if necessary\n\n3. **Test thoroughly:**\n   - Unit tests for logic\n   - Component tests for UI\n   - E2E tests for integration\n   - Test with various OpenAPI specs\n\n4. **Document:**\n   - Update `docs/` if user-facing\n   - Add JSDoc comments for APIs\n   - Update README if needed\n\n### Security Considerations\n\n1. **XSS Prevention:**\n   - ALWAYS use DOMPurify for user-provided HTML\n   - Sanitize all external input\n   - Review `test/unit/xss/` for examples\n   - Never use `dangerouslySetInnerHTML` without sanitization\n\n2. **Input Validation:**\n   - Validate API responses\n   - Handle malformed OpenAPI specs gracefully\n   - Check for prototype pollution\n\n3. **Dependency Security:**\n   ```bash\n   npm run security-audit     # Run security audit\n   ```\n\n### Working with OpenAPI Specs\n\n**Testing Different Versions:**\n- OAS 2.0: Use `src/core/plugins/swagger-client/`\n- OAS 3.0.x: Use `src/core/plugins/oas3/`\n- OAS 3.1.x: Use `src/core/plugins/oas31/`\n- OAS 3.2.x: Use `src/core/plugins/oas32/`\n\n**Adding Test Specs:**\n- Add to `test/e2e-cypress/static/documents/`\n- Reference in E2E tests\n\n---\n\n## Important Guidelines\n\n### DO's ✅\n\n1. **Always read files before modifying them**\n2. **Follow the no-semicolon convention**\n3. **Use double quotes for strings**\n4. **Add `@prettier` pragma to all new files**\n5. **Use `.jsx` extension for React components**\n6. **Write tests for new features and bug fixes**\n7. **Run linters before committing** (automatic via husky)\n8. **Use DOMPurify for HTML sanitization**\n9. **Follow conventional commit format**\n10. **Update documentation for user-facing changes**\n11. **Test with multiple OpenAPI spec versions**\n12. **Check browser compatibility** (see `.browserslistrc`)\n13. **Use the plugin architecture** - don't modify core unnecessarily\n14. **Preserve backward compatibility** unless explicitly breaking\n15. **Run full test suite before submitting PR**\n16. **Keep plugins self-contained** - avoid cross-plugin imports (see [Cross-Plugin Import Guidelines](#cross-plugin-import-guidelines))\n\n### DON'Ts ❌\n\n1. **Don't use semicolons** - project convention\n2. **Don't use single quotes** - use double quotes\n3. **Don't skip the @prettier pragma** - required for formatting\n4. **Don't put React in `.js` files** - use `.jsx`\n5. **Don't commit files in `dev-helpers/`** (except core files)\n6. **Don't commit build artifacts** (`dist/` is gitignored)\n7. **Don't skip tests** - they run in CI\n8. **Don't bypass ESLint** - pre-commit hook enforces\n9. **Don't use `console.log`** - only `console.warn` and `console.error`\n10. **Don't render unsanitized HTML** - XSS vulnerability\n11. **Don't modify `package-lock.json` manually**\n12. **Don't push directly to `main` or `next`**\n13. **Don't ignore Cypress test failures**\n14. **Don't add dependencies without justification**\n15. **Don't break the build** - verify with `npm run build`\n16. **Don't import from other plugins** - create self-contained copies instead (e.g., don't import from `oas31` in `oas32`)\n\n### When Working with AI Assistants\n\n**Before Making Changes:**\n1. Read the affected files completely\n2. Understand the plugin architecture\n3. Check for existing tests\n4. Review related documentation\n\n**During Development:**\n1. Make minimal, focused changes\n2. Follow existing patterns in the codebase\n3. Add tests alongside code changes\n4. Run linters frequently\n\n**After Changes:**\n1. Verify all tests pass\n2. Check build completes successfully\n3. Test artifact exports\n4. Review for security issues\n5. Update relevant documentation\n\n**Communication:**\n- Be explicit about file locations\n- Use line number references (e.g., `src/core/system.js:96`)\n- Provide context for changes\n- Mention any breaking changes clearly\n\n### Performance Considerations\n\n1. **Immutable.js:**\n   - Use Immutable data structures for state\n   - Use `.toJS()` sparingly (expensive)\n   - Prefer Immutable operations\n\n2. **React:**\n   - Use React.memo for pure components\n   - Implement shouldComponentUpdate for class components\n   - Avoid inline function definitions in render\n\n3. **Redux:**\n   - Use reselect for memoized selectors\n   - Keep reducers pure and fast\n   - Avoid large state trees\n\n4. **Bundle Size:**\n   - Check bundle size with `npm run deps-size`\n   - Review dependency licenses with `npm run deps-license`\n   - Consider code splitting for large features\n\n### Debugging Tips\n\n**Development Server:**\n```bash\nnpm run dev\n# Open http://localhost:3200/\n# Hot reload enabled\n# Unminified stack traces\n```\n\n**Redux DevTools:**\n- Extension supported\n- State inspection available\n- Time-travel debugging\n\n**Cypress Interactive Mode:**\n```bash\nnpm run cy:dev\n# Visual test runner\n# Step-through debugging\n# Network inspection\n```\n\n**Jest Watch Mode:**\n```bash\nnpm run test:unit -- --watch\n# Re-run on file changes\n# Filter by file name or test name\n```\n\n**Source Maps:**\n- Generated for all builds\n- Enable in browser DevTools\n- Original source debugging\n\n---\n\n## Quick Reference\n\n### Essential Commands\n\n```bash\n# Development\nnpm run dev              # Start dev server (port 3200)\nnpm start                # Static file server (port 3002)\n\n# Building\nnpm run build            # Full production build\nnpm run clean            # Remove dist/\n\n# Testing\nnpm test                 # Full test suite (lint + unit + E2E)\nnpm run test:unit        # Jest unit tests\nnpm run cy:dev           # Cypress interactive\nnpm run cy:ci            # Cypress CI mode\nnpm run test:artifact    # Artifact verification\n\n# Linting\nnpm run lint             # ESLint (errors + warnings)\nnpm run lint-errors      # ESLint (errors only)\nnpm run lint-fix         # Auto-fix ESLint issues\nnpm run lint-styles      # Stylelint\nnpm run lint-styles-fix  # Auto-fix Stylelint issues\n\n# Security\nnpm run security-audit   # Run npm audit\n\n# Dependencies\nnpm run deps-check       # Size and license report\n```\n\n### File Paths\n\n```\nCore System:           src/core/system.js\nMain Entry:            src/index.js\nReact Entry:           flavors/swagger-ui-react/index.jsx\nComponents:            src/core/components/\nPlugins:               src/core/plugins/\nStyles:                src/style/\nTests (Unit):          test/unit/\nTests (E2E):           test/e2e-cypress/e2e/\nBuild Output:          dist/\n```\n\n### Port Reference\n\n- **3200** - Development server (webpack-dev-server)\n- **3002** - Static file server (local-web-server)\n- **3204** - Mock API server (json-server)\n- **3230** - E2E test server (webpack-dev-server)\n\n---\n\n## Additional Resources\n\n### Documentation\n\n- **Setup Guide:** `docs/development/setting-up.md`\n- **Scripts Reference:** `docs/development/scripts.md`\n- **Plugin API:** `docs/customization/plugin-api.md`\n- **Configuration:** `docs/usage/configuration.md`\n- **OAuth2 Setup:** `docs/usage/oauth2.md`\n\n### External Links\n\n- **Homepage:** https://swagger.io/tools/swagger-ui/\n- **Repository:** https://github.com/swagger-api/swagger-ui\n- **npm (main):** https://www.npmjs.com/package/swagger-ui\n- **npm (dist):** https://www.npmjs.com/package/swagger-ui-dist\n- **npm (react):** https://www.npmjs.com/package/swagger-ui-react\n- **OpenAPI Spec:** https://spec.openapis.org/\n\n### Community\n\n- **Issues:** https://github.com/swagger-api/swagger-ui/issues\n- **Good First Issues:** https://github.com/swagger-api/swagger-ui/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%22\n- **Security:** security@swagger.io\n- **Contributing:** https://github.com/swagger-api/.github/blob/HEAD/CONTRIBUTING.md\n\n---\n\n**Note:** This document should be updated whenever major architectural changes, new conventions, or significant workflows are introduced to the codebase.\n"},"files":{"CLAUDE.md":"# CLAUDE.md - Swagger UI Codebase Guide\n\n> **Last Updated:** 2026-02-24\n> **Version:** 5.32.0 (in development)\n> **Purpose:** Comprehensive guide for AI assistants working with the Swagger UI codebase\n\n---\n\n## Table of Contents\n\n1. [Repository Overview](#repository-overview)\n2. [Project Architecture](#project-architecture)\n3. [Development Setup](#development-setup)\n4. [Build System](#build-system)\n5. [Testing Infrastructure](#testing-infrastructure)\n6. [Code Style & Conventions](#code-style--conventions)\n7. [Git Workflow](#git-workflow)\n8. [Plugin Architecture](#plugin-architecture)\n9. [Key Files & Directories](#key-files--directories)\n10. [Common Workflows](#common-workflows)\n11. [Important Guidelines](#important-guidelines)\n\n---\n\n## Repository Overview\n\n### What is Swagger UI?\n\nSwagger UI is a tool that allows developers to visualize and interact with API resources without having implementation logic in place. It's automatically generated from OpenAPI (formerly Swagger) Specification documents.\n\n### Multi-Package Monorepo Structure\n\nThis repository publishes **three different npm packages**:\n\n1. **swagger-ui** (main package)\n   - Traditional npm module for single-page applications\n   - Entry: `dist/swagger-ui.js`\n   - ES Module: `dist/swagger-ui-es-bundle-core.js`\n   - Includes dependency resolution via Webpack/Browserify\n\n2. **swagger-ui-dist** (distribution package)\n   - Dependency-free module for server-side projects\n   - Published separately via GitHub workflow\n   - Template location: `swagger-ui-dist-package/`\n\n3. **swagger-ui-react** (React component)\n   - React wrapper component\n   - Location: `flavors/swagger-ui-react/`\n   - Uses React hooks\n   - Released separately via GitHub workflow\n\n### OpenAPI Specification Compatibility\n\n- **Current Support:** OpenAPI 2.0, 3.0.x, 3.1.x\n- **Latest Version:** v5.31.0 (supports up to OpenAPI 3.1.2)\n\n### License\n\nApache 2.0 - See LICENSE and NOTICE files for details.\n\n---\n\n## Project Architecture\n\n### Technology Stack\n\n**Core Framework:**\n- React 18 (>=16.8.0 <20) - UI components\n- Redux 5.0.1 - State management\n- Redux Immutable 4.0.0 - Immutable state\n- Immutable.js 3.x - Immutable data structures\n- React Redux 9.2.0 - React-Redux bindings\n\n**API & Schema Processing:**\n- swagger-client 3.36.0 - OpenAPI client\n- js-yaml 4.1.1 - YAML parsing\n- remarkable 2.0.1 - Markdown rendering\n\n**Security:**\n- DOMPurify 3.2.6 - HTML sanitization (CRITICAL for XSS prevention)\n- serialize-error 8.1.0 - Error serialization\n\n**Build Tools:**\n- Webpack 5.97.1 - Module bundling\n- Babel 7.26.x - JavaScript transpilation\n- sass-embedded 1.86.0 - SCSS compilation\n- PostCSS - CSS processing\n\n**Testing:**\n- Jest 29.7.0 - Unit testing\n- Cypress 14.2.0 - E2E testing\n- Enzyme 3.11.0 - React component testing\n\n**Development:**\n- ESLint 8.57.0 - JavaScript linting\n- Prettier 3.5.3 - Code formatting\n- Stylelint 16.19.1 - CSS linting\n- Husky 9.1.7 - Git hooks\n- lint-staged 15.5.0 - Pre-commit linting\n\n### Plugin-Based Architecture\n\nSwagger UI uses a **sophisticated plugin system** powered by Redux. The core system (`src/core/system.js`) manages:\n\n- Plugin registration and lifecycle\n- Redux store creation and middleware\n- State plugin combination\n- Action/selector binding\n- Configuration management\n\n**26 Core Plugins** (in `src/core/plugins/`):\n- `auth` - Authentication handling\n- `configs` - Configuration management\n- `deep-linking` - URL-based navigation\n- `download-url` - Spec downloading\n- `err` - Error handling and transformation\n- `filter` - API filtering\n- `icons` - Icon components\n- `json-schema-2020-12` - JSON Schema 2020-12 support\n- `json-schema-2020-12-samples` - Sample generation\n- `json-schema-5` - JSON Schema Draft 5 support\n- `json-schema-5-samples` - Sample generation for Draft 5\n- `layout` - Layout system\n- `logs` - Logging\n- `oas3` - OpenAPI 3.0.x support\n- `oas31` - OpenAPI 3.1.x support\n- `oas32` - OpenAPI 3.2.x support\n- `on-complete` - Completion callbacks\n- `request-snippets` - Code snippet generation\n- `safe-render` - Safe component rendering\n- `spec` - Specification handling\n- `swagger-client` - API client integration\n- `syntax-highlighting` - Code highlighting\n- `util` - Utilities\n- `versions` - Version detection\n- `view` - View rendering\n- `view-legacy` - Legacy view support\n\n---\n\n## Development Setup\n\n### Prerequisites\n\n- **Node.js:** >=24.19.0 (Node 24.x recommended, as defined in `.nvmrc`)\n- **npm:** >=11.17.0\n- **Git:** Any version\n- **JDK 7+:** Required for Nightwatch.js integration tests\n\n### Installation Steps\n\n```bash\n# Clone the repository\ngit clone https://github.com/swagger-api/swagger-ui.git\ncd swagger-ui\n\n# Install dependencies\nnpm install\n\n# Initialize Husky (optional, for git hooks)\nnpx husky init\n\n# Start development server\nnpm run dev\n\n# Open http://localhost:3200/\n```\n\n### Development Server\n\nThe `npm run dev` command starts a hot-reloading Webpack dev server on **port 3200**.\n\n### Using Local API Definitions\n\nEdit `dev-helpers/dev-helper-initializer.js` to change the spec URL:\n\n```javascript\n// Replace\nurl: \"https://petstore.swagger.io/v2/swagger.json\",\n\n// With\nurl: \"./examples/your-local-api-definition.yaml\",\n```\n\n**Important:** Local files must be in the `dev-helpers/` directory or subdirectory. Use `dev-helpers/examples/` (already in `.gitignore`).\n\n---\n\n## Build System\n\n### Babel Environments\n\nThree Babel environments configured in `babel.config.js`:\n\n1. **development/production** - Browser builds with `modules: \"auto\"`\n2. **commonjs** - CommonJS modules with `modules: \"commonjs\"` for Node.js\n3. **esm** - ES modules with `modules: false` for modern bundlers\n\n### Babel Aliases\n\n```javascript\n{\n  root: \".\",\n  core: \"./src/core\"\n}\n```\n\n### Browserslist Environments\n\nDefined in `.browserslistrc`:\n\n- `[browser-production]` - Production browser targets\n- `[browser-development]` - Latest Chrome, Firefox, Safari\n- `[isomorphic-production]` - Browser + Node targets\n- `[node-production]` - Maintained Node versions\n- `[node-development]` - Node 24\n\n### Build Commands\n\n```bash\n# Full build (stylesheets + all bundles)\nnpm run build\n\n# Individual builds\nnpm run build:core              # Core bundle (browser)\nnpm run build:bundle            # Isomorphic bundle\nnpm run build:standalone        # Standalone preset\nnpm run build:es:bundle         # ES module bundle\nnpm run build:es:bundle:core    # ES module core\nnpm run build-stylesheets       # CSS only\n\n# Clean build artifacts\nnpm run clean\n```\n\n### Build Output (dist/)\n\n- `swagger-ui.js` - Core bundle (CommonJS)\n- `swagger-ui.css` - Compiled styles\n- `swagger-ui-bundle.js` - Isomorphic bundle\n- `swagger-ui-standalone-preset.js` - Standalone preset\n- `swagger-ui-es-bundle.js` - ES module bundle\n- `swagger-ui-es-bundle-core.js` - ES module core\n- `oauth2-redirect.html` - OAuth2 redirect page\n\n### Webpack Configurations\n\nLocated in `webpack/` directory:\n\n- `_config-builder.js` - Base configuration\n- `core.js` - Core build\n- `bundle.js` - Bundle build\n- `standalone.js` - Standalone build\n- `es-bundle.js` - ES bundle\n- `es-bundle-core.js` - ES core bundle\n- `stylesheets.js` - CSS build\n- `dev.js` - Development server\n- `dev-e2e.js` - E2E testing server\n\n---\n\n## Testing Infrastructure\n\n### Unit Tests (Jest)\n\n**Configuration:** `config/jest/jest.unit.config.js`\n\n**Environment:** jsdom (simulates browser environment)\n\n**Location:** `test/unit/`\n\n**Command:**\n```bash\nnpm run test:unit\n```\n\n**Key Features:**\n- 37 unit test files\n- Tests for core plugins, components, system\n- XSS security tests\n- Silent mode enabled by default (set to `false` for console output)\n- Module name mapper for SVG and standalone imports\n- Transform ignore patterns for node_modules exceptions\n\n**Setup Files:**\n- `test/unit/jest-shim.js` - Polyfills and shims\n- `test/unit/setup.js` - Test environment setup\n\n### E2E Tests (Cypress)\n\n**Configuration:** `cypress.config.js`\n\n**Location:** `test/e2e-cypress/`\n\n**Base URL:** http://localhost:3230/\n\n**Commands:**\n```bash\n# Run all E2E tests\nnpm run cy:ci\n\n# Interactive Cypress runner\nnpm run cy:dev\n\n# Headless run\nnpm run cy:run\n\n# Start servers and run tests\nnpm run cy:start     # Starts webpack + mock API\n```\n\n**Structure:**\n- `test/e2e-cypress/e2e/` - Test specs (99 test files)\n- `test/e2e-cypress/static/` - Test fixtures and documents\n- `test/e2e-cypress/support/` - Test helpers and commands\n\n**Test Categories:**\n- `a11y/**/*cy.js` - Accessibility tests\n- `security/**/*cy.js` - Security tests\n- `bugs/**/*cy.js` - Bug regression tests\n- `features/**/*cy.js` - Feature tests\n\n**Mock API Server:**\n```bash\nnpm run cy:mock-api  # JSON Server on port 3204\n```\n\n### Artifact Tests\n\n**Configuration:** `config/jest/jest.artifact.config.js`\n\n**Purpose:** Verify build artifacts export correctly\n\n**Command:**\n```bash\nnpm run test:artifact\n```\n\n### Complete Test Suite\n\n```bash\nnpm test  # Runs: lint-errors + test:unit + cy:ci\n```\n\n### CI/CD Testing\n\n**GitHub Actions Workflow:** `.github/workflows/nodejs.yml`\n\n**Two Jobs:**\n1. **build** - Lint, unit tests, build, artifact tests\n2. **e2e-tests** - Cypress tests (matrix strategy with 3 containers)\n\n**Branches:** `main`, `next`\n\n---\n\n## Code Style & Conventions\n\n### ESLint Configuration\n\n**File:** `.eslintrc.js`\n\n**Parser:** `@babel/eslint-parser`\n\n**Key Rules:**\n- `semi: [2, \"never\"]` - **No semicolons**\n- `quotes: [2, \"double\"]` - **Double quotes** (allow template literals)\n- `no-unused-vars: 2` - Error on unused variables\n- `camelcase: [\"error\"]` - Enforce camelCase (with exceptions for UNSAFE_, request generators, etc.)\n- `no-console: [2, {allow: [\"warn\", \"error\"]}]` - Only `console.warn` and `console.error` allowed\n- `react/jsx-no-bind: 1` - Warning for JSX bind\n- `react/jsx-filename-extension: 2` - JSX only in `.jsx` files\n- `import/no-extraneous-dependencies: 2` - Error on extraneous dependencies\n\n**Extends:**\n- `eslint:recommended`\n- `plugin:react/recommended`\n- `plugin:prettier/recommended`\n\n### Prettier Configuration\n\n**File:** `.prettierrc.yaml`\n\n**Settings:**\n```yaml\nsemi: false              # No semicolons\ntrailingComma: es5       # ES5 trailing commas\nendOfLine: lf            # Unix line endings\nrequirePragma: true      # Require @prettier pragma\ninsertPragma: true       # Insert @prettier pragma\n```\n\n**IMPORTANT:** Prettier requires `@prettier` pragma comment at the top of files:\n```javascript\n/**\n * @prettier\n */\n```\n\n### Stylelint Configuration\n\n**File:** `stylelint.config.js`\n\n**Custom Syntax:** `postcss-scss`\n\n**Rules:**\n- Uses `stylelint-prettier` plugin\n- Prettier integration without pragma requirement\n\n### Pre-commit Hooks\n\n**Husky:** `.husky/pre-commit` runs `npx lint-staged`\n\n**Lint-staged Configuration:** `.lintstagedrc`\n```json\n{\n  \"*.{js,jsx}\": [\"eslint --max-warnings 0\"],\n  \"*.scss\": [\"stylelint '**/*.scss'\"]\n}\n```\n\n**Critical:** All staged JS/JSX/SCSS files are linted with **zero warnings tolerance**.\n\n### File Structure Conventions\n\n**Components:**\n- Location: `src/core/components/`\n- Extension: `.jsx` (React components)\n- Format: PascalCase for component names\n\n**Styles:**\n- Location: `src/style/`\n- Extension: `.scss`\n- Format: SCSS with PostCSS processing\n- Dark mode: `_dark-mode.scss`\n\n**Tests:**\n- Unit: `test/unit/` (mirrors source structure)\n- E2E: `test/e2e-cypress/e2e/`\n- Naming: `*.test.js`, `*.spec.js`, `*.cy.js` (Cypress)\n\n---\n\n## Git Workflow\n\n### Branch Strategy\n\n**Main Branches:**\n- `main` - Production releases\n- `next` - Next version development\n\n**Feature Branches:**\n- Should branch from `main` or `next`\n- Use descriptive names\n\n### Commit Conventions\n\n**Format:** Conventional Commits (enforced by commitlint)\n\n**Structure:**\n```\n<type>(<scope>): <subject>\n\n<body>\n\n<footer>\n```\n\n**Types:**\n- `feat` - New feature\n- `fix` - Bug fix\n- `docs` - Documentation changes\n- `style` - Code style changes (formatting)\n- `refactor` - Code refactoring\n- `test` - Test additions/changes\n- `chore` - Build/tooling changes\n- `perf` - Performance improvements\n\n**Example:**\n```\nfeat(oas3): add support for OpenAPI 3.1.1 callbacks\n\nImplement callback rendering for OAS 3.1.1 specifications\nwith proper schema resolution and example generation.\n\nFixes #12345\n```\n\n### Pull Request Process\n\n**Template:** `.github/pull_request_template.md`\n\n**Required Sections:**\n1. **Description** - Detailed change description\n2. **Motivation and Context** - Why the change is needed\n3. **How Has This Been Tested?** - Manual testing details\n4. **Screenshots** - If UI changes\n\n**Checklist:**\n- [ ] Code type (no code/dependencies/bug fix/improvement/feature)\n- [ ] Breaking changes identification\n- [ ] Documentation updates\n- [ ] Test coverage\n- [ ] All tests passing\n\n**CI Checks:**\n- ESLint (error-only mode)\n- Unit tests (Jest)\n- Build verification\n- Artifact tests\n- E2E tests (Cypress)\n\n### Release Process\n\n**Tool:** release-it with conventional-changelog\n\n**Command:**\n```bash\nnpm run automated-release\n```\n\n**Workflows:**\n- `.github/workflows/release-swagger-ui.yml`\n- `.github/workflows/release-swagger-ui-dist.yml`\n- `.github/workflows/release-swagger-ui-react.yml`\n- `.github/workflows/release-swagger-ui-packagist.yml`\n\n---\n\n## Plugin Architecture\n\n### Core System (`src/core/system.js`)\n\nThe plugin system is the heart of Swagger UI. It uses Redux for state management with a custom plugin registration system.\n\n### Plugin Structure\n\nEach plugin is a JavaScript object/function that returns:\n\n```javascript\n{\n  statePlugins: {\n    [pluginName]: {\n      actions: {},      // Redux actions\n      reducers: {},     // Redux reducers\n      selectors: {},    // Reselect selectors\n      wrapActions: {},  // Action middleware\n      wrapSelectors: {} // Selector middleware\n    }\n  },\n  components: {},       // React components\n  fn: {},              // Utility functions\n  rootInjects: {},     // Root-level injections\n  afterLoad: Function  // Lifecycle hook\n}\n```\n\n### Key Plugin Locations\n\n**Core Plugins:** `src/core/plugins/`\n\nEach plugin has:\n- `index.js` - Main export\n- `actions.js` - Redux actions\n- `reducers.js` - Redux reducers\n- `selectors.js` - State selectors\n- `wrap-actions.js` - Action middleware\n- `wrap-selectors.js` - Selector middleware\n- Component files (`.jsx`)\n\n### Creating a Plugin\n\nSee documentation: `docs/customization/plugin-api.md`\n\n### Cross-Plugin Import Guidelines\n\n**IMPORTANT:** Avoid cross-plugin imports to maintain plugin independence and modularity.\n\n**Pattern to Follow:**\n- Each plugin should be self-contained with its own components, utilities, and functions\n- When OAS version plugins (oas3, oas31, oas32) need similar functionality, create self-contained copies within each plugin\n- Wrap components should import from their own plugin's components, not from other plugins\n\n**Example Structure:**\n```\nsrc/core/plugins/oas32/\n├── json-schema-2020-12-extensions/\n│   ├── components/              # Self-contained components\n│   │   └── keywords/\n│   │       ├── Description.jsx\n│   │       └── Properties.jsx\n│   ├── wrap-components/         # Wrappers for components\n│   │   └── keywords/\n│   │       ├── Description.jsx  # Imports from ../../components/\n│   │       └── Properties.jsx   # Not from ../../../../oas31/\n│   └── fn.js                    # Self-contained utilities\n```\n\n**Why This Matters:**\n- Prevents tight coupling between plugins\n- Makes plugins easier to test in isolation\n- Allows independent versioning and updates\n- Reduces risk of breaking changes across plugins\n- Improves code maintainability\n\n**Exceptions:**\n- Shared core utilities in `src/core/utils/` are acceptable\n- System-level functions in `src/core/system.js` are acceptable\n- Base components in `src/core/components/` are acceptable\n\n### Preset System\n\n**Base Preset:** `src/core/presets/base.js`\n\n**Standalone Preset:** `src/standalone/presets/standalone.js`\n\nPresets are collections of plugins bundled together for specific use cases.\n\n---\n\n## Key Files & Directories\n\n### Critical Source Files\n\n```\nsrc/\n├── core/\n│   ├── system.js                 # Plugin system & Redux store\n│   ├── components/               # 59 React components\n│   ├── plugins/                  # 26 core plugins\n│   ├── presets/                  # Preset configurations\n│   ├── utils/                    # Utility functions\n│   └── config/                   # Configuration system\n├── standalone/\n│   ├── plugins/                  # TopBar, StandaloneLayout\n│   └── presets/                  # Standalone preset\n├── style/                        # SCSS stylesheets\n│   ├── _dark-mode.scss          # Dark mode styles\n│   └── main.scss                # Main stylesheet entry\n└── index.js                      # Main package entry\n```\n\n### Configuration Files\n\n```\n.\n├── package.json                  # Dependencies & scripts\n├── babel.config.js              # Babel configuration\n├── .eslintrc.js                 # ESLint rules\n├── .prettierrc.yaml             # Prettier settings\n├── stylelint.config.js          # Stylelint rules\n├── .browserslistrc              # Browser targets\n├── .nvmrc                       # Node version (24.x)\n├── .lintstagedrc                # Pre-commit linting\n└── cypress.config.js            # Cypress E2E config\n```\n\n### Build & Tooling\n\n```\nwebpack/\n├── _config-builder.js           # Base Webpack config\n├── core.js                      # Core build\n├── bundle.js                    # Bundle build\n├── standalone.js                # Standalone build\n├── es-bundle.js                 # ES bundle build\n├── es-bundle-core.js           # ES core bundle\n├── stylesheets.js              # CSS compilation\n├── dev.js                       # Dev server\n└── dev-e2e.js                  # E2E dev server\n\nconfig/jest/\n├── jest.unit.config.js          # Unit test config\n└── jest.artifact.config.js      # Artifact test config\n```\n\n### Documentation\n\n```\ndocs/\n├── usage/\n│   ├── installation.md\n│   ├── configuration.md\n│   ├── cors.md\n│   ├── oauth2.md\n│   ├── deep-linking.md\n│   ├── version-detection.md\n│   └── limitations.md\n├── customization/\n│   ├── overview.md\n│   ├── plugin-api.md\n│   └── custom-layout.md\n└── development/\n    ├── setting-up.md\n    └── scripts.md\n```\n\n### Testing\n\n```\ntest/\n├── unit/                        # Jest unit tests (37 files)\n│   ├── setup.js                # Test environment setup\n│   └── jest-shim.js           # Polyfills\n├── e2e-cypress/                 # Cypress E2E tests (99 files)\n│   ├── e2e/                    # Test specs\n│   ├── static/                 # Fixtures\n│   └── support/                # Helpers\n└── e2e-selenium/               # Legacy Selenium tests\n```\n\n### Distribution\n\n```\nflavors/\n└── swagger-ui-react/            # React component wrapper\n\nswagger-ui-dist-package/         # Template for dist package\n\ndist/                            # Build output (generated)\n├── swagger-ui.js\n├── swagger-ui.css\n├── swagger-ui-bundle.js\n├── swagger-ui-standalone-preset.js\n├── swagger-ui-es-bundle.js\n├── swagger-ui-es-bundle-core.js\n└── oauth2-redirect.html\n```\n\n---\n\n## Common Workflows\n\n### Making Code Changes\n\n1. **Read before modifying:**\n   ```bash\n   # ALWAYS read files before editing them\n   # Understand the existing code structure\n   ```\n\n2. **Follow the style guide:**\n   - Use double quotes\n   - No semicolons\n   - Add `@prettier` pragma to new files\n   - Use `.jsx` extension for React components\n\n3. **Run linters:**\n   ```bash\n   npm run lint          # Check for errors and warnings\n   npm run lint-fix      # Auto-fix JavaScript issues\n   npm run lint-styles   # Check SCSS\n   npm run lint-styles-fix  # Auto-fix SCSS\n   ```\n\n4. **Test your changes:**\n   ```bash\n   npm run test:unit     # Run unit tests\n   npm run cy:dev        # Interactive E2E testing\n   npm run build         # Verify build works\n   npm run test:artifact # Verify artifacts\n   ```\n\n### Adding a New Component\n\n1. Create component in `src/core/components/` or appropriate plugin directory\n2. Use `.jsx` extension\n3. Add `@prettier` pragma\n4. Follow React best practices (functional components, hooks)\n5. Add PropTypes validation\n6. Create corresponding test in `test/unit/`\n7. Export from plugin's `index.js` if needed\n\n### Adding a New Plugin\n\n1. Create directory in `src/core/plugins/[plugin-name]/`\n2. Create `index.js` with plugin structure\n3. Add actions, reducers, selectors as needed\n4. Register plugin in preset (e.g., `src/core/presets/base.js`)\n5. Add tests in `test/unit/core/plugins/[plugin-name]/`\n6. Document the plugin\n\n### Fixing a Bug\n\n1. **Reproduce the bug:**\n   - Add a failing test in `test/unit/` or `test/e2e-cypress/`\n   - Document reproduction steps\n\n2. **Fix the issue:**\n   - Make minimal changes to fix the bug\n   - Avoid refactoring unless necessary\n   - Ensure the test now passes\n\n3. **Verify:**\n   ```bash\n   npm run test:unit\n   npm run build\n   npm run test:artifact\n   ```\n\n4. **Create PR:**\n   - Reference the issue number\n   - Include before/after behavior\n   - Add screenshots if UI-related\n\n### Adding a Feature\n\n1. **Plan the feature:**\n   - Review existing architecture\n   - Identify affected plugins/components\n   - Consider OpenAPI spec compatibility\n\n2. **Implement:**\n   - Follow plugin architecture patterns\n   - Add configuration options if needed\n   - Update presets if necessary\n\n3. **Test thoroughly:**\n   - Unit tests for logic\n   - Component tests for UI\n   - E2E tests for integration\n   - Test with various OpenAPI specs\n\n4. **Document:**\n   - Update `docs/` if user-facing\n   - Add JSDoc comments for APIs\n   - Update README if needed\n\n### Security Considerations\n\n1. **XSS Prevention:**\n   - ALWAYS use DOMPurify for user-provided HTML\n   - Sanitize all external input\n   - Review `test/unit/xss/` for examples\n   - Never use `dangerouslySetInnerHTML` without sanitization\n\n2. **Input Validation:**\n   - Validate API responses\n   - Handle malformed OpenAPI specs gracefully\n   - Check for prototype pollution\n\n3. **Dependency Security:**\n   ```bash\n   npm run security-audit     # Run security audit\n   ```\n\n### Working with OpenAPI Specs\n\n**Testing Different Versions:**\n- OAS 2.0: Use `src/core/plugins/swagger-client/`\n- OAS 3.0.x: Use `src/core/plugins/oas3/`\n- OAS 3.1.x: Use `src/core/plugins/oas31/`\n- OAS 3.2.x: Use `src/core/plugins/oas32/`\n\n**Adding Test Specs:**\n- Add to `test/e2e-cypress/static/documents/`\n- Reference in E2E tests\n\n---\n\n## Important Guidelines\n\n### DO's ✅\n\n1. **Always read files before modifying them**\n2. **Follow the no-semicolon convention**\n3. **Use double quotes for strings**\n4. **Add `@prettier` pragma to all new files**\n5. **Use `.jsx` extension for React components**\n6. **Write tests for new features and bug fixes**\n7. **Run linters before committing** (automatic via husky)\n8. **Use DOMPurify for HTML sanitization**\n9. **Follow conventional commit format**\n10. **Update documentation for user-facing changes**\n11. **Test with multiple OpenAPI spec versions**\n12. **Check browser compatibility** (see `.browserslistrc`)\n13. **Use the plugin architecture** - don't modify core unnecessarily\n14. **Preserve backward compatibility** unless explicitly breaking\n15. **Run full test suite before submitting PR**\n16. **Keep plugins self-contained** - avoid cross-plugin imports (see [Cross-Plugin Import Guidelines](#cross-plugin-import-guidelines))\n\n### DON'Ts ❌\n\n1. **Don't use semicolons** - project convention\n2. **Don't use single quotes** - use double quotes\n3. **Don't skip the @prettier pragma** - required for formatting\n4. **Don't put React in `.js` files** - use `.jsx`\n5. **Don't commit files in `dev-helpers/`** (except core files)\n6. **Don't commit build artifacts** (`dist/` is gitignored)\n7. **Don't skip tests** - they run in CI\n8. **Don't bypass ESLint** - pre-commit hook enforces\n9. **Don't use `console.log`** - only `console.warn` and `console.error`\n10. **Don't render unsanitized HTML** - XSS vulnerability\n11. **Don't modify `package-lock.json` manually**\n12. **Don't push directly to `main` or `next`**\n13. **Don't ignore Cypress test failures**\n14. **Don't add dependencies without justification**\n15. **Don't break the build** - verify with `npm run build`\n16. **Don't import from other plugins** - create self-contained copies instead (e.g., don't import from `oas31` in `oas32`)\n\n### When Working with AI Assistants\n\n**Before Making Changes:**\n1. Read the affected files completely\n2. Understand the plugin architecture\n3. Check for existing tests\n4. Review related documentation\n\n**During Development:**\n1. Make minimal, focused changes\n2. Follow existing patterns in the codebase\n3. Add tests alongside code changes\n4. Run linters frequently\n\n**After Changes:**\n1. Verify all tests pass\n2. Check build completes successfully\n3. Test artifact exports\n4. Review for security issues\n5. Update relevant documentation\n\n**Communication:**\n- Be explicit about file locations\n- Use line number references (e.g., `src/core/system.js:96`)\n- Provide context for changes\n- Mention any breaking changes clearly\n\n### Performance Considerations\n\n1. **Immutable.js:**\n   - Use Immutable data structures for state\n   - Use `.toJS()` sparingly (expensive)\n   - Prefer Immutable operations\n\n2. **React:**\n   - Use React.memo for pure components\n   - Implement shouldComponentUpdate for class components\n   - Avoid inline function definitions in render\n\n3. **Redux:**\n   - Use reselect for memoized selectors\n   - Keep reducers pure and fast\n   - Avoid large state trees\n\n4. **Bundle Size:**\n   - Check bundle size with `npm run deps-size`\n   - Review dependency licenses with `npm run deps-license`\n   - Consider code splitting for large features\n\n### Debugging Tips\n\n**Development Server:**\n```bash\nnpm run dev\n# Open http://localhost:3200/\n# Hot reload enabled\n# Unminified stack traces\n```\n\n**Redux DevTools:**\n- Extension supported\n- State inspection available\n- Time-travel debugging\n\n**Cypress Interactive Mode:**\n```bash\nnpm run cy:dev\n# Visual test runner\n# Step-through debugging\n# Network inspection\n```\n\n**Jest Watch Mode:**\n```bash\nnpm run test:unit -- --watch\n# Re-run on file changes\n# Filter by file name or test name\n```\n\n**Source Maps:**\n- Generated for all builds\n- Enable in browser DevTools\n- Original source debugging\n\n---\n\n## Quick Reference\n\n### Essential Commands\n\n```bash\n# Development\nnpm run dev              # Start dev server (port 3200)\nnpm start                # Static file server (port 3002)\n\n# Building\nnpm run build            # Full production build\nnpm run clean            # Remove dist/\n\n# Testing\nnpm test                 # Full test suite (lint + unit + E2E)\nnpm run test:unit        # Jest unit tests\nnpm run cy:dev           # Cypress interactive\nnpm run cy:ci            # Cypress CI mode\nnpm run test:artifact    # Artifact verification\n\n# Linting\nnpm run lint             # ESLint (errors + warnings)\nnpm run lint-errors      # ESLint (errors only)\nnpm run lint-fix         # Auto-fix ESLint issues\nnpm run lint-styles      # Stylelint\nnpm run lint-styles-fix  # Auto-fix Stylelint issues\n\n# Security\nnpm run security-audit   # Run npm audit\n\n# Dependencies\nnpm run deps-check       # Size and license report\n```\n\n### File Paths\n\n```\nCore System:           src/core/system.js\nMain Entry:            src/index.js\nReact Entry:           flavors/swagger-ui-react/index.jsx\nComponents:            src/core/components/\nPlugins:               src/core/plugins/\nStyles:                src/style/\nTests (Unit):          test/unit/\nTests (E2E):           test/e2e-cypress/e2e/\nBuild Output:          dist/\n```\n\n### Port Reference\n\n- **3200** - Development server (webpack-dev-server)\n- **3002** - Static file server (local-web-server)\n- **3204** - Mock API server (json-server)\n- **3230** - E2E test server (webpack-dev-server)\n\n---\n\n## Additional Resources\n\n### Documentation\n\n- **Setup Guide:** `docs/development/setting-up.md`\n- **Scripts Reference:** `docs/development/scripts.md`\n- **Plugin API:** `docs/customization/plugin-api.md`\n- **Configuration:** `docs/usage/configuration.md`\n- **OAuth2 Setup:** `docs/usage/oauth2.md`\n\n### External Links\n\n- **Homepage:** https://swagger.io/tools/swagger-ui/\n- **Repository:** https://github.com/swagger-api/swagger-ui\n- **npm (main):** https://www.npmjs.com/package/swagger-ui\n- **npm (dist):** https://www.npmjs.com/package/swagger-ui-dist\n- **npm (react):** https://www.npmjs.com/package/swagger-ui-react\n- **OpenAPI Spec:** https://spec.openapis.org/\n\n### Community\n\n- **Issues:** https://github.com/swagger-api/swagger-ui/issues\n- **Good First Issues:** https://github.com/swagger-api/swagger-ui/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%22\n- **Security:** security@swagger.io\n- **Contributing:** https://github.com/swagger-api/.github/blob/HEAD/CONTRIBUTING.md\n\n---\n\n**Note:** This document should be updated whenever major architectural changes, new conventions, or significant workflows are introduced to the codebase.\n"},"items":[{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"# CLAUDE.md - Swagger UI Codebase Guide\n\n> **Last Updated:** 2026-02-24\n> **Version:** 5.32.0 (in development)\n> **Purpose:** Comprehensive guide for AI assistants working with the Swagger UI codebase\n\n---\n\n## Table of Contents\n\n1. [Repository Overview](#repository-overview)\n2. [Project Architecture](#project-architecture)\n3. [Development Setup](#development-setup)\n4. [Build System](#build-system)\n5. [Testing Infrastructure](#testing-infrastructure)\n6. [Code Style & Conventions](#code-style--conventions)\n7. [Git Workflow](#git-workflow)\n8. [Plugin Architecture](#plugin-architecture)\n9. [Key Files & Directories](#key-files--directories)\n10. [Common Workflows](#common-workflows)\n11. [Important Guidelines](#important-guidelines)\n\n---\n\n## Repository Overview\n\n### What is Swagger UI?\n\nSwagger UI is a tool that allows developers to visualize and interact with API resources without having implementation logic in place. It's automatically generated from OpenAPI (formerly Swagger) Specification documents.\n\n### Multi-Package Monorepo Structure\n\nThis repository publishes **three different npm packages**:\n\n1. **swagger-ui** (main package)\n   - Traditional npm module for single-page applications\n   - Entry: `dist/swagger-ui.js`\n   - ES Module: `dist/swagger-ui-es-bundle-core.js`\n   - Includes dependency resolution via Webpack/Browserify\n\n2. **swagger-ui-dist** (distribution package)\n   - Dependency-free module for server-side projects\n   - Published separately via GitHub workflow\n   - Template location: `swagger-ui-dist-package/`\n\n3. **swagger-ui-react** (React component)\n   - React wrapper component\n   - Location: `flavors/swagger-ui-react/`\n   - Uses React hooks\n   - Released separately via GitHub workflow\n\n### OpenAPI Specification Compatibility\n\n- **Current Support:** OpenAPI 2.0, 3.0.x, 3.1.x\n- **Latest Version:** v5.31.0 (supports up to OpenAPI 3.1.2)\n\n### License\n\nApache 2.0 - See LICENSE and NOTICE files for details.\n\n---\n\n## Project Architecture\n\n### Technology Stack\n\n**Core Framework:**\n- React 18 (>=16.8.0 <20) - UI components\n- Redux 5.0.1 - State management\n- Redux Immutable 4.0.0 - Immutable state\n- Immutable.js 3.x - Immutable data structures\n- React Redux 9.2.0 - React-Redux bindings\n\n**API & Schema Processing:**\n- swagger-client 3.36.0 - OpenAPI client\n- js-yaml 4.1.1 - YAML parsing\n- remarkable 2.0.1 - Markdown rendering\n\n**Security:**\n- DOMPurify 3.2.6 - HTML sanitization (CRITICAL for XSS prevention)\n- serialize-error 8.1.0 - Error serialization\n\n**Build Tools:**\n- Webpack 5.97.1 - Module bundling\n- Babel 7.26.x - JavaScript transpilation\n- sass-embedded 1.86.0 - SCSS compilation\n- PostCSS - CSS processing\n\n**Testing:**\n- Jest 29.7.0 - Unit testing\n- Cypress 14.2.0 - E2E testing\n- Enzyme 3.11.0 - React component testing\n\n**Development:**\n- ESLint 8.57.0 - JavaScript linting\n- Prettier 3.5.3 - Code formatting\n- Stylelint 16.19.1 - CSS linting\n- Husky 9.1.7 - Git hooks\n- lint-staged 15.5.0 - Pre-commit linting\n\n### Plugin-Based Architecture\n\nSwagger UI uses a **sophisticated plugin system** powered by Redux. The core system (`src/core/system.js`) manages:\n\n- Plugin registration and lifecycle\n- Redux store creation and middleware\n- State plugin combination\n- Action/selector binding\n- Configuration management\n\n**26 Core Plugins** (in `src/core/plugins/`):\n- `auth` - Authentication handling\n- `configs` - Configuration management\n- `deep-linking` - URL-based navigation\n- `download-url` - Spec downloading\n- `err` - Error handling and transformation\n- `filter` - API filtering\n- `icons` - Icon components\n- `json-schema-2020-12` - JSON Schema 2020-12 support\n- `json-schema-2020-12-samples` - Sample generation\n- `json-schema-5` - JSON Schema Draft 5 support\n- `json-schema-5-samples` - Sample generation for Draft 5\n- `layout` - Layout system\n- `logs` - Logging\n- `oas3` - OpenAPI 3.0.x support\n- `oas31` - OpenAPI 3.1.x support\n- `oas32` - OpenAPI 3.2.x support\n- `on-complete` - Completion callbacks\n- `request-snippets` - Code snippet generation\n- `safe-render` - Safe component rendering\n- `spec` - Specification handling\n- `swagger-client` - API client integration\n- `syntax-highlighting` - Code highlighting\n- `util` - Utilities\n- `versions` - Version detection\n- `view` - View rendering\n- `view-legacy` - Legacy view support\n\n---\n\n## Development Setup\n\n### Prerequisites\n\n- **Node.js:** >=24.19.0 (Node 24.x recommended, as defined in `.nvmrc`)\n- **npm:** >=11.17.0\n- **Git:** Any version\n- **JDK 7+:** Required for Nightwatch.js integration tests\n\n### Installation Steps\n\n```bash\n# Clone the repository\ngit clone https://github.com/swagger-api/swagger-ui.git\ncd swagger-ui\n\n# Install dependencies\nnpm install\n\n# Initialize Husky (optional, for git hooks)\nnpx husky init\n\n# Start development server\nnpm run dev\n\n# Open http://localhost:3200/\n```\n\n### Development Server\n\nThe `npm run dev` command starts a hot-reloading Webpack dev server on **port 3200**.\n\n### Using Local API Definitions\n\nEdit `dev-helpers/dev-helper-initializer.js` to change the spec URL:\n\n```javascript\n// Replace\nurl: \"https://petstore.swagger.io/v2/swagger.json\",\n\n// With\nurl: \"./examples/your-local-api-definition.yaml\",\n```\n\n**Important:** Local files must be in the `dev-helpers/` directory or subdirectory. Use `dev-helpers/examples/` (already in `.gitignore`).\n\n---\n\n## Build System\n\n### Babel Environments\n\nThree Babel environments configured in `babel.config.js`:\n\n1. **development/production** - Browser builds with `modules: \"auto\"`\n2. **commonjs** - CommonJS modules with `modules: \"commonjs\"` for Node.js\n3. **esm** - ES modules with `modules: false` for modern bundlers\n\n### Babel Aliases\n\n```javascript\n{\n  root: \".\",\n  core: \"./src/core\"\n}\n```\n\n### Browserslist Environments\n\nDefined in `.browserslistrc`:\n\n- `[browser-production]` - Production browser targets\n- `[browser-development]` - Latest Chrome, Firefox, Safari\n- `[isomorphic-production]` - Browser + Node targets\n- `[node-production]` - Maintained Node versions\n- `[node-development]` - Node 24\n\n### Build Commands\n\n```bash\n# Full build (stylesheets + all bundles)\nnpm run build\n\n# Individual builds\nnpm run build:core              # Core bundle (browser)\nnpm run build:bundle            # Isomorphic bundle\nnpm run build:standalone        # Standalone preset\nnpm run build:es:bundle         # ES module bundle\nnpm run build:es:bundle:core    # ES module core\nnpm run build-stylesheets       # CSS only\n\n# Clean build artifacts\nnpm run clean\n```\n\n### Build Output (dist/)\n\n- `swagger-ui.js` - Core bundle (CommonJS)\n- `swagger-ui.css` - Compiled styles\n- `swagger-ui-bundle.js` - Isomorphic bundle\n- `swagger-ui-standalone-preset.js` - Standalone preset\n- `swagger-ui-es-bundle.js` - ES module bundle\n- `swagger-ui-es-bundle-core.js` - ES module core\n- `oauth2-redirect.html` - OAuth2 redirect page\n\n### Webpack Configurations\n\nLocated in `webpack/` directory:\n\n- `_config-builder.js` - Base configuration\n- `core.js` - Core build\n- `bundle.js` - Bundle build\n- `standalone.js` - Standalone build\n- `es-bundle.js` - ES bundle\n- `es-bundle-core.js` - ES core bundle\n- `stylesheets.js` - CSS build\n- `dev.js` - Development server\n- `dev-e2e.js` - E2E testing server\n\n---\n\n## Testing Infrastructure\n\n### Unit Tests (Jest)\n\n**Configuration:** `config/jest/jest.unit.config.js`\n\n**Environment:** jsdom (simulates browser environment)\n\n**Location:** `test/unit/`\n\n**Command:**\n```bash\nnpm run test:unit\n```\n\n**Key Features:**\n- 37 unit test files\n- Tests for core plugins, components, system\n- XSS security tests\n- Silent mode enabled by default (set to `false` for console output)\n- Module name mapper for SVG and standalone imports\n- Transform ignore patterns for node_modules exceptions\n\n**Setup Files:**\n- `test/unit/jest-shim.js` - Polyfills and shims\n- `test/unit/setup.js` - Test environment setup\n\n### E2E Tests (Cypress)\n\n**Configuration:** `cypress.config.js`\n\n**Location:** `test/e2e-cypress/`\n\n**Base URL:** http://localhost:3230/\n\n**Commands:**\n```bash\n# Run all E2E tests\nnpm run cy:ci\n\n# Interactive Cypress runner\nnpm run cy:dev\n\n# Headless run\nnpm run cy:run\n\n# Start servers and run tests\nnpm run cy:start     # Starts webpack + mock API\n```\n\n**Structure:**\n- `test/e2e-cypress/e2e/` - Test specs (99 test files)\n- `test/e2e-cypress/static/` - Test fixtures and documents\n- `test/e2e-cypress/support/` - Test helpers and commands\n\n**Test Categories:**\n- `a11y/**/*cy.js` - Accessibility tests\n- `security/**/*cy.js` - Security tests\n- `bugs/**/*cy.js` - Bug regression tests\n- `features/**/*cy.js` - Feature tests\n\n**Mock API Server:**\n```bash\nnpm run cy:mock-api  # JSON Server on port 3204\n```\n\n### Artifact Tests\n\n**Configuration:** `config/jest/jest.artifact.config.js`\n\n**Purpose:** Verify build artifacts export correctly\n\n**Command:**\n```bash\nnpm run test:artifact\n```\n\n### Complete Test Suite\n\n```bash\nnpm test  # Runs: lint-errors + test:unit + cy:ci\n```\n\n### CI/CD Testing\n\n**GitHub Actions Workflow:** `.github/workflows/nodejs.yml`\n\n**Two Jobs:**\n1. **build** - Lint, unit tests, build, artifact tests\n2. **e2e-tests** - Cypress tests (matrix strategy with 3 containers)\n\n**Branches:** `main`, `next`\n\n---\n\n## Code Style & Conventions\n\n### ESLint Configuration\n\n**File:** `.eslintrc.js`\n\n**Parser:** `@babel/eslint-parser`\n\n**Key Rules:**\n- `semi: [2, \"never\"]` - **No semicolons**\n- `quotes: [2, \"double\"]` - **Double quotes** (allow template literals)\n- `no-unused-vars: 2` - Error on unused variables\n- `camelcase: [\"error\"]` - Enforce camelCase (with exceptions for UNSAFE_, request generators, etc.)\n- `no-console: [2, {allow: [\"warn\", \"error\"]}]` - Only `console.warn` and `console.error` allowed\n- `react/jsx-no-bind: 1` - Warning for JSX bind\n- `react/jsx-filename-extension: 2` - JSX only in `.jsx` files\n- `import/no-extraneous-dependencies: 2` - Error on extraneous dependencies\n\n**Extends:**\n- `eslint:recommended`\n- `plugin:react/recommended`\n- `plugin:prettier/recommended`\n\n### Prettier Configuration\n\n**File:** `.prettierrc.yaml`\n\n**Settings:**\n```yaml\nsemi: false              # No semicolons\ntrailingComma: es5       # ES5 trailing commas\nendOfLine: lf            # Unix line endings\nrequirePragma: true      # Require @prettier pragma\ninsertPragma: true       # Insert @prettier pragma\n```\n\n**IMPORTANT:** Prettier requires `@prettier` pragma comment at the top of files:\n```javascript\n/**\n * @prettier\n */\n```\n\n### Stylelint Configuration\n\n**File:** `stylelint.config.js`\n\n**Custom Syntax:** `postcss-scss`\n\n**Rules:**\n- Uses `stylelint-prettier` plugin\n- Prettier integration without pragma requirement\n\n### Pre-commit Hooks\n\n**Husky:** `.husky/pre-commit` runs `npx lint-staged`\n\n**Lint-staged Configuration:** `.lintstagedrc`\n```json\n{\n  \"*.{js,jsx}\": [\"eslint --max-warnings 0\"],\n  \"*.scss\": [\"stylelint '**/*.scss'\"]\n}\n```\n\n**Critical:** All staged JS/JSX/SCSS files are linted with **zero warnings tolerance**.\n\n### File Structure Conventions\n\n**Components:**\n- Location: `src/core/components/`\n- Extension: `.jsx` (React components)\n- Format: PascalCase for component names\n\n**Styles:**\n- Location: `src/style/`\n- Extension: `.scss`\n- Format: SCSS with PostCSS processing\n- Dark mode: `_dark-mode.scss`\n\n**Tests:**\n- Unit: `test/unit/` (mirrors source structure)\n- E2E: `test/e2e-cypress/e2e/`\n- Naming: `*.test.js`, `*.spec.js`, `*.cy.js` (Cypress)\n\n---\n\n## Git Workflow\n\n### Branch Strategy\n\n**Main Branches:**\n- `main` - Production releases\n- `next` - Next version development\n\n**Feature Branches:**\n- Should branch from `main` or `next`\n- Use descriptive names\n\n### Commit Conventions\n\n**Format:** Conventional Commits (enforced by commitlint)\n\n**Structure:**\n```\n<type>(<scope>): <subject>\n\n<body>\n\n<footer>\n```\n\n**Types:**\n- `feat` - New feature\n- `fix` - Bug fix\n- `docs` - Documentation changes\n- `style` - Code style changes (formatting)\n- `refactor` - Code refactoring\n- `test` - Test additions/changes\n- `chore` - Build/tooling changes\n- `perf` - Performance improvements\n\n**Example:**\n```\nfeat(oas3): add support for OpenAPI 3.1.1 callbacks\n\nImplement callback rendering for OAS 3.1.1 specifications\nwith proper schema resolution and example generation.\n\nFixes #12345\n```\n\n### Pull Request Process\n\n**Template:** `.github/pull_request_template.md`\n\n**Required Sections:**\n1. **Description** - Detailed change description\n2. **Motivation and Context** - Why the change is needed\n3. **How Has This Been Tested?** - Manual testing details\n4. **Screenshots** - If UI changes\n\n**Checklist:**\n- [ ] Code type (no code/dependencies/bug fix/improvement/feature)\n- [ ] Breaking changes identification\n- [ ] Documentation updates\n- [ ] Test coverage\n- [ ] All tests passing\n\n**CI Checks:**\n- ESLint (error-only mode)\n- Unit tests (Jest)\n- Build verification\n- Artifact tests\n- E2E tests (Cypress)\n\n### Release Process\n\n**Tool:** release-it with conventional-changelog\n\n**Command:**\n```bash\nnpm run automated-release\n```\n\n**Workflows:**\n- `.github/workflows/release-swagger-ui.yml`\n- `.github/workflows/release-swagger-ui-dist.yml`\n- `.github/workflows/release-swagger-ui-react.yml`\n- `.github/workflows/release-swagger-ui-packagist.yml`\n\n---\n\n## Plugin Architecture\n\n### Core System (`src/core/system.js`)\n\nThe plugin system is the heart of Swagger UI. It uses Redux for state management with a custom plugin registration system.\n\n### Plugin Structure\n\nEach plugin is a JavaScript object/function that returns:\n\n```javascript\n{\n  statePlugins: {\n    [pluginName]: {\n      actions: {},      // Redux actions\n      reducers: {},     // Redux reducers\n      selectors: {},    // Reselect selectors\n      wrapActions: {},  // Action middleware\n      wrapSelectors: {} // Selector middleware\n    }\n  },\n  components: {},       // React components\n  fn: {},              // Utility functions\n  rootInjects: {},     // Root-level injections\n  afterLoad: Function  // Lifecycle hook\n}\n```\n\n### Key Plugin Locations\n\n**Core Plugins:** `src/core/plugins/`\n\nEach plugin has:\n- `index.js` - Main export\n- `actions.js` - Redux actions\n- `reducers.js` - Redux reducers\n- `selectors.js` - State selectors\n- `wrap-actions.js` - Action middleware\n- `wrap-selectors.js` - Selector middleware\n- Component files (`.jsx`)\n\n### Creating a Plugin\n\nSee documentation: `docs/customization/plugin-api.md`\n\n### Cross-Plugin Import Guidelines\n\n**IMPORTANT:** Avoid cross-plugin imports to maintain plugin independence and modularity.\n\n**Pattern to Follow:**\n- Each plugin should be self-contained with its own components, utilities, and functions\n- When OAS version plugins (oas3, oas31, oas32) need similar functionality, create self-contained copies within each plugin\n- Wrap components should import from their own plugin's components, not from other plugins\n\n**Example Structure:**\n```\nsrc/core/plugins/oas32/\n├── json-schema-2020-12-extensions/\n│   ├── components/              # Self-contained components\n│   │   └── keywords/\n│   │       ├── Description.jsx\n│   │       └── Properties.jsx\n│   ├── wrap-components/         # Wrappers for components\n│   │   └── keywords/\n│   │       ├── Description.jsx  # Imports from ../../components/\n│   │       └── Properties.jsx   # Not from ../../../../oas31/\n│   └── fn.js                    # Self-contained utilities\n```\n\n**Why This Matters:**\n- Prevents tight coupling between plugins\n- Makes plugins easier to test in isolation\n- Allows independent versioning and updates\n- Reduces risk of breaking changes across plugins\n- Improves code maintainability\n\n**Exceptions:**\n- Shared core utilities in `src/core/utils/` are acceptable\n- System-level functions in `src/core/system.js` are acceptable\n- Base components in `src/core/components/` are acceptable\n\n### Preset System\n\n**Base Preset:** `src/core/presets/base.js`\n\n**Standalone Preset:** `src/standalone/presets/standalone.js`\n\nPresets are collections of plugins bundled together for specific use cases.\n\n---\n\n## Key Files & Directories\n\n### Critical Source Files\n\n```\nsrc/\n├── core/\n│   ├── system.js                 # Plugin system & Redux store\n│   ├── components/               # 59 React components\n│   ├── plugins/                  # 26 core plugins\n│   ├── presets/                  # Preset configurations\n│   ├── utils/                    # Utility functions\n│   └── config/                   # Configuration system\n├── standalone/\n│   ├── plugins/                  # TopBar, StandaloneLayout\n│   └── presets/                  # Standalone preset\n├── style/                        # SCSS stylesheets\n│   ├── _dark-mode.scss          # Dark mode styles\n│   └── main.scss                # Main stylesheet entry\n└── index.js                      # Main package entry\n```\n\n### Configuration Files\n\n```\n.\n├── package.json                  # Dependencies & scripts\n├── babel.config.js              # Babel configuration\n├── .eslintrc.js                 # ESLint rules\n├── .prettierrc.yaml             # Prettier settings\n├── stylelint.config.js          # Stylelint rules\n├── .browserslistrc              # Browser targets\n├── .nvmrc                       # Node version (24.x)\n├── .lintstagedrc                # Pre-commit linting\n└── cypress.config.js            # Cypress E2E config\n```\n\n### Build & Tooling\n\n```\nwebpack/\n├── _config-builder.js           # Base Webpack config\n├── core.js                      # Core build\n├── bundle.js                    # Bundle build\n├── standalone.js                # Standalone build\n├── es-bundle.js                 # ES bundle build\n├── es-bundle-core.js           # ES core bundle\n├── stylesheets.js              # CSS compilation\n├── dev.js                       # Dev server\n└── dev-e2e.js                  # E2E dev server\n\nconfig/jest/\n├── jest.unit.config.js          # Unit test config\n└── jest.artifact.config.js      # Artifact test config\n```\n\n### Documentation\n\n```\ndocs/\n├── usage/\n│   ├── installation.md\n│   ├── configuration.md\n│   ├── cors.md\n│   ├── oauth2.md\n│   ├── deep-linking.md\n│   ├── version-detection.md\n│   └── limitations.md\n├── customization/\n│   ├── overview.md\n│   ├── plugin-api.md\n│   └── custom-layout.md\n└── development/\n    ├── setting-up.md\n    └── scripts.md\n```\n\n### Testing\n\n```\ntest/\n├── unit/                        # Jest unit tests (37 files)\n│   ├── setup.js                # Test environment setup\n│   └── jest-shim.js           # Polyfills\n├── e2e-cypress/                 # Cypress E2E tests (99 files)\n│   ├── e2e/                    # Test specs\n│   ├── static/                 # Fixtures\n│   └── support/                # Helpers\n└── e2e-selenium/               # Legacy Selenium tests\n```\n\n### Distribution\n\n```\nflavors/\n└── swagger-ui-react/            # React component wrapper\n\nswagger-ui-dist-package/         # Template for dist package\n\ndist/                            # Build output (generated)\n├── swagger-ui.js\n├── swagger-ui.css\n├── swagger-ui-bundle.js\n├── swagger-ui-standalone-preset.js\n├── swagger-ui-es-bundle.js\n├── swagger-ui-es-bundle-core.js\n└── oauth2-redirect.html\n```\n\n---\n\n## Common Workflows\n\n### Making Code Changes\n\n1. **Read before modifying:**\n   ```bash\n   # ALWAYS read files before editing them\n   # Understand the existing code structure\n   ```\n\n2. **Follow the style guide:**\n   - Use double quotes\n   - No semicolons\n   - Add `@prettier` pragma to new files\n   - Use `.jsx` extension for React components\n\n3. **Run linters:**\n   ```bash\n   npm run lint          # Check for errors and warnings\n   npm run lint-fix      # Auto-fix JavaScript issues\n   npm run lint-styles   # Check SCSS\n   npm run lint-styles-fix  # Auto-fix SCSS\n   ```\n\n4. **Test your changes:**\n   ```bash\n   npm run test:unit     # Run unit tests\n   npm run cy:dev        # Interactive E2E testing\n   npm run build         # Verify build works\n   npm run test:artifact # Verify artifacts\n   ```\n\n### Adding a New Component\n\n1. Create component in `src/core/components/` or appropriate plugin directory\n2. Use `.jsx` extension\n3. Add `@prettier` pragma\n4. Follow React best practices (functional components, hooks)\n5. Add PropTypes validation\n6. Create corresponding test in `test/unit/`\n7. Export from plugin's `index.js` if needed\n\n### Adding a New Plugin\n\n1. Create directory in `src/core/plugins/[plugin-name]/`\n2. Create `index.js` with plugin structure\n3. Add actions, reducers, selectors as needed\n4. Register plugin in preset (e.g., `src/core/presets/base.js`)\n5. Add tests in `test/unit/core/plugins/[plugin-name]/`\n6. Document the plugin\n\n### Fixing a Bug\n\n1. **Reproduce the bug:**\n   - Add a failing test in `test/unit/` or `test/e2e-cypress/`\n   - Document reproduction steps\n\n2. **Fix the issue:**\n   - Make minimal changes to fix the bug\n   - Avoid refactoring unless necessary\n   - Ensure the test now passes\n\n3. **Verify:**\n   ```bash\n   npm run test:unit\n   npm run build\n   npm run test:artifact\n   ```\n\n4. **Create PR:**\n   - Reference the issue number\n   - Include before/after behavior\n   - Add screenshots if UI-related\n\n### Adding a Feature\n\n1. **Plan the feature:**\n   - Review existing architecture\n   - Identify affected plugins/components\n   - Consider OpenAPI spec compatibility\n\n2. **Implement:**\n   - Follow plugin architecture patterns\n   - Add configuration options if needed\n   - Update presets if necessary\n\n3. **Test thoroughly:**\n   - Unit tests for logic\n   - Component tests for UI\n   - E2E tests for integration\n   - Test with various OpenAPI specs\n\n4. **Document:**\n   - Update `docs/` if user-facing\n   - Add JSDoc comments for APIs\n   - Update README if needed\n\n### Security Considerations\n\n1. **XSS Prevention:**\n   - ALWAYS use DOMPurify for user-provided HTML\n   - Sanitize all external input\n   - Review `test/unit/xss/` for examples\n   - Never use `dangerouslySetInnerHTML` without sanitization\n\n2. **Input Validation:**\n   - Validate API responses\n   - Handle malformed OpenAPI specs gracefully\n   - Check for prototype pollution\n\n3. **Dependency Security:**\n   ```bash\n   npm run security-audit     # Run security audit\n   ```\n\n### Working with OpenAPI Specs\n\n**Testing Different Versions:**\n- OAS 2.0: Use `src/core/plugins/swagger-client/`\n- OAS 3.0.x: Use `src/core/plugins/oas3/`\n- OAS 3.1.x: Use `src/core/plugins/oas31/`\n- OAS 3.2.x: Use `src/core/plugins/oas32/`\n\n**Adding Test Specs:**\n- Add to `test/e2e-cypress/static/documents/`\n- Reference in E2E tests\n\n---\n\n## Important Guidelines\n\n### DO's ✅\n\n1. **Always read files before modifying them**\n2. **Follow the no-semicolon convention**\n3. **Use double quotes for strings**\n4. **Add `@prettier` pragma to all new files**\n5. **Use `.jsx` extension for React components**\n6. **Write tests for new features and bug fixes**\n7. **Run linters before committing** (automatic via husky)\n8. **Use DOMPurify for HTML sanitization**\n9. **Follow conventional commit format**\n10. **Update documentation for user-facing changes**\n11. **Test with multiple OpenAPI spec versions**\n12. **Check browser compatibility** (see `.browserslistrc`)\n13. **Use the plugin architecture** - don't modify core unnecessarily\n14. **Preserve backward compatibility** unless explicitly breaking\n15. **Run full test suite before submitting PR**\n16. **Keep plugins self-contained** - avoid cross-plugin imports (see [Cross-Plugin Import Guidelines](#cross-plugin-import-guidelines))\n\n### DON'Ts ❌\n\n1. **Don't use semicolons** - project convention\n2. **Don't use single quotes** - use double quotes\n3. **Don't skip the @prettier pragma** - required for formatting\n4. **Don't put React in `.js` files** - use `.jsx`\n5. **Don't commit files in `dev-helpers/`** (except core files)\n6. **Don't commit build artifacts** (`dist/` is gitignored)\n7. **Don't skip tests** - they run in CI\n8. **Don't bypass ESLint** - pre-commit hook enforces\n9. **Don't use `console.log`** - only `console.warn` and `console.error`\n10. **Don't render unsanitized HTML** - XSS vulnerability\n11. **Don't modify `package-lock.json` manually**\n12. **Don't push directly to `main` or `next`**\n13. **Don't ignore Cypress test failures**\n14. **Don't add dependencies without justification**\n15. **Don't break the build** - verify with `npm run build`\n16. **Don't import from other plugins** - create self-contained copies instead (e.g., don't import from `oas31` in `oas32`)\n\n### When Working with AI Assistants\n\n**Before Making Changes:**\n1. Read the affected files completely\n2. Understand the plugin architecture\n3. Check for existing tests\n4. Review related documentation\n\n**During Development:**\n1. Make minimal, focused changes\n2. Follow existing patterns in the codebase\n3. Add tests alongside code changes\n4. Run linters frequently\n\n**After Changes:**\n1. Verify all tests pass\n2. Check build completes successfully\n3. Test artifact exports\n4. Review for security issues\n5. Update relevant documentation\n\n**Communication:**\n- Be explicit about file locations\n- Use line number references (e.g., `src/core/system.js:96`)\n- Provide context for changes\n- Mention any breaking changes clearly\n\n### Performance Considerations\n\n1. **Immutable.js:**\n   - Use Immutable data structures for state\n   - Use `.toJS()` sparingly (expensive)\n   - Prefer Immutable operations\n\n2. **React:**\n   - Use React.memo for pure components\n   - Implement shouldComponentUpdate for class components\n   - Avoid inline function definitions in render\n\n3. **Redux:**\n   - Use reselect for memoized selectors\n   - Keep reducers pure and fast\n   - Avoid large state trees\n\n4. **Bundle Size:**\n   - Check bundle size with `npm run deps-size`\n   - Review dependency licenses with `npm run deps-license`\n   - Consider code splitting for large features\n\n### Debugging Tips\n\n**Development Server:**\n```bash\nnpm run dev\n# Open http://localhost:3200/\n# Hot reload enabled\n# Unminified stack traces\n```\n\n**Redux DevTools:**\n- Extension supported\n- State inspection available\n- Time-travel debugging\n\n**Cypress Interactive Mode:**\n```bash\nnpm run cy:dev\n# Visual test runner\n# Step-through debugging\n# Network inspection\n```\n\n**Jest Watch Mode:**\n```bash\nnpm run test:unit -- --watch\n# Re-run on file changes\n# Filter by file name or test name\n```\n\n**Source Maps:**\n- Generated for all builds\n- Enable in browser DevTools\n- Original source debugging\n\n---\n\n## Quick Reference\n\n### Essential Commands\n\n```bash\n# Development\nnpm run dev              # Start dev server (port 3200)\nnpm start                # Static file server (port 3002)\n\n# Building\nnpm run build            # Full production build\nnpm run clean            # Remove dist/\n\n# Testing\nnpm test                 # Full test suite (lint + unit + E2E)\nnpm run test:unit        # Jest unit tests\nnpm run cy:dev           # Cypress interactive\nnpm run cy:ci            # Cypress CI mode\nnpm run test:artifact    # Artifact verification\n\n# Linting\nnpm run lint             # ESLint (errors + warnings)\nnpm run lint-errors      # ESLint (errors only)\nnpm run lint-fix         # Auto-fix ESLint issues\nnpm run lint-styles      # Stylelint\nnpm run lint-styles-fix  # Auto-fix Stylelint issues\n\n# Security\nnpm run security-audit   # Run npm audit\n\n# Dependencies\nnpm run deps-check       # Size and license report\n```\n\n### File Paths\n\n```\nCore System:           src/core/system.js\nMain Entry:            src/index.js\nReact Entry:           flavors/swagger-ui-react/index.jsx\nComponents:            src/core/components/\nPlugins:               src/core/plugins/\nStyles:                src/style/\nTests (Unit):          test/unit/\nTests (E2E):           test/e2e-cypress/e2e/\nBuild Output:          dist/\n```\n\n### Port Reference\n\n- **3200** - Development server (webpack-dev-server)\n- **3002** - Static file server (local-web-server)\n- **3204** - Mock API server (json-server)\n- **3230** - E2E test server (webpack-dev-server)\n\n---\n\n## Additional Resources\n\n### Documentation\n\n- **Setup Guide:** `docs/development/setting-up.md`\n- **Scripts Reference:** `docs/development/scripts.md`\n- **Plugin API:** `docs/customization/plugin-api.md`\n- **Configuration:** `docs/usage/configuration.md`\n- **OAuth2 Setup:** `docs/usage/oauth2.md`\n\n### External Links\n\n- **Homepage:** https://swagger.io/tools/swagger-ui/\n- **Repository:** https://github.com/swagger-api/swagger-ui\n- **npm (main):** https://www.npmjs.com/package/swagger-ui\n- **npm (dist):** https://www.npmjs.com/package/swagger-ui-dist\n- **npm (react):** https://www.npmjs.com/package/swagger-ui-react\n- **OpenAPI Spec:** https://spec.openapis.org/\n\n### Community\n\n- **Issues:** https://github.com/swagger-api/swagger-ui/issues\n- **Good First Issues:** https://github.com/swagger-api/swagger-ui/issues?q=is%3Aissue+is%3Aopen+label%3A%22Good+first+issue%22\n- **Security:** security@swagger.io\n- **Contributing:** https://github.com/swagger-api/.github/blob/HEAD/CONTRIBUTING.md\n\n---\n\n**Note:** This document should be updated whenever major architectural changes, new conventions, or significant workflows are introduced to the codebase.\n","category":"root","tokens":7201}]}