Skip to content

Bug: basePath generation breaks when outputDir folder names contain the configured docPath substring #1305

@trofim24

Description

@trofim24

Describe the bug

The sidebar ID generation in docusaurus-plugin-openapi-docs breaks when the outputDir path contains folder names that include the configured docPath as a substring. For example, with the default docPath: "docs", folders like "docspace", "mydocs", or "api-docs" generate invalid IDs (e.g., "test//api" instead of "test/docspace/api").

Expected behavior

Document IDs should be prefixed with the full path after docPath:

// Expected with outputDir: "docs/test/docspace"
{
  type: "doc",
  id: "test/docspace/api",
  label: "Introduction"
},
{
  type: "doc",
  id: "test/docspace/create-api-key",
  label: "Create a user API key"
}

Current behavior

Document IDs have double slashes or missing path segments:

// Actual with outputDir: "docs/test/docspace"
{
  type: "doc",
  id: "test//api",
  label: "Introduction"
},
{
  type: "doc",
  id: "test//create-api-key",
  label: "Create a user API key"
}

Possible solution

Replace String.split() with startsWith and substring

const getBasePathFromOutput = (
  output: string,
  doc: string | undefined
): string => {
  // Check if output starts with docPath at a path boundary
  if (doc && output.startsWith(doc + "/")) {
    return output.substring((doc + "/").length);
  }

  // Fallback: extract everything after first slash
  const slashIndex = output.indexOf("/", 1);
  return slashIndex === -1
    ? ""
    : output.slice(slashIndex).replace(/^\/+/g, "");
};

Steps to reproduce

1. Configuration

docusaurus.config.ts:

module.exports = {
  presets: [
    [
      'classic',
      {
        docs: {
          path: 'docs',  // This is the docPath that gets split on
          // ... other options
        },
      },
    ],
  ],

  plugins: [
    [
      'docusaurus-plugin-openapi-docs',
      {
        id: "api",
        docsPluginId: "classic",
        config: {
          docspace: {
            specPath: "examples/petstore.yaml",
            outputDir: "docs/test/docspace",  // "docspace" contains "docs"
            sidebarOptions: {
              groupPathsBy: "tagGroup",
            },
          }
        }
      }
    ]
  ]
}

2. Generate Documentation

yarn docusaurus gen-api-docs docspace

3. Check Generated Sidebar

Generated: docs/test/docspace/sidebar.ts

  • Version used: Version 4.7.1:

Current Implementation in Code

Version 4.7.1:

const getBasePathFromOutput = (
  output: string,        // e.g., "docs/test/docspace"
  doc: string | undefined // e.g., "docs"
): string => {
  if (doc && output.includes(doc)) {
    return output.split(doc)[1]?.replace(/^\/+/g, "") ?? ""; 
  }
  const slashIndex = output.indexOf("/", 1);
  return slashIndex === -1
    ? ""
    : output.slice(slashIndex).replace(/^\/+/g, "");
};

Code Location

File: packages/docusaurus-plugin-openapi-docs/src/sidebars/index.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions