Migrating to package:web

AngularDart 9.0 introduces a breaking change: all DOM APIs have been migrated from dart:html to package:web. This guide covers everything you need to know to migrate your application.

Why the Change?

dart:html has been deprecated by the Dart team in favor of package:web, which provides:

  • Better JS interop — Direct compatibility with JavaScript types via dart:js_interop
  • Smaller output — More efficient compilation to JavaScript
  • Modern API — Aligned with current web standards
  • Future-proofdart:html will be removed in a future Dart SDK version

What Changed

Import Changes

Replace all dart:html imports with package:web:

// Before (AngularDart 8.x)
import 'dart:html' as html;

// After (AngularDart 9.x)
import 'package:web/web.dart' as web;

Type Changes

All DOM types have been renamed:

dart:html (8.x) package:web (9.x)
html.Element web.Element
html.HtmlElement web.HTMLElement
html.DivElement web.HTMLDivElement
html.SpanElement web.HTMLSpanElement
html.InputElement web.HTMLInputElement
html.ButtonElement web.HTMLButtonElement
html.AnchorElement web.HTMLAnchorElement
html.ImageElement web.HTMLImageElement
html.Document web.Document
html.Window web.Window
html.Event web.Event
html.MouseEvent web.MouseEvent
html.KeyboardEvent web.KeyboardEvent

API Changes

Several DOM APIs have changed:

// element.classes → element.classList
element.classes.add('active');     // Before
element.classList.add('active');   // After

// element.parent → element.parentNode
html.Element? parent = element.parent;        // Before
web.Node? parent = element.parentNode;        // After

// element.remove() → parentNode?.removeChild()
element.remove();                              // Before
element.parentNode?.removeChild(element);      // After

// innerHTML setter requires .toJS
element.innerHtml = '<p>Hello</p>';           // Before
element.innerHTML = '<p>Hello</p>'.toJS;      // After (requires dart:js_interop)

// console.log requires .toJS for strings
html.window.console.log('Hello');             // Before
web.console.log('Hello'.toJS);               // After

Event Listeners

Event listeners now require .toJS conversion:

import 'dart:js_interop';

// Before (dart:html)
element.onClick.listen((event) {
  print('Clicked!');
});

// After (package:web)
element.addEventListener('click', (web.Event event) {
  print('Clicked!');
}.toJS);

NodeTreeSanitizer Removed

NodeTreeSanitizer has been removed. Use template + innerHTML instead:

// Before (AngularDart 8.x)
element.setInnerHtml(htmlContent, treeSanitizer: NodeTreeSanitizer.trusted);

// After (AngularDart 9.x)
element.innerHTML = htmlContent.toJS;

Step-by-Step Migration

1. Update Dependencies

dependencies:
  angulardart: '>=9.0.0 <10.0.0'
  web: '>=1.0.0 <2.0.0'

dev_dependencies:
  angulardart_compiler: '>=5.0.0 <6.0.0'

2. Update SDK Constraint

environment:
  sdk: '>=3.4.0 <4.0.0'

3. Replace Imports

Search and replace across your codebase:

# Find all files using dart:html
grep -r "dart:html" lib/

# Replace in each file
# import 'dart:html' as html; → import 'package:web/web.dart' as web;

4. Update Type References

Replace all html.* type references with web.*:

# Find all html.* references
grep -r "html\." lib/

5. Fix API Calls

Update the changed APIs (see table above).

6. Add dart:js_interop Import

For files using .toJS, add:

import 'dart:js_interop';

7. Fix Event Listeners

Convert all event listeners to use .toJS:

// Before
element.onClick.listen(handler);

// After
element.addEventListener('click', handler.toJS);

8. Run dart analyze

dart analyze

Fix any remaining issues.

Common Issues

"The argument type 'void Function(dynamic)' can't be assigned to 'JSFunction?'"

This means you need to add .toJS to your event handler:

// Wrong
element.addEventListener('click', handler);

// Correct
element.addEventListener('click', handler.toJS);

"The method 'toDart' isn't defined for 'JSFunction'"

Use explicit type conversion instead:

// Wrong
final handler = jsFunction.toDart;

// Correct
final handler = (jsFunction as JSFunction).toDart<void Function(web.Event)>();

"A value of type 'ElementRef' can't be assigned to 'HTMLElement'"

ElementRef.nativeElement returns Object in AngularDart 9.x. Cast explicitly:

final element = elementRef.nativeElement as web.HTMLElement;

Third-Party Packages

If you use third-party packages that depend on dart:html, check for updated versions that support package:web. Common packages:

Package package:web compatible version
angulardart >=9.0.0 <10.0.0
angulardart_components >=3.0.0 <4.0.0
angulardart_router >=5.0.0 <6.0.0
angulardart_forms >=6.0.0 <7.0.0

See Also