XMLUI Config Reference

xmluiConfig is the home for framework and runtime settings that change how the XMLUI engine behaves. Use it for routing mode, inline-style handling, validation severity, XMLScript diagnostics, and other runtime-level switches.

Application-specific values belong under appGlobals. appGlobals is exposed to markup as the global identifier appGlobals; xmluiConfig is read by the framework and is not exposed as a separate global.

When the engine looks up a runtime setting, it reads a merged view where xmluiConfig overrides the same key in appGlobals, and any key not set in xmluiConfig falls back to appGlobals. This keeps existing apps working while giving new apps a dedicated place for runtime settings.

Removed keys: compileBindings, compileEventHandlers, compiledScriptSourceMaps, and logCompiledEventHandlerSource no longer do anything. Use compileScripts for all script compilation and reportCompileFallbacks for its diagnostics; source maps follow xmlui start. A project that still carries one of the removed keys is told so, once, by the CLI and at app startup.

Deprecation notice: placing framework / runtime settings under appGlobals is still supported today via the fallback mechanism, but this behaviour will be deprecated in an upcoming minor release. Move framework settings such as apiUrl, headers, notifications, prefetchedContent, showHeadingAnchors, useHashBasedRouting, disableInlineStyle, xsVerbose, and the strict* family to xmluiConfig. Application-specific values remain under appGlobals.

// config.ts (Vite / built mode)
const App: StandaloneAppDescription = {
  name: "My App",
  appGlobals: {
    currentUser: { displayName: "Ada" },
  },
  xmluiConfig: {
    apiUrl: "https://api.example.com",
    headers: { "X-App-Version": "1.0.0" },
    useHashBasedRouting: false,
    disableInlineStyle: false,
    lintSeverity: "warning",
    xsVerbose: false,
  },
};
// config.json (standalone / buildless mode)
{
  "appGlobals": {
    "currentUser": { "displayName": "Ada" }
  },
  "xmluiConfig": {
    "apiUrl": "https://api.example.com",
    "useHashBasedRouting": false,
    "lintSeverity": "warning"
  }
}

Standalone vs build config: in standalone / buildless mode, the browser runtime reads config.json next to Main.xmlui. It does not read a root xmlui.config.json; that file is consumed by XMLUI build and analysis tooling, such as xmlui build and xmlui check. To affect a standalone app at runtime, put settings under xmluiConfig in config.json.

Component authors should use useXmluiConfig() for framework / runtime settings. It returns the merged read-only view (xmluiConfig overlaying appGlobals). Use useAppGlobals() only for raw application-specific values.


Quick reference

