You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Create a runnable WebUI example with app structure, theme wiring, Playwright tests, demo metadata, and demo-shell registration.
4
+
---
5
+
6
+
# Checklist
7
+
8
+
1. Create the app folder with `src/`, `data/state.json` when SSR state is needed, `package.json`, `tsconfig.json`, and a concise `demo.toml`.
9
+
2. Use the shared theme for example UI: add `@microsoft/webui-examples-theme`, pass `--theme=@microsoft/webui-examples-theme`, and inject `/*{{{tokens.light}}}*/` plus `/*{{{tokens.dark}}}*/` in the entry template.
10
+
3. Keep `package.json` scripts consistent: `build`, `start:client`, `start:server`, `start`, `test`, and `test:update-snapshots` when Playwright applies.
11
+
4. Add Playwright coverage in `tests/` and a `playwright.config.ts` using the app's fixed dev port. Prefer behavior tests over screenshots unless the UI is the point.
12
+
5. Register the app in `xtask/src/e2e.rs` when it has Playwright tests. Use `pre_script: Some("build")` for custom build pipelines that the generic esbuild step cannot reproduce.
13
+
6. Add `demo.toml`, copy the app into `examples/demo/Dockerfile`, and list it in `examples/README.md`.
14
+
7. Run the focused app test, then `cargo xtask check`.
Copy file name to clipboardExpand all lines: DESIGN.md
+61-1Lines changed: 61 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -339,6 +339,64 @@ emit WebUI `templates` or `templateFns`.
339
339
340
340
**Cache control:** The server can include `cacheControl: { staleTime: number }` in the partial response to override the client's default stale time for this specific route.
manifest loader. This loader is not re-exported from the framework root package
387
+
entrypoint, keeping it out of normal framework bundles unless an app imports the
388
+
optional subpath. The loader uses the manifest tag as the registered-template
389
+
fast path, so hashed asset filenames still skip importing when
390
+
`window.__webui.templates[tag]` already exists. Otherwise it deduplicates
391
+
in-flight imports by resolved asset URL and deduplicates module-style importmaps
392
+
against `window.__webui.styles` plus previously injected asset styles.
393
+
`defineComponentAssets().create(tag)` waits for the asset/module, mounts without
394
+
blocking on data by default, and applies data later with `setState()`; callers
395
+
can opt into bounded data blocking with `{ awaitData: true, dataTimeoutMs }`.
396
+
397
+
FAST plugin builds can emit the same ESM asset shape with trusted `<f-template>`
398
+
payloads in `templates`; those assets require a FAST-owned runtime loader.
399
+
342
400
**Navigation cache:** The client router maintains a tagged navigation cache. Partial responses are stored keyed by request path and tagged with `cacheTags`. On revisit within `staleTime`, the cache is used and the network fetch is skipped. After a mutation action, `Router.invalidateTags()` evicts all entries whose tags overlap with the invalidated tags. Configuration: `Router.start({ cache: { staleTime, gcTime, maxEntries } })`.
343
401
344
402
**Mutation actions:** Components can declare `static action(ctx: RouteActionContext)` as the write counterpart to `static loader()`. The router intercepts `<form method="post">` submissions, finds the nearest route component's `static action()`, calls it, and auto-invalidates the cache using both the action's returned tags and the route's build-time `invalidates` attribute. This ensures the compiler-declared invalidation graph is always respected — developers cannot forget.
0 commit comments