Skip to content

Instantly share code, notes, and snippets.

@holyjak
Created January 22, 2021 11:30
Show Gist options
  • Save holyjak/6ead10c0b447e098026f3e24e4f1e519 to your computer and use it in GitHub Desktop.
Save holyjak/6ead10c0b447e098026f3e24e4f1e519 to your computer and use it in GitHub Desktop.
Experiments in Fulcro SSR with dynamic routers
(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)
,)
@holyjak
Copy link
Author

holyjak commented Aug 13, 2021

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