Content will appear here.
Playground
Interactive examples using µJS. Each demo loads real HTML fragments via AJAX — open DevTools (Network tab) to see the requests.
Basic navigation #
A link that replaces a specific zone using mu-target and mu-source. Click the link, then follow the link inside the loaded fragment.
<a href="/demos/fragment-about.html"
mu-target="#content"
mu-source="#content"
mu-history="false" mu-scroll="false">Load About fragment</a>
<div id="content">
<p>Content will appear here.</p>
</div>
Injection modes #
Append and prepend items to a list using mu-mode.
<a href="/demos/append-item.html"
mu-target="#demo-list"
mu-source="#new-item"
mu-mode="append"
mu-history="false" mu-scroll="false">Append item</a>
<a href="/demos/prepend-item.html"
mu-target="#demo-list"
mu-source="#new-item"
mu-mode="prepend"
mu-history="false" mu-scroll="false">Prepend item</a>
Patch mode #
A single request that updates two different zones simultaneously.
<a href="/demos/patch-response.html"
mu-mode="patch">Update both zones</a>
<div id="patch-zone-a">Zone A: waiting...</div>
<div id="patch-zone-b">Zone B: waiting...</div>
History & Scroll #
Compare normal navigation (adds to browser history) vs mu-history="false" (does not). Watch the URL bar.
<!-- Normal: URL changes -->
<a href="/demos/fragment-about.html"
mu-target="#history-demo"
mu-source="#content">Normal link</a>
<!-- No history: URL stays the same -->
<a href="/demos/fragment-contact.html"
mu-target="#history-demo"
mu-source="#content"
mu-history="false">No history link</a>
Normal link (URL changes) No history link (URL stays)
Watch the browser URL bar when you click each link.
Prefetch #
Hover over the link and watch the Network tab in DevTools — the page is fetched before you click.
<a href="/demos/fragment-about.html"
mu-target="#prefetch-demo"
mu-source="#content"
mu-history="false" mu-scroll="false">Hover me, then click</a>
Form (GET) #
A search form that loads results via AJAX. The query string is appended to the URL.
<form action="/demos/search-results.html" method="get"
mu-target="#search-results"
mu-source="#search-results"
mu-history="false" mu-scroll="false">
<input type="text" name="q" placeholder="Search...">
<button type="submit">Search</button>
</form>
Results will appear here.
Programmatic API #
Click the button to trigger mu.load() from JavaScript — no link needed.
<button onclick="mu.load('/demos/loaded-content.html', {
target: '#api-demo',
source: '#api-content',
history: false,
scroll: false
})">Load via mu.load()</button>
Content will be loaded programmatically.
Events #
µJS fires custom events during navigation. Click the link below and watch the event log fill up.
document.addEventListener("mu:before-fetch", function(e) {
console.log("Fetching:", e.detail.url);
});
document.addEventListener("mu:after-render", function() {
console.log("Page updated");
});
Triggers — Live search #
An input field that fetches search results on every keystroke, with a 500ms debounce. Uses mu-trigger="change".
<input type="text" name="q" placeholder="Search..."
mu-trigger="change" mu-debounce="500"
mu-url="/demos/trigger-search.html"
mu-target="#trigger-results" mu-source="#trigger-results"
mu-mode="update">
<div id="trigger-results">
<p>Results will appear here.</p>
</div>
Results will appear here.
Triggers — Load on render #
Content is loaded automatically when the element is rendered, using mu-trigger="load".
<div mu-trigger="load"
mu-url="/demos/loaded-content.html"
mu-target="#load-demo" mu-source="#api-content"
mu-mode="update">
</div>
Loading content automatically...
HTTP methods #
Use mu-method to send PUT, PATCH, or DELETE requests from any element.
<!-- DELETE button -->
<button mu-url="/dyn/showMethod/42" mu-method="delete"
mu-mode="remove" mu-target="#item-42" mu-history="false">
Delete
</button>
<!-- PUT link -->
<a href="/dyn/showMethod/5" mu-method="put" mu-mode="none" mu-history="false">
Publish
</a>
Item to remove
Server-Sent Events (SSE) #
Open a real-time SSE connection with mu-method="sse". Combine with patch mode for multi-fragment streaming.
<!-- Client -->
<div mu-trigger="load" mu-url="/chat/stream"
mu-mode="patch" mu-method="sse">
</div>
<!-- Server response (SSE format) -->
event: message
data: <div mu-patch-target="#messages" mu-patch-mode="append"><p>New message!</p></div>
event: message
data: <span mu-patch-target="#online-count">42</span>
Polling #
Combine mu-trigger="load" with mu-repeat to fetch content at regular intervals. The timestamp below updates every 3 seconds.
<div mu-trigger="load" mu-repeat="3000"
mu-url="/demos/polling-content.html"
mu-target="#poll-zone" mu-source="#polling-content"
mu-mode="update">
</div>
<div id="poll-zone">
Waiting for first poll...
</div>
Waiting for first poll...
Form POST with patch response #
A POST form combined with patch mode to append a new comment and reset the form in a single response.
<!-- Form -->
<form id="comment-form" action="/comment/create"
method="post" mu-mode="patch">
<textarea name="body"></textarea>
<button type="submit">Send</button>
</form>
<div id="comments"></div>
<!-- Server response -->
<div class="comment" mu-patch-target="#comments"
mu-patch-mode="append">
<p>The new comment</p>
</div>
<form action="/comment/create" method="post"
mu-patch-target="#comment-form">
<textarea name="body"></textarea>
<button type="submit">Send</button>
</form>
Confirm dialog #
The mu-confirm attribute shows a browser confirmation dialog before navigating. If the user cancels, navigation is aborted.
<a href="/demos/fragment-about.html"
mu-target="#confirm-demo" mu-source="#content"
mu-history="false" mu-scroll="false"
mu-confirm="Are you sure you want to load this content?">
Load with confirmation
</a>
View Transitions #
µJS uses the View Transitions API by default. Compare a normal link (with transitions) and one with mu-transition="false".
<!-- With transitions (default) -->
<a href="/demos/fragment-about.html"
mu-target="#transition-demo" mu-source="#content"
mu-history="false" mu-scroll="false">With transition</a>
<!-- Without transitions -->
<a href="/demos/fragment-contact.html"
mu-target="#transition-demo" mu-source="#content"
mu-history="false" mu-scroll="false" mu-transition="false">Without transition</a>
Live validation #
As-you-type email validation using mu-trigger="change" with debounce. DOM morphing (idiomorph) preserves cursor position and focus — the input is never replaced, only the validation message is updated.
<div id="email-wrapper">
<label for="email-input">Email</label>
<input type="email" id="email-input" name="email"
mu-trigger="change" mu-debounce="300"
mu-url="/validate/email"
mu-target="#email-wrapper"
mu-source="#email-wrapper"
mu-mode="update"
placeholder="you@example.com">
<small id="email-error"></small>
</div>
Interdependent fields #
A country selector that updates the city list and postal code format using mu-mode="patch". Only the dependent fields are replaced — the name field (already filled in) stays untouched.
<input type="text" name="name" placeholder="Your name">
<select name="country"
mu-trigger="change"
mu-url="/form/update"
mu-mode="patch">
<option value="">Choose a country...</option>
<option value="us">United States</option>
<option value="fr">France</option>
<option value="jp">Japan</option>
</select>
<div id="city-wrapper">
<!-- Updated by the server -->
</div>
<div id="postal-wrapper">
<!-- Updated by the server -->
</div>