diff --git a/packages/react-native/React/Base/RCTJavaScriptLoader.mm b/packages/react-native/React/Base/RCTJavaScriptLoader.mm
index 8839095e6a4ea0..5330bb4d4700b9 100755
--- a/packages/react-native/React/Base/RCTJavaScriptLoader.mm
+++ b/packages/react-native/React/Base/RCTJavaScriptLoader.mm
@@ -303,7 +303,17 @@ static void attemptAsynchronousLoadOfBundleAtURL(
           return;
         }
 
-        RCTSource *source = RCTSourceCreate(scriptURL, data, data.length);
+        // Prefer `Content-Location` as the canonical source URL, if given, or fall back to scriptURL.
+        NSURL *sourceURL = scriptURL;
+        NSString *contentLocationHeader = headers[@"Content-Location"];
+        if (contentLocationHeader) {
+          NSURL *contentLocationURL = [NSURL URLWithString:contentLocationHeader relativeToURL:scriptURL];
+          if (contentLocationURL) {
+            sourceURL = contentLocationURL;
+          }
+        }
+
+        RCTSource *source = RCTSourceCreate(sourceURL, data, data.length);
         parseHeaders(headers, source);
         onComplete(nil, source);
       }
diff --git a/packages/react-native/React/CxxBridge/RCTCxxBridge.mm b/packages/react-native/React/CxxBridge/RCTCxxBridge.mm
index 777268dbb7eff4..2d11205b006d36 100644
--- a/packages/react-native/React/CxxBridge/RCTCxxBridge.mm
+++ b/packages/react-native/React/CxxBridge/RCTCxxBridge.mm
@@ -475,6 +475,7 @@ - (void)start
   // Load the source asynchronously, then store it for later execution.
   dispatch_group_enter(prepareBridge);
   __block NSData *sourceCode;
+  __block NSURL *sourceURL = self.bundleURL;
 
 #if RCT_DEV_MENU && __has_include(<React/RCTDevLoadingViewProtocol.h>)
   {
@@ -490,6 +491,9 @@ - (void)start
         }
 
         sourceCode = source.data;
+        if (source.url) {
+          sourceURL = source.url;
+        }
         dispatch_group_leave(prepareBridge);
       }
       onProgress:^(RCTLoadingProgress *progressData) {
@@ -504,7 +508,7 @@ - (void)start
   dispatch_group_notify(prepareBridge, dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
     RCTCxxBridge *strongSelf = weakSelf;
     if (sourceCode && strongSelf.loading) {
-      [strongSelf executeSourceCode:sourceCode sync:NO];
+      [strongSelf executeSourceCode:sourceCode withSourceURL:sourceURL sync:NO];
     }
   });
   RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
@@ -1050,7 +1054,7 @@ - (void)registerModuleForFrameUpdates:(id<RCTBridgeModule>)module withModuleData
   [_displayLink registerModuleForFrameUpdates:module withModuleData:moduleData];
 }
 
-- (void)executeSourceCode:(NSData *)sourceCode sync:(BOOL)sync
+- (void)executeSourceCode:(NSData *)sourceCode withSourceURL:(NSURL *)url sync:(BOOL)sync
 {
   // This will get called from whatever thread was actually executing JS.
   dispatch_block_t completion = ^{
@@ -1075,12 +1079,13 @@ - (void)executeSourceCode:(NSData *)sourceCode sync:(BOOL)sync
   };
 
   if (sync) {
-    [self executeApplicationScriptSync:sourceCode url:self.bundleURL];
+    [self executeApplicationScriptSync:sourceCode url:url];
     completion();
   } else {
-    [self enqueueApplicationScript:sourceCode url:self.bundleURL onComplete:completion];
+    [self enqueueApplicationScript:sourceCode url:url onComplete:completion];
   }
 
+  // Use the original request URL here - HMRClient uses this to derive the /hot URL and entry point.
   [self.devSettings setupHMRClientWithBundleURL:self.bundleURL];
 }