swtl
A Service Worker Templating Language (swtl) for component-like templating i...
README
swtl
Check out the swtl-starter app
A Service Worker Templating Language (swtl) for component-like templating in service workers. Streams templates to the browser as they're being parsed, and handles rendering iterables/Responses in templates by default.
- ```bash
- npm i swtl
- ```
Example
- ```js
- import { html, Router, CacheFirst } from 'swtl';
- import { BreadCrumbs } from './BreadCrumbs.js'
- function HtmlPage({children, title}) {
- return html`<html><head><title>${title}</title>head><body>${children}</body>html>`;
- }
- function Footer() {
- return html`<footer>Copyright</footer>`;
- }
- const router = new Router({
- routes: [
- {
- path: '/',
- render: ({url, params, query, request}) => html`
- <${HtmlPage} title="Home">
- <h1>Home</h1>
- <nav>
- <${BreadCrumbs} path=${request.url.pathname}/>
- </nav>
- ${fetch('./some-partial.html')}
- ${caches.match('./another-partial.html')}
- <ul>
- ${['foo', 'bar', 'baz'].map(i => html`<li>${i}</li>`)}
- </ul>
- <${CacheFirst} file="./some-file.html"/>
- <${Footer}/>
- <//>
- `
- },
- ]
- });
- self.addEventListener('fetch', (event) => {
- if (event.request.mode === 'navigate') {
- event.respondWith(router.handleRequest(event.request));
- }
- });
- ```
Router
Uses URLPattern internally for matching thepaths. The render callback gets passed the native [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object, as well as any route params or query params.
- ```js
- import { html, Router } from 'swtl';
- const router = new Router({
- routes: [
- {
- path: '/',
- render: () => html`<h1>Home</h1>`
- },
- {
- path: '/:foo',
- render: ({params}) => html`<h1>${params.foo}</h1>`
- },
- {
- path: '/:foo/:bar',
- render: ({params}) => html`<h1>${params.foo}/${params.bar}h1>`
- },
- {
- path: '/:foo/:bar',
- render: ({url, params, query, request}) => html`<h1>${params.foo}/${params.bar}h1>`
- },
- ]
- });
- self.addEventListener('fetch', (event) => {
- if (event.request.mode === 'navigate') {
- event.respondWith(router.handleRequest(event.request));
- }
- });
- ```
baseHref
You can also specify a baseHref, for example if your app is served under a specific base route, like https://my-app.com/foo/bar/:
- ```js
- const router = new Router({
- baseHref: '/foo/bar/',
- routes: [
- {
- // The url will be: https://my-app.com/foo/bar/
- path: '',
- render: () => html`<${Home}/>`
- },
- {
- // The url will be: https://my-app.com/foo/bar/users/1
- path: 'users/:id',
- render: ({params}) => html`<${User} id=${params.id}/>`
- }
- ]
- });
- ```
Note that you also have the set the base tag in your HTML:
- ```html
- <base href="/foo/bar/">
- ```
fallback
You can also provide a fallback in case no routes are matched. If you don't provide a fallback, the request will not be handled by the service worker, and go through to the network.
- ```js
- const router = new Router({
- routes: [
- {
- path: '/',
- render: () => html`<${Home}/>`
- }
- ],
- fallback: ({query, request}) => html`<${NotFound}/>`
- });
- ```