Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
leolorenzoluis opened this issue Sep 27, 2022 · 15 comments

Comments

@leolorenzoluis
Copy link

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.

@JordanMarr
Copy link
Owner

JordanMarr commented Sep 27, 2022

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?

@leolorenzoluis
Copy link
Author

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

@leolorenzoluis
Copy link
Author

@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
Copy link
Author

leolorenzoluis commented Sep 27, 2022

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?

@JordanMarr
Copy link
Owner

JordanMarr commented Sep 27, 2022

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.

@leolorenzoluis
Copy link
Author

leolorenzoluis commented Sep 27, 2022

@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?

@JordanMarr
Copy link
Owner

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

@leolorenzoluis
Copy link
Author

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...

@JordanMarr
Copy link
Owner

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
Copy link
Owner

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. 🙂

@leolorenzoluis
Copy link
Author

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 :)

@JordanMarr
Copy link
Owner

That would be great.

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

@JordanMarr
Copy link
Owner

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>

@leolorenzoluis
Copy link
Author

Ah good catch that was it. Thank you!

@JordanMarr
Copy link
Owner

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants