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);

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.