A Web Component router for Component Islands
Ferry is a simple, performant, and incrementally adoptable routing library built for and by web components.
pnpm add --save @auzmartist/ferry
<script type="module" src="node_modules/@auzmartist/ferry/dist/ferry.js"></script>
<!-- OR -->
<script type="module">
import '@auzmartist/ferry'
</script>
OR
import '@auzmartist/ferry'
Ferry exposes three components:
- route-r: router context - must wrap all routes
- route-c: route content - wraps routed content and shows/hides
- route-a: route anchor - link to a route
`<!-- Root Router -->
<route-r>
<nav>
<!-- Links To Routes -->
<route-a href="/">Home</route-a>
<route-a href="/about">About</route-a>
<route-a href="/about/more">More</route-a>
</nav>
<!-- Route Content (can be nested) -->
<route-c path="/"> Home Page </route-c>
<route-c path="/about">
About Page
<route-c path="/">Default Content</route-c>
<route-c path="/more">More Content</route-c>
</route-c>
</route-r>
By default, all routed content is loaded at once. However, you may want to only import what users see with 11ty/is-land
<route-r>
<nav>
<route-a href="/">Home</route-a>
<route-a href="/about">About</route-a>
<route-a href="/about/more">More</route-a>
</nav>
<route-c path="/">
<!-- Eagerly Imported -->
<view-home></view-home>
</route-c>
<!-- Imported Only Once Active (on:visible) -->
<route-c path="/about" import="/src/views/view-about.ts">
<view-about></view-about>
</route-c>
</route-r>
Component Islands must be bundled as separate chunks in production. Ferry provides a Rollup plugin, compatible with Vite, for such use cases.
import ferry from '@auzmartist/ferry/plugin'
export default {
// rollup/vite config
plugins: [
// ...
ferry({
islands: ['/src/views/view-about.ts'],
}),
],
}
This will transform your <route-c>
imports to the appropriate output chunk so you only load the modules you need.
The plugin only transforms the root index.html file. Future improvements will allow for imports in nested routes from template strings.
The only limitation should be that your import paths are statically templated.