Support router integrations of solid-app-router
example usage: src/entry-client.tsx
import { render } from "solid-js/web";
import { hashIntegration } from "solid-app-router";
import { StartClient } from "solid-start/entry-client";
render(() => <StartClient routerIntergration={hashIntegration} />, document.body);
example change: packages/start/entry-client/StartClient.tsx
import { MetaProvider } from "solid-meta";
import { Router } from "solid-app-router";
import { StartProvider } from "../entry-server/StartContext";
import Root from "~/root";
const rootData = Object.values(import.meta.globEager("/src/root.data.(js|ts)"))[0];
const dataFn = rootData ? rootData.default : undefined;
// typeof routerIntergration = RouterIntegration | undefined
// TODO: validate routerIntergration
export default ({ routerIntergration }) => {
return (
<StartProvider>
<MetaProvider>
<Router source={routerIntergration && routerIntergration()} data={dataFn}>
<Root />
</Router>
</MetaProvider>
</StartProvider>
);
};
I hardcoded hashIntegration from the above solution, the outcome looks good to me
I've been thinking about exposing this more. The challenge in Solid is that component depth affects hydration so I sort of didn't want to expose the context tree. I'm thinking though this might be better to just do. But yeah now that we support client only mode I think having the ability to do hash routing makes sense.
@rturnq Could you review this once and see if its okay to do, and if there is anything we should consider specially? Otherwise I'll implement it as suggested
Is this still under consideration? Or is there another way to use "hashIntegration" with solid-start
I also have a need to do hash routing. My SolidStart app be loaded into another app as a "widget", hence, I don't want to modify the main url path.
dug through the code and concluded the easiest change is to add a prop to <StartClient
It could be more intuitive let users to see this in their generated root.tsx:
<Router>
<Routes>
<FileRoutes />
But idk. SolidStart's router has it's own intricacies. Maybe we expose a StartRouter instead, and only allow certain props to be passed in.
I don't mind passing something into StartClient, because reading and writing the apps state to the browsers url is a very global thing by nature....
~...but... If we are passing something into StartClient we'll need to pass something into StartServer. With that, arises questions about client vs server routing semantics... I think ultimately people will just keep creating issues asking how to customize router props.~
UPDATE: It seems StartServer will use staticIntegration, we should be able to use anything client side.
I think it's good to maintain a simple path spec for routing across application code, although the underlying implementation of reading/writing to browser url needs to be customizable.
Glancing at the code for a few seconds, it seemed reasonable to shift <Router> into root.tsx.
====
While I think code that necessitates more docs (prop passed to <StartClient is less good than code that doesn't necessitate more docs (<Router> exposed in generated root.tsx), in this case I view it as necessary because I'm coming from 5 years with react, where all those apps had a <Router> component around the root of the application.
Even if there was a <Router> in my generated root.tsx, I probably would still have searched Google for "solid.js/SolidStart hash routing" to find out what the prop is, at least.
I don't know what the performance cost is, but the cost in dx is very tiny imo. Adding a prop to <StartClient seems best.
I've been thinking about exposing this more. The challenge in Solid is that component depth affects hydration so I sort of didn't want to expose the context tree. I'm thinking though this might be better to just do. But yeah now that we support client only mode I think having the ability to do hash routing makes sense.
Although hash routing would work for my use case, I'd definitely prefer a kind of query string/searchParams based routing mechanism. I think it only really makes sense when embedding solid into larger apps.
I got this crazy "micro-app" thing mostly working, and noticed an issue related to routing/paths. I think once scripts start hydrating the app, Solid router see's that the current route is not what the server originally rendered for. it's converting to a 404 because the consuming host doesn't have the url I
fetch()d.
UPDATE: I've hide this issue for now by creating a catch-all route in my "demo host app".
I guess what I really need this minute is a "memory" router. We could also create a sessionStorageIntegration which is the same thing as the memory router already implemented, but uses sessionStorage to persist route across page reloads. Could look like:
<StartClient
routerIntegration={
sessionStorageIntegration({
sessionStorageKey: 'chatWidgetUiRoute'
})
}
>
Note that sessionStorage is per-tab, just like urls
I think a prop passed to <StartClient and <StartServer should be pretty easy, but would we then have some duplication across client/server? Maybe for hash/memory/sessionStorage routing, would we only need to pass something into <StartClient and not <StartServer?
And ryan said this will have an effect on hydration... I don't even know if hard-coding in a different router source will even work...
@nksaraf @ryansolid @zackpi @timbasel @arksun-bc @rturnq - I have opened a PR here: https://github.com/solidjs/solid-start/pull/1026