docusaurus-openapi-docs icon indicating copy to clipboard operation
docusaurus-openapi-docs copied to clipboard

Output docs URL path prefix

Open thomasheartman opened this issue 1 year ago β€’ 6 comments

Is your feature request related to a problem?

I'm looking for a way to set a custom path on the generated documents, so that it doesn't necessarily match their path in the file system.

Specifically:

  • I'd like to generate files into a .generated/openapi directory that can easily be ignored by git etc.
  • I'd like the rendered paths to be /reference/api, so that the paths match the rest of the documentation and that you don't get a .generated in the actual path.

Describe the solution you'd like

I'd like an option on a spec config object to set the base path to be used for documents belonging to that spec. In my case, I would then set:

{
  // ... other options
  specPath: '<path-to-spec>',
  outputDir: '.generated/api',
  basePath: 'reference/api'
}

Describe alternatives you've considered

The current workaround is to generate the docs into a directory that already exists and then just not committing the new directory. This does work and as long as all files below the path prefix are generated, it should be fine.

Maybe customProps can be used for this somehow? I tried, but couldn't make it work.

Also, that config object already accepts a baseUrl prop, but that is related to versioning and doesn't seem to do what I want.

Additional context

I'm trying to integrate this into a pre-existing docusaurus page and have the paths stay relatively consistent. I'm not sure I have more context to supply, but would be happy to if you have questions πŸ˜„

Also: This might already be possible, but I couldn't figure out how. The readme doesn't seem to make much of a mention of it, and I couldn't find anything for this specifically in the docusaurus docs.


Finally: thanks a lot for this package and all the work you put in! And thanks for responding and helping me out with my questions thus far πŸ’―

thomasheartman avatar Aug 11 '22 09:08 thomasheartman

Hi @thomasheartman, if I'm understanding correctly I believe you want the generated API docs to have the same/similar base path as your non-API docs? Or, at least, you would like to be able to render them on a route that differs from the actual file path?

There's probably a few ways you could handle this...for example you could:

  1. Use a separate plugin-content-docs instance for your API docs with a routeBasePath set to /reference/api.
  2. Write the API docs to the same outputDir as your non-API docs, so they can share the same base path.

Let me know if this makes sense for what you're trying to achieve.

sserrata avatar Aug 11 '22 12:08 sserrata

@sserrata Yes, that's correct!

  1. Oh, I hadn't considered that. That .. could work!
  2. Yeah, that's the solution that I've opted for initially, as it's easier to implement. But it does mean you end up mixing generated and non-generated files, which can be a little messy.

Thanks for the explanation! The way you put it, it makes sense that this isn't necessarily on you, but rather a docusaurus configuration feature. I like the idea of approach 1 (the extra plugin content docs instance), but I couldn't find any docs describing what you suggest. I found this Stack Overflow suggestion , which almost seems to work, but when I try and run it, I get lots of errors saying "react has already been declared":

Compiled with problems:

ERROR in ./docs/generated/openapi/unleash/add-environment-to-project.api.mdx

Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/thomas/projects/work/unleash/website/docs/generated/openapi/unleash/add-environment-to-project.api.mdx: Identifier 'React' has already been declared. (163:194)

  161 | };
  162 |
> 163 | import _extends from"/Users/thomas/projects/work/unleash/website/node_modules/@babel/runtime/helpers/esm/extends.js";/* @jsxRuntime classic */ /* @jsx mdx */ /* @jsxFrag React.Fragment */import React from'react';import{mdx}from'@mdx-js/react';

I know it's only tangential to this package, but if you could give me some pointers on how to achieve this, I'd be very grateful! Looking at the docusaurus.config.js file we use, we don't reference @docusaurus/plugin-content-docs directly. Adding an extra instance to the end of the plugin section did seem to work, but I don't know if it needs to be referenced differently in the sidebars.js file, then?

