Public
Host and share HTML and Markdown artifacts with your team
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.

Team Artifacts

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.

What you get

  • 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.

Access

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.

Creating 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.

How it works

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

Storage

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.

Security model

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/raw also sends Content-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.