docusaurus-openapi-docs
docusaurus-openapi-docs copied to clipboard
Output docs URL path prefix
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 π―
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:
- Use a separate
plugin-content-docs
instance for your API docs with arouteBasePath
set to/reference/api
. - 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 Yes, that's correct!
- Oh, I hadn't considered that. That .. could work!
- 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'),
}
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.
Hi @thomasheartman, any updates to share?
We can work on documenting the "standalone plugin-content-docs
" usage and mixing API with non-API docs.
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 ππΌ
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!
Hi @thomasheartman, any updates to share?
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 βΊοΈ