KeyPurpose
applyLayoutPropertiesControls which layout properties the engine applies.
apiUrlBase URL for relative API request URLs.
allowConsoleLets XMLScript access console even when DOM sandbox checks are active.
allowedOriginsRestricts cross-origin calls made through App.fetch().
allowInlineRawCssControls raw CSS checks in inline style values.
auditPolicyConfigures audit log redaction, sampling, retention, and sink delivery.
autoSkipLinkInserts the default skip link before app content.
blogData consumed by the Blog component.
codeHighlighterSyntax highlighter used by markdown and code fences.
columnCanSortDefaultOverrides the default sortable behavior for table columns.
compileScriptsCompiles XMLUI scripts to JavaScript — bindings, handlers, and code-behind alike.
strictCompilationTurns any interpreted execution under compileScripts into an error.
csrfHeaderNameOverrides the form CSRF header name.
reportCompileFallbacksReports each script block that could not be compiled, with a code.
defaultToOptionalMemberAccessControls optional member access semantics in XMLScript.
defaultHandlerTimeoutMsSets the ambient async handler timeout.
defaultLocaleSets the fallback locale for i18n.
disableInlineStyleDisables inline style props while preserving layout dimensions.
disposeTimeoutMsSets the onBeforeDispose timeout budget.
errorBufferSizeSets the size of the App.errors FIFO buffer.
errorResponseTransformTransforms API error responses before XMLUI surfaces them.
guardOnPopStateControls whether navigation guards run for browser back/forward navigation.
headersDefault HTTP headers for outgoing API requests.
idempotencyHeaderNameOverrides the form idempotency header name.
interceptExternalNavigationRoutes same-origin raw anchors and GET forms through XMLUI navigation.
localeBundlesRegisters i18n locale bundles at app startup.
localePersistKeyControls the localStorage key used for persisted locale selection.
lintSeverityControls standalone startup validation severity.
logRestApiErrorsLogs REST API response parsing errors.
maxQueuedPerTraceCaps queued handlers per scheduler trace.
maxZIndexSets the highest allowed zIndex value in layout-style validation.
notificationsToast notification defaults.
prefetchedContentStartup content cache for pre-fetched resources.
requireFormCsrfRequires mutating forms to provide a CSRF token.
schedulerSelects the handler scheduler mode.
searchIndexEnabledEnables startup search index construction.
showHeadingAnchorsDefault heading anchor behavior.
strictAccessibilityEscalates accessibility diagnostics.
strictAuditLoggingEscalates audit-policy and PII diagnostics.
strictConcurrencyEscalates handler timeout diagnostics.
strictDeterminismEnables deterministic scheduling checks and defaults.
strictDomSandboxEnforces the DOM API sandbox.
strictErrorsWarns when non-AppError values enter the error pipeline.
strictFormsEscalates form validation discipline diagnostics.
strictI18nEscalates i18n diagnostics.
strictLifecycleEscalates lifecycle violations.
strictReactiveGraphEscalates reactive dependency cycle warnings.
strictRoutingEscalates defended-routing diagnostics.
strictThemingEscalates theming sandbox diagnostics.
strictTypeContractsControls runtime type-contract validation strictness.
strictUdcSandboxEnforces UDC scope and capability contracts.
strictVersioningEscalates enforced-versioning diagnostics.
syncExecutionTimeoutSets the synchronous expression execution timeout.
udcTrustControls handling of UDCs marked trust="untrusted".
useHashBasedRoutingSelects hash-based or history-based routing.
withXSRFTokenAdds the XSRF token header to same-origin API requests.
xsVerboseEnables verbose XMLScript and data loader diagnostics.
xsVerboseLogMaxLimits verbose diagnostic log entries.

Keys in this table are read through the merged compatibility view, so placing them under appGlobals continues to work for now. Prefer xmluiConfig for all new code.


Settings

apiUrl

apiUrl?: string;

The base URL prepended to all relative API request URLs. When set, data sources, API calls, file actions, and managed fetches that use a relative URL, such as /api/contacts, are resolved against this base.

xmluiConfig: {
  apiUrl: "https://api.example.com",
}

applyLayoutProperties

applyLayoutProperties?: "all" | "dims" | "spacing" | "none";

Controls which layout properties the rendering engine applies to components. This restriction applies to both base properties, such as backgroundColor, and responsive variants, such as backgroundColor-lg. It is useful when embedding XMLUI into a host application that manages its own layout.

ValueBehavior
"all"All layout properties are applied (default).
"dims"Only dimension properties are applied: width, height, minWidth, maxWidth, minHeight, maxHeight.
"spacing"Dimension properties plus spacing: gap, padding*, margin* and their variants. Other properties like borders, colors, and typography are ignored.
"none"No layout properties are applied; the markup values are silently ignored.
xmluiConfig: {
  applyLayoutProperties: "spacing",
}

defaultToOptionalMemberAccess

defaultToOptionalMemberAccess?: boolean; // default: true

When true, property access expressions in XMLScript use optional chaining semantics. Accessing a property of undefined or null returns undefined instead of throwing an error. Set to false to use strict member access and surface access errors explicitly.

xmluiConfig: {
  defaultToOptionalMemberAccess: false,
}

blog

blog?: {
  posts: BlogPost[];
};

Configuration for the Blog component. Must contain at least a posts array of blog post objects. Additional layout behavior, table of contents, and tag display are controlled via theme variables on the Blog component.


codeHighlighter

codeHighlighter?: CodeHighlighter;

An object conforming to the CodeHighlighter interface that provides syntax highlighting for code blocks inside Markdown and CodeFence components. When not set, code blocks are rendered as plain text unless a global browser highlighter is present.


columnCanSortDefault

columnCanSortDefault?: boolean;

Overrides the default canSort value for Column components that do not set canSort explicitly.

xmluiConfig: {
  columnCanSortDefault: false,
}

compileScripts

compileScripts?: boolean; // default: false

One switch for script compilation. When true, XMLUI compiles every script it can to JavaScript: binding expressions, event handlers, inline <script> functions, .xmlui.xs code-behind, Globals.xs, imported .xs helpers, and inline component codeBehind. There is no per-path variant to set — this key decides for all of them.

