Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

```
packages/
core/ # vitepress-openapi-docs Vue components + VitePress plugin
create/ # create-vitepress-openapi-docs scaffolder CLI
core/ # vitepress-openapi-docs: Vue components + VitePress plugin
create/ # create-vitepress-openapi-docs: scaffolder CLI
docs/ # VitePress dogfood site
e2e/ # Playwright tests (a11y + happy-path)
scripts/ # Release helpers
Expand Down Expand Up @@ -64,22 +64,22 @@ npm run test:a11y

## Commit conventions

- **Conventional commits** `feat:`, `fix:`, `chore:`, `docs:`, `test:`, `ci:`, `refactor:`, `perf:`
- **Conventional commits**: `feat:`, `fix:`, `chore:`, `docs:`, `test:`, `ci:`, `refactor:`, `perf:`
- Keep commits focused: one concern per commit
- No `Co-Authored-By` trailers

## Release flow

1. `node scripts/sync-versions.js <version>` sync all packages
2. Update `CHANGELOG.md` rename the `Unreleased` heading to `## <version>`
1. `node scripts/sync-versions.js <version>` to sync all packages
2. Update `CHANGELOG.md`: rename the `Unreleased` heading to `## <version>`
3. Commit: `chore(release): v<version>`
4. Tag: `git tag v<version>`
5. Push: `git push origin main --tags`
6. CI publishes both packages with provenance

## Code style

- TypeScript strict no `any`
- TypeScript strict, no `any`
- Single quotes, no semicolons (Prettier)
- Vue SFC order: `<template>`, `<script setup lang="ts">`
- CSS classes: BEM with `vod-` prefix
Expand Down
30 changes: 12 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ A Vue-native VitePress plugin that composes OpenAPI endpoints inline with your m

## Why this exists

Scalar, RapiDoc, Stoplight Elements — they render API docs inside web components or iframes. They work, but you can't put a paragraph between two endpoints. You can't style them with your VitePress CSS variables. They're embedded apps, not documentation.
Swagger UI, Scalar, RapiDoc, Stoplight Elements all render API docs inside a web component or iframe. They work, but the output is a standalone widget: you can't put a paragraph between two endpoints, and you can't style it with your VitePress CSS variables.

This plugin is different:
This plugin renders endpoints as Vue components in light DOM, so they compose inline with your markdown prose:

```md
# Authentication
Expand All @@ -24,7 +24,7 @@ Then use the token on subsequent calls:
<OpenApiEndpoint id="users.list" auth="bearer" />
```

Endpoints render natively in VitePress — light DOM, Vue components, same theme.
On top of that you get a full docs site, not just a widget: auto-generated pages, Cmd+K search, schema cross-links, a git-driven changelog, and multi-API support with independent sidebars. SDK snippets refresh as you change the auth token, and auth persists across pages.

## Install

