No SSR
Force React stream server-side rendering to include the closet <Suspense>
boundary's fallback UI (e.g. a loading indicator) into the generated server HTML. On the browser, the user will see the fallback UI first when the page loads, while React attempts to render the same component again during the hydration, and the user will see the proper content once React finishes the hydration. See <Suspense> Providing a fallback for server errors and client-only content (opens in a new tab) at React docs.
The noSSR
function can only be used with React stream server-side rendering. If you are using the React synchronous server-side rendering (e.g. renderToString
), you should use the useIsClient
approach instead. See useIsClient
.
Usage
import { noSSR } from 'foxact/no-ssr';
function Chat() {
noSSR();
// ...
return (
// ...
);
}
<Suspense fallback={<Loading />}>
<Chat />
</Suspense>
The server HTML will include the loading indicator. It will be replaced by the <Chat />
component on the client.
Note that if you are calling hydrationRoot
yourself and you are using the onRecoverableError
option, you should add the following codes to your callback:
import { hydrateRoot } from 'react-dom/client';
import { App } from './app';
const el = document.getElementById('root');
if (el) {
const root = hydrateRoot(el, <App />, {
onRecoverableError(incomingError) {
if ('recoverableError' in incomingError && incomingError.recoverableError === 'NO_SSR') {
// Ignoring the error generated by `noSSR()`.
return;
}
// handle other errors
// ...
}
});
}
// patch console.error to prevent the recoverable error from being called
const origConsoleError = window.console.error;
const isRecoverableError = (error) => {
return error && typeof error === 'object' && 'recoverableError' in error && error.recoverableError
};
window.console.error = (...args) => {
if (isRecoverableError(args[0])) {
return;
}
origConsoleError.apply(window.console, args);
};
window.addEventListener('error', (ev) => {
if (isRecoverableError(ev.error)) {
ev.preventDefault();
return;
}
});