Angular — version compatibility
@mms/pdirect-pay is tested against Angular 17–21 with RxJS
7.8+. The package declares the full peer-dep range so npm won’t
complain on any of them.
Peer dependency declaration
Section titled “Peer dependency declaration”From package.json:
{ "peerDependencies": { "@angular/common": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0", "@angular/core": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0", "@angular/forms": "^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0", "rxjs": "^7.8.0" }}| Angular | Notes |
|---|---|
| 17 | Standalone components are stable. Some signals helpers (input() factory, output() factory) are experimental — the SDK does not use them. Works fully. |
| 18 | Signals stable. Defer blocks stable. Works fully. |
| 19 | Linked signals, signal-based forms. Works fully. |
| 20 | inject() improvements, deferrable views. Works fully. |
| 21 | Latest tested. Works fully. |
The SDK’s services return Observables, so RxJS is a peer dep, not
a bundled dep. We use BehaviorSubject, map, catchError, and
tap — all stable since RxJS 7.x.
If your app is on RxJS 8 (which became GA mid-Angular-21), the SDK works without changes.
Standalone vs NgModule
Section titled “Standalone vs NgModule”The SDK supports both. Every component is standalone: true
internally, so you can:
- Import
PdirectPayCheckoutComponentdirectly into your standalone app — no module imports needed beyondprovideHttpClient()and the two injection tokens. - Or import
PdirectPayModule.forRoot(...)once at the root for a classic module-based app.
There is no API difference between the two paths.
Zoneless mode
Section titled “Zoneless mode”The SDK uses Observables, not signals, internally. Both modes
work, but in zoneless mode you must not rely on Angular’s automatic
change detection between subscription emissions — wrap state
updates in signals on your end if you need them.
When the SDK migrates to signal-based outputs in v2.0.0, that will become the default and the Observable wrappers will remain as a deprecated layer.
Server-side rendering (SSR)
Section titled “Server-side rendering (SSR)”The SDK is browser-only. The checkout component touches
window.location for redirect handling and uses document for the
hosted-checkout form. Wrap usage in
isPlatformBrowser(this.platformId) checks if you’re running under
@angular/ssr:
import { isPlatformBrowser } from "@angular/common";import { Component, Inject, PLATFORM_ID } from "@angular/core";
@Component({ /* ... */ })export class CheckoutComponent { isBrowser: boolean; constructor(@Inject(PLATFORM_ID) platformId: object) { this.isBrowser = isPlatformBrowser(platformId); }}@if (isBrowser) { <pdirect-pay-checkout [configs]="configs" [paymentBody]="paymentBody" />}The component also won’t render meaningfully on the server (it needs DOM events to advance) so this is the right pattern anyway.
Build target
Section titled “Build target”The package ships as fesm2022, which targets ES2022. Angular’s
default build configuration ships ES2022 from Angular 18+; if you’re
on Angular 17 with a custom legacy tsconfig that targets ES2020 or
older, raise the target to ES2022:
{ "compilerOptions": { "target": "ES2022", "module": "ES2022", // ... }}Tree-shaking
Section titled “Tree-shaking”sideEffects: false is set, so unused exports are eliminated by
production builds. Importing PdirectPayApiResponseCode does not
pull in the entire payment-status component tree.
The standalone-component approach gives you the smallest bundle — import only the components you actually use.
See also
Section titled “See also”- Installation — peer-dep notes
- Configuration — DI tokens and standalone bootstrap
- Changelog — what changed per version