Expand All @@ -39,26 +39,20 @@ Or add to an existing VitePress site:
npm i vitepress-openapi-docs vue-api-playground
```

Two files to wire up [full guide](https://rodindev.github.io/vitepress-openapi-docs/guide/existing-site).
Two files to wire up. See the [full guide](https://rodindev.github.io/vitepress-openapi-docs/guide/existing-site).

## What's included

- **`<OpenApiEndpoint>`** one operation inline in any markdown page: params, request/response types, SDK snippets, try-it panel, auth
- **`<OpenApiSpec>`** full spec grouped by tag
- **`<OpenApiSchema>`** property table with clickable `$ref` links
- **`<OpenApiChangelog>`** git-history-driven spec diff (added/removed/renamed operations per commit)
- **Cmd+K jumper** fuzzy search across all operations and schemas
- **Multi-API** N specs, one config, independent sidebar per spec, one jumper
- **Auth** bearer / basic / apikey / OAuth2 passthrough, stored in sessionStorage
- **Syntax highlighting** - SDK snippets and response JSON share a VS Code Default palette via vue-api-playground tokens; no Prism or Shiki dependency
- **`<OpenApiEndpoint>`**: one operation inline in any markdown page: params, request/response types, SDK snippets, try-it panel, auth
- **`<OpenApiSpec>`**: full spec grouped by tag
- **`<OpenApiSchema>`**: property table with clickable `$ref` links
- **`<OpenApiChangelog>`**: git-history-driven spec diff (added/removed/renamed operations per commit)
- **Cmd+K jumper**: fuzzy search across all operations and schemas
- **Multi-API**: N specs, one config, independent sidebar per spec, one jumper
- **Auth**: bearer / basic / apikey / OAuth2 passthrough, stored in sessionStorage
- **Syntax highlighting**: SDK snippets and response JSON share a VS Code Default palette via vue-api-playground tokens; no Prism or Shiki dependency
- **< 14 KB** client bundle (peer deps excluded), enforced in CI

## Why this over Swagger UI or Scalar

Swagger UI is heavy and looks dated. Scalar is modern but renders inside a web component — a black box you can't mix with your own content. Both give you a standalone widget, not documentation.

This gives you a full docs site: auto-generated pages, Cmd+K search, schema cross-links, git-driven changelog, multi-API with independent sidebars. SDK snippets that update with your auth token. Auth that persists across pages. And one thing no other tool does: endpoints that compose inline with your markdown prose.

## Requirements

- Node.js >= 20
Expand Down
2 changes: 1 addition & 1 deletion docs/api/mock/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ aside: false

The live reference demo for `vitepress-openapi-docs`, backed by a mock server at [api.rodin.dev/mock](https://api.rodin.dev/mock/). OpenAPI 3.1, 107 operations across 15 tags, 34 webhooks, bearer auth, callbacks, `oneOf`, rich examples: everything the plugin renders, rendered here.

Pick any operation from the sidebar and hit **Try-It** the request goes to the real origin, CORS is open, you get real JSON back. The spec is fetched at build time so this page mirrors the live contract.
Pick any operation from the sidebar and hit **Try-It**: the request goes to the real origin, CORS is open, you get real JSON back. The spec is fetched at build time so this page mirrors the live contract.

<OpenApiSpec name="mock" :show-header="false" />
6 changes: 3 additions & 3 deletions docs/api/petstore/index.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
title: Petstore API
description: The classic Swagger Petstore rendered by vitepress-openapi-docs 19 operations, three tags, full interactivity.
description: The classic Swagger Petstore rendered by vitepress-openapi-docs. 19 operations, three tags, full interactivity.
aside: false
---

# Petstore API

The canonical [Swagger Petstore](https://petstore3.swagger.io/) spec rendered as a second API alongside the [Mock API](/api/mock/). Demonstrates multi-API support each spec gets its own sidebar, search index, and URL prefix.
The canonical [Swagger Petstore](https://petstore3.swagger.io/) spec rendered as a second API alongside the [Mock API](/api/mock/). Demonstrates multi-API support: each spec gets its own sidebar, search index, and URL prefix.

Pick any operation from the sidebar and hit **Try-It** requests go to `petstore3.swagger.io`, CORS is open.
Pick any operation from the sidebar and hit **Try-It**: requests go to `petstore3.swagger.io`, CORS is open.

<OpenApiSpec name="petstore" :show-header="false" />
20 changes: 10 additions & 10 deletions docs/guide/authentication.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: How authentication works in vitepress-openapi-docs bearer, basic, API key, and OAuth2.
description: How authentication works in vitepress-openapi-docs with bearer, basic, API key, and OAuth2.
---

# Authentication
Expand All @@ -20,10 +20,10 @@ description: How authentication works in vitepress-openapi-docs — bearer, basi
1. The parser reads `components.securitySchemes` from your spec
2. Each operation's `security` array references a scheme by name
3. `<OpenApiEndpoint>` resolves the scheme type and renders `<AuthControls>`
4. The user enters a credential stored in `sessionStorage` under `vod:auth:{specName}`
4. The user enters a credential, stored in `sessionStorage` under `vod:auth:{specName}`
5. The credential auto-injects into:
- **SDK snippets** (curl, fetch, Python) visible and copy-pasteable
- **Try-It panel** via the `before-send` hook
- **SDK snippets** (curl, fetch, Python): visible and copy-pasteable
- **Try-It panel**: via the `before-send` hook

## Session storage

Expand All @@ -33,7 +33,7 @@ Credentials persist across SPA navigation within the same tab. They clear when:
- The browser tab is closed
- `sessionStorage` is cleared

Each spec has its own credential store setting auth on one API doesn't affect another.
Each spec has its own credential store; setting auth on one API doesn't affect another.

## Override per endpoint

Expand Down Expand Up @@ -82,12 +82,12 @@ The scheme's `in` field decides where the key goes:

For `oauth2` schemes, the plugin renders:

- **Authorization URL** clickable link
- **Token URL** shown for reference
- **Scopes** collapsible list with descriptions
- **Token paste input** paste the token obtained from the OAuth2 flow
- **Authorization URL**: clickable link
- **Token URL**: shown for reference
- **Scopes**: collapsible list with descriptions
- **Token paste input**: paste the token obtained from the OAuth2 flow

The pasted token is injected as a `Bearer` token in snippets and Try-It. This is a passthrough the plugin does not perform the OAuth2 redirect flow itself.
The pasted token is injected as a `Bearer` token in snippets and Try-It. This is a passthrough; the plugin does not perform the OAuth2 redirect flow itself.

```yaml
components:
Expand Down
8 changes: 4 additions & 4 deletions docs/guide/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ How `vitepress-openapi-docs` differs from other OpenAPI documentation tools.

