Skip to content

Commit 5aa1c60

Browse files
committed
feat: Add specInfoPagePath configuration option
- Add specInfoPagePath option to APIOptions interface - Update createItems function to use specInfoPagePath if provided, falling back to kebab-cased info.title - Update README with documentation for the new option - Add comprehensive tests for the new configuration option This allows users to customize the URL path of the info page independently from the title that is rendered on the page.
1 parent 6cd891e commit 5aa1c60

File tree

4 files changed

+98
-1
lines changed

4 files changed

+98
-1
lines changed

packages/docusaurus-plugin-openapi-docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ The `docusaurus-plugin-openapi-docs` plugin can be configured with the following
179179
| `showInfoPage` | `boolean` | `true` | _Optional:_ If set to `false`, disables generation of the info page (overview page with API title and description). |
180180
| `schemasOnly` | `boolean` | `false` | _Optional:_ If set to `true`, generates only schema pages (no API endpoint pages). Also available as `--schemas-only` CLI flag. |
181181
| `externalJsonProps` | `boolean` | `true` | _Optional:_ If set to `false`, disables externalization of large JSON props. By default, large JSON is written to external files for better build performance. |
182+
| `specInfoPagePath` | `string` | `null` | _Optional:_ The path the root information page will be rendered at. Defaults to kebab case `info.title`. |
182183

183184
### sidebarOptions
184185

packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.test.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,95 @@ describe("openapi", () => {
9595
expect(schemaItems[0].id).toBe("without-tags");
9696
});
9797
});
98+
99+
describe("specInfoPagePath", () => {
100+
it("uses default kebab-cased info.title when specInfoPagePath is not provided", async () => {
101+
const openapiData = {
102+
openapi: "3.0.0",
103+
info: {
104+
title: "Company Foo",
105+
version: "1.0.0",
106+
description: "Test API",
107+
},
108+
paths: {},
109+
};
110+
111+
const options: APIOptions = {
112+
specPath: "dummy",
113+
outputDir: "build",
114+
};
115+
116+
const sidebarOptions = {} as SidebarOptions;
117+
118+
const [items] = await processOpenapiFile(
119+
openapiData as any,
120+
options,
121+
sidebarOptions
122+
);
123+
124+
const infoItem = items.find((item) => item.type === "info");
125+
expect(infoItem).toBeDefined();
126+
expect(infoItem?.id).toBe("company-foo");
127+
});
128+
129+
it("uses custom specInfoPagePath when provided", async () => {
130+
const openapiData = {
131+
openapi: "3.0.0",
132+
info: {
133+
title: "Company Foo",
134+
version: "1.0.0",
135+
description: "Test API",
136+
},
137+
paths: {},
138+
};
139+
140+
const options: APIOptions = {
141+
specPath: "dummy",
142+
outputDir: "build",
143+
specInfoPagePath: "custom-api-intro",
144+
};
145+
146+
const sidebarOptions = {} as SidebarOptions;
147+
148+
const [items] = await processOpenapiFile(
149+
openapiData as any,
150+
options,
151+
sidebarOptions
152+
);
153+
154+
const infoItem = items.find((item) => item.type === "info");
155+
expect(infoItem).toBeDefined();
156+
expect(infoItem?.id).toBe("custom-api-intro");
157+
});
158+
159+
it("kebab-cases custom specInfoPagePath", async () => {
160+
const openapiData = {
161+
openapi: "3.0.0",
162+
info: {
163+
title: "Company Foo",
164+
version: "1.0.0",
165+
description: "Test API",
166+
},
167+
paths: {},
168+
};
169+
170+
const options: APIOptions = {
171+
specPath: "dummy",
172+
outputDir: "build",
173+
specInfoPagePath: "Custom API Introduction",
174+
};
175+
176+
const sidebarOptions = {} as SidebarOptions;
177+
178+
const [items] = await processOpenapiFile(
179+
openapiData as any,
180+
options,
181+
sidebarOptions
182+
);
183+
184+
const infoItem = items.find((item) => item.type === "info");
185+
expect(infoItem).toBeDefined();
186+
expect(infoItem?.id).toBe("custom-api-introduction");
187+
});
188+
});
98189
});

packages/docusaurus-plugin-openapi-docs/src/openapi/openapi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ function createItems(
9494
// TODO: Find a better way to handle this
9595
let items: PartialPage<ApiMetadata>[] = [];
9696
const infoIdSpaces = openapiData.info.title.replace(" ", "-").toLowerCase();
97-
const infoId = kebabCase(infoIdSpaces);
97+
const infoId = kebabCase(options?.specInfoPagePath ?? infoIdSpaces);
9898
const schemasOnly = options?.schemasOnly === true;
9999

100100
// Only create an info page if we have a description/title AND showInfoPage is not false

packages/docusaurus-plugin-openapi-docs/src/types.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ export interface APIOptions {
6262
* @see https://github.com/facebook/docusaurus/discussions/11664
6363
*/
6464
externalJsonProps?: boolean;
65+
/**
66+
* The path the root information page will be rendered at.
67+
* Defaults to kebab case info.title
68+
*/
69+
specInfoPagePath?: string;
6570
}
6671

6772
export interface MarkdownGenerator {

0 commit comments

Comments
 (0)