We do something a little crazy: we walk the component tree before we render it, and prefetch all the data that is required.
E.g. a component might look something like:
(defn greeting 
(let [user-data (pull! :user-data [:first-name])]
(when-not (:loading? @user-data)
[:div "Hello, " (-> @user-data :data :first-name)]))))
In the browser, this function will render initially without any data and then reactively re-render when it’s fetched the user data.
On the server side, we have a function called
prefetch that executes the entire component tree, and captures all of calls to
pull!, waiting for the data to come back before continuing to walk the tree.
After the data has been fetched, it’s loaded into a cache and we call
render-to-string using that cached data, so it’s already fully loaded when it renders to the string.
I’m not sure I would actually suggest going this route, because it has it’s downsides. The deeper your component tree gets, the longer your load times can become. This can be ameliorated by hoisting your fetches higher in the tree, but this can lead to over fetching and breaking encapsulation of your components.
I think that declarative data fetching on the server-side is still an open question and it’s not being pursued much in the Clojure(Script) community at large at the moment.