UNPKG

vite-ssr

Version:

Vite utility for server side rendering

48 lines (47 loc) 1.92 kB
import React from 'react'; import ReactDOM from 'react-dom'; import createClientContext from '../core/entry-client.js'; import { BrowserRouter, useNavigate } from 'react-router-dom'; import { HelmetProvider } from 'react-helmet-async'; import { withoutSuffix } from '../utils/route'; import { createRouter } from './utils'; import { provideContext } from './components.js'; export { ClientOnly, useContext } from './components.js'; export const viteSSR = async function (App, { routes, base, suspenseFallback, PropsProvider, pageProps, debug = {}, styleCollector, ...options }, hook) { const url = new URL(window.location.href); const routeBase = base && withoutSuffix(base({ url }), '/'); const ctx = await createClientContext({ ...options, url, spaRedirect: (location) => { const navigate = useNavigate(); React.useEffect(() => navigate(location), [navigate]); }, }); const context = ctx; context.router = createRouter({ routes, base, initialState: context.initialState, pagePropsOptions: pageProps, PropsProvider, }); if (hook) { await hook(context); } let app = React.createElement(HelmetProvider, {}, React.createElement( // @ts-ignore BrowserRouter, { basename: routeBase }, React.createElement(React.Suspense, { fallback: suspenseFallback || '' }, provideContext(React.createElement(App, context), context)))); const styles = styleCollector && (await styleCollector(context)); if (styles && styles.provide) { app = styles.provide(app); } if (debug.mount !== false) { // @ts-ignore const el = document.getElementById(__CONTAINER_ID__); styles && styles.cleanup && styles.cleanup(); // @ts-ignore __VITE_SSR_DEV__ ? ReactDOM.render(app, el) : ReactDOM.hydrate(app, el); } }; export default viteSSR;