Data and integration
Start with three questions: who owns the data, how long it must last, and whether several machines must share it. Then select a capability. This keeps temporary state, recipes, production records, and external-system data in the right places.
Quick choice
| Need | Capability | Typical example |
|---|---|---|
| Share a small value during the current run | App Variable | Current work order, mode, temporary result |
| Keep a small value after the runtime target restarts | Saved Variable | Calibration, threshold, accumulated count |
| Keep state inside one running QG instance | QG state | Loop index, intermediate decision |
| Save and switch a named parameter set | Recipe | Product model, temperature, and pressure set |
| Maintain lightweight rows on one target | TableStore | Point list, material list, batch rows |
| Read or write an external business system | HTTP Query | MES order, ERP recipe, production report |
| Switch runtime-page language | i18n | Button, alarm, and status text |
| Deliver read-only files with the App | Asset | Images, video, 3D models, read-only templates |
Use an external database or business system for large histories, complex queries, or data shared by several machines, and access it through a Query.
Variable: small state
| Type | Lifetime | Reminder |
|---|---|---|
| App Variable | Current running instance | Returns to its defined initial value after restart or redelivery |
| Saved Variable | App state on the current runtime target | Survives restart; changing to another target does not migrate the current value |
| QG state | Current QG instance | Top-level let fits temporary state; use QG.saved for a value that must persist |
Page source uses App Variables through getApp().variables. To change equipment or business state owned by an Object, call the Object method instead of keeping a second Variable as another source of truth.
Acceptance should cover the initial value, a normal update, behavior after restart, and behavior after changing runtime target.
Recipe: parameter sets
Recipe fits fixed fields that users select, save, and switch as a named set.
- Define fields and defaults under App Settings → Recipes.
- Confirm that a usable
RecipeManagerexists under Objects. - Make the moments to select, apply, and save explicit in the Page or QG.
- Test missing fields, invalid ranges, switching, and reopening with a non-production recipe.
Recipe is not a history database. Send batch records, audit data, and cross-machine data to an external system.
TableStore: lightweight rows on a target
TableStore fits a bounded set of rows on one runtime target.
- Install
Table Storeunder Settings → Packages. - Add a
TableStoreunder Objects. - Configure columns, the primary key, format, and maximum rows in Properties.
- Verify create, read, update, delete, and clear from a Page or QG.
Use a stable unique primary key. The format can be csv or modern Excel .xlsx. Move to an external system and Query when volume, query complexity, or sharing grows.
HTTP Query: reusable external calls
Maintain HTTP calls centrally under App Settings → Queries. Pages and QG should reuse one Query instead of keeping separate URLs and authentication settings.
You can configure:
GET,POST,PUT,DELETE, orPATCH;- a URL with runtime
{{parameter}}values; - Headers, URL Params, and JSON, Form, or Raw Body;
- None, Bearer, or Basic Auth;
- Timeout.
A Page event handler can call getApp().queries.<name>.run(...); QG uses the corresponding Query capability.
Use Send first against a test environment and a side-effect-free request. Then test timeout, authentication failure, invalid responses, and duplicate submission. Production writes need an idempotency or duplicate-prevention strategy approved by the responsible person.
Tokens, usernames, and passwords in a Query are part of App configuration. Do not commit production credentials to uncontrolled Git, project copies, or ordinary AI conversations. Review and replace them according to the delivery policy.
i18n: one screen, several languages
- Define supported and default languages under App Settings → Internationalization (I18n).
- Use stable
lower_snake_casemessage IDs; do not assemble IDs dynamically in source. - Reuse one message set across Pages and Components instead of copying source per language.
- Switch language at runtime and inspect variable substitution, long-text layout, and fallback for missing translations.
Page source accesses messages and locale through @qx/i18n. Evaluate translated text while rendering so a language change is not blocked by a string cached at module load.
Asset: read-only content delivered with a version
- Put images, video, models, and templates under
assets/. - Use workspace-root-relative
assets/...paths in Pages, Components, and CSS, always with/. - Do not use absolute paths from a development machine or depend on filename case differences.
- Assets are read-only delivered content. Reports, uploads, and other mutable runtime data need an explicit Object or Provider capability.
Inspect important Assets in Design, Preview, and the real runtime page, especially on a remote target.
Delivery acceptance
- Confirm names, types, defaults, fields, and parameters in Settings or Object Properties.
- Save and Build, then repair broken Page or QG references.
- Test restart, failure, and recovery on the correct runtime target.
- Use test accounts and reversible data for the first Query write.
- Switch language and inspect long text; check Assets on the remote runtime page.
- Record which data travels with the project version and which remains on one target or external system.
Clean in the Build menu removes only the local Build result for the current project. It does not delete project source or clear Saved Variables, TableStore, Vision, or other runtime data on the target. Reset and migration require an explicit operation from the capability that owns the data.
Common selection mistakes
| Symptom | Better choice |
|---|---|
| A Variable is holding a large history | Use an external database or TableStore; prefer an external system when several machines share it |
| TableStore is treated as a shared business database | Call MES, ERP, or a database service through a Query |
| Production credentials are written in a Page | Put them in the central Query settings, then replace and review them during delivery |
| Runtime uploads are kept as Assets | Manage mutable data through an explicit Object or Provider capability |
| Data is checked only in the editor | Build and verify restart, errors, and permissions on the correct target |