App shapes

Publish a vanilla HTML + JS app

If your app is one `index.html` with a few `<script>` tags, it publishes on Ellivate. The GLOBAL SDK attaches to `window.ellivate`; include it with one script tag. No Node, no build, no bundler.

The smallest Ellivate app

Save as index.html:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Our list</title>
    <script src="ellivate-client.global.js" defer></script>
    <script src="ellivate-config.js" defer></script>
  </head>
  <body>
    <h1>Our list</h1>
    <ul id="list"></ul>
    <input id="box" placeholder="Add item" />
    <button onclick="add()">Add</button>

    <script>
      async function load() {
        const items = (await ellivate.kv.get("shared:items")) ?? [];
        document.getElementById("list").innerHTML =
          items.map(i => `<li>${i}</li>`).join("");
      }
      async function add() {
        const box = document.getElementById("box");
        const items = (await ellivate.kv.get("shared:items")) ?? [];
        items.push(box.value);
        await ellivate.kv.set("shared:items", items);
        box.value = "";
        load();
      }
      window.addEventListener("DOMContentLoaded", load);
    </script>
  </body>
</html>

Run ellivate publish. That's the whole app.

What Ellivate does

  • Writes ellivate-client.global.js and ellivate-config.js to both your project root and public/. They're attached to window.ellivate.
  • Serves the HTML via a lightweight static server. The classifier recognizes the shape from your index.html + lack of package.json/requirements.txt.
  • Handles the viewer token for you. The GLOBAL SDK reads window.ELLIVATE_VIEWER_TOKEN (injected by the shell), or falls back to the URL fragment (#__ellivate_auth=...) on first page load. Scrubbed from the URL automatically.

The SDK surface

Same API as the JS module SDK, attached globally:

// Read / write / delete
await ellivate.kv.get("shared:items");
await ellivate.kv.set("shared:items", [...]);
await ellivate.kv.delete("shared:items");
await ellivate.kv.list("personal:");

// Who's watching
const viewer = await ellivate.viewer();
// { id, email, username, verified } or null

Scopes by prefix

"shared:items"    // everyone with access to the app
"personal:draft"  // per-viewer
"public:splash"   // readable by anonymous visitors

Anonymous (no sign-in) apps

Vanilla HTML apps are the typical shape for public + open apps — anyone can open the URL, no sign-in required. In the dashboard, toggle Requires auth off. The public:-scope keys are the ones anonymous visitors can read.

Things to avoid

  • localStorage for user data. The SDK's kv store is the persistence layer; localStorage vanishes when the user opens your app on a different device.
  • Sign-in forms. If the app needs authentication, flip Requires auth on and the shell handles sign-in. Don't build a login page.
  • Relative paths to the SDK that include ./public/. The static server maps public/ to root — just src="ellivate-client.global.js".

What's next