xmluiConfig: {
  compileScripts: true,
}

Where it is read from. The app description (src/config.ts in Vite mode, config.json in standalone mode) under xmluiConfig or appGlobals, and xmlui.config.json — at its top level or nested under either record. When the same key appears in more than one place, xmlui.config.json wins over xmluiConfig, which wins over appGlobals. App descriptions that only Vite can evaluate — the getLocalIcons() pattern uses import.meta.glob, for instance — are loaded through Vite's module runner, so the switch is honoured there too.

Where compilation happens. xmlui start and xmlui build compile handlers, code-behind, and script declarations into the emitted modules. Binding expressions compile on first use in the browser: prop values are stored as strings and parsed there, so there is no build-time artifact to carry — a build's artifact count says nothing about bindings, and counting compiled: objects in a bundle will never find one. Either way the same switch decides.

Because bindings compile in the browser, the browser has to know the setting. xmlui.config.json lives on the build machine, so xmlui start and xmlui build bake whatever it states into the app; the app description reaches the browser on its own. The one line that tells you which mode an app is really running in is the startup line in the browser console:

[xmlui] App started in compiled script mode

If that says interpreted while your build reported compiled artifacts, the switch is reaching the build tooling but not the app.

Source maps for compiled scripts are not configurable: xmlui start turns them on, builds leave them out — the payload is large and a production bundle has no use for it.

strictCompilation

strictCompilation?: boolean | "off" | "report" | "error"; // default: "report" with compileScripts

Controls what happens when a script would run interpreted. Inert without compileScripts — there would be nothing to be strict about — and the CLI says so rather than ignoring the combination.

ValueMeaning
unset"report" when compileScripts is on. Every interpretation is named in the console; nothing fails.
true / "error"Interpretation is an error. xmlui build fails, and the runtime throws.
false / "off"Silent fallbacks, as before.

Reporting is the default rather than failing on purpose. A hard-error default would break an app the moment it met any interpretation nobody predicted — and finding out what nobody predicted is the whole reason to have this on. Each distinct site is reported once, not once per evaluation, because these guards sit on per-row, per-render paths.

It catches more than a refused construct. A script can end up interpreted three ways, and only the first leaves a trace today:

  1. the compiler refused a construct and the caller fell back;
  2. the compiled path chose to interpret — a lazy arrow, or anything routed through the synchronous statement queue, which has no compiled target;
  3. the evaluation context never carried compileScripts at all.

So the rule is not "no fallbacks" but "no interpretation", enforced at the interpreter's own entry points. An app can report zero fallbacks while running mostly interpreted; strict mode is what makes that visible.

xmlui build fails and prints every violation, sorted by file, so a project adopting strict mode does not discover its constructs one build at a time. xmlui start reports them and keeps serving.

What still gets reported. The remaining interpretation is narrow: a construct the compiler refuses — today only an async arrow — and a mock backend in an app that declares compileScripts in its app description rather than in xmlui.config.json. Synchronous callbacks, helper functions called from bindings, and arrows stored in data all compile.

What compilation reports

xmlui start and xmlui build always report what compilation produced:

[xmlui] Script compilation: 128 compiled artifact(s) (74 event handler(s), 54 declaration function(s)) from 130 script block(s) in 24 file(s), 2 fell back to interpretation (unsupported construct)
[xmlui] Binding expressions (`var.` initializers and attribute bindings) are not compiled here: prop values are parsed lazily in the browser, so each one compiles on its first evaluation and is cached. The app's startup line reports the mode it actually runs in.

The counts name the kinds on purpose. A single total could read as complete success while a whole category sat at zero, and bindings — which never appear in these counts — are the category most apps care about most.

At startup the app repeats the effective state in the browser console:

[xmlui] App started in compiled script mode
[xmlui] Script artifacts: 128 compiled at build time, 2 fell back to interpretation. Fallback reasons: compile-unserializable-literal: literal cannot be carried into interpreted execution at line 12, column 24. Binding expressions are not counted here; they compile on first evaluation.

Every block that fell back also carries its reason as compiledUnsupportedReason in the emitted module, so the state is checkable from a built bundle and not only from a console. For per-block detail, turn on reportCompileFallbacks.

What compiles

