Host and share HTML pages and Markdown docs. Drop an .html or .md file onto
the dashboard and get a link you can send to your team.
Live demo: https://artifacts-demo.val.run/
Click Remix to get your own isolated copy.
- A dashboard that lists every artifact and supports drag-and-drop uploads.
- HTML and Markdown support — HTML is served as-is; Markdown becomes a clean, readable page.
- Rename artifacts and see who uploaded each one.
- Team-only: Orgs can enable restricted access so only designated team members can access the page, behind a Val Town login with a single click.
- Artifact contents in this val's blob storage, with searchable metadata in SQLite.
- Each artifact rendered in a sandboxed iframe, so its scripts can't act as the viewer.
- Example artifacts to start — delete them whenever.
The app is public by default. An org should enable restricted access in Val
Town to put the whole app behind Val Town login and choose which team members
can open it. Because Val Town applies the gate before the request reaches
main.tsx, every page and action is covered without callback routes, secrets,
or app-level auth code.
If you leave access public, anyone with the URL can view, upload, rename, and delete artifacts.
Open /dashboard, then drag in an .html, .htm, .md, or .markdown file.
The format is detected from the extension and the artifact gets a short URL such
as /a/3fa9c21b1e.
On a restricted app, Val Town supplies the uploader's username through its
signed viewer identity. Public and automation-bypass uploads are recorded as
anonymous.
Agents can create an artifact by posting multipart form data to /upload with a
file field. A kind field can explicitly select html or md.
main.tsx Hono routes (the HTTP entry)
backend/
db.ts SQLite metadata + val-scoped blob contents
render.ts Markdown → HTML; HTML passes through as-is
frontend/
Layout.tsx HTML shell
Landing.tsx overview and dashboard link
Dashboard.tsx list, upload, rename, and delete artifacts
Viewer.tsx sandboxed iframe for one artifact
upload.client.ts drag-and-drop browser script
examples/ seed artifacts
SQLite stores each artifact's id, name, kind, blob key, uploader, and creation
time. The uploaded source lives under the artifacts/ prefix in this val's
project-scoped blob storage. New remixes therefore start with isolated data.
Artifacts are untrusted content, including Markdown that contains raw HTML:
- They render in an iframe without
allow-same-origin. JavaScript can run, but it cannot read the app's cookies or call app routes as the viewer. /a/:id/rawalso sendsContent-Security-Policy: sandbox, so opening it directly keeps the same opaque-origin boundary.- Markdown goes through the same sandbox as uploaded HTML.
If the app is restricted, anyone allowed through the Val Town access gate can upload, rename, and delete artifacts.