How can I use StaticRouter inside renderToString in typescript ssr?

492 Views Asked by At

This is what I currently have

export const renderer = () => {
  const content = renderToString(React.createElement(Home));
  return ` <html> 
    <head>
   
    </head>
    <body>
    <div  id="root">${content}</div>
    <script></script>
    <script src="main-bundle.js"> </script>
    </body></html> `;
};

I created a Routes file, I need to wrap it with StaticRouter and ship it to the browser. However I cannot pass it like this:

<StaticRouter>
  <Routes />
</StaticRouter>

In the client side for BrowserRouter, I created an app component and rendered this app.

export const app: React.FC<appProps> = ({}) => {
  return (
    <BrowserRouter>
      <Routes />
    </BrowserRouter>
  );
};

inside client.tsx

   ReactDOM.hydrate(React.createElement(app), document.getElementById("root"));

I could not figure out it in server side. The only thing I am thinking is to create a component like app.tsx, instead of BrowserRouter using StaticRouter but I don't think that creating a react component component on the server is the right way.

Currently I am processing with this but that is not the proper way neither:

const routes = React.createElement(Routes, {}, "");
const router = React.createElement(StaticRouter, {}, routes);

enter image description here

1

There are 1 best solutions below

0
davnicwil On

That pattern is absolutely correct!

I.e. define an <App> component containing your routes, then wrap it with the appropriate router implementation provider on server and client, as you suggest.

I think the way to think about it is similar to dependency injection. You have all your actual app logic encapsulated in <App> - the <BrowserRouter> or <StaticRouter> is just a provider, an implementation detail.

It doesn't change how <App> behaves, it just applies the appropriate implementation to make routing work in the environment you're running in.