Routing

Migration from v0.9.x

Edit this page

v0.10.0 brings some big changes to support the future of routing including Islands/Partial Hydration hybrid solutions. Most notably there is no Context API available in non-hydrating parts of the application.

The biggest changes are around removed APIs that need to be replaced.


<Outlet>, <Routes>, useRoutes

These components are no longer present in the new router version. Instead, props.children is passed into the page components in the place of outlets. This keeps the outlet directly passed from its page and avoids trying to use context across Islands boundaries. Similarly, nested <Routes> components cause waterfalls and are <Outlets> themselves thus sharing the same concerns.

With no <Routes> means the <Router> API has changed. The <Router> component acts as the <Routes> component now and its children must now be <Route> components. The top-level layout should go in the root prop of the router as shown above


element prop removed from Route

Related without Outlet component it has to be passed in manually. At which point the element prop has less value. Removing the second way to define route components to reduce confusion and edge cases.


data functions & useRouteData

data functions & useRouteData have been replaced by a load mechanism. This allows link hover preloads, since the load function can be run as much as wanted without worrying about reactivity.

This supports deduping/cache APIs which give more control over how things are cached. It also addresses TypeScript issues with getting the right types in the Component without typeof checks.

That being said the old pattern can be reproduced by turning off preloads at the router level and then injecting your own Context:

import { lazy } from "solid-js";
import { Route } from "@solidjs/router";
const User = lazy(() => import("./pages/users/[id].js"));
// load function
function loadUser({ params, location }) {
const [user] = createResource(() => params.id, fetchUser);
return user;
}
// Pass it in the route definition
<Router preload={false}>
<Route path="/users/:id" component={User} load={loadUser} />
</Router>;

And then in your component taking the page props and putting them in a Context.

function User(props) {
<UserContext.Provider value={props.data}>
{/* my component content */}
</UserContext.Provider>;
}
// Somewhere else
function UserDetails() {
const user = useContext(UserContext);
// render stuff
}
Report an issue with this page