From f3479b8f48f0f24be2dc0c326546c5b709df29ab Mon Sep 17 00:00:00 2001 From: Justin Wyne <1986068+wyne@users.noreply.github.com> Date: Wed, 17 Jun 2026 00:25:25 -0400 Subject: [PATCH] fix(android): strip dangling splashscreen_logo reference expo-splash-screen always writes windowSplashScreenAnimatedIcon -> @drawable/splashscreen_logo into styles.xml, but only generates that drawable when an image is configured. Our splash is color-only (logo is handled in JS by SplashOverlay), so a clean Android prebuild produced a dangling reference and failed resource linking: error: resource drawable/splashscreen_logo not found Add a config plugin that removes the icon item after expo-splash-screen runs (listed before it so its withAndroidStyles mod runs last). Co-Authored-By: Claude Opus 4.8 --- app.config.js | 4 ++++ plugins/withAndroidSplashNoIcon.js | 37 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 plugins/withAndroidSplashNoIcon.js diff --git a/app.config.js b/app.config.js index c4d28d1b..193e15e7 100644 --- a/app.config.js +++ b/app.config.js @@ -120,6 +120,10 @@ export default { githubUrl: 'https://github.com/wyne/scorepad-react-native', owner: 'wyne', plugins: [ + // Listed BEFORE expo-splash-screen: Expo runs the most recently registered + // mod first, so an earlier-listed plugin's withAndroidStyles mod runs LAST, + // i.e. after expo-splash-screen has written its style items. + './plugins/withAndroidSplashNoIcon', ['expo-splash-screen', { backgroundColor: '#F2F2F7', dark: { backgroundColor: '#000000' }, diff --git a/plugins/withAndroidSplashNoIcon.js b/plugins/withAndroidSplashNoIcon.js new file mode 100644 index 00000000..9475586e --- /dev/null +++ b/plugins/withAndroidSplashNoIcon.js @@ -0,0 +1,37 @@ +const { withAndroidStyles } = require('expo/config-plugins'); + +/** + * expo-splash-screen always writes a `windowSplashScreenAnimatedIcon` item that + * points at `@drawable/splashscreen_logo`, even when the splash config only sets + * a `backgroundColor` (no image). With no icon image configured, that drawable is + * never generated, so a clean Android prebuild fails resource linking with: + * error: resource drawable/splashscreen_logo not found + * + * We intentionally use a color-only native splash (the animated logo is handled in + * JS by src/components/SplashOverlay.tsx), so this plugin strips the dangling icon + * reference after expo-splash-screen runs. It MUST be listed AFTER + * 'expo-splash-screen' in the plugins array so its withAndroidStyles mod runs last. + */ +module.exports = (config) => + withAndroidStyles(config, (config) => { + const styles = config.modResults.resources.style ?? []; + let removed = false; + + for (const style of styles) { + if (!Array.isArray(style.item)) continue; + const before = style.item.length; + style.item = style.item.filter( + ({ $ }) => $.name !== 'windowSplashScreenAnimatedIcon' + ); + if (style.item.length !== before) removed = true; + } + + if (!removed) { + throw new Error( + 'withAndroidSplashNoIcon: did not find a windowSplashScreenAnimatedIcon item to remove. ' + + 'Ensure this plugin is listed after expo-splash-screen.' + ); + } + + return config; + });