Skip to content

fix(ios): stop the config plugin dropping the app's URL schemes - #280

Open
rlods wants to merge 1 commit into
callstackincubator:mainfrom
rlods:fix/expo-plugin-url-scheme-guard
Open

fix(ios): stop the config plugin dropping the app's URL schemes#280
rlods wants to merge 1 commit into
callstackincubator:mainfrom
rlods:fix/expo-plugin-url-scheme-guard

Conversation

@rlods

@rlods rlods commented Sep 11, 2026

Copy link
Copy Markdown

Problem

Adding @use-voltra/ios-client to an app silently removes the app's own URL schemes from the built Info.plist: after a prebuild, CFBundleURLTypes no longer contains expo.scheme, so every deep link into the app fails (LSApplicationWorkspace error 115 for us).

Ironic for a plugin whose job is to make sure widgetURL can open the app. 😄

Root cause

ensureURLScheme writes ios.infoPlist.CFBundleURLTypes in the config.

Expo's own withScheme mod, which is what actually fills that key from expo.scheme / expo.ios.scheme plus the bundle identifier, is wrapped in createInfoPlistPluginWithPropertyGuard, and that guard skips the mod entirely as soon as ios.infoPlist.CFBundleURLTypes is set.

The guard reads modRawConfig, a clone taken after all plugins have run, so a plugin's own write trips it.

Net effect: the plugin replaces Expo's whole scheme list with a single entry instead of adding to it.

Secondary bug in the same function: typeof config.scheme === 'string' misses the documented array form of scheme, so a multi-scheme app fell back to the bundle identifier.

Fix

  • Only top up a CFBundleURLTypes list the app already owns. If the app hasn't set the key, leave it alone and let Expo's withScheme do its job (it already appends the bundle identifier, which is what the previous fallback was after).

  • Collect schemes from both scheme and ios.scheme, string or array, and add the ones missing from a hand-written list.

Testing

  • New urlScheme.node.test.ts (4 cases) + full expo-plugin jest suite green.

  • Verified on a real app with expo prebuild --platform ios: before the fix Info.plist carried only the bundle identifier, after it the app's expo.scheme entries are back and deep links work again.

ensureURLScheme wrote ios.infoPlist.CFBundleURLTypes, which trips the property
guard around Expo's own withScheme mod, so expo.scheme never reached Info.plist.
Only top up a CFBundleURLTypes list the app already owns, and read array
scheme / ios.scheme values instead of falling back to the bundle identifier.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@rlods
rlods marked this pull request as ready for review September 11, 2026 16:02
@rlods

rlods commented Sep 11, 2026

Copy link
Copy Markdown
Author

@V3RON I hope you don't mind all those fixes, but they are real blockers! 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant