Fork me on GitHub
#reitit
<
2020-08-12
>
ramblurr11:08:38

I'm looking for an example of using reitit on the frontend and backend, where the frontend is an SPA and does not use hash fragments but normal urls. I can't quite figure out how to have the backend serve the frontend on any un-matched route, while still reserving certain routes for the backend (like /api)

tkjone13:08:42

Hey hey! I asked a similar question a little while back and this is what I came up with: https://gist.github.com/athomasoriginal/14c6cfa1500bc1ab1a90a98b9d7217a0 - let me know if this helps!!

valtteri13:08:10

I have nginx sitting in front that redirects 404s to index.html. I guess you could achieve the same with a default handler that always returns index.html. If you’re using reitit-ring, you can provide the default-handler when creating the router.

tkjone13:08:34

The general idea is that you have a main set of routes, if anything is not matched by those, you can use the default handler and add in another route check.

tkjone13:08:47

This is another good place to go to checkout other examples: https://github.com/metosin/reitit/tree/master/examples

ramblurr15:08:33

@ thanks! your example works great.

ramblurr15:08:36

On the frontend side however, how do you initialize when landing on a nested (non-root /) route? I'm using re-frame. The backend is serving the SPA properly now on any path, but on the frontend itself reitit isn't matching the path when I enter the page at a non root path (that is, / works client side but /something/deeper doesn't)

tkjone15:08:35

Do you have a simple example of your routing setup + entry point to your app?

tkjone15:08:48

Example: this is another simple example of handling front end routing: https://gist.github.com/athomasoriginal/eadc022482c3432943c400cc8eeb1788

ramblurr15:08:01

importantly i'm also using :use-fragment false

tkjone15:08:46

Yeah, the above example should also work with HistoryAPI

ramblurr15:08:07

(def router
  (reitit/router
    [""
     ["/" {:name :home :view #'home-ui}]
     ["/something-else" {:name :home :view #'another-ui}]]
    {:compile coercion/compile-request-coercers}))

(defn navigate! [match _]
  (rf/dispatch [:common/navigate match]))


(defn start-router! []
  (rfe/start!
   router
   navigate!
   {:use-fragment false}))

(start-router!)

tkjone15:08:43

What’s navigate! doing?

ramblurr15:08:41

(this is from the luminus project generation with +re-frame)

ramblurr15:08:11

(added the navigate! function)

tkjone15:08:55

Yeah, so I just want to see what navigate! is doing. For example, in the gist I provided, mine just updates the match atom. The general idea is i’m trying to isolate where something is going wrong. A quick way to do that is to see if the problem is in your routing logic (reitit) (in my example, routes) or is the problem in the app entry point (in my example current-page)

ramblurr15:08:12

so browsing to / loads the :home route, but navigating to /something-else loads a blank page as the match is nil.

ramblurr15:08:40

but that only happens on a fresh page load.

ramblurr15:08:54

if i load / and then click a button to something-else it works

ramblurr15:08:14

Should I be seeding it with the initial window location or does reitit frontend pick that up?

ramblurr15:08:53

navigate! is called with a nil value for match when browsing to /something-else

tkjone15:08:43

It should pickup on it. The idea is: • page loads • the url is read + passed to reitit • reitit matches • the match is passed to Reagent I’m not an expert with reitit yet, but can you try updating your routing structure to

[["/" {:name :home :view #'home-ui}]
 ["/something-else" {:name :home :view #'another-ui}]]
Also, why add the #' (var quote) in front of your :views?

pithyless13:08:47

I'd like to extend reitit.http.coercion/coerce-request-interceptor to also check additional :env data I attach during the processing of a request (think of dynamic per-request things like db and cache connections, etc). Ideally, I'd just re-use the existing reitit-malli plumbing for coercion, but that's only checking for specific keys: https://github.com/metosin/reitit/blob/master/modules/reitit-core/src/reitit/coercion.cljc#L37-L42 This doesn't seem like a far-fetched feature requests - perhaps someone has already done this? Not sure if I should just write a new interceptor, extend the existing malli-coercion interceptor with new ParameterCoercion keys, or perhaps just hack and piggyback on an existing params key.

ilyab15:08:24

Hi, is there something like compojure's wrap-routes in reitit? https://weavejester.github.io/compojure/compojure.core.html#var-wrap-routes

ikitommi15:08:05

@ilyab you can do ~same by mounting middleware to specific routes or methods, so no.

pithyless15:08:58

@ikitommi thanks for the pointer!

ikitommi15:08:51

wrap-routes caused lot of troubles with nginx-clojure back in the days.

ilyab15:08:59

Thanks @ikitommi!

haywood19:08:50

anyone using reitit frontend easy with Html5History and have back / forward buttons ‘just working’? Should I be calling pushState myself in my on-navigate function?

haywood19:08:25

how do I get <a href="" tags to not cause a page refresh?