Hypermedia
HTMX vibes, built right in. Load HTML fragments, fetch JSON, clone templatesโall with the src
attribute.
Requires lightview-x.js
Fetching HTML
Point src at an HTML file and Lightview loads it as children:
const { tags } = Lightview;
const { div, header, main } = tags;
// Load HTML partials
const app = div(
header({ src: '/partials/nav.html' }),
main({ src: '/partials/content.html' })
);
// The HTML is fetched, parsed, and made reactive automatically!
Fetching JSON
JSON files are converted to vDOM elements:
// /api/cards.json
[
{ "tag": "div", "attributes": { "class": "card" }, "children": ["Card 1"] },
{ "tag": "div", "attributes": { "class": "card" }, "children": ["Card 2"] }
]
// Load JSON as elements
div({ src: '/api/cards.json' })
Cloning DOM Elements
Use CSS selectors to clone existing elements:
// Clone a template
div({ src: '#my-template' })
// Clone multiple elements
div({ src: '.card-template' })
<!-- Hidden template in HTML -->
<template id="my-template">
<div class="modal">
<h2>Modal Title</h2>
<p>Modal content here</p>
</div>
</template>
Interactive href & Navigation
Add href to any element to make it interactive. The behavior depends on the target
attribute:
1. Self-Loading (Default)
If no target is specified, clicking sets the element's own src to the href value:
// Loads content into itself on click
button({ href: '/partials/data.html' }, 'Load Data')
2. Browser Navigation
Use standard underscore targets for window navigation:
// Opens new tab
button({ href: 'https://example.com', target: '_blank' }, 'Open External')
// Navigates current page
div({ href: '/home', target: '_self' }, 'Go Home')
3. Targeting Other Elements
Use a CSS selector as the target to load content into other elements:
// Loads content into element with id="main"
button({ href: '/pages/about.html', target: '#main' }, 'Load About Page')
div({ id: 'main' }) // Content appears here
4. Positioning Content
Control where content is inserted using the location attribute or a target suffix.
Supported locations: innerhtml (default), outerhtml,
beforebegin, afterbegin, beforeend, afterend,
shadow.
// Option A: Suffix syntax (Target Selector:Location)
button({
href: '/partials/item.html',
target: '#list:beforeend' // Append to list
}, 'Add Item')
// Option B: Explicit attribute on target
div({
src: '/partials/banner.html',
location: 'afterbegin'
})
Smart Replacement: Lightview tracks inserted content. Fetching the same content to the same location is a no-op. Fetching different content replaces the previous content at that specific location.
HTML Template Literals
External HTML can reference named signals or state with template syntax:
// main.js - Register named signals and state
const count = signal(0, 'count');
const userName = signal('Guest', 'userName');
const userPrefs = state({ theme: 'dark', lang: 'en' }, 'userPrefs');
// Load template that uses them
div({ src: '/partials/dashboard.html' })
<!-- /partials/dashboard.html -->
<div class="dashboard">
<h1>Welcome, ${signal.get('userName').value}!</h1>
<p>You have ${signal.get('count').value} notifications.</p>
<p>Theme: ${state.get('userPrefs').theme}</p>
</div>
Shadow DOM
Load content into shadow DOM for style isolation using location="shadow" or the
:shadow suffix:
// Option A: location attribute
div({ src: '/components/widget.html', location: 'shadow' })
// Option B: target suffix
button({ href: '/components/widget.html', target: '#container:shadow' }, 'Load Widget')
Building HTMX-style Apps
Combine src and href for hypermedia-driven UIs:
const { tags } = Lightview;
const { div, nav, button, main } = tags;
const app = div({ class: 'app' },
nav({ class: 'sidebar' },
button({ href: '/pages/dashboard.html' }, '๐ Dashboard'),
button({ href: '/pages/settings.html' }, 'โ๏ธ Settings'),
button({ href: '/pages/profile.html' }, '๐ค Profile')
),
main({
id: 'content',
src: '/pages/dashboard.html' // Initial content
})
);
// Clicking nav buttons updates the main content area!
The enhance() Function
Make existing DOM elements reactive:
// HTML
<button id="my-btn">Click me</button>
<span id="output"></span>
// JS
const count = signal(0);
// Enhance existing elements
LightviewX.enhance('#my-btn', {
onclick: () => count.value++
});
LightviewX.enhance('#output', {
innerText: () => `Clicked ${count.value} times`
});
Click a button to load content
// Simulated hypermedia navigation
nav(
button({ onclick: () => loadContent('home') }, 'Home'),
button({ onclick: () => loadContent('about') }, 'About')
)
main({ id: 'content' })