Appearance
Extension patterns
A consumer rarely extends a plugin by editing the plugin package itself. The normal pattern is to keep the plugin responsible for its shared concern, then add application-specific business logic around its supported inputs, outputs, and extension hooks.
The extension boundary
Treat a plugin as owning:
- its exported functions, classes, types, and state objects;
- its endpoint selection, merge rules, and internal caches;
- any environment switch exposed through
activeEnvironment; - any explicit extension subjects or callback parameters it exports.
Treat the consumer as owning:
- when the plugin is called;
- what context is passed in;
- how emitted state is persisted or transformed into app state;
- UI-specific filtering, presentation, analytics naming, and navigation policy;
- business rules that apply only to one consuming application.
The four safe extension patterns
1. Shape the plugin input
Add business logic before the plugin runs by controlling:
- auth context pushed into a builder plugin;
- selected profile or currency;
- template names passed to personalisation;
- current URL and custom rules passed to client-type-router.
Use this when the plugin already supports the behaviour through its public inputs.
2. Wrap the plugin output
Let the plugin produce its canonical result, then map it into application-owned state:
- persist
menuBuilder.updateAppStatein app state; - build a page-specific nav model from
getLoggedInMenuState(); - transform portfolio state before rendering;
- enrich analytics payloads before sending them.
Use this when the core plugin result is correct but your application needs a product-specific view of it.
3. Compose extra logic after the plugin
Run business rules after the plugin returns:
- filter feature-library cards for a product surface;
- decide whether to open a feature based on plugin eligibility plus app rules;
- apply route decisions after experience-manager returns a destination.
Use this when the extra rule is application-owned and should not become a shared platform rule.
4. Use explicit extension hooks
Some plugins expose supported extension points:
client-type-routeracceptscustomRulesleftNavBuilderexposesaddGenericMenuList,businessBankingLeftNavData, andixLeftNavDataportfolioexposes direct portfolio methods andUpdatePortfolioExcludes(...)feature-libraryexposes context setters and API-requirement checks
Use these first when they fit, because they keep the consumer within the published contract.
When a plugin change is required
Change the plugin package, not just the consumer, when you need to:
- add a new upstream endpoint or portfolio family;
- change shared merge logic or default routing behaviour;
- introduce a new reusable state shape or public export;
- support a new client type or new left-nav base template;
- add a new Adobe/analytics/chat integration contract;
- fix a bug in the shared logic rather than work around it in one app.
If the new rule must apply consistently across multiple consumers, it belongs in the plugin.
Quick reference
| Plugin type | Extend in consumer | Requires plugin change |
|---|---|---|
| Decision plugins | pass different inputs, custom rules, or post-process result | new shared rule model or default decision path |
| Builder plugins | push context, subscribe once, transform output, use explicit hook subjects | new endpoint selection, merge logic, or exported state |
| Registry/discovery plugins | set context, run eligibility helpers, filter final list | new requirement source, cache model, or registry contract |
| Integration wrappers | enrich payloads, own UI and event wiring | new provider behaviour or transport contract |
Per-plugin rule of thumb
| Plugin | Consumer can extend by | Plugin change is needed for |
|---|---|---|
| Adobe analytics | naming events, adding context before sending, choosing when to send | new standardised event shape or shared analytics builder behaviour |
| Client type router | passing customRules, post-processing returned interactions | new default route family or shared merge rule |
| Experience manager | wrapping the returned destination with app-only policy | changing the shared pre-/post-login journey rules |
| Feature flags builder | composing returned flags with app-owned gating | new upstream endpoints or merge semantics |
| Feature library | setting context, running API checks, filtering rendered results | new requirement source or shared eligibility rule |
| Left nav builder | injecting generic/business/IX lists and wrapping built nav state | new base nav templates or duplicate-routing rules |
| Livechat | owning the UI and listening to document events | new auth/session/provider contract |
| Menu builder | subscribing to menu state and decorating the result in app state | new menu endpoint mappings or region URL rules |
| Personalisation | choosing templates and using mapping helpers before posting updates | new Target endpoint contract or shared mapping rules |
| Portfolio builder | calling direct methods, streaming results, excluding totals | new portfolio families or new shared aggregation logic |
| Profiles builder | consuming profilesList, mirroring selected profiles into app state | new profile families or new profile-source endpoints |
| Toggles builder | applying toggles to an app-specific feature list | new shared toggle mappings or fetch behaviour |
See the individual plugin pages for concrete extension snippets using the published package APIs.