Repository navigation
Static assets fail to load in monorepo since 0.81 #3909
Description
Activity
- changed the title
[-]Static images fail to load in monorepo since 0.81[/-][+]Static assets fail to load in monorepo since 0.81[/+]on Jan 5, 2026 Thanks for reporting this! Would you be able to verify that this fix works: #3910?
Reacted by Aure77Thanks for your quick solution, it's works !
As
enhanceMiddlewarehas been deprecated for a while in metro. Maybe useful to switch to rewriteRequestUrl for this use case ?Reacted by Tommy NguyenThanks for verifying. I've just noticed the deprecation as well. Added
rewriteRequestUrlbut keptenhanceMiddlewarefor backwards compatibility.I got something strange. Yesterday it seems worked on both platform. This morning, after removing metro cache, app cache, starting from clean node_modules with metro 0.83.3, it's only works on iOS... On Android, assets outside project root are not prefixed with public path (
/assets) when handled by server:Metro:Server:parseBundleOptionsFromBundleRequestUrl entryFile: ./index +13s Metro:Server Handling request: /node_modules/react-native/Libraries/LogBox/UI/LogBoxImages/close.png?platform=android&hash=369745d4a4a6fa62fa0ed495f89aa964 +265ms Metro:Server Formatted as: http://10.0.2.2:8081/node_modules/react-native/Libraries/LogBox/UI/LogBoxImages/close.png?platform=android&hash=369745d4a4a6fa62fa0ed495f89aa964 +1msAs there is no
/assetsprefix, middleware is not called... I don't understand why metro doesn't consider this png as asset resource. Any idea ?The only thing I can think of is if the config is missing
pnginassetExts, or added tosourceExtsby accident. You can inspect your config by runningnode --print 'require("./metro.config.js")'.
Is this with or without
@rnx-kit/metro-config?Yes it was my suspicion too but I already checked that (& it's works on iOS...):
resolver: { assetExts: [ 'bmp', 'gif', 'jpg', 'jpeg', 'png', 'psd', 'svg', 'webp', 'xml', 'm4v', 'mov', 'mp4', 'mpeg', 'mpg', 'webm', 'aac', 'aiff', 'caf', 'm4a', 'mp3', 'wav', 'html', 'pdf', 'yaml', 'yml', 'otf', 'ttf', 'zip' ], assetResolutions: [ '1', '1.5', '2', '3', '4' ], platforms: [ 'android', 'ios' ], sourceExts: [ 'js', 'jsx', 'json', 'ts', 'tsx' ], ...Images from project are loaded correctly. Issue only appears with assets outside project root.
Yes it's with @rnx-kit/metro-config from your PR (withmakeMetroConfig({}), so default settings).I found a solution with assetPlugins:
transformer: { assetPlugins: [ require.resolve("@rnx-kit/metro-config/src/assetPluginForMonorepos") // or any other path with custom asset plugin ], },
I used similar way to update
httpServerLocationwithunstable_path(like in your PR):assetPlugin function:
function assetPlugin(assetData) { assetData.httpServerLocation = assetData.httpServerLocation.replace( "/assets/../", "/assets?unstable_path=../" ); return assetData; }
It seems that Android use a different request url when
httpServerLocationcontains "..". It's modified before to be passed to middleware, so enhanceMiddleware cannot handle it as asset.
enhanceMiddlewareis unnecessary with that plugin.Thanks! I've been digging into why
..was being resolved only for Android but you were faster in finding a solution. I'll do some testing on my side and update the PR.Can you check what happens when you bundle? What does the folder structure look like? It doesn't look like Android handles this correct and saves assets under
dist/assets?unstable_path=/*.Update: See react/react-native#55072
Yes I got asset path like this:
assetsunstable_path__node_modules_reactnavigation_elements_src_assets_backicon.png
in Android generated assets res (android/app/build/generated/res/createBundleReleaseJsAndAssets).
There is also string match of/assets?unstable_path=../../insideandroid/app/build/generated/assets/createBundleReleaseJsAndAssets/index.android.bundle(Hermes bytecode is hard to analyze).Assets doesn't works in Release mode with this metro config...
I can't figure out how to fix release mode so I've put the workaround behind an option for now. You can enable it like this:
diff --git a/metro.config.js b/metro.config.js index 499dfd3db..732d2143e 100644 --- a/metro.config.js +++ b/metro.config.js @@ -34,4 +34,5 @@ module.exports = makeMetroConfig({ blacklistRE: blockList, blockList, }, + unstable_allowAssetsOutsideProjectRoot: true, });
You can use an env var to enable it in your setup and hide it behind a
startcommand.
What happened?
Since I upgrade to RN 0.81, images (assets) are not loaded in dev (with metro server).
I think there is a issue with monorepo settings (
enhanceMiddleware) with RN 0.81+Affected Package
@rnx-kit/metro-config
Version
2.2.1
Which platforms are you seeing this issue on?
System Information
Steps to Reproduce
Use default metro-config settings in a monorepo with RN 0.81+:
Fail silently, image are not loaded:

(close image is not loaded for ex)
I mitigated issue on Android by overriding/remove
enhanceMiddleware:But path with ".." doesn't works with iOS. So monorepo support doesn't works anymore with
@rnx-kit/metro-configCode of Conduct