Routing
How to do routing in Jaspr.
A core feature of almost every website is routing between separate pages. With Jaspr you can use the core jaspr_router
package for a powerful routing system that adapts to your needs.
Setup
To start, add jaspr_router
to your project, use the Router component and provide a list
of Route
s:
import 'package:jaspr_router/jaspr_router.dart';
import 'pages/home.dart';
import 'pages/about.dart' ;
class App extends StatelessComponent {
@override
Iterable<Component> build(BuildContext context) sync* {
yield Router(routes: [
Route(path: '/', builder: (context, state) => Home()),
Route(path: '/about', builder: (context, state) => About()),
]);
}
}
See the Router docs for a full description of its API.
As with many Jaspr components, Router
can be used both on the server and on the client. However, there is an important
difference in routing behavior based on where it is rendered. Read the section below for more details.
Single-page vs multi-page routing
When creating a new Jaspr project, you can choose between two routing setups:
- multi-page (server-side) routing or
- single-page (client-side) routing.
This defined how navigating between routes will behave. With multi-page routing a "real" page load is performed when navigating to a new route (aka. the browser requests the new page using its url from the server). With single-page routing the routing happens purely on the client without any request to the server.
Usually you would choose multi-page routing for more "traditional" websites with multiple pages and single-page routing for more self-contained app-like websites.
There are different advantages and disadvantages for both types. To help you decide you can find many articles about this topic.
Flutter for example only does single-page routing.
To set up routing for either strategy is really straight forward:
-
For multi-page routing place the
Router
component in the section of the component tree where it is only pre-rendered on the server. For example if you are using @client components place theRouter
above these components in the tree.Since this requires pre-rendering, multi-page routing is only available with static or server mode.
If you are unsure about how the separation between server and client works, check out the Hydration docs, specifically the Separation of Environments section.
To navigate to a different page, use the Link component, which wraps the
<a>
html element.When using multi-page routing and the
Router
component is only rendered on the server, you cannot useRouter.of(context).push('/path)'
for navigating on the client as it would fail to locate theRouter
in the client-side component tree. -
For single-page routing place the
Router
in the client-rendered section of the component tree, i.e. below any @client components.To navigate to a different page, either use the Link component or call
Router.of(context).push('/path');
.When using client-side routing we recommend code-splitting your client bundle based on your routes to improve load times. See the section below for more details.
Route based code splitting
This is only relevant when using single-page routing.
For larger web apps, we don't want to load everything together, but rather split our pages into smaller chunks.
jaspr
can do this automatically using LazyRoutes
and deferred imports.
To use lazy routes, change the above code to the following:
import 'pages/home.dart';
import 'pages/about.dart' deferred as about;
class App extends StatelessComponent {
@override
Iterable<Component> build(BuildContext context) sync* {
yield Router(
routes: [
Route(path: '/', builder: (context, state) => Home()),
Route.lazy(path: '/about', builder: (context, state) => about.About(), load: about.loadLibrary),
],
);
}
}
This will lazy load the appropriate javascript files for the '/about' route when navigating to it.
Read more in the docs about Lazy Routes.