Summary
Add a configuration option to opt out of the automatic KlaviyoNotificationServiceExtension setup, for projects that already include a Notification Service Extension.
Background / Use Case
We are using Klaviyo alongside a second push notification provider that ships its own Notification Service Extension. Since iOS only executes one NSE per app, having two NSE targets in the same project leads to an unpredictable state. It is not deterministic which extension will be invoked at runtime.
Because the plugin currently always adds the KlaviyoNotificationServiceExtension target, there is no way to avoid this conflict without workarounds like patching the package or writing a custom cleanup plugin.
Proposed Solution
Add a boolean config option under the ios key, for example:
{
"plugins": [
[
"klaviyo-expo-plugin",
{
"ios": {
"includeNotificationServiceExtension": false
}
}
]
]
}
Implementation Plan
Files to Modify
plugin/types/index.ts — Add includeNotificationServiceExtension?: boolean to KlaviyoPluginIosBaseProps; add required field to KlaviyoPluginIosProps; set default to true in IOS_DEFAULTS
plugin/support/validateConfig.ts — Add validation: ensure field is boolean if provided
plugin/withKlaviyoIos.ts — Conditionally include withKlaviyoNSE and withKlaviyoAppGroup in the plugin chain only if props.includeNotificationServiceExtension === true
example/app.config.js — Add example showing both true and false configurations
README.md — Document the new iOS configuration option
tests/withKlaviyoIos.test.ts — Add test cases for conditional behavior
Approach
Follow the existing pattern of optional iOS features (like geofencingEnabled):
- Add to type definitions with default value
true (preserves current behavior)
- Validate as boolean
- Conditionally include NSE setup functions in the plugin chain
Acceptance Criteria
- ✅ Config option works with both
true and false
- ✅ Defaults to
true (current behavior preserved)
- ✅ NSE setup skipped entirely when
false
- ✅ Documentation and example updated
- ✅ Unit tests verify conditional behavior
- ✅ Example app builds successfully
Related References
geofencingEnabled pattern in plugin/types/index.ts
- NSE setup functions:
withKlaviyoNSE (lines 357–423), withKlaviyoAppGroup (lines 428–444)
- NSE source files:
KlaviyoNotificationServiceExtension/ directory
Summary
Add a configuration option to opt out of the automatic
KlaviyoNotificationServiceExtensionsetup, for projects that already include a Notification Service Extension.Background / Use Case
We are using Klaviyo alongside a second push notification provider that ships its own Notification Service Extension. Since iOS only executes one NSE per app, having two NSE targets in the same project leads to an unpredictable state. It is not deterministic which extension will be invoked at runtime.
Because the plugin currently always adds the
KlaviyoNotificationServiceExtensiontarget, there is no way to avoid this conflict without workarounds like patching the package or writing a custom cleanup plugin.Proposed Solution
Add a boolean config option under the
ioskey, for example:{ "plugins": [ [ "klaviyo-expo-plugin", { "ios": { "includeNotificationServiceExtension": false } } ] ] }Implementation Plan
Files to Modify
plugin/types/index.ts— AddincludeNotificationServiceExtension?: booleantoKlaviyoPluginIosBaseProps; add required field toKlaviyoPluginIosProps; set default totrueinIOS_DEFAULTSplugin/support/validateConfig.ts— Add validation: ensure field is boolean if providedplugin/withKlaviyoIos.ts— Conditionally includewithKlaviyoNSEandwithKlaviyoAppGroupin the plugin chain only ifprops.includeNotificationServiceExtension === trueexample/app.config.js— Add example showing bothtrueandfalseconfigurationsREADME.md— Document the new iOS configuration optiontests/withKlaviyoIos.test.ts— Add test cases for conditional behaviorApproach
Follow the existing pattern of optional iOS features (like
geofencingEnabled):true(preserves current behavior)Acceptance Criteria
trueandfalsetrue(current behavior preserved)falseRelated References
geofencingEnabledpattern inplugin/types/index.tswithKlaviyoNSE(lines 357–423),withKlaviyoAppGroup(lines 428–444)KlaviyoNotificationServiceExtension/directory