Troubleshooting
If a shared element transition is not triggering or looks slightly off, check the solutions below.
The transition does not run at all
- Check that both
idandnamespacematch: Add anonTransitionStartcallback or log bothidvalues. Both endpoints must share the sameidandnamespace(which defaults to"default"). - Verify
enabledis notfalse: Both the source and destination<SharedHero>must haveenabled={true}(the default). - For in-place toggles on the same screen, use distinct React
keyprops: When swapping two<SharedHero id="x">branches via React state on the same screen, give the two branches differentkeyprops (key="collapsed"andkey="expanded") so React unmounts the source and mounts the destination instead of reusing the same view instance. - Ensure both views have non-zero layout dimensions: If a
<SharedHero>wraps an<Image>with no explicitwidth/heightoraspectRatio, its initial layout size may be0x0when the screen mounts. Always give the<SharedHero>or its child explicit layout dimensions. - Confirm New Architecture (Fabric) is enabled:
react-native-shared-herois a Fabric-only component.
Return animation cuts off early on Android Stack Navigator
Symptom: Navigating forward works smoothly, but pressing Back on Android makes the destination screen disappear halfway through the return flight.
Cause: Setting animation: 'fade' in @react-navigation/native-stack on Android uses a short native XML fade animation (~150 ms) that detaches the outgoing Fragment view hierarchy before a 320 ms return flight completes.
Fix: Only apply animation: 'fade' on iOS, and keep the default stack animation on Android:
const detailOptions = Platform.select({
ios: { animation: 'fade' as const },
default: {},
});borderRadius or backgroundColor does not morph
Symptom: You set mode="morph", but the corners jump at the end of the flight instead of rounding progressively.
Cause: borderRadius and backgroundColor were placed on an inner child <View> or <Image> where they cannot be inspected or overridden cleanly during snapshot capture.
Fix: Place borderRadius, backgroundColor, and overflow: 'hidden' directly on <SharedHero style={...}>:
<SharedHero
id={`card-${item.id}`}
mode="morph"
style={{ borderRadius: 20, backgroundColor: '#1E293B', overflow: 'hidden' }}
>
<Image source={{ uri: item.url }} style={{ width: '100%', height: 240 }} />
</SharedHero>Destination image flashes or looks blurry during zoom-in
Symptom: Expanding a tiny thumbnail into a full-screen photo looks blurry during flight and then sharpens when the flight lands.
Cause: If the destination screen fetches a completely different remote URL that is not yet in disk/memory cache and takes longer than ~120 ms to download over the network, HeroRegistry starts the flight using the source thumbnail bitmap rather than freezing your navigation.
Fix:
- Prefetch the full-resolution URL (
Image.prefetch(item.fullUrl)) when the card enters the viewport or ononPressIn. - Or use the same cached image URL on both endpoints when the resolution is already sufficient for the detail header.
CocoaPods build error with use_frameworks!
Symptom: Xcode reports 'SharedHero/SharedHero-Swift.h' file not found in an older release.
Fix: Upgrade to the latest version of react-native-shared-hero, which includes a conditional __has_include(<SharedHero/SharedHero-Swift.h>) fallback in ios/SharedHeroView.mm that supports both static libraries and use_frameworks!.