Build pages › Worker mode
Docs › Build pages › Worker mode

Worker mode

Worker mode is invite-only for now. For forms, polls, boards and shared data, use static HTML with the built-in records API described in the publishing skill. With Worker access, include a worker.js file. Spacesheep detects it automatically and deploys it as a live server-side app.

// worker.js — ES module format
export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    if (url.pathname === "api/items") {
      await env.AWS_DB.exec("CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)");
      if (request.method === "POST") {
        const { name } = await request.json();
        await env.AWS_DB.prepare("INSERT INTO items (name) VALUES (?)").bind(name).run();
        return Response.json({ ok: true });
      }
      const rows = await env.AWS_DB.prepare("SELECT * FROM items").all();
      return Response.json(rows.results);
    }

    return new Response("<h1>My App</h1>", {
      headers: { "Content-Type": "text/html" }
    });
  }
};

Database migrations: Include a schema.sql file — it runs against the space's database on every deploy. Write idempotent SQL:

-- schema.sql
CREATE TABLE IF NOT EXISTS items (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  created_at TEXT NOT NULL DEFAULT (datetime('now'))
);

What your Worker gets:

  • env.AWS_DB — a SQL database binding (SQLite dialect)
  • schema.sql — auto-executed on deploy for migrations
  • A standard fetch-handler runtime — fetch, crypto, Request/Response, WebSocket support
Important: Use relative URLs in frontend code (fetch("api/data") not fetch("/api/data")). Your Worker's paths are relative to the space URL.
Was this page helpful?