fable-lit-fullstack-template icon indicating copy to clipboard operation
fable-lit-fullstack-template copied to clipboard

Question - How to handle router that was fully typed from the browser?

Open leolorenzoluis opened this issue 3 years ago • 15 comments

Not familiar with Graphnel, but if a user types in the address bar the full URL then it won't obviously load the correct page. I haven't tried looking deep into the library but just leaving this here maybe you've already solve it.

leolorenzoluis avatar Sep 27 '22 05:09 leolorenzoluis

The latest version of the template is using a port of Fable.LitRouter instead of Grapnel. You should definitely be able to load a URL that is typed into the address bar manually.

Do you have an example of what is failing?

JordanMarr avatar Sep 27 '22 05:09 JordanMarr

Ahh I'll try that instead of Grapnel. Let me try that and will update

leolorenzoluis avatar Sep 27 '22 20:09 leolorenzoluis

@JordanMarr so I've updated using Fable.LitRouter. However, if I try to type in https://localhost:3000/cat-facts# I expect it to load to cats page but it goes to the home page instead.

leolorenzoluis avatar Sep 27 '22 21:09 leolorenzoluis

I'm using Elmish and I get the following error when I use

let ctx = Hook.useStore(AppContext.store)
let path = Hook.useRouter(RouteMode.Path)

My root is not HookComponent but instead something like this:

open Elmish
open Lit
type Model = ..
type Msg = ..
let init() = ..
let update msg model = ..
let view model dispatch = ..
open Lit.Elmish
Program.mkProgram initialState update view
|> Program.withLit "app-container"
|> Program.run

How do I use the router with Elmish?

leolorenzoluis avatar Sep 27 '22 21:09 leolorenzoluis

Sorry, I forgot you switched to use vanilla Elmish. Sadly, Fable.LitRouter will not work for your site because it requires a hook component. 🙁

You can still use Grapnel router (which should allow you to navigate directly to URLs). But personally, I find it much easier to use components, especially now that the template also includes the useStore hook which allows you to share state between components.

If you do decide to use a component + Fable.LitRouter, you can configure the router to use RouteMode.Path or RouteMode.Hash. My example uses RouteMode.Path which means you do not need to include the # in the URL.

JordanMarr avatar Sep 27 '22 21:09 JordanMarr

@JordanMarr Actually it worked when I wrapped something like this:

[<HookComponent>]
let view (model: Model) dispatch =

No error but not sure if there's side effects.

The reason I'm using vanilla elmish is because of

|> Program.withBridgeConfig (Bridge.endpoint socketEndpoint |> Bridge.withMapping ServerMsg)

If you could show me how to use that ^ without vanilla elmish i'll gladly switch to the Lit one.

So I did test but it's still not capturing the correct page when I type manually the URL. Still home page.

Update:

@JordanMarr - Looks like the side effect is that it keeps adding the "#" if I use Router.navigate lol. What is needed to make the Fable.LitRouter work with this pattern of Elmish?

leolorenzoluis avatar Sep 27 '22 22:09 leolorenzoluis

You just need to use Router.navigatePath when using RouteMode.Path.

JordanMarr avatar Sep 28 '22 06:09 JordanMarr

Ahh that did it. This might sound obvious to you but I don't know why it's adding # at the end? Is that intended?

I'm going to test out the url changed, but so far I think your Fable.LitReact works with the vanilla elmish...

leolorenzoluis avatar Sep 28 '22 06:09 leolorenzoluis

It wasn't obvious to me either. 😓 I ported it from Feliz.Router and it took me a while to realize that it has Hash and Path modes. It shouldn't be putting a hash in the path at all unless you are still using one of the Hash based methods. https://github.com/Zaid-Ajaj/Feliz.Router#using-path-routes-without-hash-sign

Glad that it's working!

I also changed it so that useRouter just returns a path, whereas the original project works a little differently. But it's still close enough that it might be worth perusing the documentation.

JordanMarr avatar Sep 28 '22 14:09 JordanMarr

Re: Elmish.Bridge / WebSockets

If it were me, I'd probably try to use the generated Fable client bindings for SignalR as this guy did here: https://github.com/chestercodes/fable-signalr-giraffe That would allow simply creating a SignalR hub manually on the client.

But overall, Fable.Bridge looks like a nice library, so maybe worth sticking with unless you enjoy F# science projects as I do. 🙂

JordanMarr avatar Sep 28 '22 15:09 JordanMarr

Awesome. Thank you. It's using the navigatePath now but still appending the # at the end. I think it's just my knowledge of being a web developer. I'm sure there's a reason why it appends # in the lib.

If you don't mind publishing the repo for the LitRouter so I can make some pull requests to make it work with Elmish :P. I could get the source from nuget but prefer Github :)

leolorenzoluis avatar Sep 29 '22 05:09 leolorenzoluis

That would be great.

You can find the repo here: https://github.com/JordanMarr/Fable.LitRouter

JordanMarr avatar Sep 29 '22 05:09 JordanMarr

Just curious: are you using anchor links or buttons for navigation?

I'm using buttons with a click event and I don't have any # added to the path:

<sl-button @click={fun _ -> Router.navigatePath("/")}>
    Home
</sl-button>
<sl-button @click={fun _ -> Router.navigatePath("/projects")}>
    Projects
</sl-button>

JordanMarr avatar Sep 29 '22 16:09 JordanMarr

Ah good catch that was it. Thank you!

leolorenzoluis avatar Sep 29 '22 19:09 leolorenzoluis

If you still want the look of a link, shoelace has a text button: https://shoelace.style/components/button?id=text-buttons

JordanMarr avatar Sep 30 '22 01:09 JordanMarr