Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,15 @@ const routeConfig = {
tagName: 'APP-USER-PAGE',
path: '/users/:userId([0-9]{1,6})',
params: ['userId'],
beforeEnter: () => import('../app-user-page.js')
beforeEnter: () => import('../app-user-page.js'),
metaData: { title: 'User Page' }
}, {
id: 'app-user-account',
tagName: 'APP-ACCOUNT-PAGE',
path: '/users/:userId([0-9]{1,6})/accounts/:accountId([0-9]{1,6})',
params: ['userId', 'accountId'],
beforeEnter: () => import('../app-account-page.js')
beforeEnter: () => import('../app-account-page.js'),
metaData: {title: 'Account Page', layoutMode: 'single-column' }
}, {
id: 'app-about',
tagName: 'APP-ABOUT',
Expand All @@ -156,6 +158,16 @@ Example:

When using this method the default is that a route requires authentication, as shown above in the 'about' route, set `authenticated` to false to create a route which does not require authentication.

## RouteConfig metaData
The `metaData` property of a route allows you to attach arbitrary data to a route. This can be useful for storing information such as page titles, layout modes, or any other custom data that you may need to access when the route is activated. You can access this metaData in the `routeEnter` method of your component by retrieving the destination node from the router's route tree.

```javascript
const destinationNode = this.router.routeTree.getNodeByKey(routeId);
const metaData = destinationNode.getValue().metaData || {};
// do something with metaData
// ...
```

## Redirecting

To programmatically redirect to a page, use `router.go()`:
Expand Down
7 changes: 7 additions & 0 deletions demo/src/components/base-route.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ class BaseRoute extends routingMixin(LitElement) {
console.log('Context:', context);

this.activeRouteId = routeId;
// reference the metaData to set the document title
const destinationNode = this.router.routeTree.getNodeByKey(routeId);
const metaData = destinationNode.getValue().metaData || {};
if (metaData.title) {
document.title = metaData.title;
}
// Log the active route ID
console.log('Active route ID:', this.activeRouteId);

}
Expand Down
7 changes: 7 additions & 0 deletions demo/src/js/route-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,40 +29,47 @@ export const ROUTE_CONFIG = {
id: ROUTE_IDS.DASHBOARD,
path: ROUTE_PATHS.DASHBOARD,
tagName: 'dashboard-route',
metaData: {title: 'Dashboard'}
}, {
id: ROUTE_IDS.SECTION_A,
path: ROUTE_PATHS.SECTION_A,
tagName: 'section-a-route',
metaData: {title: 'Section A'},
subRoutes: [
{
id: ROUTE_IDS.SECTION_A1,
path: ROUTE_PATHS.SECTION_A1,
tagName: 'section-a1-route',
params: ['sectionAId'],
metaData: {title: 'Section A1'}
}
],
}, {
id: ROUTE_IDS.SECTION_B,
path: ROUTE_PATHS.SECTION_B,
tagName: 'section-b-route',
metaData: {title: 'Section B'},
subRoutes: [
{
id: ROUTE_IDS.SECTION_B1,
path: ROUTE_PATHS.SECTION_B1,
tagName: 'section-b1-route',
params: ['sectionB1Id'],
metaData: {title: 'Section B1'}
},
{
id: ROUTE_IDS.SECTION_B2,
path: ROUTE_PATHS.SECTION_B2,
tagName: 'section-b2-route',
params: ['sectionB2Id'],
metaData: {title: 'Section B2'},
subRoutes: [
{
id: ROUTE_IDS.SECTION_B2A,
path: ROUTE_PATHS.SECTION_B2A,
tagName: 'section-b2a-route',
params: ['sectionB2Id', 'sectionB2AId'],
metaData: {title: 'Section B2A'}
}
],
}
Expand Down
5 changes: 3 additions & 2 deletions lib/route-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ class RouteData {
* converted to a map of camelCase and hyphenated.
* @param {boolean=} requiresAuthentication
* @param {BeforeEnter=} beforeEnter
* @param {!Object<string, *>=} metaData optional metadata associated with this route
*/
constructor(id, tagName, path, namedParameters, requiresAuthentication, beforeEnter) {
constructor(id, tagName, path, namedParameters, requiresAuthentication, beforeEnter, metaData = {}) {
namedParameters = namedParameters || [];
/** @type {!Object<string, string>} */
const params = {};
Expand All @@ -36,7 +37,7 @@ class RouteData {
this.tagName = tagName;
this.path = path;
this.attributes = params;

this.metaData = metaData;
/** @type {!Element|undefined} */
this.element = undefined;
this.requiresAuthentication = requiresAuthentication !== false;
Expand Down
5 changes: 3 additions & 2 deletions router.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
* params: (Array<string>|undefined),
* authenticated: (boolean|undefined),
* subRoutes: (Array<RouteConfig>|undefined),
* beforeEnter: (function():Promise)
* beforeEnter: (function():Promise),
* metaData: (Object<string, *>|undefined)
* }} RouteConfig
*/
let RouteConfig;
Expand Down Expand Up @@ -99,7 +100,7 @@ class Router {
/** @param {!RouteConfig} routeConfig */
buildRouteTree(routeConfig) {
const authenticated = [true, false].includes(routeConfig.authenticated) ? routeConfig.authenticated : true;
const node = new RouteTreeNode(new RouteData(routeConfig.id, routeConfig.tagName, routeConfig.path, routeConfig.params || [], authenticated, routeConfig.beforeEnter));
const node = new RouteTreeNode(new RouteData(routeConfig.id, routeConfig.tagName, routeConfig.path, routeConfig.params || [], authenticated, routeConfig.beforeEnter, routeConfig.metaData || {}));
if (routeConfig.subRoutes) {
routeConfig.subRoutes.forEach(route => {
node.addChild(this.buildRouteTree(route));
Expand Down
8 changes: 8 additions & 0 deletions test/router-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,14 @@ describe('Router', () => {
expect(subRoutes[0].getValue().requiresAuthentication).toBe(true);
expect(subRoutes[2].getValue().requiresAuthentication).toBe(false);
});

it('should set metaData to to the correct values', () => {
const routeTree = router.buildRouteTree(testRouteConfig);
const subRoutes = routeTree.getChildren();
expect(subRoutes[0].getValue().metaData).toEqual({title:'User Page'});
expect(subRoutes[1].getValue().metaData).toEqual({});
expect(subRoutes[2].getValue().metaData).toEqual({});
});
});

describe('url()', () => {
Expand Down
1 change: 1 addition & 0 deletions test/utils/test-route-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const testRouteConfig = {
path: '/users/:userId([0-9]{1,6})',
params: ['userId'],
beforeEnter: (currentNode, nextNodeIfExists, routeId, context) => Promise.resolve(),
metaData: {title:'User Page'}
}, {
id: 'app-user-account',
tagName: 'APP-ACCOUNT-PAGE',
Expand Down