Bumps [@angular/platform-browser-dynamic](https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic) from 21.2.16 to 22.0.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/angular/angular/releases">@angular/platform-browser-dynamic's releases</a>.</em></p> <blockquote> <h2>VSCode Extension: 22.0.0</h2> <h3>Breaking Changes</h3> <p>The extension now bundles TypeScript version 6.0, which itself includes breaking changes, including <a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-6-0.html#simple-default-changes">new defaults</a> such as <code>strict</code> being <code>true</code>. You will need to explicitly set <code>"strict": false</code> in your <code>tsconfig.json</code>. Alternatively, the extension supports configuring the <code>tsdk</code> in the <a href="https://code.visualstudio.com/docs/typescript/typescript-transpiling#_using-the-workspace-version-of-typescript">same way</a> as the built in TS/JS extension.</p> <h3>Fixes and features</h3> <ul> <li>fix(language-service): Add support for <code>@Input</code> with transforms (<a href="dc9c72da9b">dc9c72da9b</a>)</li> <li>feat(language-service): add Document Symbols support for Angular templates (<a href="cfd0f9950c">cfd0f9950c</a>)</li> <li>feat(language-service): add angular template inlay hints support (<a href="5a6d88626b">5a6d88626b</a>)</li> <li>feat(language-service): Add support for idle timeout in defer blocks (<a href="c6f98c723c">c6f98c723c</a>)</li> </ul> <h2>22.0.0</h2> <h3>compiler</h3> <table> <thead> <tr> <th>Commit</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><a href="47fcbc4704"><img src="https://img.shields.io/badge/47fcbc4704-feat-blue" alt="feat - 47fcbc4704" /></a></td> <td>allow safe navigation to correctly narrow down nullables</td> </tr> <tr> <td><a href="2896c93cc1"><img src="https://img.shields.io/badge/2896c93cc1-feat-blue" alt="feat - 2896c93cc1" /></a></td> <td>Angular expressions with optional chaining returns <code>undefined</code></td> </tr> <tr> <td><a href="e850643b1b"><img src="https://img.shields.io/badge/e850643b1b-feat-blue" alt="feat - e850643b1b" /></a></td> <td>Support comments in html element.</td> </tr> <tr> <td><a href="96be4f429b"><img src="https://img.shields.io/badge/96be4f429b-fix-green" alt="fix - 96be4f429b" /></a></td> <td>abstract emitter producing incorrect code for dynamic imports</td> </tr> <tr> <td><a href="488d962bc7"><img src="https://img.shields.io/badge/488d962bc7-fix-green" alt="fix - 488d962bc7" /></a></td> <td>Don't bind inputs/outputs for <code>data-</code> attributes</td> </tr> <tr> <td><a href="2c5aabb9da"><img src="https://img.shields.io/badge/2c5aabb9da-fix-green" alt="fix - 2c5aabb9da" /></a></td> <td>don't escape dollar sign in literal expression</td> </tr> <tr> <td><a href="c7aef8ec5d"><img src="https://img.shields.io/badge/c7aef8ec5d-fix-green" alt="fix - c7aef8ec5d" /></a></td> <td>enforce parentheses containing arguments for :host-context</td> </tr> <tr> <td><a href="b225a5d902"><img src="https://img.shields.io/badge/b225a5d902-fix-green" alt="fix - b225a5d902" /></a></td> <td>invalid type checking code if field name needs to be quoted</td> </tr> <tr> <td><a href="ab9154ab75"><img src="https://img.shields.io/badge/ab9154ab75-fix-green" alt="fix - ab9154ab75" /></a></td> <td>normalize tag names with custom namespaces in DomElementSchemaRegistry (<a href="https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic/issues/68868">#68868</a>)</td> </tr> <tr> <td><a href="8a1533c9ad"><img src="https://img.shields.io/badge/8a1533c9ad-fix-green" alt="fix - 8a1533c9ad" /></a></td> <td>preserve leading commas in animation definitions</td> </tr> <tr> <td><a href="194f723f66"><img src="https://img.shields.io/badge/194f723f66-fix-green" alt="fix - 194f723f66" /></a></td> <td>remove dedicated support for legacy shadow DOM selectors</td> </tr> <tr> <td><a href="4c25a42e98"><img src="https://img.shields.io/badge/4c25a42e98-fix-green" alt="fix - 4c25a42e98" /></a></td> <td>remove deprecated shadow CSS encapsulation polyfills</td> </tr> <tr> <td><a href="6ff620a033"><img src="https://img.shields.io/badge/6ff620a033-fix-green" alt="fix - 6ff620a033" /></a></td> <td>sanitize dynamic href and xlink:href bindings on SVG a elements (<a href="https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic/issues/68868">#68868</a>)</td> </tr> <tr> <td><a href="7dc1017e51"><img src="https://img.shields.io/badge/7dc1017e51-fix-green" alt="fix - 7dc1017e51" /></a></td> <td>simplify handling of colon host with a selector list</td> </tr> <tr> <td><a href="d99ab0e040"><img src="https://img.shields.io/badge/d99ab0e040-fix-green" alt="fix - d99ab0e040" /></a></td> <td>stop generating unused field</td> </tr> <tr> <td><a href="03db2aefaa"><img src="https://img.shields.io/badge/03db2aefaa-fix-green" alt="fix - 03db2aefaa" /></a></td> <td>throw on duplicate input/outputs</td> </tr> <tr> <td><a href="786ef8261f"><img src="https://img.shields.io/badge/786ef8261f-fix-green" alt="fix - 786ef8261f" /></a></td> <td>throw on invalid in expressions</td> </tr> <tr> <td><a href="ccb7d427e4"><img src="https://img.shields.io/badge/ccb7d427e4-fix-green" alt="fix - ccb7d427e4" /></a></td> <td>type check invalid for loops</td> </tr> </tbody> </table> <h3>compiler-cli</h3> <table> <thead> <tr> <th>Commit</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><a href="b8d3f36ed9"><img src="https://img.shields.io/badge/b8d3f36ed9-feat-blue" alt="feat - b8d3f36ed9" /></a></td> <td>add support for Node.js 26.0.0</td> </tr> <tr> <td><a href="7f9450219f"><img src="https://img.shields.io/badge/7f9450219f-feat-blue" alt="feat - 7f9450219f" /></a></td> <td>Adds warning for prefetch without main defer trigger</td> </tr> <tr> <td><a href="2eae497a04"><img src="https://img.shields.io/badge/2eae497a04-feat-blue" alt="feat - 2eae497a04" /></a></td> <td>support external TCBs with copied content in specific mode</td> </tr> <tr> <td><a href="e5f96c2d88"><img src="https://img.shields.io/badge/e5f96c2d88-fix-green" alt="fix - e5f96c2d88" /></a></td> <td>animation events not type checked properly when bound through HostListener decorator</td> </tr> <tr> <td><a href="9218140348"><img src="https://img.shields.io/badge/9218140348-fix-green" alt="fix - 9218140348" /></a></td> <td>resolve TCB mapping failure for safe property reads with as any</td> </tr> <tr> <td><a href="7a0d6b8df2"><img src="https://img.shields.io/badge/7a0d6b8df2-fix-green" alt="fix - 7a0d6b8df2" /></a></td> <td>transform dropping exclamationToken from properties</td> </tr> <tr> <td><a href="ca67828ee2"><img src="https://img.shields.io/badge/ca67828ee2-refactor-yellow" alt="refactor - ca67828ee2" /></a></td> <td>introduce NG8023 compile-time diagnostic for duplicate selectors</td> </tr> </tbody> </table> <h3>core</h3> <table> <thead> <tr> <th>Commit</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><a href="17d3ea44e2"><img src="https://img.shields.io/badge/17d3ea44e2-feat-blue" alt="feat - 17d3ea44e2" /></a></td> <td>add <code>IdleRequestOptions</code> support to <code>IdleService</code></td> </tr> <tr> <td><a href="3b0ae5fef0"><img src="https://img.shields.io/badge/3b0ae5fef0-feat-blue" alt="feat - 3b0ae5fef0" /></a></td> <td>add <code>provideWebMcpTools</code></td> </tr> </tbody> </table> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/angular/angular/blob/main/CHANGELOG.md">@angular/platform-browser-dynamic's changelog</a>.</em></p> <blockquote> <h1>22.0.0 (2026-06-03)</h1> <p><a href="https://goo.gle/angular-v22-blog">Blog post "Announcing Angular v22"</a>.</p> <h2>Breaking Changes</h2> <h3>compiler</h3> <ul> <li>This change will trigger the <code>nullishCoalescingNotNullable</code> and <code>optionalChainNotNullable</code> diagnostics on exisiting projects. You might want to disable those 2 diagnotiscs in your <code>tsconfig</code> temporarily.</li> <li>data prefixed attribute no-longer bind inputs nor outputs.</li> <li>The compiler will throw when there a when inputs, outputs or model are binding to the same input/outputs.</li> <li><code>in</code> variables will throw in template expressions.</li> </ul> <h3>compiler-cli</h3> <ul> <li>Elements with multiple matching selectors will now throw at compile time.</li> </ul> <h3>core</h3> <ul> <li>The second arguement of appRef.bootstrap does not accept <code>any</code> anymore. Make sure the element you pass is not nullable.</li> <li> <ul> <li>TypeScript versions older than 6.0 are no longer supported.</li> </ul> </li> <li>Leave animations are no longer limited to the element being removed.</li> <li>Component with undefined <code>changeDetection</code> property are now <code>OnPush</code> by default. Specify <code>changeDetection: ChangeDetectionStrategy.Eager</code> to keep the previous behavior.</li> <li>change AnimationCallbackEvent.animationComplete signature</li> <li><code>ChangeDetectorRef.checkNoChanges</code> was removed. In tests use <code>fixture.detectChanges()</code> instead.</li> <li><code>createNgModuleRef</code> was removed, use <code>createNgModule</code> instead</li> <li><code>ComponentFactoryResolver</code> and <code>ComponentFactory</code> are no longer available. Pass the component class directly to APIs that previously required a factory, such as <code>ViewContainerRef.createComponent</code> or use the standalone <code>createComponentFunction</code>.</li> <li><code>ComponentFactoryResolver</code> and <code>ComponentFactory</code> are no longer available. Pass the component class directly to APIs that previously required a factory, such as <code>ViewContainerRef.createComponent</code> or use the standalone <code>createComponent</code> function.</li> </ul> <h3>forms</h3> <ul> <li><code>min</code> and <code>max</code> validation rules no longer support string values. Bound values must be numbers or null.</li> </ul> <h3>http</h3> <ul> <li>Use the <code>HttpXhrBackend</code> with <code>provideHttpClient(withXhr)</code> if you want to keep supporting upload progress reports.</li> </ul> <h3>platform-browser</h3> <ul> <li>This removes styles when they appear to no longer be used by an associated <code>host</code>. However other DOM on the page may still be affected by those styles if not leveraging <code>ViewEncapsulation.Emulated</code> or if those styles are used by elements outside of Angular, potentially causing other DOM to appear unstyled.</li> <li>Hammer.js integration has been removed. Use your own implementation.</li> </ul> <h3>router</h3> <ul> <li> <p>The return type for <code>TitleStrategy.getResolvedTitleForRoute</code> was previously 'any' while the actual return type could only be either <code>string</code> or <code>undefined</code>. The return type now reflects the possible values correctly. Code that reads the value may need to be adjusted.</p> <p>(cherry picked from commit ad37f52c1212164c51ffcc533067af05c2c33c89)</p> </li> <li> <p>The <code>currentSnapshot</code> parameter in <code>CanMatchFn</code> and the <code>canMatch</code> method of the <code>CanMatch</code> interface is now required. While this was already the behavior of the Router at runtime, existing class implementations of <code>CanMatch</code> must now include the third argument to satisfy the interface.</p> </li> <li> <p>paramsInheritanceStrategy now defaults to 'always'</p> <p>The default value of paramsInheritanceStrategy has been changed from 'emptyOnly' to 'always'. This means that route parameters are inherited from all parent routes by default. To restore the previous behavior, set paramsInheritanceStrategy to 'emptyOnly' in your router configuration.</p> </li> <li> <p><code>provideRoutes()</code> has been removed. Use <code>provideRouter()</code> or <code>ROUTES</code> as multi token if necessary.</p> </li> </ul> <h3>upgrade</h3> <ul> <li>Deprecated <code>getAngularLib</code>/<code>setAngularLib</code> have been removed use <code>getAngularJSGlobal</code>/<code>setAngularJSGlobal</code> instead.</li> </ul> <h2>Deprecations</h2> <h3>http</h3> <ul> <li><code>withFetch</code> is now deprecated, it can be safely removed.</li> <li>The <code>reportProgress</code> option is deprecated please use <code>reportUploadProgress</code> & <code>reportDownloadProgress</code> instead.</li> </ul> <h3>compiler</h3> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="a97d5ec22d"><code>a97d5ec</code></a> build: update minimum supported Node.js versions</li> <li><a href="b8d3f36ed9"><code>b8d3f36</code></a> feat(compiler-cli): add support for Node.js 26.0.0</li> <li><a href="4ad3a1fe37"><code>4ad3a1f</code></a> refactor(core): Don't throw when there are not async metadata</li> <li><a href="7f3f3d7da1"><code>7f3f3d7</code></a> ci: remove remainings of saucelabs tests</li> <li><a href="d550bf713a"><code>d550bf7</code></a> build: update minimum supported Node.js versions</li> <li>See full diff in <a href="https://github.com/angular/angular/commits/v22.0.0/packages/platform-browser-dynamic">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details>
ng-flutter
This Angular project is a simple example of how Angular and Flutter web apps could be integrated, and have them interop.
Points of Interest
Angular
This repository is a quite standard Angular app. The following changes were made to be able to use (and interop) with a Flutter web application:
package.jsonhas a customprebuildscript that builds the Flutter web app, so Angular can find it later.flutter.jsis added as a"scripts"entry inangular.json. Angular takes care of minimizing and injecting it as any other script.- The rest of the flutter app
flutter/build/web/is registered as an"assets"entry inangular.json, and moved to/flutter. - The
ng-fluttercomponent takes care of embedding Flutter web, and yielding control to Angular through anappLoadedEventEmitter. The object yielded by this emitter is a state controller exposed by flutter via a JS custom event!
Flutter
The embedded Flutter application lives in the flutter directory of this repo.
That application is a standard web app, that doesn't need to be aware that it's
going to be embedded in another framework.
- Flutter uses new
@staticInteropmethods to allow certain Dart functions to be called from JavaScript. - Look at how
createDartExportandbroadcastAppEventwork together to make the_statecontroller of the Flutter app available to Angular!
How to build the app
Requirements
If you want to build and run this demo on your machine, you'll need a moderately recent version of Angular:
$ ng version
Angular CLI: 17.0.0
Node: 20.9.0
Package Manager: npm 10.1.0
OS: linux x64
And Flutter:
$ flutter --version
Flutter 3.13.9 • channel stable
Framework • revision d211f42860 (2 weeks ago) • 2023-10-25 13:42:25 -0700
Engine • revision 0545f8705d
Tools • Dart 3.1.5 • DevTools 2.25.0
Ensure npm, ng and flutter are present in your $PATH.
Building the app
This repository is a moderately standard Angular app. It integrates
Flutter web by making it part of the Angular assets.
In order to build this app, first fetch its npm dependencies:
$ npm install
added 963 packages, and audited 964 packages in 17s
93 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Then run the build script. It'll take care of building Flutter
automatically:
$ npm run build
> ng-flutter@0.0.0 prebuild
... Flutter web build output ...
Compiling lib/main.dart for the Web...
> ng-flutter@0.0.0 build
> ng build
... Angular build output ...
✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.
Local Angular development
Once you've reached this point, you should be able to work with your Angular application normally, for example to run a local web server:
$ npm run start
> ng-flutter@0.0.0 start
> ng serve
✔ Browser application bundle generation complete.
Initial Chunk Files | Names | Raw Size
vendor.js | vendor | 4.38 MB |
... Angular build output...
** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ **
✔ Compiled successfully.
Navigate to http://localhost:4200/. The application will automatically reload
if you change any of its Angular source files.
Local Flutter web development
The Flutter app lives inside the flutter directory, and can be
developed independently. Just do any changes on Flutter web as you'd
normally do. It even includes a small web/index.html so you can see
changes to your app without running the whole Angular setup.
Note
For now, Angular does not auto-detect changes to your Flutter web app, so once you're happy with your Flutter web app, make sure to call
npm run buildso everything rebuilds and gets placed into its correct location.
Deploying the app
After npm run build, you should have a deployable Angular + Flutter
web app in the dist directory of this Angular project.
Your built app can can be deployed anywhere, but do check Firebase hosting for a super-easy deployment experience!
Troubleshooting
Flutter
Ensure your flutter app is properly rebuilt after any changes.
- Run
npm run buildto re-build the Flutter app.
If you encounter error messages like:
Error: Can't resolve 'flutter/build/web/flutter.js' in '/my/checkout/of/ng-flutter'
You definitely need to run npm run build!
Reach out to the team(s)!
Have you had any problem not covered in this README? Do you want to see other embedding examples?
Let us know by creating an issue or opening a new pull request.
Thanks!