redoc icon indicating copy to clipboard operation
redoc copied to clipboard

Browser side rendering

Open webark opened this issue 4 years ago • 13 comments

Describe the bug I followed the "quick start" guide and am attempting to load a spec in the browser and getting a "path.join is not a function". Is only server-side rendering supported? I didn't see anything to that effect in the quickstart guide.

Expected behavior To be able to use the RedocStandalone in an existing react application

I might be missing something, but from the docs it seems that all I need are the packages installed, and then can use the RedocStandalone react component to render the docs in the browser without utilizing the server side redering abilites. If this is not correct, what am I missing?


import { RedocStandalone } from 'redoc';

export const ApiSpec = (definition: any) => (
  <RedocStandalone
    spec={definition}
    options={{
      theme: { colors: { primary: { main: '#dd5522' } } },
    }}
  />
);

webark avatar Sep 01 '21 22:09 webark

yea, so dd calls the StoreBuilder, which then calls dd, which then gets to https://github.com/Redocly/redoc/blob/1d088a8dd806101d326d39f95ae370ccbdf93b45/src/utils/loadAndBundleSpec.ts#L13-L18 This new Config({}) that is being pulled from https://github.com/Redocly/openapi-cli/blob/master/packages/core/src/config/config.ts can not be run in the browser. It seems like the config needs to be pulled in differently for the IS_BROWSER option.

webark avatar Sep 01 '21 23:09 webark

@swapnilogale is this just a docs issue? From reading the code it doesn't seem possible with the current implementation. Is there a config I am missing to unblock me? currently, I'm having to do

import React, { useEffect } from 'react';

import { RedocStandaloneProps } from 'redoc';

declare const Redoc: any;

async function loadScript(scriptSrc: string) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = scriptSrc;
    script.async = true;
    script.onload = resolve;
    script.onerror = reject;
    document.head.appendChild(script);
  });
}

function RedocStandalone({ spec, specUrl, options, onLoaded }: RedocStandaloneProps) {
  useEffect(() => {
    async function setupRedoc() {
      if (typeof Redoc === 'undefined') await loadScript('https://cdn.jsdelivr.net/npm/redoc@latest/bundles/redoc.standalone.js');

      Redoc.init(spec || specUrl, options, document.getElementById('redoc-container'), onLoaded);
    }

    setupRedoc();
  });

  return <div id="redoc-container" data-testid="redoc-container" />;
}

webark avatar Sep 09 '21 19:09 webark

@webark I assigned the docs label for our tech writer to see if they can document this better. I'll see if I can get someone to help you with the actual code as well.

swapnilogale avatar Sep 15 '21 00:09 swapnilogale

that would be great @swapnilogale ! I dug through the code, and since the switch to using the cli for generation, I didn't see any way it could work in a browser, but i wonder if i'm just missing something. Any assistance would be appreciated!

webark avatar Sep 15 '21 03:09 webark

@webark this seems like webpack 5 related issue: https://github.com/Redocly/redoc/issues/1584

Could you confirm?

RomanHotsiy avatar Oct 20 '21 04:10 RomanHotsiy

I'm using this in backstage which runs on webpack 5. But from my comment above, following the code path, I do not believe it's possible to use the component directly outside of a "server side rendering" setup.

webark avatar Oct 20 '21 05:10 webark

No, it should be possible. You just have to provide polyfills when you include it in your build.

RomanHotsiy avatar Oct 20 '21 06:10 RomanHotsiy

@RomanHotsiy do you have any documentation on how to overwrite that "Config" module then?

webark avatar Oct 20 '21 12:10 webark

@RomanHotsiy or could you look over https://github.com/Redocly/openapi-cli/blob/master/packages/core/src/config/config.ts briefly and let me know how to polyfil some of those code paths?

webark avatar Oct 20 '21 12:10 webark

@webark can you try this: https://github.com/Redocly/redoc/issues/1575#issuecomment-887461961

Also, you may need to add

resolve: {     
      fallback: {
        "fs": false,
         "path": require.resolve("path-browserify")
      }
    }

RomanHotsiy avatar Oct 21 '21 03:10 RomanHotsiy

hmmm... Backstage doesn't provide that level of customization unless you basically rewrite the whole webpack config.

I assume that the long term solution will to end up using a different browser config class? one where the node one would be a sub class or sibling class of?

But I get the notion of beta and all that entails.

I'll probably just keep with what i have for now then.. :( Feel free to close the issue out if you don't want to use it to track the future work of not having to add those webpack configs.

thanks @RomanHotsiy !!

webark avatar Oct 21 '21 04:10 webark

@webark any luck getting this to work in backstage?

CarltonHowell avatar Dec 14 '21 20:12 CarltonHowell

@CarltonHowell I did! I used the component I referenced above. Are you on the backstage discord?

webark avatar Dec 15 '21 01:12 webark