Routing
Routing is handled by the framework in a similar way to express routing. A list of routes with paths is provided by the application, and Tungsten matches the current request against these routes
The application can provide a simple routes objects, or a function that received the request and response objects from express during server side render, or null during client side navigation
// routes.tsximport { Home } from './pages/Home.jsx'import { Profile } from './pages/Profile.jsx'export routes = {'/': {content: <Home />},'/profile': {content: <Profile />}}
The routes file is assumed to be routes.jsx within your code directory, and the export is assumed to be routes or the default export. If either of these are different you must specify this in the tungsten config, for example:
// tungsten.config.jsexport default {...routesLocations: ['client/routes.jsx', 'getRoutes']}
Typing routes
The basic type for a route is Route<Params extends object, Data>. It is often useful to add additional properties to your routes, to do this you can create your own Route type extending the Route type in Tungsten. You can also create a Routes type using the CustomRoutes helper, providing your route type as a type parameter.
// routes.tsximport { Route, CustomRoutes } from 'tungsten'type AppRoute<Params extends object, Data> = Route<Params, Data> & {name: stringinNav: boolean}type AppRoutes = CustomRoutes<AppRoute<any, any>>
To preserve information about our routes, we don't define are routes as the AppRoutes, instead creating it with as const, indicating that it will not change, and saving its exact type. We ensure compliance with the AppRoutes type using satisfies
// routes.tsximport { Route, CustomRoutes } from 'tungsten'import { Home } from './pages/Home.jsx'import { Profile } from './pages/Profile.jsx'type AppRoute<Params extends object, Data> = Route<Params, Data> & {name: stringinNav: boolean}type AppRoutes = CustomRoutes<AppRoute<any, any>>export routes = {'/': {content: <Home />},'/profile': {content: <Profile />}} as const satisfies AppRoutes
Route Params
Like in express, routes can have parameters
export routes = {// ...'/post/:id': {content: (_, { id }: ParamsFromPath<'/post/:id'>) => <Post id={id} />}} as const satisfies AppRoutes
A param like :id is converted into a regular expression match group that matches everything up to the next slash or end of line. A specific regular expression match can be substituted after the param, e.g. '/post/:id(\\d+)/'. The first backslash escapes the first which is needed within a JS string literal, giving (\d+). \d matches any digit and + requires 1 or more. A path that does not meet this pattern will not match, and other routes will be searched for a match instead.
To Do: Code splitting (to be completed)
The above code will bundle the site together, loading everything into the browser on first load. This works well for small sites, but could become problematic for very large sites.
There is a plan to enable code-splitting, which is separating some pages into a different bundle, and either loading these only when required, or eager-loading them (loading the extra bundle after the current page is loaded, possible only on pages that are likely to lead to pages that require the additional bundle).
Splitting would be activated by specifying that the content for that route is to be split, in a way yet to be decided.
This feature has not been implemented yet