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' })