Routing using reflex-dom without Obelisk (or how to get Obelisk working)

I have a reflex SPA that’s working fine but now I need to do routing.

I’m using Obelisk but I cannot use their router because while it’s working fine using ob run, after I build my application via nix-build -o frontend-result -A ghcjs.frontend it won’t run - the generated app fails with the following error:

reflex-dom warning: hydration failed: the DOM was not as expected at switchover time. This may be due to invalid HTML which the browser has altered upon parsing, some external JS altering the DOM, or the page being served from an outdated cache.

It says warning but after that it says can't access property parentNode of undefined or something.

This error will even appear on a brand new application using ob init so I’ve completely given up.

Eventually I’ve landed onto the following setup:

  • I have a frontend :: Frontend route in my Frontend.hs only to get ob run to function (it won’t otherwise)
  • My main is using mainWidgetWithHead to get around the hydration error

That has been working fine for a few months but now I’m completely lost with routing.

  • I tried using the router from reflex-dom-contrib but I couldn’t even add the dependency.
  • I tried copying the code from reflex-dom-contrib and I got some parts of it working but while it “works” using ob run I can’t get the application to compile because it says jsaddle doesn’t have a GHCJS.Foreign module (even though HLS with cabal will find it just fine)
  • I tried adapting the 6 years old servant-router to work for my use case without success.
  • I really tried getting the Obelisk setup to run but as mentioned above, even with a brand new application it will throw the hydration error and fail. This user had the same issue 3 years ago but never posted about a resolution.

Routing is such a common thing to do I’m finding it very hard to believe that this isn’t a solved problem, but I’m probably missing something.

Hey, Its probably a year too late, but I find myself facing the same issue.

Ive been trying for a few days now to get a basic routing with auth set up. I avoided Obelisk because it seemed very opinionated towards nixos and aws for deployments so I took a reflex-platform approach. I finally implemented a basic routing with set up, but now im trying to incorporate the router from the reflex-dom-contrib as it looks to have really nice features.

I also couldnt get reflex-dom-contrib to work as a library, I was thinking about trying to fix the nix package but decided to simply import the code I wanted directly. In the Router.hs most of it worked out of the box with the exception of HasJsContent this is from Foreign.JavaScript.TH .

The api of this library and for this type has changed at least twice since the router.hs in contrib was written first to HasJS and now to JSContextSingleton. Unfortunately its not as easy as just changing the name, Im guessing the Singleton was introduced in an effort of efficiency, tbh I need to do some research and understand the implementation a bit better.

Regardless when I find a fix I will make a PR to contrib but at this stage ive had to change so much I might create a new standalone library with a subset of the essential features that will be easier to maintain into the future.

If anyone comes across this and has an interest please let me know.

I don’t actively work on this project anymore but I remember that the solution I ended up with was literally copying the code from arohi-route-client and adapting it to work with my codebase.