The page below is static, server-rendered HTML. The three interactive widgets are tina4-js Web Components that hydrate on their own the moment the script defines them. Each island is shadow-DOM encapsulated: it brings its own markup and its own styles.
Over-ear, 40-hour battery, active noise cancellation. This copy, the price, and the layout arrived as static HTML. The stars, the cart, and the live viewer count are islands.
Each widget is a Tina4Element that calls customElements.define().
Drop its tag into any server-rendered page - PHP, Twig, Go templates, plain HTML - and it
upgrades in place. An island ships around 2 KB of its own logic instead of booting a
whole framework for the entire page. It reads its own attributes, owns its own signals,
scopes its own styles, and cleans up when removed.
import { Tina4Element, signal, html } from 'tina4js';
class AddToCart extends Tina4Element {
static props = { sku: String, price: Number }; // attr names == keys
static styles = \`.buy { background: var(--primary); }\`; // scoped to the shadow root
qty = signal(1); // each island owns its state
inCart = signal(0);
render() {
return html\`
<button @click=\${() => this.qty.value++}>+</button>
<span>\${this.qty}</span>
<button class="buy" @click=\${() => this.inCart.value += this.qty.value}>
Add \${() => this.prop('price')}
</button>
\`;
}
}
customElements.define('add-to-cart', AddToCart);
Then in any server page: <add-to-cart sku="WH-100" price="79.99"></add-to-cart>