Description
Have you read the Contributing Guidelines on issues?
- I have read the Contributing Guidelines on issues.
Description
There exist many libraries that depend on accessing window
, so they can't be top-level imported and instead
<BrowserOnly>
must be used (https://docusaurus.io/docs/advanced/ssg#browseronly)useEffect
can be used to load the lib and then set it...
Has this been requested on Canny?
No response
Motivation
Since this is a common usecase, it could be streamlined as a hook and be document s.t. new users can directly use it
API design
Introduce a new hook in the client api and document it here: https://docusaurus.io/docs/docusaurus-core.
The hook would look something like this:
import React from 'react';
const cachedLibs = new Map<string, any>();
export const useClientLib = <T>(dynamicImport: () => Promise<T>, moduleName?: string): T | null => {
const [Lib, setLib] = React.useState<T>(moduleName ? cachedLibs.get(moduleName) : null);
React.useEffect(() => {
if (Lib) {
return;
}
dynamicImport().then((Lib) => {
setLib(Lib);
if (moduleName) {
cachedLibs.set(moduleName, Lib);
}
});
}, []);
return Lib || null;
};
And can then easily be used like this:
import React from 'react';
import type { default as ClientLib } from 'some-lib';
const SomeComponent = () => {
const Lib = useClientLib<typeof ClientLib>(() => import('some-lib'), 'some-lib');
if (!Lib) {
return <div>Loading...</div>;
}
return <Lib.LibComponent />;
};
Have you tried building it?
I add this hook to all my docusaurus pages which needs some-lib-using-window
- if there is interest to include this in dpcusaurus, i'm happy to put together a PR.
What i"ve not tried is to use it with relative imports (as you do here for the css (which should be fine to import directly?) https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-search-algolia/src/theme/SearchBar/index.tsx#L63 , anyway, the rest of the importDocSearchModalIfNeeded
should work with the new hook...)
Self-service
- I'd be willing to contribute this feature to Docusaurus myself.