## vs. vitepress-openapi

`vitepress-openapi` is the closest peer also Vue-native, also a VitePress plugin. The data model is similar; the composition story and scope are what differ.
`vitepress-openapi` is the closest peer: also Vue-native, also a VitePress plugin. The data model is similar; the composition story and scope are what differ.

### Config

Expand Down Expand Up @@ -47,8 +47,8 @@ export default defineConfig({
| `<OASpec />` | `<OpenApiSpec name="..." />` |
| (per-spec sidebar helper) | auto-generated via `openApiDocs()` |
| (schemas shown inline) | `<OpenApiSchema name="..." spec-name="..." />` + auto-generated pages |
| | `<OpenApiChangelog name="..." />` |
| | Cmd+K search via `<OperationJumper />` |
| (not included) | `<OpenApiChangelog name="..." />` |
| (not included) | Cmd+K search via `<OperationJumper />` |

### What's different

Expand Down Expand Up @@ -76,7 +76,7 @@ Scalar gives you a self-contained widget that works anywhere. `vitepress-openapi
If you're moving from either tool:

1. Install: `npm i vitepress-openapi-docs vue-api-playground`
2. Set up config and theme see [existing site guide](/guide/existing-site)
2. Set up config and theme; see [existing site guide](/guide/existing-site)
3. Replace component tags: `<OAOperation>` / `<ApiReference>` → `<OpenApiEndpoint>` / `<OpenApiSpec>`
4. Add `docs/_openapi/` to `.gitignore`
5. Run `npm run dev`
Expand Down
16 changes: 8 additions & 8 deletions docs/guide/composing-endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Embed interactive API endpoints inline with your markdown prose.

# Composing endpoints

The plugin registers components globally use them directly in any markdown file.
The plugin registers components globally; use them directly in any markdown file.

## Inline endpoints

Expand All @@ -22,7 +22,7 @@ Use the token on subsequent calls:
<OpenApiEndpoint id="api.users.list" />
```

The endpoint renders natively in the page light DOM, Vue components, VitePress routing.
The endpoint renders natively in the page: light DOM, Vue components, VitePress routing.

## The `id` format

Expand Down Expand Up @@ -79,13 +79,13 @@ Render a component schema with property table, required badges, and clickable `$

## Changelog

Show a git-history-driven spec diff added, removed, and renamed operations per commit:
Show a git-history-driven spec diff of added, removed, and renamed operations per commit:

```md
<OpenApiChangelog name="public" />
```

The changelog needs at least two commits touching the spec file. In CI, set `fetch-depth: 0` shallow clones have no history. Remote URL specs don't support changelog.
The changelog needs at least two commits touching the spec file. In CI, set `fetch-depth: 0` (shallow clones have no history). Remote URL specs don't support changelog.

## Webhooks

Expand Down Expand Up @@ -122,8 +122,8 @@ See [Components reference](/reference/components#searchtrigger) for props.

For each spec, the plugin generates:

- `/{prefix}/{operationId}` one page per operation
- `/schemas/{specName}/{typeName}` one page per named component schema
- `/changelog/{specName}` spec change history
- `/{prefix}/{operationId}` for one page per operation
- `/schemas/{specName}/{typeName}` for one page per named component schema
- `/changelog/{specName}` for spec change history

Hand-written landing pages (`/{prefix}/index.md`) coexist the generator only writes to `docs/_openapi/`.
Hand-written landing pages (`/{prefix}/index.md`) coexist; the generator only writes to `docs/_openapi/`.
2 changes: 1 addition & 1 deletion docs/guide/existing-site.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ title: API Reference
<OpenApiSpec name="api" />
```

`<OpenApiSpec>` renders every operation from the spec in a single scrollable page a good default for the landing. You can also hand-write prose around individual `<OpenApiEndpoint>` embeds instead; see [Composing endpoints](/guide/composing-endpoints).
`<OpenApiSpec>` renders every operation from the spec in a single scrollable page, a good default for the landing. You can also hand-write prose around individual `<OpenApiEndpoint>` embeds instead; see [Composing endpoints](/guide/composing-endpoints).

::: tip
The scaffolder (`npm create vitepress-openapi-docs@latest`) creates this file automatically. This step only applies when integrating into an existing site.
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/multiple-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Always prefix the `operationId` with the spec name:

## Landing pages

The plugin doesn't generate landing pages write them yourself:
The plugin doesn't generate landing pages; write them yourself:

```md
<!-- docs/api/public/index.md -->
Expand Down
12 changes: 6 additions & 6 deletions docs/guide/theming.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Customize the look of vitepress-openapi-docs with CSS variables.

# Theming

`vitepress-openapi-docs` themes through a three-layer CSS variable cascade. Override at any level lower layers stay as fallbacks.
`vitepress-openapi-docs` themes through a three-layer CSS variable cascade. Override at any level; lower layers stay as fallbacks.

## The cascade

Expand All @@ -16,9 +16,9 @@ description: Customize the look of vitepress-openapi-docs with CSS variables.

Each layer falls back to the next. Override whichever layer you want; everything below stays as a default.

- **`--vod-*`** the public surface. Override these to restyle the plugin's UI.
- **`--vap-*`** shipped by `vue-api-playground`. Inherited so both packages stay in sync.
- **`--vp-c-*`** VitePress's standard tokens. Most sites already theme through these.
- **`--vod-*`** - the public surface. Override these to restyle the plugin's UI.
- **`--vap-*`** - shipped by `vue-api-playground`. Inherited so both packages stay in sync.
- **`--vp-c-*`** - VitePress's standard tokens. Most sites already theme through these.
- The hex fallback is only reached outside a VitePress host.

Not every token chains. The method badge `-bg` / `-text` tokens (`--vod-method-get-bg`, `--vod-method-delete-text`, and the rest) are flat hex by design: each light and dark pair is tuned for AA contrast, so they do not fall through `--vap-*` or `--vp-c-*`. Override the pair directly if you need to retint a badge.
Expand All @@ -29,14 +29,14 @@ Drop these into a stylesheet imported after the plugin styles in your [theme set

```css
:root {
/* Method accents borders, tab indicators, text highlights */
/* Method accents: borders, tab indicators, text highlights */
--vod-method-get: #2563eb;
--vod-method-post: #16a34a;
--vod-method-put: #d97706;
--vod-method-patch: #8b5cf6;
--vod-method-delete: #dc2626;

/* Method badges the pill-shaped labels (e.g. GET, POST) */
/* Method badges: the pill-shaped labels (e.g. GET, POST) */
--vod-method-get-bg: #dcfce7;
--vod-method-get-text: #166534;
--vod-method-post-bg: #dbeafe;
Expand Down
6 changes: 3 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
layout: home
title: VitePress OpenAPI Docs
titleTemplate: Interactive OpenAPI docs for VitePress
description: Drop interactive OpenAPI 3.x endpoints anywhere in your markdown. Vue-native VitePress plugin no shadow DOM, no iframes. Multi-API, SDK snippets, auth, git-driven changelog.
description: Drop interactive OpenAPI 3.x endpoints anywhere in your markdown. Vue-native VitePress plugin with no shadow DOM and no iframes. Multi-API, SDK snippets, auth, git-driven changelog.

hero:
text: VitePress OpenAPI Docs
Expand Down Expand Up @@ -35,7 +35,7 @@ Or [add to an existing VitePress site](/guide/existing-site).

## What you get

- **Inline composition** endpoints render as Vue components in light DOM. Weave them into tutorials, drop them between paragraphs, theme them with VitePress CSS variables.
- **Multiple APIs** array of specs, each with its own sidebar, URL prefix, and search index.
- **Inline composition** - endpoints render as Vue components in light DOM. Weave them into tutorials, drop them between paragraphs, theme them with VitePress CSS variables.
- **Multiple APIs** - array of specs, each with its own sidebar, URL prefix, and search index.
- **Auth and SDK snippets** - bearer / basic / API key / OAuth2 with session persistence. curl / fetch / Python snippets with syntax highlighting, refreshed live as credentials change.
- **< {{ $facts.bundleBudget }} client bundle** - peer dependencies (Vue, VitePress, vue-api-playground) excluded.
Loading
Loading