Content and resource loading
For Avalonia and Uno applications, package content for the framework's
WebSceneComponentHost. Both hosts validate the manifest, perform compatibility
preflight, and serve only declared assets from an isolated per-instance virtual
origin. Direct document URLs remain available for advanced presenter-level use.
Recommended component package
components/
StatusPanel/
webscene-component.json
dist/
main.js
styles.css
{
"schemaVersion": "1.0",
"id": "com.example.status-panel",
"displayName": "Status panel",
"version": "1.0.0",
"profileVersion": "1.0",
"entryPoint": "dist/main.js",
"assets": [
"dist/main.js",
"dist/styles.css"
],
"capabilities": [
"dom",
"css.layout"
]
}
<ItemGroup>
<Content Include="components/**"
CopyToOutputDirectory="PreserveNewest"
CopyToPublishDirectory="PreserveNewest" />
</ItemGroup>
<ws:WebSceneComponentHost
PackagePath="components/StatusPanel" />
PackagePath is resolved against AppContext.BaseDirectory. The host creates a
unique https://<instance>.component.webscene.invalid/ origin for each mounted
instance. A request succeeds only when it stays on that origin and its normalized
relative path appears in the manifest's assets array.
Component Profile 1 currently serves UTF-8 text assets. Declare the entry point and
every script or stylesheet it loads. Binary assets, undeclared files, absolute external
origins, .. traversal, and malformed paths are rejected by the package loader.
The entry point itself is evaluated after the empty component document and
capability-gated host bridge are ready. It must publish the manifest's mount and
unmount lifecycle exports on globalThis; it is not an HTML document.
See Package and host a component for a complete package.
Advanced direct-document layout
Keep the web bundle together and copy it without flattening its directory structure:
MyApp/
web/
index.html
app.js
styles.css
assets/
logo.svg
app.woff2
<ItemGroup>
<Content Include="web/**" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
When using NativeWebSceneView directly, load index.html through an absolute file
URI:
var documentPath = Path.Combine(
AppContext.BaseDirectory,
"web",
"index.html");
var documentUri = new Uri(documentPath).AbsoluteUri;
await webSceneView.LoadAsync(
documentUri,
nativeLibraryPath,
compilationCacheDirectory,
cancellationToken);
Relative references such as ./app.js and ./assets/logo.svg then resolve against the
document directory. Avoid building file: URLs by string concatenation; Uri handles
platform separators and escaping.
Direct-document resource schemes by host
The direct presenters do not expose identical resource loaders. These schemes do not change the component host's manifest-isolated resource policy:
| Scheme | Avalonia | Uno Skia | Notes |
|---|---|---|---|
file: |
Yes | Yes | Best-supported packaged-content path |
http: / https: |
Yes | Yes | Uses an internal HttpClient; HTTP cache validators are honored |
data: |
Yes | Yes | Text and inline data; use only for bounded content |
avares: |
Yes | No | Loads Avalonia application resources through AssetLoader |
Use file: when the same bundle must run unchanged in Avalonia and Uno. Avalonia-only
applications can load an avares: resource, but external files are easier to inspect,
update during development, and share with native/headless fixtures.
Direct HTTP and HTTPS content
Both loaders follow relative URLs from an absolute HTTP(S) document and retain common
cache metadata such as ETag, Last-Modified, Cache-Control, and Expires. An HTTP
error fails the resource request rather than silently substituting empty content.
Remote loading does not turn WebScene into a safe general-purpose browser. Only load origins and content controlled by the application. The built-in views do not expose a public per-request allow/deny callback, certificate policy, cookie profile, or browser permission model.
For reproducible UI and offline behavior, prefer a versioned local bundle. If remote content is necessary, pin the endpoint, define an application-level update policy, and test failure and stale-cache behavior.
Direct Avalonia resources
The Avalonia loader understands avares: URLs:
await webSceneView.LoadAsync(
"avares://MyApp/Assets/Web/index.html",
nativeLibraryPath,
compilationCacheDirectory,
cancellationToken);
Mark the files as AvaloniaResource in the application project. Every relative
resource must be reachable through the same asset URI structure. This path is specific
to Avalonia and should not be used in a framework-neutral document configuration.
AvaloniaResourceLoader also exposes search-directory and mounted-directory helpers
for advanced backend integrations. NativeWebSceneView creates and owns its default
loader internally, so its standard public loading surface does not currently offer a
hook to configure those helpers.
Document-start scripts
Set WebSceneComponentHost.DocumentStartScripts before mounting a component. When
hosting a document directly, use
NativeWebSceneLoadOptions.DocumentStartScripts for the same ordered startup hook:
var options = new NativeWebSceneLoadOptions
{
Source = documentUri,
NativeLibraryPath = nativeLibraryPath,
CompilationCacheDirectory = compilationCacheDirectory,
DocumentStartScripts =
[
new WebSceneDocumentScript(
"globalThis.appHost = Object.freeze({ version: '1.0' });",
"app-host.js",
AllFrames: false)
]
};
await webSceneView.LoadAsync(options, cancellationToken);
Scripts execute in list order. A script exception fails the initial load and records
its configured name in native diagnostics. AllFrames: true also injects the script
before authored code in subsequently created frames.
Keep these scripts static and application-owned. Do not interpolate unescaped user or network data into JavaScript source. Use generated typed interop for runtime values and commands.
Storage behavior
The current native runtime supplies synchronous in-memory localStorage and
sessionStorage for the engine/page lifetime. It implements the common item methods
and stable insertion order, but does not promise persistence, quotas, storage events,
origin/reload semantics, shared profiles, or IndexedDB.
Do not store durable application state in the WebScene storage subset. Persist through an explicit application service and expose only the narrow operations the trusted document needs.
Content update checklist
When replacing a packaged web bundle:
- Review the changed HTML, JavaScript, CSS, fonts, and binary assets as application code.
- Run the required WebScene compatibility profile plus a product-specific fixture.
- Regenerate and review typed interop manifests if TypeScript declarations changed.
- Verify the bundle from publish output, not only from the source directory.
- Exercise missing-resource, offline, and slow-resource behavior.
See Compatibility and security for the support and trust boundaries that apply to every content strategy.