HyperclayJS API Reference
Documentation for all exported functions and utilities.
UI Components
toast
Display a toast notification for success or error messages.
window.toast, hyperclay.toasttoast(message, messageType)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
message |
string |
— | The message to display |
messageType |
string |
`'success'` |
Either `'success'` or `'error'` |
Returns
void
Example
// Show a success message
toast('Changes saved!', 'success');
// Show an error message
toast('Something went wrong', 'error');
// Success is the default type
toast('Uploaded successfully');ask
Display a modal with an input field to prompt the user for text input.
window.ask, hyperclay.askask(promptText, yesCallback, defaultValue, extraContent)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
promptText |
string |
— | The question or prompt to display |
yesCallback |
function |
— | Called with the input value when user confirms |
defaultValue |
string |
`''` |
Pre-filled value in the input field |
extraContent |
string |
`''` |
Additional HTML content to display below the input |
Returns
Promise<string> — Resolves with the input value, rejects if user closes modal
Example
// Basic usage with async/await
const name = await ask('What is your name?');
console.log('Hello, ' + name);
// With a default value
const title = await ask('Enter title:', null, 'Untitled');
// With callback
ask('Enter your email:', (email) => {
console.log('Email:', email);
});
// With extra content
ask('Confirm action:', null, '', '<p class="warning">This cannot be undone</p>');consent
Display a confirmation modal to get user consent before an action.
window.consent, hyperclay.consentconsent(promptText, yesCallback, extraContent)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
promptText |
string |
— | The question or prompt to display |
yesCallback |
function |
— | Called when user confirms |
extraContent |
string |
`''` |
Additional HTML content to display |
Returns
Promise<void> — Resolves when user confirms, rejects if user closes modal
Example
// Basic usage with async/await
try {
await consent('Delete this item?');
deleteItem();
} catch (e) {
// User cancelled
}
// With callback
consent('Are you sure?', () => {
performAction();
});
// With extra content
consent('Publish changes?', null, '<p>This will be visible to all users.</p>');tell
Display an informational modal with a title and optional content paragraphs.
window.tell, hyperclay.telltell(promptText, ...content)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
promptText |
string |
— | The title/heading text |
...content |
string[] |
— | Additional content paragraphs (variadic) |
Returns
Promise<void> — Resolves when user confirms, rejects on close
Example
// Simple message
await tell('Welcome!');
// With additional content
await tell(
'About This App',
'This is a collaborative editing platform.',
'Changes are saved automatically.',
'Press CMD+S to save manually.'
);
// Informational popup
tell('Tip', 'You can drag and drop items to reorder them.');snippet
Display a modal with a code snippet and a copy-to-clipboard button.
window.snippet, hyperclay.snippetsnippet(title, content, extraContent)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
title |
string |
— | The modal heading |
content |
string |
— | The code/text to display and copy |
extraContent |
string |
`''` |
Optional warning or info text below the copy button |
Returns
Promise<void> — Resolves when modal is closed
Example
// Show embed code
snippet('Embed Code', '<iframe src="https://example.com"></iframe>');
// With a warning message
snippet(
'API Key',
'sk-1234567890abcdef',
'Keep this key secret. Do not share it publicly.'
);
// Show configuration
const config = JSON.stringify({ theme: 'dark', lang: 'en' }, null, 2);
snippet('Your Settings', config);themodal
A flexible modal window creation system. Configure and display custom modals with full control over content and behavior.
window.themodal, hyperclay.themodalthemodal.html = content;
themodal.yes = buttonContent;
themodal.no = buttonContent;
themodal.open();
themodal.close();Methods
| Method | Description |
|---|---|
open() |
Show the modal |
close() |
Close the modal (triggers onNo callbacks) |
onYes(callback) |
Add callback for confirm action. Return `false` to prevent closing |
onNo(callback) |
Add callback for cancel/close action |
onOpen(callback) |
Add callback for when modal opens |
Example
// Basic custom modal
themodal.html = '<h2>Custom Title</h2><p>Your content here</p>';
themodal.yes = 'Confirm';
themodal.no = 'Cancel';
themodal.onYes(() => {
console.log('User confirmed');
});
themodal.onNo(() => {
console.log('User cancelled');
});
themodal.open();
// Modal with form validation
themodal.html = '<input class="micromodal__input" type="email" required>';
themodal.yes = 'Submit';
themodal.onYes(() => {
const email = document.querySelector('.micromodal__input').value;
if (!email.includes('@')) {
toast('Invalid email', 'error');
return false; // Prevent modal from closing
}
processEmail(email);
});
themodal.open();DOM Utilities
All
A lightweight DOM manipulation library with jQuery-like syntax. Select elements, chain methods, handle events with delegation, and more.
window.All, hyperclay.AllAll(selector)
All(selector, context)
All(element)
All(elements)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
selector |
string |
— | CSS selector to match elements |
context |
string | Element | Element[] | Document |
— | Optional context to limit search scope |
element |
Element |
— | Wrap a single DOM element |
elements |
Element[] |
— | Wrap an array of DOM elements |
Returns
Proxy<Element[]> — A proxied array of elements with chainable methods
Example
// Toggle visibility on all cards
All('.card').classList.toggle('hidden');
// Get values from all inputs
const values = All('input').map(el => el.value);
// Event delegation for dynamic content
All(document).onclick('.dynamic-btn', function() {
console.log('Button clicked:', this.dataset.id);
});
// Chained operations
All('.notification')
.classList.add('fade-out')
.style.opacity = '0';
// Iterate with for...of
for (const el of All('.item')) {
el.textContent = 'Updated';
}insertStyles
Insert styles into the document — either an external stylesheet or inline CSS. With a persistent DOM (hyperclay), new styles are inserted first, then duplicates are removed to prevent flickering.
window.insertStyles, hyperclay.insertStylesinsertStyles(href)
insertStyles(name, css)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
href |
string |
— | URL of the stylesheet to inject (1-arg form) |
name |
string |
— | Unique name for inline styles, used as data-name attribute (2-arg form) |
css |
string |
— | CSS content to inject inline (2-arg form) |
Returns
HTMLElement
Example
// External stylesheet
insertStyles('/styles/theme.css');
// Load from CDN
insertStyles('https://cdn.example.com/lib.css');
// Inline CSS with a name (for deduplication)
insertStyles('my-theme', `
.dark-mode { background: #1a1a1a; color: #fff; }
`);
// Safe to call multiple times - old duplicates are removed
insertStyles('/styles/theme.css'); // Replaces previousgetDataFromForm
Extract all form field values as a plain JavaScript object. Works with `<form>` elements or any container with named inputs.
window.getDataFromForm, hyperclay.getDataFromFormgetDataFromForm(container)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
container |
HTMLFormElement|Element |
— | Form element or container with named inputs |
Returns
object — Key-value pairs of field names and their values
Example
// From a form element
const form = document.querySelector('form');
const data = getDataFromForm(form);
// { username: 'john', email: 'john@example.com' }
// From any container
const container = document.querySelector('.filter-panel');
const filters = getDataFromForm(container);
// Checkbox handling
// <input type="checkbox" name="tags" value="js" checked>
// <input type="checkbox" name="tags" value="css" checked>
// Result: { tags: ['js', 'css'] }
// Use with fetch
const formData = getDataFromForm(form);
fetch('/api/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData)
});onDomReady
Execute a callback when the DOM is ready. If the DOM is already loaded, the callback runs immediately.
hyperclay.onDomReadyonDomReady(callback)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
callback |
function |
— | Function to execute when DOM is ready |
Returns
void
Example
// Initialize app when DOM is ready
onDomReady(() => {
initializeApp();
setupEventListeners();
});
// Safe to call after page load - runs immediately
onDomReady(() => {
console.log('This runs right away if DOM is already loaded');
});onLoad
Execute a callback when the window load event fires (all resources loaded). If already loaded, the callback runs immediately.
hyperclay.onLoadonLoad(callback)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
callback |
function |
— | Function to execute when window is fully loaded |
Returns
void
Example
// Wait for all images and resources to load
onLoad(() => {
initializeImageGallery();
calculateLayoutDimensions();
});
// Difference from onDomReady:
// - onDomReady: DOM structure ready, images may still be loading
// - onLoad: Everything loaded including images, fonts, iframesdom-helpers
Adds convenience methods to all HTML elements for finding and manipulating nearby elements. Built on top of the `nearest` utility.
Methods
| Method | Description |
|---|---|
el.cycle(order, attr) |
Replace element with next element having same attribute |
el.cycleAttr(order, setAttr, lookupAttr?) |
Cycle through attribute values |
Example
// Find nearest element with [project] or .project const projectEl = this.nearest.project; // Get/set values (smart: uses .value for form elements, attribute otherwise) const projectName = this.val.project; this.val.project = "New Name"; // Get/set innerText const label = this.text.title; this.text.title = "Updated Title"; // Execute code from an attribute // If <div sync_out="savePage()"> exists nearby, this runs savePage() this.exec.sync_out(); // Cycle through elements // Replaces current element with next element having [variant] attribute this.cycle(1, 'variant'); // forward this.cycle(-1, 'variant'); // backward // Cycle through attribute values // Sets theme to next value found on any [theme] element this.cycleAttr(1, 'theme'); // Cycle with different lookup attribute // Sets color based on values from [option:color] elements this.cycleAttr(1, 'color', 'option:color');
String Utilities
slugify
Convert text into a URL-friendly slug. Handles accents, spaces, and special characters.
window.slugify, hyperclay.slugifyslugify(text)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
text |
string |
— | The text to convert to a slug |
Returns
string — URL-friendly slug
Example
slugify('Hello World');
// 'hello-world'
slugify('Café & Restaurant');
// 'cafe-restaurant'
slugify(' Multiple Spaces ');
// 'multiple-spaces'
slugify('Ñoño with Accénts');
// 'nono-with-accents'
// Use for URLs
const title = 'My Blog Post Title!';
const url = `/posts/${slugify(title)}`;
// '/posts/my-blog-post-title'copyToClipboard
Copy text to the system clipboard.
hyperclay.copyToClipboardcopyToClipboard(text)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
text |
string |
— | The text to copy to clipboard |
Returns
void
Example
// Copy a URL
copyToClipboard('https://example.com/share/123');
// Copy with user feedback
copyToClipboard(embedCode);
toast('Copied to clipboard!');
// Copy from an element
const code = document.querySelector('pre').textContent;
copyToClipboard(code);query
An object containing parsed URL query parameters from the current page URL.
window.query, hyperclay.queryqueryExample
// URL: https://example.com/page?name=john&page=2&active=true
query.name; // 'john'
query.page; // '2'
query.active; // 'true'
// Check if parameter exists
if (query.debug) {
enableDebugMode();
}
// Use with defaults
const page = query.page || '1';
const sort = query.sort || 'date';
// Destructure parameters
const { name, page, sort = 'date' } = query;Utilities
throttle
Limit how often a function can be called. The function executes at most once per specified delay period.
hyperclay.throttlethrottle(callback, delay, executeFirst)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
callback |
function |
— | The function to throttle |
delay |
number |
— | Minimum time between calls in milliseconds |
executeFirst |
boolean |
`true` |
Execute immediately on first call |
Returns
function — Throttled version of the callback
Example
// Throttle scroll handler to once per 100ms
const handleScroll = throttle(() => {
updateScrollPosition();
}, 100);
window.addEventListener('scroll', handleScroll);
// Throttle resize handler
const handleResize = throttle(() => {
recalculateLayout();
}, 200);
window.addEventListener('resize', handleResize);
// Don't execute immediately on first call
const lazyUpdate = throttle(updateUI, 500, false);debounce
Delay function execution until after a period of inactivity. The timer resets each time the function is called.
hyperclay.debouncedebounce(callback, delay)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
callback |
function |
— | The function to debounce |
delay |
number |
— | Wait time in milliseconds after last call |
Returns
function — Debounced version of the callback
Example
// Debounce search input
const searchInput = document.querySelector('#search');
const handleSearch = debounce((query) => {
fetchSearchResults(query);
}, 300);
searchInput.addEventListener('input', (e) => {
handleSearch(e.target.value);
});
// Debounce window resize
const handleResize = debounce(() => {
recalculateLayout();
}, 250);
window.addEventListener('resize', handleResize);
// Auto-save after user stops typing
const autoSave = debounce(() => {
saveDraft();
}, 1000);cacheBust
Cache-bust an element's href or src attribute by adding or updating a version query parameter. Useful for reloading stylesheets or scripts after dynamic changes.
window.cacheBust, hyperclay.cacheBustcacheBust(element)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
element |
HTMLElement |
— | Element with href or src attribute to cache-bust |
Returns
void
Example
// Cache-bust a stylesheet link
const link = document.querySelector('link[rel="stylesheet"]');
cacheBust(link);
// href="/styles.css" becomes "/styles.css?v=1702847291234"
// Cache-bust an image
const img = document.querySelector('img');
cacheBust(img);
// src="/photo.jpg?v=123" becomes "/photo.jpg?v=1702847291234"
// Use with onaftersave to reload Tailwind CSS after save
// <link href="/tailwindcss/mysite.css" onaftersave="cacheBust(this)">cookie
Utility object for reading and removing browser cookies.
window.cookie, hyperclay.cookiecookie.get(name)
cookie.remove(name)Methods
| Method | Description |
|---|---|
get(name) |
Get cookie value. Returns parsed JSON if valid, otherwise decoded string, or `null` if not found. |
remove(name) |
Remove cookie from current path, host domain, and apex domain. |
Example
// Get a cookie value
const userId = cookie.get('userId');
// Get JSON cookie (auto-parsed)
const preferences = cookie.get('userPrefs');
// { theme: 'dark', lang: 'en' }
// Check if cookie exists
if (cookie.get('authToken')) {
showLoggedInUI();
}
// Remove a cookie
cookie.remove('sessionId');
// Clear authentication
cookie.remove('authToken');
cookie.remove('userId');Mutation
A lightweight wrapper around MutationObserver for watching DOM changes. Provides methods to observe element additions, removals, and attribute changes.
window.Mutation, hyperclay.MutationMutation.onAnyChange(options, callback)
Mutation.onAddOrRemove(options, callback)
Mutation.onAddElement(options, callback)
Mutation.onRemoveElement(options, callback)
Mutation.onAttribute(options, callback)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
options |
object |
`{}` |
Configuration options |
options.debounce |
number |
`0` |
Debounce delay in milliseconds |
options.selectorFilter |
string|function |
— | Filter changes to matching elements |
options.omitChangeDetails |
boolean |
`false` |
Call callback without change data |
callback |
function |
— | Called with array of changes |
Methods
| Method | Description |
|---|---|
onAnyChange |
Watch all DOM changes |
onAddOrRemove |
Watch element additions and removals |
onAddElement |
Watch only element additions |
onRemoveElement |
Watch only element removals |
onAttribute |
Watch attribute changes |
Returns
function — Call to stop observing
Example
// Watch for any DOM changes (debounced)
const unsubscribe = Mutation.onAnyChange({ debounce: 200 }, (changes) => {
changes.forEach(change => {
console.log(change.type, change.element);
});
});
// Watch for new elements matching a selector
Mutation.onAddElement({ selectorFilter: '.card' }, (changes) => {
changes.forEach(({ element }) => {
initializeCard(element);
});
});
// Watch for attribute changes
Mutation.onAttribute({ debounce: 100 }, (changes) => {
changes.forEach(({ element, attribute, oldValue, newValue }) => {
console.log(`${attribute} changed from ${oldValue} to ${newValue}`);
});
});
// Simple debounced callback without change details
Mutation.onAnyChange({ debounce: 500, omitChangeDetails: true }, () => {
console.log('DOM changed');
});
// Stop observing
unsubscribe();nearest
Search for elements matching a CSS selector by exploring outward from a starting point. Unlike `element.closest()` which only searches ancestors, this explores siblings, cousins, and nearby elements in visual proximity.
window.nearest, hyperclay.nearestnearest(startElem, selector, elementFoundReturnValue)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
startElem |
Element |
— | Starting element for the search |
selector |
string |
— | CSS selector to match |
elementFoundReturnValue |
function |
`x => x` |
Transform function for the found element |
Returns
Element | any | null — Found element (or transformed value), or `null` if not found
Example
// Find the nearest button const btn = nearest(clickedElement, 'button'); // Find nearest input field from a label const input = nearest(label, 'input'); // Find nearest and get its value const value = nearest(el, '[data-value]', el => el.dataset.value); // Find related UI elements const card = nearest(deleteBtn, '.card'); card.remove(); // Find next input in reading order const nextInput = nearest(currentInput, 'input:not(:disabled)'); nextInput?.focus();
Communication
sendMessage
Send form data or a custom object to the `/message` endpoint. Automatically collects form data, includes behavior tracking, and handles success/error toasts.
hyperclay.sendMessagesendMessage(eventOrObj, successMessage, callback)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
eventOrObj |
Event|object |
— | Form submit event, click event, or data object to send |
successMessage |
string |
`'Successfully sent'` |
Toast message on success |
callback |
function |
— | Called with response data on success |
Returns
Promise<object> — Resolves with server response, rejects on error
Example
// Handle form submission
document.querySelector('form').onsubmit = (e) => {
sendMessage(e, 'Message sent!');
};
// Event outside a form (sends behavior data only)
document.querySelector('#contact-btn').onclick = (e) => {
sendMessage(e, 'Contact request sent!');
};
// Send custom data object
sendMessage({
name: 'John',
email: 'john@example.com'
}, 'Contact form submitted');
// With async/await
try {
const result = await sendMessage(formEvent);
redirectToThankYou();
} catch (error) {
console.error('Failed:', error);
}uploadFile
Upload a file to the `/upload` endpoint with progress toasts and automatic clipboard copy of the resulting URL.
hyperclay.uploadFileuploadFile(eventOrFile, callback, extraData)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
eventOrFile |
Event|File |
— | File input change event or File object |
callback |
function |
`() => {}` |
Called with response on success |
extraData |
object |
`{}` |
Additional data to include in the request |
Returns
Promise<object> — Resolves with server response containing URLs
Example
// Handle file input
document.querySelector('input[type="file"]').onchange = (e) => {
uploadFile(e, (response) => {
console.log('Uploaded to:', response.urls);
});
};
// Upload a File object directly
const file = new File(['content'], 'test.txt', { type: 'text/plain' });
uploadFile(file);
// With extra metadata
uploadFile(event, null, {
folder: 'images',
public: true
});
// Progress is shown automatically via toasts:
// "10% uploaded" → "50% uploaded" → "80% uploaded" → "Uploaded! URL copied"createFile
Create and upload a file from text content. Automatically detects content type (HTML, CSS, JS, JSON, etc.) and adjusts the file extension.
hyperclay.createFilecreateFile(eventOrData)
createFile(fileName, fileBody)Returns
Promise<object> — Resolves with server response containing URLs
Example
// From form submission
document.querySelector('#create-file-form').onsubmit = (e) => {
createFile(e);
};
// From object
createFile({
fileName: 'styles.css',
fileBody: '.container { max-width: 1200px; }'
});
// From arguments
createFile('config.json', JSON.stringify({ theme: 'dark' }));
// Content type auto-detection:
// - HTML content → .html
// - CSS content → .css
// - JavaScript → .js
// - Valid JSON → .json
// - Unknown → .txtuploadFileBasic
Upload a file with custom progress, completion, and error callbacks. A lower-level alternative to `uploadFile` without progress toasts (HTTP errors still trigger toast notifications).
hyperclay.uploadFileBasicuploadFileBasic(eventOrFile, options)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
eventOrFile |
Event|File |
— | File input change event or File object |
options |
object |
`{}` |
Callback options |
options.onProgress |
function |
`() => {}` |
Called with percent complete (0-100) |
options.onComplete |
function |
`() => {}` |
Called with response on success |
options.onError |
function |
`() => {}` |
Called with error on failure |
Returns
Promise<object> — Resolves with server response, rejects on error
Example
// With custom progress UI
uploadFileBasic(fileInput.files[0], {
onProgress: (percent) => {
progressBar.style.width = percent + '%';
progressText.textContent = percent + '%';
},
onComplete: (response) => {
progressBar.classList.add('complete');
showSuccessMessage(response.urls[0]);
},
onError: (error) => {
progressBar.classList.add('error');
showErrorMessage(error.message);
}
});
// Minimal usage
uploadFileBasic(event, {
onComplete: (res) => console.log('Done:', res.urls)
});
// With async/await
try {
const result = await uploadFileBasic(file, {
onProgress: p => console.log(p + '%')
});
console.log('Uploaded:', result);
} catch (err) {
console.error('Failed:', err);
}live-sync
Real-time DOM sync across browsers. When one user saves, all connected browsers see the changes instantly. Works with Hyperclay Local app as well.
Event Attributes
onclickaway
Execute code when a click occurs outside the element.
onclickchildren
Execute code when any direct child of the element is clicked.
onclone
Execute code when an element is cloned via `cloneNode()`.
onmutation
Execute code when the element or its descendants change.
onpagemutation
Execute code when any element on the page changes. Also available as `onglobalmutation`.
onrender
Execute code once when an element is rendered (added to the DOM).
Custom Attributes
persist
Sync form input values to the saved/synced page snapshot.
onaftersave
Execute code after a successful page save.
prevent-enter
Prevent the Enter key from creating newlines in an element.
autosize
Automatically grow textarea height to fit content.
sortable
Enable drag-and-drop sorting on child elements.
option-visibility
Show or hide elements based on ancestor attribute values.
Save/Edit Features
edit-mode
Provides edit mode detection and toggling for page editing.
Methods
| Method | Description |
|---|---|
toggleEditMode() |
Toggle edit mode on/off (reloads page) |
Example
// Check if in edit mode
if (hyperclay.isEditMode) {
// Show edit UI
}
// Check if user owns the resource
if (hyperclay.isOwner) {
// Show owner-only controls
}
// Toggle edit mode (reloads page with ?editmode=true/false)
hyperclay.toggleEditMode();edit-mode-helpers
Combines edit mode detection with page type attribute. Automatically sets `pagetype` attribute on `<html>` based on URL.
save-system
Manual save with change detection, state management, keyboard shortcuts, and save button support.
Example
// Manual save
hyperclay.savePage();
// Save with callback
hyperclay.savePage(({msg, msgType}) => {
if (msgType === 'error') {
console.error('Save failed:', msg);
}
});
// Register before-save hook
hyperclay.beforeSave((clone) => {
// Modify the snapshot clone before saving
clone.querySelectorAll('.temp').forEach(el => el.remove());
});
// Replace page with template
hyperclay.replacePageWith('/templates/blog.html');save-toast
Shows toast notifications for save lifecycle events.
unsaved-warning
Warns users before leaving the page if there are unsaved changes.
autosave
Automatically saves the page when DOM changes are detected.
tailwind-inject
Automatically injects the Tailwind CSS link with cache-busting on save.