The basic idea:
-
Create a custom App (
/pages/_app.tsx) -
Return
nulliftypeof window === "undefined". This is required to prevent react-router from throwing errors during the SSR step!
// pages/_app.tsx
import { AppProps } from 'next/app';
function App({ Component, pageProps }: AppProps) {
return (
<div suppressHydrationWarning> // <- ADD THIS
{typeof window === 'undefined' ? null : <Component {...pageProps} />}
</div>
);
}
export default App;-
Use optional catch all to catch all routes in the
/spapath. You have to create apages/spa/[[...slug]].tsxfile inside the directory of your next app. -
Use the
StaticRoutercomponent to not bypass the history of the next router. -
You have to manually feed the
Switchcomponent fromreact-routerwith a custom location object.
// pages/spa/[[...slug]].tsx
const router = useRouter();
<Switch
location={{
pathname: router.asPath,
search: "",
state: "",
hash: "",
}}
>
...
</Switch>;- Replace all the
LinkandNavLinkcomponents fromreact-routerbyNextLink. All theRedirectcomponents by a call to therouter.pushmethod of thenext-router.
⚠️ As you can't use theLinkcomponent fromreact-routeranymore nested routes will no longer work as expected. You need to provide the full path of the route to yourNextLinkcomponent.