Both compiler targets accept the same language surface: literals, identifiers, member access, operators and assignments, conditional (a ? b : c) and sequence expressions, array / object / template literals including spread, function invocation, new, and arrow functions. The event-handler target additionally compiles statements — if, loops, switch, try, throw, destructuring declarations, and nested function declarations. Arrow callbacks passed to array methods (.some(), .filter(), .map(), .forEach()) compile to native JavaScript functions.

Two constructs never compile, because XMLScript does not support them at all: await expressions and async arrow functions. A regular-expression literal compiles unless it sits inside an arrow that has to be handed to the interpreter, since it cannot be serialised into one.

Compiled and interpreted execution are expected to agree. If you find a case where they do not, that is a bug — please report it.


reportCompileFallbacks

reportCompileFallbacks?: boolean; // default: false

Reports every script block that could not be compiled — at build time in the CLI output, and at run time in the browser console:

[xmlui] compile-unsupported-node: /src/Globals.xs#function-roleHint
        await expression at line 4, column 12 — falling back to interpretation
xmluiConfig: {
  compileScripts: true,
  reportCompileFallbacks: true,
}

Each report carries one of these codes:

CodeMeaning
compile-unsupported-nodethe compiler met a construct it cannot emit (await, an async arrow)
compile-unserializable-literala literal the emitter cannot write into generated JavaScript. Regular expressions used to report this; they compile now
compile-runtime-fallbacka compiled block reported an unsupported construct while running and the interpreter took over
compile-source-unavailablecompilation failed for some other reason

With the flag off, the counts above are still reported and the reason still travels with the block — only the per-block console detail is withheld. Fallbacks are also recorded as kind:"compile" Inspector entries whenever xsVerbose is on.


disableInlineStyle

disableInlineStyle?: boolean; // default: false

When true, inline style properties such as backgroundColor, color, and padding set directly on components in markup are not applied. Dimension-related properties (width, height, and their min/max variants) are still applied because they participate in flex layout. Use this when the host application manages styling exclusively through its own CSS.

Individual Theme components can override this per-subtree via their own disableInlineStyle property.

xmluiConfig: {
  disableInlineStyle: true,
}

errorResponseTransform

errorResponseTransform?: string;

An XMLScript expression that transforms API error responses before XMLUI surfaces them. The expression receives the response as $response.

{
  "xmluiConfig": {
    "errorResponseTransform": "{ $response.message || $response.error || 'Request failed' }"
  }
}

headers

headers?: Record<string, string>;

A dictionary of HTTP headers added to outgoing API requests. Headers specified per request override these defaults.

xmluiConfig: {
  headers: {
    Authorization: "Bearer my-token",
    "X-App-Version": "1.0.0",
  },
}

lintSeverity

lintSeverity?: "warning" | "error" | "strict" | "skip"; // default: "warning"

Controls how standalone startup validation issues are shown in the browser. These issues come from the type-contract verifier, such as unknown props, invalid literal values, missing required props, unknown events, and unknown exposed methods.

ValueBehavior
"warning"Issues are printed to the browser console as warnings (default).
"error"Issues block app rendering and are displayed as an error screen.
"strict"Issues are displayed as toast notifications in the UI and also printed to the browser console.
"skip"Standalone startup validation is disabled.
xmluiConfig: {
  lintSeverity: "error",
}

logRestApiErrors

logRestApiErrors?: boolean; // default: false

When true, REST API response parsing errors are logged to the browser console. This is useful during development when diagnosing unexpected API response shapes.

xmluiConfig: {
  logRestApiErrors: true,
}

notifications

notifications?: {
  duration?: number;
  position?: "top-start" | "top-center" | "top-end" | "bottom-start" | "bottom-center" | "bottom-end";
};

Configuration for toast notifications.

Position valueDescription
"top-start"Top-left corner.
"top-center"Top edge, horizontally centered.
"top-end"Top-right corner.
"bottom-start"Bottom-left corner.
"bottom-center"Bottom edge, horizontally centered.
"bottom-end"Bottom-right corner (default).
xmluiConfig: {
  notifications: {
    duration: 5000,
    position: "top-end",
  },
}

prefetchedContent

prefetchedContent?: Record<string, string>;

A dictionary mapping URL paths to pre-fetched content strings. XMLUI data loading checks this map before it needs fetched content, which helps avoid redundant network requests for content already available at startup.

xmluiConfig: {
  prefetchedContent: {
    "/pages/home.md": "# Welcome",
  },
}

