Skip to content

Initialization

XWidget initializes with a single call in your main(). Paths, component registration, and resource loading are all handled — the only thing you need to pass is the generated registry function.

import 'package:flutter/material.dart';
import 'package:xwidget/xwidget.dart';

import 'xwidget/generated/registry.g.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await XWidget.initialize(register: registerXWidgetComponents);

  runApp(MyApp());
}

This section walks through what each part does, and the common variations.

The initialize Signature

static Future<void> initialize({
void Function()? register,
Resources? resources,
Level logLevel = Level.INFO,
bool verboseErrors = false,
});

All four parameters are optional.

  • register — a callback that registers your generated components and sets XWidget.config. In normal use, pass registerXWidgetComponents from the generated registry.g.dart. See Registry.

  • resources — the resource provider. Defaults to a LocalResources() with the paths from XWidget.config. Pass an explicit instance to customize behavior or to switch to cloud-hosted resources. See LocalResources and CloudResources.

  • logLevel — log level for the logging package's root logger. Defaults to Level.INFO. Set to Level.FINE or lower to see diagnostic output from XWidget's internals during development.

  • verboseErrors — when true, XML inflation errors include a dump of the failing element and the surrounding dependencies in the log output. Defaults to false.

Default Behavior

Without any arguments, XWidget.initialize() loads resources from the asset bundle at the default paths (resources/fragments and resources/values) and registers nothing — meaning no fragments will inflate because no inflaters are registered. You always pass at least register.

The minimal app is:

await XWidget.initialize(register: registerXWidgetComponents);

That reads XWidget.config from the generated registry, creates a default LocalResources that picks up those paths, and activates it.

Custom Local Paths

If your project keeps fragments or values in non-default locations, configure the paths once in xwidget_config.yaml and the registry will carry them through:

fragmentsPath: "assets/ui/fragments"
valuesPath: "assets/ui/values"

After regenerating, the paths appear in XWidget.config automatically. No changes to main() needed.

For per-environment overrides, pass them directly to LocalResources:

await XWidget.initialize(
  register: registerXWidgetComponents,
  resources: LocalResources(
    fragmentsPath: 'assets/ui/fragments',
    valuesPath: 'assets/ui/values',
  ),
);

Local Resources with Analytics

To collect XWidget Cloud analytics without serving UI from the cloud, use LocalResources.withAnalytics:

await XWidget.initialize(
  register: registerXWidgetComponents,
  resources: LocalResources.withAnalytics(
    projectKey: '<your-project-key>',
    version: '1.0.0',
  ),
);

This loads resources from your app's asset bundle exactly like LocalResources(), but also boots the analytics client so renders, errors, and navigation transitions flow to XWidget Cloud. The channel is implicitly 'local'.

See LocalResources.

Cloud Resources

To serve UI from XWidget Cloud, use CloudResources:

await XWidget.initialize(
  register: registerXWidgetComponents,
  resources: CloudResources(
    projectKey: '<your-project-key>',
    storageKey: '<your-storage-key>',
    channel: 'production',
    version: '1.0.0',
  ),
);

CloudResources downloads the revision the channel currently serves for the given version, verifies and caches it, and falls back to a previously cached bundle on network errors. If nothing is cached, it falls back further to local assets at the same paths.

See CloudResources.

Custom Resource Providers

The Resources class is public and subclassable. If you self-host bundles, have a proprietary delivery mechanism, or need custom loading logic (encrypted archives, multi-tenant switching, offline-first strategies), extend Resources directly.

Minimum contract:

class MyResources extends Resources {
  @override
  Future<void> load() async {
    // Populate a FragmentResourceBundle and ValueResourceBundle,
    // then register them.
    final fragments = FragmentResourceBundle('fragments');
    final values = ValueResourceBundle('values');

    // ... load your content into the bundles ...

    replaceResourceBundles([fragments, values]);
  }
}

await XWidget.initialize(
  register: registerXWidgetComponents,
  resources: MyResources(),
);

Use CloudResources as a reference implementation — it demonstrates download, verification, caching, and fallback patterns you may want to adapt.