Skip to main content

Page source development

Most Page work can be completed in Design, Inspector, and AI Command Center without first learning a frontend framework. Use Source only when you need precise state logic, custom events, complex styling, or a reusable Component.

Source technology

Pages (.qp) and Components (.qpc) use Svelte 5 source with standard HTML, CSS, and TypeScript. Design and Source edit the same Page content: after either mode saves, the other mode reads the same result.

Common source capabilities include:

  • keeping temporary interface state for the current Page instance with $state;
  • handling Page events with TypeScript functions;
  • connecting Pages and Components through props, events, or callbacks;
  • importing an App Component relatively from a .qp or .qpc file;
  • using public Components from @theseus/qp-core and installed packages.
<script lang="ts">
let running = $state(false);

function toggleRunning() {
running = !running;
}
</script>

<button onclick={toggleRunning}>
{running ? "Stop simulation" : "Start simulation"}
</button>

Component roots and permissions

An App-defined .qpc uses @theseus/qp-core/Widget as its only measurable root, receives business values through props, returns user actions through events or callbacks, and forwards class, style, required DOM attributes, requiredRoles, and unauthorized.

An empty role list allows everyone. Multiple roles use any-match semantics, and App Admin always matches. On mismatch, hidden omits the root and disabled keeps it visible but inert. Native HTML elements do not expose these Component permission properties directly. UI visibility never replaces authorization for Object, Query, file, or Safety capabilities.

Import an App Component relatively from .qp or another .qpc. Use the public module path for a package Component; do not copy package internals.

Use App capabilities

Page source uses getApp() for App-level Queries, Variables, and navigation. External-service addresses and authentication still belong centrally in Settings → Queries, not in multiple Pages. Use @qx/i18n for localized text while maintaining locales and messages under Settings → I18n.

Use CurrentUser when a Page should display or switch the current operator, and keep it outside a region that its own role rules could hide:

<script lang="ts">
import CurrentUser from "@theseus/qp-core/CurrentUser";
import { m } from "@qx/i18n";
</script>

<CurrentUser signedOutLabel={m.not_signed_in()} />

CurrentUser manages only App users. It does not switch the Qixin account or runtime-target account.

Engineering boundaries

  • Page events coordinate the interface only. Equipment sequences, waits, timeouts, recovery, and safety interlocks belong in an Object, QG, or reviewed Provider.
  • $state belongs to the current Page instance and resets after refresh or re-entry. Use an explicit App or Object storage capability for durable data.
  • An App may use only public modules from installed packages. Do not add external dependencies that are not managed by the project, and do not copy package internals.
  • Live markers follow the current document. Problems contains diagnostics for saved project files from the latest Build. Before delivery, save, Build, and accept the result on the real runtime Page or Player.

Continue learning