dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

Router: Hash support for the web

Open comcloudway opened this issue 3 years ago • 11 comments

Specific Demand

Right now the Router has no hash support for the web, which means that if the server does not redirect every request to the index.html file, a user visiting the /new route, without visiting the / route first, will be greeted by a 404 Error code.

Instead there should be the option to specify # as the route root, or maybe have a HashRouter for the web. This would allow single page operations.

Using the current router Using a hash router
/ /#/
/new /#/new
/posts/:id /#/posts/:id

Implement Suggestion

As far as I can tell, the router currently works using the history, but a hash change is not committed to history. But one might be able to use the onhashchange callback to update the router. And then either the current Link { to: "/#" } coult be used to change it, or there could be a method in the use_route hook to change the current route (would support navigation after e.g. a web request (without using web_sys::location::set_pathname())

I don't think it is that hard to implement and if I find the time I might write a stand alone library (no promises though)

comcloudway avatar Apr 11 '22 07:04 comcloudway

Yes! I think this is important!

mrxiaozhuox avatar Apr 11 '22 11:04 mrxiaozhuox

In this project: https://github.com/mrxiaozhuox/diogen I have write the hash-router by myself. This is an important feature!

mrxiaozhuox avatar Apr 11 '22 11:04 mrxiaozhuox

Looks like a great starting point, but I guess we should be using the Context feature, so one would be able to do

rsx!(
HashRouter {
Route {},
Route {}
}
)

Unless I'm missing something (not sure why you chose Atoms over Context [I'm guessing the feature didn't exist at that point? Can't tell, this projects website/docs seem broken in a lot of places - still prefer dioxus over react])

EDIT: Fixed the formatting

comcloudway avatar Apr 11 '22 11:04 comcloudway

If I or someone else implemented this feature, would it be merged into the current router or should the person write a separate library (e.g. dioxus-web-hashrouter).

If it is going to be merged, I probably would have to fork this repo to change the files I guess? Why is the router in the packages folder? I mean you guys could have separated all these modules into separate git repos, would have made small contributions a lot easier (although I see, that it would be harder to manage)

comcloudway avatar Apr 11 '22 11:04 comcloudway

If I or someone else implemented this feature, would it be merged into the current router or should the person write a separate library (e.g. dioxus-web-hashrouter).

If it is going to be merged, I probably would have to fork this repo to change the files I guess? Why is the router in the packages folder? I mean you guys could have separated all these modules into separate git repos, would have made small contributions a lot easier (although I see, that it would be harder to manage)

If you have a PR to add this feature, it's will be merged to dioxus repo.

mrxiaozhuox avatar Apr 11 '22 11:04 mrxiaozhuox

Small update

I've rewritten parts of the router service and replaced the old path based router with a HashRouter. I also edited the route_matches_path function to allow for easier path comparison, by filtering out empty segments (e.g. //// is the same as /).

Disclaimer

I haven't finished implementing everything yet, which is why the code hasn't been cleaned up. I also haven't tested if the Router still works in the non-web version, but I plan on doing that before doing a PR.

Progress & Problems

As I stated above, not everything is working properly. I'm currently testing with an admin panel I'm working on, which is why I can't open source the testing repo, but it has a lot of different navigation techniques build in, so I'm able to find bugs.

Route does it work? / notes
/ works
/new works
/c/:id does not work: route_matches_path returns the correct value, but the element is not being rendered, no error is being thrown
Redirect {} works
Link {} seems to be broken, not sure though, might be my code

Check my progress here

Future plans

I'm putting this on hold for a couple of days, because I want to write my own router implementation from the ground up, to be able to compare the two. I hope that this way I'm able to determine if an error is caused by my rust code or web assembly.

After finishing or stopping development of my own router, I plan on finishing the code to get a PR ready. I'm not sure if replacing the old web router entirely was a good idea, but that way I didn't have to add a router_type: WebRouterType option to the RouterCore.

As always I'll keep you updated

EDIT: Expanded Note for /c/:id route

comcloudway avatar Apr 12 '22 12:04 comcloudway

May Update

I finished writing my own router implementation only to learn that nearly no std::sync feature is supported at the moment, which meant that I could not implement my Router into a component. This means that I probably wont continue working on this unless I find a way to work without Mutexs or thread safety is implemented.

EDIT: I noticed that the current router is using a futures-channel library - maybe I'll try that out in the future.

EDIT: Update

I finally got futures and cells figured out and am working on an alpha version now

comcloudway avatar May 07 '22 07:05 comcloudway

I'm happy to announce that I was in fact successful in porting my router core to a system without using threads.

Introducing: Roux

And I'm finally able to release my own router: dioxus-roux. In case you want to track the development of it, I host it over on codeberg.org as it is not meant to be merged (the router code bases are totally different).

Roux allows the user to add as many back-ends as they wish, and even specifying custom back-ends is possible. (Only a web hash back-end is available at the moment).

Conclusion

As I'll probably be working on my own router, I will probably not finish the PR anytime soon (I haven't worked on it since then, but the hash router is working in my dioxus fork). Which is why I think, that we should be closing this.

comcloudway avatar May 08 '22 13:05 comcloudway

Since when this issue was opened, many things changed. I guess it's an important thing to bring back, given the newly written April 2023 dioxus router is still url based and hashes can't be used.

https://dioxuslabs.com/blog/release-040#enum-router

MassiminoilTrace avatar Nov 16 '23 18:11 MassiminoilTrace

A hash router is partially implemented (but currently commented out) here

ealmloff avatar Nov 16 '23 18:11 ealmloff