diff --git a/packages/docusaurus-plugin-redoc/src/index.ts b/packages/docusaurus-plugin-redoc/src/index.ts index 04564e14..7e495f53 100644 --- a/packages/docusaurus-plugin-redoc/src/index.ts +++ b/packages/docusaurus-plugin-redoc/src/index.ts @@ -33,10 +33,6 @@ const version = require('../package.json').version; export { PluginOptions, PluginDirectUsageOptions, loadRedoclyConfig }; -function getIsExternalUrl(url = '') { - return ['http://', 'https://'].some((protocol) => url.startsWith(protocol)); -} - export default function redocPlugin( context: LoadContext, opts: PluginOptions, @@ -49,7 +45,7 @@ export default function redocPlugin( const { debug, spec, url: downloadUrl, config, themeId } = options; let url = downloadUrl; - const isExternalUrl = getIsExternalUrl(url); + const isExternalUrl = !!url; const fileName = path.join( 'redocusaurus', @@ -129,7 +125,7 @@ export default function redocPlugin( } const data: SpecDataResult = { - url, + downloadSpecUrl: url, themeId, // eslint-disable-next-line @typescript-eslint/no-explicit-any spec: content.converted as any, diff --git a/packages/docusaurus-theme-redoc/src/theme/ApiSchema/ApiSchema.tsx b/packages/docusaurus-theme-redoc/src/theme/ApiSchema/ApiSchema.tsx index a278a4bf..357180cb 100644 --- a/packages/docusaurus-theme-redoc/src/theme/ApiSchema/ApiSchema.tsx +++ b/packages/docusaurus-theme-redoc/src/theme/ApiSchema/ApiSchema.tsx @@ -11,6 +11,7 @@ const ApiSchema: React.FC = ({ showExample, pointer, id, + themeId, spec, optionsOverrides, ...rest @@ -18,6 +19,7 @@ const ApiSchema: React.FC = ({ const { store } = useSpec( { id, + themeId, spec, }, optionsOverrides, diff --git a/packages/docusaurus-theme-redoc/src/theme/Redoc/Redoc.tsx b/packages/docusaurus-theme-redoc/src/theme/Redoc/Redoc.tsx index 17bf7280..40b5e46c 100644 --- a/packages/docusaurus-theme-redoc/src/theme/Redoc/Redoc.tsx +++ b/packages/docusaurus-theme-redoc/src/theme/Redoc/Redoc.tsx @@ -6,10 +6,6 @@ import useSpecOptions from '@theme/useSpecOptions'; import './styles.css'; import ServerRedoc from './ServerRedoc'; -function getIsExternalUrl(url = '') { - return ['http://', 'https://'].some((protocol) => url.startsWith(protocol)); -} - /*! * Redocusaurus * https://redocusaurus.vercel.app/ @@ -20,7 +16,7 @@ function Redoc(props: RedocProps): JSX.Element { const { className, optionsOverrides, url, themeId } = props; const { options } = useSpecOptions(themeId, optionsOverrides); - if (getIsExternalUrl(url)) { + if (url) { return (
diff --git a/packages/docusaurus-theme-redoc/src/theme/Redoc/ServerRedoc.tsx b/packages/docusaurus-theme-redoc/src/theme/Redoc/ServerRedoc.tsx index 8d81ee0a..6c4b72d1 100644 --- a/packages/docusaurus-theme-redoc/src/theme/Redoc/ServerRedoc.tsx +++ b/packages/docusaurus-theme-redoc/src/theme/Redoc/ServerRedoc.tsx @@ -13,11 +13,12 @@ import './styles.css'; * Released under the MIT License */ function ServerRedoc(props: RedocProps): JSX.Element { - const { className, optionsOverrides, url, id, themeId } = props; + const { className, optionsOverrides, id, themeId, downloadSpecUrl } = props; const { store, spec, darkThemeOptions, lightThemeOptions, hasLogo } = useSpec( { spec: props.spec, themeId, + downloadSpecUrl, id, }, optionsOverrides, @@ -27,7 +28,7 @@ function ServerRedoc(props: RedocProps): JSX.Element { <> diff --git a/packages/docusaurus-theme-redoc/src/theme/useSpec/useSpec.ts b/packages/docusaurus-theme-redoc/src/theme/useSpec/useSpec.ts index a60f4e9d..b50eff92 100644 --- a/packages/docusaurus-theme-redoc/src/theme/useSpec/useSpec.ts +++ b/packages/docusaurus-theme-redoc/src/theme/useSpec/useSpec.ts @@ -20,13 +20,17 @@ export function useSpec( specInfo: SpecProps, optionsOverrides?: RedocRawOptions, ): SpecResult { - const { spec, url, themeId } = useSpecData( + const { spec, downloadSpecUrl, themeId } = useSpecData( specInfo.id, specInfo.spec, specInfo.themeId, ); const specOptions = useSpecOptions(themeId, optionsOverrides); - const fullUrl = useBaseUrl(url, { absolute: true }); + // build download URL by using downloadSpecUrl, fallback to useSpecData result + const fullDownloadSpecUrl = useBaseUrl( + specInfo.downloadSpecUrl || downloadSpecUrl, + { absolute: true }, + ); const isBrowser = useIsBrowser(); const isDarkTheme = useColorMode().colorMode === 'dark'; @@ -34,7 +38,7 @@ export function useSpec( if (currentStore !== null && isBrowser) { currentStore.dispose(); } - currentStore = new AppStore(spec, fullUrl, specOptions.options); + currentStore = new AppStore(spec, fullDownloadSpecUrl, specOptions.options); return { ...specOptions, @@ -43,7 +47,7 @@ export function useSpec( store: currentStore, spec, }; - }, [isBrowser, spec, fullUrl, specOptions]); + }, [isBrowser, spec, fullDownloadSpecUrl, specOptions]); useEffect(() => { // to ensure that menu is properly loaded when theme gets changed diff --git a/packages/docusaurus-theme-redoc/src/types/common.ts b/packages/docusaurus-theme-redoc/src/types/common.ts index 03937907..39b59e03 100644 --- a/packages/docusaurus-theme-redoc/src/types/common.ts +++ b/packages/docusaurus-theme-redoc/src/types/common.ts @@ -15,14 +15,13 @@ export interface SpecProps { * docusaurus theme to use */ themeId?: string; -} - -export type SpecDataResult = Omit & { /** * Public path to the spec file used, used by Redoc as download url */ - url?: string; -}; + downloadSpecUrl?: string; +} + +export type SpecDataResult = Omit; export interface MdxProps { /** diff --git a/packages/docusaurus-theme-redoc/src/types/modules.ts b/packages/docusaurus-theme-redoc/src/types/modules.ts index 7cf9b28d..f5b731ac 100644 --- a/packages/docusaurus-theme-redoc/src/types/modules.ts +++ b/packages/docusaurus-theme-redoc/src/types/modules.ts @@ -12,6 +12,10 @@ interface SpecProps { * docusaurus theme to use */ themeId?: string; + /** + * Public path to the spec file used, used by Redoc as download url + */ + downloadSpecUrl?: string; } interface SpecResult { hasLogo: boolean; @@ -85,12 +89,7 @@ declare module '@theme/ApiSchema' { } declare module '@theme/useSpecData' { - type SpecDataResult = Omit & { - /** - * Public path to the spec file used, used by Redoc as download url - */ - url?: string; - }; + type SpecDataResult = Omit; /** * Load redocusaurus plugin data by ID diff --git a/website/docs/guides/component-redoc.mdx b/website/docs/guides/component-redoc.mdx index 54072ee4..23b75bbd 100644 --- a/website/docs/guides/component-redoc.mdx +++ b/website/docs/guides/component-redoc.mdx @@ -24,13 +24,28 @@ import Redoc from '@theme/Redoc'; ## Props -| Name | Type | Description | -|------|--------------|-------------------------------------| -| spec | OpenAPI spec | A JSON content spec to use | -| url | String | External URL to load spec file from | +| Name | Type | Description | +|-----------------|--------------|---------------------------------------------------------------------------------------------| +| id | String | When spec not provided, load the spec from docusaurus config. Use first spec if not defined | +| spec | OpenAPI spec | A JSON content spec to use | +| url | String | External URL to load spec file from | +| themeId | String | redocusaurus theme to use - default to `theme-redoc` | +| downloadSpecUrl | String | Public path to the spec file used, used by Redoc as download url | ## Examples +### Basic example + +It displays here the first element of the redocusaurus configuration. + +```tsx +import Redoc from '@theme/Redoc'; + + +``` + + + ### External URL example ```tsx @@ -41,6 +56,26 @@ import Redoc from '@theme/Redoc'; +### Specific id example + +```tsx +import Redoc from '@theme/Redoc'; + + +``` + + + +### Download url example + +```tsx +import Redoc from '@theme/Redoc'; + + +``` + + + ### Webpack loader example You can provide a JSON spec to the component like this. Webpack will load the file directly, @@ -57,9 +92,11 @@ import openApi from './api-with-examples.json' :::info YAML support You cannot load yaml file like this: + ```tsx import openApi from './api-with-examples.yaml' ``` + Without the right webpack configuration to handle such file format. :::