We are the Superlative Components!
- HTML first (The Rule of Least Power)
- Stay close to web standards
- Define and create a superlative component authoring experience
- Server language agnostic
A streaming web component bundler written in Rust using the lol-html parser.
The idea is to create a single-file HTML component format and builder that builds the HTML result super fast (streaming, low memory) and is server language agnostic.
- Streaming HTML bundler
- Web component definition
- Default and named slots with fallback content
- Declarative Shadow DOM
- CSS bundling
- JS bundling
wesc ./index.html
index.html
<!doctype html>
<html>
<head>
<link rel="definition" name="w-card" href="./components/card.html">
</head>
<body>
<w-card>
<h3 slot="title">Title</h3>
Description
</w-card>
</body>
</html>
components/card.html
<template>
<!-- or <template shadowrootmode="open"> -->
<style>
@scope {
h3 {
color: red;
}
}
</style>
<div>
<h3><slot name="title">Add a slotted title</slot></h3>
<p><slot>Add default slotted content</slot></p>
</div>
</template>
<style>
w-card {
display: block;
}
</style>
<!-- TODO: bundle to a global scripts.js -->
<script>
class WCard extends HTMLElement {
connectedCallback() {
console.log('w-card connected');
}
}
customElements.define('w-card', WCard);
</script>
Custom elements are a crucial part of reaching these goals. The first problem WeSC is aiming to solve is rendering DSD (declarative shadow DOM) in a simple and approachable way for most use cases.
Have a look at the examples to see if your use case is handled and feel free to open an issue if not.
- Cloudflare Worker (source)
- Eleventy (source)
- Astro (source)
- Next.js (source)
- Sveltekit (source)
- Remix (source)
- Node (source)
npm install wesc
import { promises as fs } from 'fs';
import { renderToString } from 'wesc/dom/server';
// Import web component library
import 'media-chrome';
// Process full page
let html = await fs.readFile('./app.html');
let out = await renderToString(html);
await fs.writeFile('./index.html', out);
<!-- ... -->
<media-controller>
<video
playsinline
slot="media"
src="https://stream.mux.com/A3VXy02VoUinw01pwyomEO3bHnG4P32xzV7u1j1FSzjNg/high.mp4"
></video>
<media-poster-image
slot="poster"
src="https://image.mux.com/A3VXy02VoUinw01pwyomEO3bHnG4P32xzV7u1j1FSzjNg/thumbnail.jpg"
placeholdersrc="data:image/jpeg;base64,/9j/2wBDABQODxIPDRQSEBIXFRQYHjIhHhwcHj0sLiQySUBMS0dARkVQWnNiUFVtVkVGZIhlbXd7gYKBTmCNl4x9lnN gXz/2wBDARUXFx4aHjshITt8U0ZTfHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHz/wAARCAAUADADASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAECBAP/xAAdEAEBAAEEAwAAAAAAAAAAAAAAARECAxITFCFR/8QAGQEAAwADAAAAAAAAAAAAAAAAAAEDAgQF/8QAGBEBAQEBAQAAAAAAAAAAAAAAAAETERL/2gAMAwEAAhEDEQA/ANeC4ldyI1b2EtIzzrrIqYZLvl5FGkGdbfQzGPvo76WsPxXLlfqbaA5va2iVJADgPELACsD/2Q=="
></media-poster-image>
<media-loading-indicator slot="centered-chrome" noautohide></media-loading-indicator>
<media-control-bar>
<media-play-button></media-play-button>
<media-mute-button></media-mute-button>
<media-volume-range></media-volume-range>
<media-time-display></media-time-display>
<media-time-range></media-time-range>
<media-duration-display></media-duration-display>
<media-playback-rate-button></media-playback-rate-button>
<media-fullscreen-button></media-fullscreen-button>
</media-control-bar>
</media-controller>
<!-- ... -->
view-source:https://wesc-node.netlify.app
- Linkedom - This project is powered by Linkedom.
- Ocean - Web component server-side rendering.
- Web Components Compiler (WCC) - Experimental native Web Components compiler.
- custom-elements-ssr - Renders Lit custom elements on the server.
- WebC