Created
January 22, 2021 11:30
-
-
Save holyjak/6ead10c0b447e098026f3e24e4f1e519 to your computer and use it in GitHub Desktop.
Experiments in Fulcro SSR with dynamic routers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns ssr-test | |
"Try server-side rendering in Fulcro where we want to display a non-default | |
dynamic router target. | |
*BEWARE*: This is an exploration. I have *no* idea what is the correct way." | |
(:require | |
[com.fulcrologic.fulcro.application :as app] | |
[com.fulcrologic.fulcro.algorithms.denormalize :as denorm] | |
[com.fulcrologic.fulcro.algorithms.server-render :as ssr] | |
[com.fulcrologic.fulcro.components :as comp :refer [defsc]] | |
[com.fulcrologic.fulcro.dom-server :as dom :refer [div label input]] | |
[com.fulcrologic.fulcro.routing.dynamic-routing :as dr :refer [defrouter]])) | |
(defsc AlternativeTarget [_ _] | |
{:query ['* :whatever] | |
:initial-state {:whatever 123} | |
:route-segment ["alt"]} | |
(dom/p "Alternative")) | |
(defsc DefaultTarget [_ _] | |
{:query ['* :default] | |
:initial-state {:default true} | |
:route-segment ["default"]} | |
(dom/p "Default")) | |
(defrouter TopRouter [_ _] | |
{:router-targets [DefaultTarget AlternativeTarget]}) | |
(defsc Root [this {:keys [router]}] | |
{:query [{:router (comp/get-query TopRouter)}] | |
:initial-state {:router {}}} | |
(dom/div | |
(dom/h1 "Test App") | |
((comp/factory TopRouter) router))) | |
(defn server-render [] | |
(let [; Should I use --v ? In this example the result HTML is the same anyway. | |
;state (ssr/build-initial-state | |
; ; {} ; with this <-- the state would be empty so let's ensure some stuff there: | |
; (comp/get-initial-state Root) | |
; Root) | |
state {} | |
state' (-> state | |
(assoc-in (conj [::dr/id :ssr-test/TopRouter] | |
::dr/current-route) | |
(comp/get-initial-state AlternativeTarget)) | |
(comp/set-query* ; do we need to re-index? But our `state` is likely not `@(:state app)` | |
TopRouter | |
{:query [::dr/id | |
;[::uism/asm-id router-id] | |
{::dr/current-route (comp/get-query AlternativeTarget state)}]})) | |
script-tag (ssr/initial-state->script-tag state') | |
props (denorm/db->tree (comp/get-query Root) | |
state' | |
state') | |
;_ (do (app/set-root! app Root {:initialize-state? true})) | |
app (app/fulcro-app {:initial-db state'}) | |
html (binding [comp/*app* app] | |
(dom/render-to-str ((comp/factory Root) props)))] | |
(str | |
script-tag | |
"\n" | |
html))) | |
(comment | |
(server-render) | |
,) |
Here are some functions for working with Fulcro dynamic routers that might be useful - most of them work without React/active mount.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tony comments:
I.e. you want to init routing and UISMs similarly to what the fulcro-rad-demo init does but in clj. Notice that it also triggers the
fix-route
mutation, which callsrouting/route-to!
(RAD's thin wrapper ofdr/change-route!
) to display the desired routers based on the current URL. As Tony explains, if any of those does anydf/load!
or similar, you also want to register a server-side "remote" with the app so that those would work.