searchIndexEnabled

searchIndexEnabled?: boolean; // default: false

When true, the Pages component walks all Page children at startup and builds an in-memory search index. This is required for full-text search to work in apps that use the search components.

xmluiConfig: {
  searchIndexEnabled: true,
}

showHeadingAnchors

showHeadingAnchors?: boolean; // default: false

When true, heading components (H1-H6) and markdown headings display a clickable anchor icon that lets users link directly to that heading. Individual headings can override this with their own showAnchor or showHeadingAnchors property.

xmluiConfig: {
  showHeadingAnchors: true,
}

syncExecutionTimeout

syncExecutionTimeout?: number; // default: 1000ms

Affects the synchronous expression execution timeout for bindings in markup attributes. If an expression times out, an error is thrown.

xmluiConfig: {
  syncExecutionTimeout: 500,
}

useHashBasedRouting

useHashBasedRouting?: boolean; // default: true (standalone mode)

Selects the routing strategy used by the app.

ValueBehavior
trueHash-based routing (/#/path). Works on any static file server without server-side URL rewriting.
falseHistory-based routing (/path). Requires the server to serve index.html for all routes.
xmluiConfig: {
  useHashBasedRouting: false,
}

withXSRFToken

withXSRFToken?: boolean; // default: true

When true, the engine reads the XSRF-TOKEN cookie and includes it as an X-XSRF-TOKEN header on all same-origin API requests. Set to false to disable this behavior if your backend does not use XSRF token validation.

xmluiConfig: {
  withXSRFToken: false,
}

xsVerbose

xsVerbose?: boolean; // default: false

When true, the engine emits detailed diagnostic logs for XMLScript expression evaluation and data loader activity to the browser console. This is useful for debugging reactive data flows and script execution.

xmluiConfig: {
  xsVerbose: true,
}

xsVerboseLogMax

xsVerboseLogMax?: number; // default: 200

Limits the number of log entries emitted when xsVerbose is true. This prevents the console from being overwhelmed in apps with many reactive expressions.

xmluiConfig: {
  xsVerbose: true,
  xsVerboseLogMax: 50,
}

Managed React settings

Managed React features use xmluiConfig for their framework/runtime switches. The detailed behavior is documented in the Managed React articles; this table is the central placement and default reference.

KeyDefaultSee
allowConsoletrueDOM API Isolation
allowedOriginsunsetCentralized HTTP
allowInlineRawCsstrueSealed Theming Sandbox
auditPolicyunsetAudit-Grade Observability
autoSkipLinkfalseEnforced Accessibility
csrfHeaderName"X-CSRF-Token"Forms Validation Discipline
defaultHandlerTimeoutMs30000Cooperative Concurrency
defaultLocale"en"I18n Foundations
disposeTimeoutMs250Managed Lifecycle Vocabulary
errorBufferSize50Structured Exception Model
guardOnPopStatetrueDefended Routing
idempotencyHeaderName"Idempotency-Key"Forms Validation Discipline
interceptExternalNavigationfalseDefended Routing
localeBundlesunsetI18n Foundations
localePersistKey"xmlui.locale"I18n Foundations
maxQueuedPerTrace64Concurrent State Determinism
maxZIndex9999Sealed Theming Sandbox
requireFormCsrffalseForms Validation Discipline
scheduler"concurrent"; "fifo" when strictDeterminism is onConcurrent State Determinism
strictAccessibilityfalseEnforced Accessibility
strictAuditLoggingtrueAudit-Grade Observability
strictConcurrencyfalseCooperative Concurrency
strictDeterminismtrueConcurrent State Determinism
strictDomSandboxfalseDOM API Isolation
strictErrorstrueStructured Exception Model
strictFormsfalseForms Validation Discipline
strictI18nfalseI18n Foundations
strictLifecycletrueManaged Lifecycle Vocabulary
strictReactiveGraphtrueReactive Cycle Detection
strictRoutingtrueDefended Routing
strictThemingtrueSealed Theming Sandbox
strictTypeContractstrueVerified Type Contracts
strictUdcSandboxtrueUDC Sandbox
strictVersioningfalseEnforced Versioning
udcTrust"open"UDC Sandbox

strictBuildValidation is discussed in Build Validation Analyzers. Build-time strictness is currently selected through the CLI or Vite plugin; the xmluiConfig.strictBuildValidation name is reserved for the app-wide switch described there.