Skip to Content

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:

  1. Open your malleable HTML file in view mode
  2. Press F12 to open DevTools
  3. Navigate to the Elements panel
  4. Edit HTML directly by double-clicking elements
  5. 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 completion

File 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

  1. Download your malleable HTML file
  2. Open it in a web browser
  3. 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:

  1. Download your malleable HTML file
  2. Upload to any static file host (GitHub Pages, Netlify, Vercel, etc.)
  3. 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:

ActionURLWhat it does
Sign upyourapp.hyperclay.com/signupCreate new account & get personal instance
Loginyourapp.hyperclay.com/loginAccess their instance
Forgot passwordyourapp.hyperclay.com/forgot-passwordReset password via email

What happens after signup:

  1. They create an account with username, email, and password
  2. They automatically get their own instance at: yourapp-by-[username].hyperclay.com
    1. If you’re using a custom domain, it’ll be yourapp-by-[username].customdomain.com
  3. They’re redirected to their personal instance after signup
  4. 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');
Last updated on