This problem can be divided into two parts: 1, how to fetch data, 2 how to render HTML. Before either of them is done, we only get a router from the request, which is a string, and with some cookies or other header.
Problem 2 is easier, like said renderToString is already there. It can be easy. Just pass the data to the component as props, and render it. But it also can be hard based on which store library you use, might be a lot of spaghetti.
Problem 1 is somehow a bit stranger. As front-end developer, fetching data from database may lead to bad code. At least my code does, when I was trying server side rendering, actually my teammate did that for me, and that project was quite simple. After all backend developer are familiar with such tasks.
After both problems are solved, you need to make sure client renders first pages the same as that the server do. It's passing the same store to browsers with JSON, to help browsers initialise the same runtime.
My code is very obscure since I didn't use Redux github.com/jianliaoim/talk-os/tree/master/talk-ac… but the idea behind it is still clear.