docusauraus.config.js
/** @type {import('@docusaurus/types').DocusaurusConfig} */
module.exports = {
    title: 'Unleash',
    tagline: 'The enterprise ready feature toggle service',
    url: 'https://docs.getunleash.io',
    baseUrl: '/',
    onBrokenLinks: 'throw',
    onBrokenMarkdownLinks: 'warn',
    favicon: 'img/favicon.ico',
    organizationName: 'Unleash', // Usually your GitHub org/user name.
    projectName: 'unleash.github.io', // Usually your repo name.
    trailingSlash: false,
    customFields: {
        // expose env vars etc here
        unleashProxyUrl: process.env.UNLEASH_PROXY_URL,
        unleashProxyClientKey: process.env.UNLEASH_PROXY_CLIENT_KEY,
        unleashFeedbackTargetUrl: process.env.UNLEASH_FEEDBACK_TARGET_URL,
        environment: process.env.NODE_ENV,
    },
    themeConfig: {
        defaultMode: 'light',
        disableSwitch: true,
        respectPrefersColorScheme: false,
        algolia: {
            appId: 'BH4D9OD16A',
            apiKey: '9772249a7262b377ac876853d32bd760',
            indexName: 'getunleash',
        },
        navbar: {
            title: 'Unleash',
            logo: {
                alt: 'Unleash logo',
                src: 'img/logo.svg',
            },
            items: [
                {
                    href: 'https://www.getunleash.io/plans',
                    label: 'Unleash Enterprise',
                    position: 'right',
                },
                {
                    href: 'https://github.com/Unleash/unleash',
                    position: 'right',
                    className: 'header-github-link',
                    'aria-label': 'Unleash GitHub repository',
                },
            ],
        },
        prism: {
            additionalLanguages: [
                'csharp',
                'http',
                'java',
                'kotlin',
                'php',
                'ruby',
                'swift',
            ],
        },
        footer: {
            style: 'dark',
            links: [
                {
                    title: 'Product',
                    items: [
                        {
                            label: 'Docs',
                            to: '/',
                        },
                        {
                            label: 'Unleash on GitHub',
                            href: 'https://github.com/Unleash/unleash',
                        },
                        {
                            label: 'Roadmap',
                            href: 'https://github.com/orgs/Unleash/projects/5',
                        },
                    ],
                },
                {
                    title: 'Community',
                    items: [
                        {
                            label: 'Stack Overflow',
                            href: 'https://stackoverflow.com/questions/tagged/unleash',
                        },
                        {
                            label: 'Slack',
                            href: 'https://slack.unleash.run/',
                        },
                        {
                            label: 'Twitter',
                            href: 'https://twitter.com/getunleash',
                        },
                    ],
                },
            ],
            copyright: `Copyright Β© ${new Date().getFullYear()} Unleash. Built with Docusaurus.`,
            logo: {
                src: 'img/logo.svg',
                alt: 'Unleash logo',
            },
        },
        image: 'img/logo.png',
    },
    presets: [
        [
            '@docusaurus/preset-classic',
            {
                docs: {
                    sidebarPath: require.resolve('./sidebars.js'),
                    // Please change this to your repo.
                    editUrl:
                        'https://github.com/Unleash/unleash/edit/main/website/',
                    routeBasePath: '/',
                    remarkPlugins: [
                        [
                            require('@docusaurus/remark-plugin-npm2yarn'),
                            { sync: true },
                        ],
                    ],
                    docLayoutComponent: '@theme/DocPage',
                    docItemComponent: '@theme/ApiItem',
                },
                theme: {
                    customCss: require.resolve('./src/css/custom.css'),
                },
                googleAnalytics: {
                    trackingID: 'UA-134882379-1',
                },
            },
        ],
    ],
    plugins: [
        [
            '@docusaurus/plugin-client-redirects',
            {
                fromExtensions: ['html', 'htm'],
                redirects: [
                    {
                        to: '/sdks',
                        from: [
                            '/user_guide/client-sdk',
                            '/client-sdk',
                            '/user_guide/connect_sdk',
                            '/sdks/community',
                        ],
                    },
                    {
                        to: '/user_guide/api-token',
                        from: '/deploy/user_guide/api-token',
                    },
                    {
                        to: '/sdks/unleash-proxy',
                        from: '/user_guide/native_apps/',
                    },
                    {
                        to: '/advanced/toggle_variants',
                        from: '/toggle_variants',
                    },
                    {
                        to: '/integrations',
                        from: '/integrations/integrations',
                    },
                    {
                        to: '/user_guide/activation_strategy',
                        from: '/user_guide/control_rollout',
                    },
                    {
                        from: '/advanced/impression_data',
                        to: '/advanced/impression-data',
                    },
                ],
                createRedirects: function (toPath) {
                    if (
                        toPath.indexOf('/docs/') === -1 &&
                        toPath.indexOf('index.html') === -1
                    ) {
                        return `/docs/${toPath}`;
                    }
                },
            },
        ],
        [
            'docusaurus-plugin-openapi-docs',
            {
                id: 'api-operations',
                docsPluginId: 'classic',
                config: {
                    server: {
                        specPath: 'http://localhost:4242/docs/openapi.json',
                        outputDir: 'docs/reference/api/unleash',
                        sidebarOptions: {
                            groupPathsBy: 'tag',
                            categoryLinkSource: 'tag',
                        },
                    },
                },
            },
        ],
    ],
    themes: ['docusaurus-theme-openapi-docs'], // Allows use of @theme/ApiItem and other components
};
sidebars.js item that sets up generated docs
                        {
                            label: 'OpenAPI docs',
                            collapsed: true,
                            type: 'category',
                            link: {
                                title: 'Unleash Server APIs',
                                type: 'generated-index',
                                description:
                                    'Generated API docs based on the Unleash OpenAPI schema.',
                                slug: '/reference/api/unleash',
                            },
                            items: require('./docs/reference/api/unleash/sidebar.js'),
                        }

