Hyperclay.com Platform
Platform Features
Hyperclay provides essential tools for creating and managing malleable HTML files without the complexity of traditional web development infrastructure.
Code Editor
The code editor is available at the /edit route of each malleable HTML file (e.g., yourapp.hyperclay.com/edit).
Features:
- Mobile-friendly interface that works on any device
- Syntax highlighting for HTML, CSS, and JavaScript
- Auto-indentation and bracket matching
- Line numbers and search functionality
- Real-time preview of your changes
Alternative: Browser DevTools
Many developers prefer using the browser’s built-in Developer Tools as their editor:
- Open your malleable HTML file in view mode
- Press F12 to open DevTools
- Navigate to the Elements panel
- Edit HTML directly by double-clicking elements
- Changes persist when you save (if you’re the owner)
Upload Files and Images
Hyperclay supports file uploads directly within your malleable HTML files.
hyperclay.uploadFile(eventOrFile); // Uploads a file from either a file input event or File object, showing progress toasts and copying the URL on completionFile limits:
- Maximum file size: 10MB per upload
- Supported formats: Images (JPG, PNG, GIF), documents, and other common file types
- Files are organized by path in your dashboard for easy management
- Files automatically scanned for security
- URLs are unique and unguessable
Using uploads in your app:
<img src="/uploads/{username}/my-image.png" alt="My uploaded image">Upload with progress tracking:
await hyperclay.uploadFileBasic(file, {
onProgress: (percent) => {
progressBar.style.width = percent + '%';
},
onComplete: (result) => {
console.log('Uploaded:', result.url);
gallery.innerHTML += `<img src="${result.url}">`;
},
onError: (error) => {
console.error('Upload failed:', error);
}
});Drag and drop:
<div class="upload-zone"
ondrop="handleDrop(event)"
ondragover="event.preventDefault()">
Drag files here
</div>
<script>
async function handleDrop(event) {
event.preventDefault();
const files = event.dataTransfer.files;
for (const file of files) {
await hyperclay.uploadFile(file);
}
}
</script>Creating files programmatically:
const result = await hyperclay.createFile({
fileName: 'backup.json',
fileBody: JSON.stringify(data)
});Batch upload:
const uploads = files.map(file =>
hyperclay.uploadFile(file)
);
const results = await Promise.all(uploads);Mobile camera capture:
<input type="file" accept="image/*" capture="environment">Form Submissions
Handle form submissions from users without a backend using the sendMessage method.
hyperclay.sendMessage(eventOrObj, successMessage, successCallback?)Sends a message from an anonymous viewer to the app owner’s Hyperclay account, but only if the sender is likely to be human and not a bot. If passing in a submit event, all form fields will be sent. Otherwise, object will be converted to JSON and sent.
Contact form example:
async function handleSubmit(form) {
const data = getDataFromForm(form);
await hyperclay.sendMessage(data,
'Message sent successfully!',
() => form.reset()
);
}Form with attachments:
const attachments = [];
for (const file of files) {
const result = await hyperclay.uploadFile(file);
attachments.push(result.url);
}
formData.attachments = attachments;
await hyperclay.sendMessage(formData);Custom Domains
Each Hyperclay app automatically gets a subdomain:
yourappname.hyperclay.com
Custom domain support:
- Connect your own domain (e.g.,
myapp.com) - Automatic SSL certificates
- No DNS configuration complexity
Hosting Locally
Run Hyperclay apps on your own machine for development or offline use.
Option 1: Direct file access
- Download your malleable HTML file
- Open it in a web browser
- Works immediately (though without save persistence)
Option 2: Hyperclay Local
- Desktop application for full local hosting
- Maintains save/edit functionality
- Perfect for development and testing
- See the Hyperclay Local documentation for details
Hosting on Your Own Server
Hyperclay apps are just HTML files, so they work on any web server.
Basic hosting:
- Download your malleable HTML file
- Upload to any static file host (GitHub Pages, Netlify, Vercel, etc.)
- The app works immediately in view mode
Advanced hosting with persistence: To enable edit/save functionality on your own server, you’ll need:
- A simple backend to handle save requests
- Basic authentication for edit permissions
- File write capabilities
Integrate with Other Services
Hyperclay apps can connect to external services and APIs.
Using fetch for API calls:
<script>
async function loadData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
document.getElementById('content').innerHTML = data.content;
}
</script>Function-as-a-Service integration: Services like Val.town let you add backend functionality without managing servers:
<script>
// Call a Val.town function
async function processData() {
const response = await fetch('https://api.val.town/v1/run/yourname.yourfunction');
const result = await response.json();
// Use the result in your app
}
</script>CORS considerations: When integrating external services, ensure they support CORS or use services designed for client-side access.
Tailwind CSS
Hyperclay automatically generates Tailwind CSS for your apps. No build tools, no config files required.
Add this to your <head>:
<link rel="stylesheet" href="/tailwindcss/YOUR-APP-NAME.css">Replace YOUR-APP-NAME with your HTML filename (without .html). For a file named my-app.html:
<link rel="stylesheet" href="/tailwindcss/my-app.css">Then use Tailwind classes anywhere in your HTML:
<button class="px-4 py-2 bg-blue-500 text-white rounded">
Click me
</button>Save your file and the CSS regenerates automatically with only the utilities you use. Works on hyperclay.com and Hyperclay Local.
Multi-Tenant Apps
After enabling signups on your app (click “Enable Signups” in your app’s menu), make sure your users know about these URLs (i.e. link to them from your app’s UI):
For app at yourapp.hyperclay.com:
| Action | URL | What it does |
|---|---|---|
| Sign up | yourapp.hyperclay.com/signup | Create new account & get personal instance |
| Login | yourapp.hyperclay.com/login | Access their instance |
| Forgot password | yourapp.hyperclay.com/forgot-password | Reset password via email |
What happens after signup:
- They create an account with username, email, and password
- They automatically get their own instance at:
yourapp-by-[username].hyperclay.com- If you’re using a custom domain, it’ll be
yourapp-by-[username].customdomain.com
- If you’re using a custom domain, it’ll be
- They’re redirected to their personal instance after signup
- Each instance is a complete copy of your app that they can edit
As the developer, you can access and edit the app from your dashboard.
Billing & Limits: Currently, there are no limits on the number of free signups you can get for your app, but in the future we’ll need to limit it if there’s high demand.
Multi-Page Applications
While each Hyperclay document is self-contained, you can create multi-page experiences.
Navigation between documents:
Create a consistent navigation structure across multiple HTML files:
<nav id="global-nav">
<a href="https://myhomepage.hyperclay.com">Home</a>
<a href="https://myaboutpage.hyperclay.com">About</a>
<a href="https://mycontactpage.hyperclay.com">Contact</a>
</nav>
<script>
// Highlight current page
const currentPath = window.location.pathname;
document.querySelectorAll('#global-nav a').forEach(link => {
if (link.getAttribute('href') === currentPath) {
link.classList.add('active');
}
});
</script>Sharing state across pages:
Using URL parameters:
// Page 1: Set user preference
const params = new URLSearchParams();
params.set('theme', 'dark');
params.set('user', 'john');
window.location.href = `/page2.html?${params}`;
// Page 2: Read preference
const params = new URLSearchParams(window.location.search);
const theme = params.get('theme');
const user = params.get('user');Using localStorage:
// Shared state manager
const appState = {
save(key, value) {
localStorage.setItem(`myapp_${key}`, JSON.stringify(value));
},
load(key) {
const data = localStorage.getItem(`myapp_${key}`);
return data ? JSON.parse(data) : null;
},
clear(key) {
localStorage.removeItem(`myapp_${key}`);
}
};
// Usage across pages
appState.save('user', { name: 'John', role: 'admin' });
const user = appState.load('user');