A simple page decorator that integrates with LitElement to handle routing in single-page applications.
npm install lit-page
Use the @page
decorator, which is provided by the Router
instance, to create pages and associate them with routes:
import { html } from 'lit';
import { property } from 'lit/decorators.js';
import { Router } from 'lit-page';
// Create a Router instance and extract the `page` decorator and `initialize` function
const { page, initialize } = Router({ target: 'body', routing_type: 'hash' });
// Define Home Page
@page({ tag: 'home-page', routes: ['/'] })
class HomePage {
render() {
return html`<h1>Welcome to the Home Page</h1>`;
}
}
<!-- Initial DOM when on / -->
<body>
<home-page>
<!-- Shadow DOM from <home-page> -->
<h1>Welcome to the Home Page</h1>
<!-- End Shadow DOM -->
</home-page>
</body>
// Define Login Page with a dynamic route parameter
@page({ tag: 'login-page', routes: ['/login', '/login/:callback'] })
class LoginPage {
@property({ type: String }) callback = '';
render() {
return html`<p>Callback: ${this.callback}</p>`;
}
}
<!-- DOM after navigating to /login/abc123 -->
<body>
<login-page callback="abc123">
<!-- Shadow DOM from <login-page> -->
<p>Callback: abc123</p>
<!-- End Shadow DOM -->
</login-page>
</body>
// Define 404 Page to handle unknown routes
@page({ tag: 'page-404', routes: ['/404'] })
class NotFoundPage {
render() {
return html`<h1>404: Page Not Found</h1>`;
}
}
<!-- DOM when no matching route is found -->
<body>
<page-404>
<!-- Shadow DOM from <page-404> -->
<h1>404: Page Not Found</h1>
<!-- End Shadow DOM -->
</page-404>
</body>
When no route matches the current path, the /404
route is used to render the 404 page automatically. There is no need to navigate to it manually.
To manually navigate to a specific route, use the navigate
function:
const { navigate } = Router({ target: 'body', routing_type: 'hash' });
navigate('/login/abc123');
This would update the DOM like so:
<!-- DOM after manually navigating to /login/abc123 -->
<body>
<login-page callback="abc123">
<!-- Shadow DOM from <login-page> -->
<p>Callback: abc123</p>
<!-- End Shadow DOM -->
</login-page>
</body>
Initialize the router by calling the initialize
function:
initialize();
This setup defines the custom elements and sets up routing based on the configuration provided in the Router
instance.
Note: To keep your project organized, you can extract the router setup into a separate file like router.ts
and then import the page
, initialize
, and navigate
functions where needed. This is how you can structure it:
src
├── router.ts
├── index.ts
// router.ts
import { Router } from 'lit-page';
const { page, initialize, navigate } = Router({ target: 'body', routing_type: 'hash' });
export { page, initialize, navigate };
This allows you to simply import these functions into your components:
// index.ts
import { initialize } from './router';
// Import pages
import './pages/404';
import './pages/home';
import './pages/login';
initialize();
This way, your routing configuration is centralized, making it easy to maintain and update.