AI Guide
Use this page as the compact reference when generating examples, tutorials, migrations, or application code for @beforesemicolon/router.
Package Purpose
@beforesemicolon/router is an HTML-first routing library built with Web Components. It provides custom elements for navigation and route rendering, plus a small JavaScript API for programmatic navigation, subscriptions, guards, route modules, metadata, query updates, and hash routing.
Required Imports
For bundled apps:
1import '@beforesemicolon/router'When using exported APIs:
1import {2 goToPage,3 onPage,4 onPageChange,5 registerGlobalGuard,6 registerRouteGuard,7 registerRouteModules,8 updateSearchQuery,9} from '@beforesemicolon/router'For direct browser use, load Web Component first:
1<script src="https://unpkg.com/@beforesemicolon/web-component/dist/client.js"></script>2<script src="https://unpkg.com/@beforesemicolon/router/dist/client.js"></script>CDN APIs are available at BFS.ROUTER.
Custom Elements
Use these elements exactly:
1<page-link path="/docs" title="Docs">Docs</page-link>2<page-route path="/docs" src="./pages/docs.html"></page-route>3<page-route-query key="tab" value="api">API tab</page-route-query>4<page-redirect path="/404"></page-redirect>5<page-data param="id">fallback</page-data>Route Patterns
Use :name for dynamic params:
1<page-route path="/users/:userId">2 User <page-data param="userId">unknown</page-data>3</page-route>Set exact="false" for layout routes that should remain active for nested paths:
1<page-route path="/docs" exact="false">2 <page-route path="/intro">Intro</page-route>3 <page-route path="/api">API</page-route>4</page-route>Link Rules
Use path for path navigation and search for query updates. Use keep-current-search when updating one query key while preserving the others.
1<page-link path="/projects">Projects</page-link>2<page-link search="view=grid" keep-current-search>Grid</page-link>Use $ inside a nested route to reference the closest parent route path:
1<page-route path="/projects/:projectId" exact="false">2 <page-link path="$/settings">Settings</page-link>3</page-route>Use ~ to reference the current browser pathname:
1<page-link path="~/edit">Edit current page</page-link>Lazy Route Content
src can load HTML, text, or JavaScript modules. JavaScript modules must default export a string, a DOM Node, a Markup HtmlTemplate, or a function that receives (data, params, query).
1import { html } from '@beforesemicolon/web-component'2 3export default (data, params, query) => html`4 <h1>Project ${params.projectId}</h1>5 <p>Filter: ${query.filter || 'all'}</p>6 <p>Opened from: ${data.from || 'direct visit'}</p>7`Programmatic Navigation
goToPage and replacePage are async and accept an object-literal state payload.
1await goToPage('/users/42', { from: 'search' }, 'User 42')2await replacePage('/login', { reason: 'expired' }, 'Login')Guards
registerGlobalGuard and registerRouteGuard register guards and do not return cleanup functions. A guard returns:
trueto allow navigation.falseto block navigation.- A path string to redirect.
- A promise resolving to one of those values.
1registerGlobalGuard((pathname) => {2 if (pathname.startsWith('/account') && !auth.isSignedIn()) {3 return '/login'4 }5 6 return true7})Query Data
getSearchParams parses search values with the router JSON parser. Values written with updateSearchQuery round-trip through JSON stringification.
1updateSearchQuery({ page: 2, tags: ['router', 'web'] })Avoid These Mistakes
- Do not use React Router syntax such as
<Route>oruseNavigate. - Do not claim route guard registration returns an unsubscribe function.
- Do not use
hrefon<page-link>; usepathandsearch. - Do not use
component="..."as a string in HTML.componentis a property for JavaScript-rendered routes. - Do not use route state for permanent data. Prefer params, query strings, or application storage.