thomasheartman avatar Aug 12 '22 06:08 thomasheartman

You can find an example of a standalone plugin-content-docs config here

Yeah, that's the solution that I've opted for initially, as it's easier to implement. But it does mean you end up mixing generated and non-generated files, which can be a little messy.

I agree it's not ideal, but should work in theory. That's the reason we opted to use special filename suffixes, e.g. *.api.mdx, *.info.mdx, *.tag.mdx, so you could easily .gitignore, cleanup, etc.

sserrata avatar Aug 12 '22 13:08 sserrata

Hi @thomasheartman, any updates to share?

We can work on documenting the "standalone plugin-content-docs" usage and mixing API with non-API docs.

sserrata avatar Aug 15 '22 16:08 sserrata

Hey, @sserrata! Thanks for following up!

I tried to follow the link you shared, but our docusaurus.config.js doesn't quite match it, so I wasn't able to make it do what I want. I suspect that it might just take some more fiddling.

Anyway, I've just started my vacation, so I won't look at this for another three weeks now. I'll return to it when I get back.

That's the reason we opted to use special filename suffixes, e.g. *.api.mdx, *.info.mdx, *.tag.mdx, so you could easily .gitignore, cleanup, etc.

I wasn't aware of the special filename suffixes! Maybe I've just missed them? Are they configurable?

We can work on documenting the "standalone plugin-content-docs" usage and mixing API with non-API docs.

I think that might make sense, but I'm only a single data point, so I can't say whether I'm an average user or not. But in my experience: if one person wonders about something, then they're probably not the only one πŸ’πŸΌ

thomasheartman avatar Aug 15 '22 18:08 thomasheartman

Hey! πŸ™‹πŸΌ Just wanted to say that I'm back and that I'll be working on this for a bit going forward. I did notice that the generated files use the ".api.mdx" suffix now, so that might be enough for now. In that case, I should be able to generate them to where I want and take it from there πŸ˜„ I'll let you know again when I do end up solving it!

thomasheartman avatar Sep 08 '22 11:09 thomasheartman

Hi @thomasheartman, any updates to share?

sserrata avatar Sep 21 '22 14:09 sserrata

Yes! We finally got around to actually deploying this (though there's still work to be done). For now we just ignore *.api.mdx and generate it into a folder with the rest of the docs. Simple, but it works. Thanks for the input! Feel free to close this issue ☺️

thomasheartman avatar Sep 23 '22 08:09 thomasheartman