remote-components 0.0.50 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/{component-loader-1838f572.d.ts → component-loader-76eb1b8b.d.ts} +3 -1
  2. package/dist/html/host.cjs +486 -242
  3. package/dist/html/host.cjs.map +1 -1
  4. package/dist/html/host.d.ts +2 -0
  5. package/dist/html/host.js +485 -242
  6. package/dist/html/host.js.map +1 -1
  7. package/dist/html/remote.cjs +123 -21
  8. package/dist/html/remote.cjs.map +1 -1
  9. package/dist/html/remote.js +123 -21
  10. package/dist/html/remote.js.map +1 -1
  11. package/dist/internal/next/host/app-router-client.cjs +12 -3
  12. package/dist/internal/next/host/app-router-client.cjs.map +1 -1
  13. package/dist/internal/next/host/app-router-client.d.ts +11 -2
  14. package/dist/internal/next/host/app-router-client.js +12 -3
  15. package/dist/internal/next/host/app-router-client.js.map +1 -1
  16. package/dist/internal/react/context.cjs +43 -0
  17. package/dist/internal/react/context.cjs.map +1 -0
  18. package/dist/internal/react/context.d.ts +20 -0
  19. package/dist/internal/react/context.js +18 -0
  20. package/dist/internal/react/context.js.map +1 -0
  21. package/dist/internal/react/hooks/use-resolve-client-url.cjs +39 -0
  22. package/dist/internal/react/hooks/use-resolve-client-url.cjs.map +1 -0
  23. package/dist/internal/react/hooks/use-resolve-client-url.d.ts +5 -0
  24. package/dist/internal/react/hooks/use-resolve-client-url.js +15 -0
  25. package/dist/internal/react/hooks/use-resolve-client-url.js.map +1 -0
  26. package/dist/internal/shared/client/apply-origin.cjs +10 -5
  27. package/dist/internal/shared/client/apply-origin.cjs.map +1 -1
  28. package/dist/internal/shared/client/apply-origin.d.ts +3 -1
  29. package/dist/internal/shared/client/apply-origin.js +10 -5
  30. package/dist/internal/shared/client/apply-origin.js.map +1 -1
  31. package/dist/internal/shared/client/default-resolve-client-url.cjs +32 -0
  32. package/dist/internal/shared/client/default-resolve-client-url.cjs.map +1 -0
  33. package/dist/internal/shared/client/default-resolve-client-url.d.ts +5 -0
  34. package/dist/internal/shared/client/default-resolve-client-url.js +10 -0
  35. package/dist/internal/shared/client/default-resolve-client-url.js.map +1 -0
  36. package/dist/internal/shared/client/protected-rc-fallback.cjs +41 -0
  37. package/dist/internal/shared/client/protected-rc-fallback.cjs.map +1 -0
  38. package/dist/internal/shared/client/protected-rc-fallback.d.ts +7 -0
  39. package/dist/internal/shared/client/protected-rc-fallback.js +16 -0
  40. package/dist/internal/shared/client/protected-rc-fallback.js.map +1 -0
  41. package/dist/internal/shared/client/proxy-through-host.cjs +51 -0
  42. package/dist/internal/shared/client/proxy-through-host.cjs.map +1 -0
  43. package/dist/internal/shared/client/proxy-through-host.d.ts +57 -0
  44. package/dist/internal/shared/client/proxy-through-host.js +26 -0
  45. package/dist/internal/shared/client/proxy-through-host.js.map +1 -0
  46. package/dist/internal/shared/client/remote-component.cjs +208 -134
  47. package/dist/internal/shared/client/remote-component.cjs.map +1 -1
  48. package/dist/internal/shared/client/remote-component.d.ts +7 -5
  49. package/dist/internal/shared/client/remote-component.js +207 -134
  50. package/dist/internal/shared/client/remote-component.js.map +1 -1
  51. package/dist/internal/shared/constants.cjs +32 -0
  52. package/dist/internal/shared/constants.cjs.map +1 -0
  53. package/dist/internal/shared/constants.d.ts +4 -0
  54. package/dist/internal/shared/constants.js +7 -0
  55. package/dist/internal/shared/constants.js.map +1 -0
  56. package/dist/internal/shared/error.cjs +70 -0
  57. package/dist/internal/shared/error.cjs.map +1 -1
  58. package/dist/internal/shared/error.d.ts +3 -1
  59. package/dist/internal/shared/error.js +71 -0
  60. package/dist/internal/shared/error.js.map +1 -1
  61. package/dist/internal/shared/ssr/fetch-remote-component.cjs +1 -2
  62. package/dist/internal/shared/ssr/fetch-remote-component.cjs.map +1 -1
  63. package/dist/internal/shared/ssr/fetch-remote-component.js +1 -2
  64. package/dist/internal/shared/ssr/fetch-remote-component.js.map +1 -1
  65. package/dist/internal/shared/ssr/fetch-with-hooks.cjs +7 -2
  66. package/dist/internal/shared/ssr/fetch-with-hooks.cjs.map +1 -1
  67. package/dist/internal/shared/ssr/fetch-with-hooks.js +7 -2
  68. package/dist/internal/shared/ssr/fetch-with-hooks.js.map +1 -1
  69. package/dist/internal/shared/utils/logger.cjs +26 -10
  70. package/dist/internal/shared/utils/logger.cjs.map +1 -1
  71. package/dist/internal/shared/utils/logger.d.ts +7 -2
  72. package/dist/internal/shared/utils/logger.js +24 -9
  73. package/dist/internal/shared/utils/logger.js.map +1 -1
  74. package/dist/next/config.cjs +2 -2
  75. package/dist/next/config.cjs.map +1 -1
  76. package/dist/next/config.js +2 -2
  77. package/dist/next/config.js.map +1 -1
  78. package/dist/next/host/client/index.cjs +363 -207
  79. package/dist/next/host/client/index.cjs.map +1 -1
  80. package/dist/next/host/client/index.d.ts +3 -1
  81. package/dist/next/host/client/index.js +336 -181
  82. package/dist/next/host/client/index.js.map +1 -1
  83. package/dist/next/host/pages-router-client.cjs +15 -2
  84. package/dist/next/host/pages-router-client.cjs.map +1 -1
  85. package/dist/next/host/pages-router-client.d.ts +12 -1
  86. package/dist/next/host/pages-router-client.js +15 -2
  87. package/dist/next/host/pages-router-client.js.map +1 -1
  88. package/dist/next/host/pages-router-server.cjs +3 -2
  89. package/dist/next/host/pages-router-server.cjs.map +1 -1
  90. package/dist/next/host/pages-router-server.d.ts +16 -0
  91. package/dist/next/host/pages-router-server.js +3 -2
  92. package/dist/next/host/pages-router-server.js.map +1 -1
  93. package/dist/next/proxy.cjs +66 -27
  94. package/dist/next/proxy.cjs.map +1 -1
  95. package/dist/next/proxy.d.ts +0 -1
  96. package/dist/next/proxy.js +66 -27
  97. package/dist/next/proxy.js.map +1 -1
  98. package/dist/proxy-through-host-a676a522.d.ts +52 -0
  99. package/dist/react/index.cjs +381 -206
  100. package/dist/react/index.cjs.map +1 -1
  101. package/dist/react/index.d.ts +28 -4
  102. package/dist/react/index.js +354 -181
  103. package/dist/react/index.js.map +1 -1
  104. package/dist/shared/host/proxy.cjs +52 -23
  105. package/dist/shared/host/proxy.cjs.map +1 -1
  106. package/dist/shared/host/proxy.d.ts +0 -3
  107. package/dist/shared/host/proxy.js +55 -22
  108. package/dist/shared/host/proxy.js.map +1 -1
  109. package/dist/shared/remote/proxy.cjs +9 -1
  110. package/dist/shared/remote/proxy.cjs.map +1 -1
  111. package/dist/shared/remote/proxy.d.ts +7 -1
  112. package/dist/shared/remote/proxy.js +8 -1
  113. package/dist/shared/remote/proxy.js.map +1 -1
  114. package/package.json +1 -1
  115. package/dist/internal/shared/ssr/fetch-with-protected-rc-fallback.cjs +0 -62
  116. package/dist/internal/shared/ssr/fetch-with-protected-rc-fallback.cjs.map +0 -1
  117. package/dist/internal/shared/ssr/fetch-with-protected-rc-fallback.d.ts +0 -14
  118. package/dist/internal/shared/ssr/fetch-with-protected-rc-fallback.js +0 -37
  119. package/dist/internal/shared/ssr/fetch-with-protected-rc-fallback.js.map +0 -1
@@ -31,13 +31,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/next/host/client/index.tsx
32
32
  var client_exports = {};
33
33
  __export(client_exports, {
34
- RemoteComponent: () => RemoteComponent2
34
+ RemoteComponent: () => RemoteComponent2,
35
+ RemoteComponentsProvider: () => import_context3.RemoteComponentsProvider
35
36
  });
36
37
  module.exports = __toCommonJS(client_exports);
37
38
  var Image = __toESM(require("next/image"), 1);
38
39
 
39
40
  // src/react/index.tsx
40
- var import_react2 = require("react");
41
+ var import_react3 = require("react");
41
42
  var import_react_dom = require("react-dom");
42
43
 
43
44
  // src/shared/client/apply-origin.ts
@@ -52,7 +53,7 @@ var tagNames = [
52
53
  "script",
53
54
  "link"
54
55
  ];
55
- function applyOriginToNodes(doc, url) {
56
+ function applyOriginToNodes(doc, url, resolveClientUrl) {
56
57
  if (url.origin !== location.origin) {
57
58
  const nodes = doc.querySelectorAll(
58
59
  tagNames.map(
@@ -61,12 +62,15 @@ function applyOriginToNodes(doc, url) {
61
62
  );
62
63
  nodes.forEach((node) => {
63
64
  if (node.hasAttribute("src") && /^[./]+\/?/.test(node.getAttribute("src") ?? "")) {
64
- node.src = new URL(node.getAttribute("src") ?? "/", url).href;
65
+ const absoluteSrc = new URL(node.getAttribute("src") ?? "/", url).href;
66
+ const isScript = node.tagName.toLowerCase() === "script";
67
+ node.src = isScript ? absoluteSrc : resolveClientUrl?.(absoluteSrc) ?? absoluteSrc;
65
68
  }
66
69
  if (node.hasAttribute("href") && /^[./]+\/?/.test(node.getAttribute("href") ?? "")) {
70
+ const absoluteHref = new URL(node.getAttribute("href") ?? "/", url).href;
67
71
  node.setAttribute(
68
72
  "href",
69
- new URL(node.getAttribute("href") ?? "/", url).href
73
+ resolveClientUrl?.(absoluteHref) ?? absoluteHref
70
74
  );
71
75
  }
72
76
  if (node.hasAttribute("srcset")) {
@@ -75,7 +79,8 @@ function applyOriginToNodes(doc, url) {
75
79
  if (!urlPart)
76
80
  return entry;
77
81
  const absoluteUrl = new URL(urlPart, url).href;
78
- return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;
82
+ const resolvedUrl = resolveClientUrl?.(absoluteUrl) ?? absoluteUrl;
83
+ return descriptor ? `${resolvedUrl} ${descriptor}` : resolvedUrl;
79
84
  }).join(", ");
80
85
  if (srcSet) {
81
86
  node.setAttribute("srcset", srcSet);
@@ -87,7 +92,8 @@ function applyOriginToNodes(doc, url) {
87
92
  if (!urlPart)
88
93
  return entry;
89
94
  const absoluteUrl = new URL(urlPart, url).href;
90
- return descriptor ? `${absoluteUrl} ${descriptor}` : absoluteUrl;
95
+ const resolvedUrl = resolveClientUrl?.(absoluteUrl) ?? absoluteUrl;
96
+ return descriptor ? `${resolvedUrl} ${descriptor}` : resolvedUrl;
91
97
  }).join(", ");
92
98
  if (srcSet) {
93
99
  node.setAttribute("imagesrcset", srcSet);
@@ -97,6 +103,31 @@ function applyOriginToNodes(doc, url) {
97
103
  }
98
104
  }
99
105
 
106
+ // src/shared/constants.ts
107
+ var RC_PROTECTED_REMOTE_FETCH_PATHNAME = "/rc-fetch-protected-remote";
108
+ var CORS_DOCS_URL = "https://vercel.com/docs/remote-components/concepts/cors-external-urls#accessing-cross-site-protected-remote-components";
109
+
110
+ // src/shared/client/protected-rc-fallback.ts
111
+ function isProxiedUrl(url) {
112
+ try {
113
+ return new URL(url, location.href).pathname === RC_PROTECTED_REMOTE_FETCH_PATHNAME;
114
+ } catch {
115
+ return false;
116
+ }
117
+ }
118
+
119
+ // src/shared/utils/abort.ts
120
+ function isAbortError(error) {
121
+ if (error instanceof DOMException && error.name === "AbortError") {
122
+ return true;
123
+ }
124
+ if (error !== null && typeof error === "object" && "name" in error && error.name === "AbortError" && "message" in error && typeof error.message === "string") {
125
+ const e = error;
126
+ return typeof e.code === "number" || e.constructor?.name === "DOMException";
127
+ }
128
+ return false;
129
+ }
130
+
100
131
  // src/shared/error.ts
101
132
  var RemoteComponentsError = class extends Error {
102
133
  code = "REMOTE_COMPONENTS_ERROR";
@@ -116,6 +147,69 @@ function failedToFetchRemoteComponentError(url, { status, statusText }, help = "
116
147
  { cause: new Error(`${status} ${statusText}`) }
117
148
  );
118
149
  }
150
+ async function errorFromFailedFetch(originalUrl, resolvedUrl, res) {
151
+ const isProxied = isProxiedUrl(resolvedUrl.href);
152
+ if (isProxied && res) {
153
+ const body = await res.text().catch(() => "");
154
+ return failedProxyFetchError(
155
+ originalUrl,
156
+ resolvedUrl.href,
157
+ res.status,
158
+ body
159
+ );
160
+ }
161
+ const fallback = failedToFetchRemoteComponentError(
162
+ originalUrl,
163
+ res ?? { status: 0, statusText: "No Response" }
164
+ );
165
+ if (!res)
166
+ return fallback;
167
+ try {
168
+ const body = await res.text();
169
+ const parser = new DOMParser();
170
+ const doc = parser.parseFromString(body, "text/html");
171
+ const errorTemplate = doc.querySelector(
172
+ "template[data-next-error-message]"
173
+ );
174
+ const errorMessage = errorTemplate?.getAttribute("data-next-error-message");
175
+ if (errorMessage) {
176
+ const error = new RemoteComponentsError(errorMessage);
177
+ const errorStack = errorTemplate?.getAttribute("data-next-error-stack");
178
+ if (errorStack) {
179
+ error.stack = errorStack;
180
+ }
181
+ return error;
182
+ }
183
+ } catch (parseError) {
184
+ if (isAbortError(parseError))
185
+ throw parseError;
186
+ }
187
+ return fallback;
188
+ }
189
+ function failedProxyFetchError(originalUrl, proxyUrl, status, responseBody) {
190
+ if (status === 404) {
191
+ return new RemoteComponentsError(
192
+ `Could not proxy the request to "${originalUrl}" \u2014 the proxy endpoint "${RC_PROTECTED_REMOTE_FETCH_PATHNAME}" returned 404.
193
+
194
+ The host server needs middleware or a route that handles "${RC_PROTECTED_REMOTE_FETCH_PATHNAME}".
195
+
196
+ Proxying requires two pieces:
197
+ 1. resolveClientUrl={proxyClientRequestsThroughHost} on <RemoteComponent>
198
+ 2. Middleware or a route for "${RC_PROTECTED_REMOTE_FETCH_PATHNAME}" on the host server
199
+
200
+ Docs: ${CORS_DOCS_URL}`
201
+ );
202
+ }
203
+ if (status === 403) {
204
+ const detail = responseBody ? ` ${responseBody}` : "";
205
+ return new RemoteComponentsError(
206
+ `Proxied request to "${proxyUrl}" was forbidden.${detail} See: ${CORS_DOCS_URL}`
207
+ );
208
+ }
209
+ return new RemoteComponentsError(
210
+ `Proxied request for "${originalUrl}" via "${proxyUrl}" failed with status ${status}. See: ${CORS_DOCS_URL}`
211
+ );
212
+ }
119
213
 
120
214
  // src/shared/utils/logger.ts
121
215
  var PREFIX = "remote-components";
@@ -125,9 +219,6 @@ function logDebug(location2, message) {
125
219
  console.debug(`[${PREFIX}:${location2}]: ${message}`);
126
220
  }
127
221
  }
128
- function logInfo(location2, message) {
129
- console.info(`[${PREFIX}:${location2}]: ${message}`);
130
- }
131
222
  function logWarn(location2, message) {
132
223
  console.warn(`[${PREFIX}:${location2}]: ${message}`);
133
224
  }
@@ -138,6 +229,19 @@ function logError(location2, message, cause) {
138
229
  })
139
230
  );
140
231
  }
232
+ function warnCrossOriginFetchError(logLocation, url) {
233
+ try {
234
+ const parsed = typeof url === "string" ? new URL(url) : url;
235
+ if (typeof location === "undefined" || parsed.origin === location.origin) {
236
+ return;
237
+ }
238
+ logWarn(
239
+ logLocation,
240
+ `Failed to fetch cross-origin resource "${parsed.href}". If this is a protected deployment, ensure withRemoteComponentsHost middleware is configured in your host and that the remote URL is included in allowedProxyUrls. See: ${CORS_DOCS_URL}`
241
+ );
242
+ } catch {
243
+ }
244
+ }
141
245
 
142
246
  // src/shared/client/polyfill.tsx
143
247
  var import_jsx_runtime = (
@@ -581,28 +685,40 @@ function createRSCStream(rscName, data) {
581
685
  });
582
686
  }
583
687
 
688
+ // src/shared/client/webpack-patterns.ts
689
+ var NEXT_BUNDLE_PATH_RE = /\/_next\/\[.+\](?:%20| )/;
690
+
584
691
  // src/shared/client/script-loader.ts
585
- async function loadScripts(scripts) {
692
+ async function loadScripts(scripts, resolveClientUrl) {
586
693
  await Promise.all(
587
694
  scripts.map((script) => {
588
695
  return new Promise((resolve, reject) => {
589
696
  const newSrc = new URL(
590
697
  // remove the remote component bundle name identifier from the script src
591
- script.src.replace(/\/_next\/\[.+\](?<whitespace>%20| )/, "/_next/"),
698
+ script.src.replace(NEXT_BUNDLE_PATH_RE, "/_next/"),
592
699
  location.origin
593
700
  ).href;
701
+ const resolvedSrc = resolveClientUrl?.(newSrc) ?? newSrc;
594
702
  const newScript = document.createElement("script");
595
- newScript.onload = () => {
596
- resolve();
597
- };
703
+ newScript.onload = () => resolve();
598
704
  newScript.onerror = () => {
599
- reject(
600
- new RemoteComponentsError(
601
- `Failed to load <script src="${script.src}"> for Remote Component. Check the URL is correct.`
602
- )
603
- );
705
+ const isProxied = isProxiedUrl(resolvedSrc);
706
+ if (isProxied) {
707
+ reject(
708
+ new RemoteComponentsError(
709
+ `Failed to load script "${newSrc}" via proxy "${resolvedSrc}". Ensure withRemoteComponentsHost middleware is configured and "${RC_PROTECTED_REMOTE_FETCH_PATHNAME}" is in the matcher. See: ${CORS_DOCS_URL}`
710
+ )
711
+ );
712
+ } else {
713
+ warnCrossOriginFetchError("ScriptLoader", newSrc);
714
+ reject(
715
+ new RemoteComponentsError(
716
+ `Failed to load <script src="${newSrc}"> for Remote Component. Check the URL is correct.`
717
+ )
718
+ );
719
+ }
604
720
  };
605
- newScript.src = newSrc;
721
+ newScript.src = resolvedSrc;
606
722
  newScript.async = true;
607
723
  document.head.appendChild(newScript);
608
724
  });
@@ -610,50 +726,6 @@ async function loadScripts(scripts) {
610
726
  );
611
727
  }
612
728
 
613
- // src/shared/utils/abort.ts
614
- function isAbortError(error) {
615
- if (error instanceof DOMException && error.name === "AbortError") {
616
- return true;
617
- }
618
- if (error !== null && typeof error === "object" && "name" in error && error.name === "AbortError" && "message" in error && typeof error.message === "string") {
619
- const e = error;
620
- return typeof e.code === "number" || e.constructor?.name === "DOMException";
621
- }
622
- return false;
623
- }
624
-
625
- // src/shared/ssr/fetch-with-protected-rc-fallback.ts
626
- var RC_PROTECTED_REMOTE_FETCH_PATHNAME = "/rc-fetch-protected-remote";
627
- async function fetchWithProtectedRcFallback(url, init) {
628
- try {
629
- const res = await fetch(url, init);
630
- return res;
631
- } catch (error) {
632
- if (isAbortError(error)) {
633
- throw error;
634
- }
635
- if (typeof document === "object" && typeof document.location === "object" && document.location.origin !== new URL(url).origin) {
636
- logInfo(
637
- "FetchRemoteComponent",
638
- "Request failed due to CORS, attempting to fetch it via the withRemoteComponentsHost proxy."
639
- );
640
- const proxiedRes = await fetch(
641
- `${RC_PROTECTED_REMOTE_FETCH_PATHNAME}?url=${url}`,
642
- init?.signal ? { signal: init.signal } : void 0
643
- );
644
- if (proxiedRes.status === 200) {
645
- return proxiedRes;
646
- } else {
647
- logError(
648
- "FetchRemoteComponent",
649
- `Could not proxy remote: [response status ${proxiedRes.status}] ${await proxiedRes.text()}`
650
- );
651
- }
652
- }
653
- throw error;
654
- }
655
- }
656
-
657
729
  // src/shared/utils/index.ts
658
730
  function escapeString(str) {
659
731
  return str.replace(/[^a-z0-9]/g, "_");
@@ -682,11 +754,10 @@ var REMOTE_SHARED_ASSIGNMENT_RE = /\.TURBOPACK_REMOTE_SHARED=await (?:__turbopac
682
754
  var ASYNC_MODULE_LOADER_RE = /(?:__turbopack_context__|e)\.A\((?<asyncSharedModuleId>[0-9]+)\)/;
683
755
  var ASYNC_MODULE_RESOLVE_RE = /(?<ctx>__turbopack_context__|e)=>\{\k<ctx>\.v\((?<inner>parentImport|e)=>Promise\.resolve\(\)\.then\(\(\)=>\k<inner>\((?<sharedModuleId>[0-9]+)\)\)\)\}/;
684
756
  var ASYNC_MODULE_ALL_RE = /(?<ctx>__turbopack_context__|e)=>\{\k<ctx>\.v\((?<vCb>parentImport|t)=>Promise\.all\(\["[^"]+"\]\.map\((?<mapCb>chunk|t)=>\k<ctx>\.l\(\k<mapCb>\)\)\)\.then\(\(\)=>\k<vCb>\((?<sharedModuleId>[0-9]+)\)\)\)\}/;
685
- var NUMERIC_MODULE_ID_RE = /^[0-9]+$/;
686
757
  var TURBOPACK_GLOBAL_RE = /(?:globalThis|self)\s*(?:\.TURBOPACK|\[\s*["']TURBOPACK["']\s*\])/;
687
758
 
688
759
  // src/shared/client/chunk-loader.ts
689
- function createChunkLoader(runtime) {
760
+ function createChunkLoader(runtime, resolveClientUrl) {
690
761
  return function __turbopack_chunk_load__(chunkId, scriptBundle) {
691
762
  logDebug("ChunkLoader", `Loading chunk: "${chunkId}"`);
692
763
  const self = globalThis;
@@ -726,9 +797,10 @@ function createChunkLoader(runtime) {
726
797
  logDebug("ChunkLoader", `Returning cached promise for: "${url}"`);
727
798
  return self.__remote_components_turbopack_chunk_loader_promise__[url];
728
799
  }
729
- logDebug("ChunkLoader", `Fetching chunk from: "${url}"`);
800
+ const resolvedUrl = resolveClientUrl?.(url) ?? url;
801
+ logDebug("ChunkLoader", `Fetching chunk from: "${resolvedUrl}"`);
730
802
  self.__remote_components_turbopack_chunk_loader_promise__[url] = new Promise((resolve, reject) => {
731
- fetchWithProtectedRcFallback(url).then((res) => res.text()).then((code) => {
803
+ fetch(resolvedUrl).then((res) => res.text()).then((code) => {
732
804
  const hasTurbopack = TURBOPACK_GLOBAL_RE.test(code);
733
805
  if (hasTurbopack) {
734
806
  return handleTurbopackChunk(code, bundle ?? "", url);
@@ -741,7 +813,19 @@ function createChunkLoader(runtime) {
741
813
  "ChunkLoader",
742
814
  `First 500 chars of chunk: ${code.slice(0, 500)}`
743
815
  );
744
- }).then(resolve).catch(reject);
816
+ }).then(resolve).catch((error) => {
817
+ const isProxied = isProxiedUrl(resolvedUrl);
818
+ if (isProxied) {
819
+ reject(
820
+ new RemoteComponentsError(
821
+ `Failed to load chunk "${url}" via proxy "${resolvedUrl}". Ensure withRemoteComponentsHost middleware is configured and "${RC_PROTECTED_REMOTE_FETCH_PATHNAME}" is in the matcher. See: ${CORS_DOCS_URL}`
822
+ )
823
+ );
824
+ } else {
825
+ warnCrossOriginFetchError("ChunkLoader", url);
826
+ reject(error);
827
+ }
828
+ });
745
829
  });
746
830
  return self.__remote_components_turbopack_chunk_loader_promise__[url];
747
831
  };
@@ -888,10 +972,14 @@ async function handleTurbopackChunk(code, bundle, url) {
888
972
  function handleTurbopackModule(bundle, moduleId, id) {
889
973
  const self = globalThis;
890
974
  const bundleKey = getBundleKey(bundle);
891
- let modules = self[`TURBOPACK_${bundleKey}`];
892
- if (modules && typeof modules === "object" && "__chunks__" in modules) {
893
- const chunks = modules.__chunks__;
894
- modules = chunks.flat();
975
+ const raw = self[`TURBOPACK_${bundleKey}`];
976
+ let modules;
977
+ if (raw && typeof raw === "object" && "__chunks__" in raw) {
978
+ modules = raw.__chunks__.flat();
979
+ } else if (Array.isArray(raw)) {
980
+ modules = raw.flat();
981
+ } else {
982
+ modules = raw;
895
983
  }
896
984
  if (!self.__remote_components_turbopack_modules__) {
897
985
  self.__remote_components_turbopack_modules__ = {};
@@ -920,13 +1008,12 @@ function handleTurbopackModule(bundle, moduleId, id) {
920
1008
  if (!self.__remote_components_turbopack_global__[bundle]) {
921
1009
  self.__remote_components_turbopack_global__[bundle] = {};
922
1010
  }
923
- const allModules = Array.isArray(modules) ? modules.flat() : modules ? Object.values(modules) : [];
924
1011
  moduleInit(
925
1012
  createTurbopackContext(
926
1013
  bundle,
927
1014
  exports,
928
1015
  moduleExports,
929
- allModules,
1016
+ modules,
930
1017
  moduleInit,
931
1018
  id,
932
1019
  self
@@ -940,46 +1027,27 @@ function handleTurbopackModule(bundle, moduleId, id) {
940
1027
  return moduleExports.exports;
941
1028
  }
942
1029
  function findModuleInit(modules, moduleId) {
943
- if (modules && !Array.isArray(modules) && typeof modules === "object") {
944
- const normalizedId = NUMERIC_MODULE_ID_RE.test(moduleId) ? Number(moduleId) : moduleId;
945
- if (normalizedId in modules) {
946
- return modules[normalizedId];
947
- }
948
- if (typeof normalizedId === "number" && String(normalizedId) in modules) {
949
- return modules[String(normalizedId)];
950
- }
951
- const matchingKey = Object.keys(modules).find(
952
- (key) => typeof key === "string" && key.includes(String(moduleId))
1030
+ if (!modules || typeof modules !== "object")
1031
+ return;
1032
+ if (!Array.isArray(modules)) {
1033
+ const key = moduleId in modules ? moduleId : Object.keys(modules).find((k) => k.startsWith(moduleId));
1034
+ return key !== void 0 ? modules[key] : void 0;
1035
+ }
1036
+ const flat = modules.flat();
1037
+ let idx = flat.findIndex((e) => String(e) === String(moduleId));
1038
+ if (idx < 0) {
1039
+ idx = flat.findIndex(
1040
+ (e) => typeof e === "string" && e.startsWith(moduleId)
953
1041
  );
954
- if (matchingKey) {
955
- return modules[matchingKey];
956
- }
957
- logError("TurbopackModule", `No match found for module ID: ${moduleId}`);
958
- return void 0;
959
- }
960
- const allModules = modules?.flat() ?? [];
961
- if (typeof allModules[1] === "string" || typeof allModules[1] === "number") {
962
- const normalizedId = NUMERIC_MODULE_ID_RE.test(moduleId) ? Number(moduleId) : moduleId;
963
- let moduleIdIndex = allModules.indexOf(normalizedId);
964
- if (moduleIdIndex === -1) {
965
- moduleIdIndex = allModules.findIndex(
966
- (bundleEntry) => typeof bundleEntry === "string" && bundleEntry.startsWith(moduleId) || bundleEntry === normalizedId
967
- );
968
- }
969
- if (moduleIdIndex !== -1) {
970
- while (typeof allModules[moduleIdIndex] !== "function" && moduleIdIndex < allModules.length) {
971
- moduleIdIndex++;
972
- }
973
- return allModules[moduleIdIndex];
974
- }
975
- } else {
976
- return allModules.find(
977
- (bundleEntry) => typeof bundleEntry === "object" && bundleEntry !== null && moduleId in bundleEntry
978
- )?.[moduleId];
979
1042
  }
980
- return void 0;
1043
+ if (idx >= 0) {
1044
+ return flat.slice(idx + 1).find((e) => typeof e === "function");
1045
+ }
1046
+ return flat.find(
1047
+ (e) => Boolean(e && typeof e === "object" && moduleId in e)
1048
+ )?.[moduleId];
981
1049
  }
982
- function createTurbopackContext(bundle, exports, moduleExports, allModules, moduleInit, id, self) {
1050
+ function createTurbopackContext(bundle, exports, moduleExports, modules, moduleInit, id, self) {
983
1051
  return {
984
1052
  // HMR not implemented for Remote Components
985
1053
  k: {
@@ -1100,13 +1168,17 @@ function createTurbopackContext(bundle, exports, moduleExports, allModules, modu
1100
1168
  (parentId) => self.__webpack_require__?.(`[${bundle}] ${parentId}`)
1101
1169
  );
1102
1170
  },
1171
+ // dynamic import tracking — no-op for remote components
1172
+ j() {
1173
+ },
1103
1174
  // chunk loader
1104
1175
  l(url) {
1105
- const moduleInitIndex = allModules.indexOf(moduleInit);
1176
+ const flatModules = Array.isArray(modules) ? modules : [];
1177
+ const moduleInitIndex = flatModules.indexOf(moduleInit);
1106
1178
  if (moduleInitIndex !== -1) {
1107
- const scriptIndex = allModules.slice(0, moduleInitIndex).findLastIndex((bundleEntry) => bundleEntry instanceof Element);
1179
+ const scriptIndex = flatModules.slice(0, moduleInitIndex).findLastIndex((bundleEntry) => bundleEntry instanceof Element);
1108
1180
  if (scriptIndex !== -1) {
1109
- const script = allModules[scriptIndex];
1181
+ const script = flatModules[scriptIndex];
1110
1182
  const scriptSrc = script.getAttribute("data-turbopack-src") || "";
1111
1183
  const nextIndex = scriptSrc.indexOf("/_next");
1112
1184
  const baseUrl = nextIndex !== -1 ? scriptSrc.slice(0, nextIndex) : "";
@@ -1246,7 +1318,7 @@ function getSharedModule(bundle, id) {
1246
1318
  }
1247
1319
 
1248
1320
  // src/shared/client/webpack-adapter.ts
1249
- async function setupWebpackRuntime(runtime, scripts = [], url = new URL(location.href), bundle, shared = {}, remoteShared = {}) {
1321
+ async function setupWebpackRuntime(runtime, scripts = [], url = new URL(location.href), bundle, shared = {}, remoteShared = {}, resolveClientUrl) {
1250
1322
  const self = globalThis;
1251
1323
  if (!self.__remote_bundle_url__) {
1252
1324
  self.__remote_bundle_url__ = {};
@@ -1258,7 +1330,7 @@ async function setupWebpackRuntime(runtime, scripts = [], url = new URL(location
1258
1330
  self.__original_webpack_chunk_load__ = self.__webpack_chunk_load__;
1259
1331
  self.__original_webpack_require__ = self.__webpack_require__;
1260
1332
  }
1261
- self.__webpack_chunk_load__ = createChunkLoader(runtime);
1333
+ self.__webpack_chunk_load__ = createChunkLoader(runtime, resolveClientUrl);
1262
1334
  self.__webpack_require__ = createModuleRequire(runtime);
1263
1335
  self.__webpack_require_type__ = runtime;
1264
1336
  if (self.__remote_webpack_require__ && runtime === RUNTIME_TURBOPACK) {
@@ -1353,7 +1425,8 @@ async function loadRemoteComponent({
1353
1425
  scripts = [],
1354
1426
  shared = Promise.resolve({}),
1355
1427
  remoteShared = {},
1356
- container
1428
+ container,
1429
+ resolveClientUrl
1357
1430
  }) {
1358
1431
  try {
1359
1432
  if (runtime === "webpack") {
@@ -1362,7 +1435,7 @@ async function loadRemoteComponent({
1362
1435
  self.__DISABLE_WEBPACK_EXEC__ = {};
1363
1436
  }
1364
1437
  self.__DISABLE_WEBPACK_EXEC__[bundle] = true;
1365
- await loadScripts(scripts);
1438
+ await loadScripts(scripts, resolveClientUrl);
1366
1439
  }
1367
1440
  const hostShared = await shared;
1368
1441
  logDebug(
@@ -1383,7 +1456,8 @@ async function loadRemoteComponent({
1383
1456
  url,
1384
1457
  bundle,
1385
1458
  hostShared,
1386
- remoteShared
1459
+ remoteShared,
1460
+ resolveClientUrl
1387
1461
  );
1388
1462
  if (bundle) {
1389
1463
  const resolve = {
@@ -1472,6 +1546,11 @@ function loadNextPagesComponent(bundle, route, nextData, name, container) {
1472
1546
  return { component };
1473
1547
  }
1474
1548
 
1549
+ // src/shared/client/proxy-through-host.ts
1550
+ function withRemoteSrc(resolveClientUrl, remoteSrc) {
1551
+ return (url) => resolveClientUrl(remoteSrc, url);
1552
+ }
1553
+
1475
1554
  // src/shared/client/set-attributes-from-props.ts
1476
1555
  var DOMAttributeNames = {
1477
1556
  acceptCharset: "accept-charset",
@@ -1515,7 +1594,81 @@ function setAttributesFromProps(el, props) {
1515
1594
  }
1516
1595
 
1517
1596
  // src/shared/client/static-loader.ts
1518
- async function loadStaticRemoteComponent(scripts, url) {
1597
+ async function importViaCallback(absoluteSrc, resolveClientUrl) {
1598
+ const resolvedUrl = resolveClientUrl(absoluteSrc) ?? absoluteSrc;
1599
+ const fetchUrl = new URL(resolvedUrl, location.href).href;
1600
+ const response = await fetch(fetchUrl);
1601
+ if (!response.ok)
1602
+ throw new Error(`Proxied fetch failed: ${response.status}`);
1603
+ const content = (await response.text()).replace(/import\.meta\.url/g, JSON.stringify(absoluteSrc)).replace(
1604
+ /\b(from|import)\s*(["'])(\.\.?\/[^"']+)\2/g,
1605
+ (_, keyword, quote, relativePath) => {
1606
+ const absoluteImportUrl = new URL(relativePath, absoluteSrc).href;
1607
+ const resolvedImportUrl = new URL(
1608
+ resolveClientUrl(absoluteImportUrl) ?? absoluteImportUrl,
1609
+ location.href
1610
+ ).href;
1611
+ return `${keyword} ${quote}${resolvedImportUrl}${quote}`;
1612
+ }
1613
+ );
1614
+ const moduleBlobUrl = URL.createObjectURL(
1615
+ new Blob([content], { type: "text/javascript" })
1616
+ );
1617
+ const wrapperContent = [
1618
+ `import*as m from${JSON.stringify(moduleBlobUrl)};`,
1619
+ `globalThis.__rc_module_registry__=globalThis.__rc_module_registry__||{};`,
1620
+ `globalThis.__rc_module_registry__[${JSON.stringify(absoluteSrc)}]=m;`
1621
+ ].join("");
1622
+ const wrapperBlobUrl = URL.createObjectURL(
1623
+ new Blob([wrapperContent], { type: "text/javascript" })
1624
+ );
1625
+ const scriptEl = document.createElement("script");
1626
+ scriptEl.type = "module";
1627
+ scriptEl.src = wrapperBlobUrl;
1628
+ try {
1629
+ await new Promise((resolve, reject) => {
1630
+ scriptEl.onload = () => resolve();
1631
+ scriptEl.onerror = () => reject(new Error(`Failed to load module for ${absoluteSrc}`));
1632
+ document.head.appendChild(scriptEl);
1633
+ });
1634
+ } finally {
1635
+ scriptEl.remove();
1636
+ URL.revokeObjectURL(moduleBlobUrl);
1637
+ URL.revokeObjectURL(wrapperBlobUrl);
1638
+ }
1639
+ const registry = globalThis.__rc_module_registry__;
1640
+ const mod = registry?.[absoluteSrc] ?? {};
1641
+ if (registry)
1642
+ delete registry[absoluteSrc];
1643
+ return mod;
1644
+ }
1645
+ async function importDirectly(absoluteSrc) {
1646
+ try {
1647
+ return await import(
1648
+ /* @vite-ignore */
1649
+ /* webpackIgnore: true */
1650
+ absoluteSrc
1651
+ );
1652
+ } catch (importError) {
1653
+ if (!absoluteSrc.startsWith("blob:")) {
1654
+ warnCrossOriginFetchError("StaticLoader", absoluteSrc);
1655
+ }
1656
+ throw importError;
1657
+ }
1658
+ }
1659
+ function resolveScriptSrc(script, url) {
1660
+ const rawSrc = typeof script.getAttribute === "function" ? script.getAttribute("src") ?? script.src : script.src;
1661
+ if (!rawSrc && script.textContent) {
1662
+ return URL.createObjectURL(
1663
+ new Blob(
1664
+ [script.textContent.replace(/import\.meta\.url/g, JSON.stringify(url))],
1665
+ { type: "text/javascript" }
1666
+ )
1667
+ );
1668
+ }
1669
+ return rawSrc;
1670
+ }
1671
+ async function loadStaticRemoteComponent(scripts, url, resolveClientUrl) {
1519
1672
  const self = globalThis;
1520
1673
  if (self.__remote_script_entrypoint_mount__?.[url.href]) {
1521
1674
  self.__remote_script_entrypoint_mount__[url.href] = /* @__PURE__ */ new Set();
@@ -1526,26 +1679,9 @@ async function loadStaticRemoteComponent(scripts, url) {
1526
1679
  const mountUnmountSets = await Promise.all(
1527
1680
  scripts.map(async (script) => {
1528
1681
  try {
1529
- let src = typeof script.getAttribute === "function" ? script.getAttribute("src") ?? script.src : script.src;
1530
- if (!src && script.textContent) {
1531
- const blob = new Blob(
1532
- [
1533
- script.textContent.replace(
1534
- /import\.meta\.url/g,
1535
- JSON.stringify(url)
1536
- )
1537
- ],
1538
- {
1539
- type: "text/javascript"
1540
- }
1541
- );
1542
- src = URL.createObjectURL(blob);
1543
- }
1544
- const mod = await import(
1545
- /* @vite-ignore */
1546
- /* webpackIgnore: true */
1547
- new URL(src, url).href
1548
- );
1682
+ const src = resolveScriptSrc(script, url);
1683
+ const absoluteSrc = new URL(src, url).href;
1684
+ const mod = resolveClientUrl ? await importViaCallback(absoluteSrc, resolveClientUrl) : await importDirectly(absoluteSrc);
1549
1685
  if (src.startsWith("blob:")) {
1550
1686
  URL.revokeObjectURL(src);
1551
1687
  }
@@ -1643,7 +1779,12 @@ async function fetchWithHooks(url, additionalInit, options = {}) {
1643
1779
  };
1644
1780
  let res = await onRequest?.(url, init, hookOptions);
1645
1781
  if (!res) {
1646
- res = await fetchWithProtectedRcFallback(url, init);
1782
+ try {
1783
+ res = await fetch(url, init);
1784
+ } catch (error) {
1785
+ warnCrossOriginFetchError("FetchRemoteComponent", url);
1786
+ throw error;
1787
+ }
1647
1788
  }
1648
1789
  const transformedRes = await onResponse?.(url, res, hookOptions);
1649
1790
  if (transformedRes) {
@@ -1661,15 +1802,34 @@ function getClientOrServerUrl(src, serverFallback) {
1661
1802
  return typeof src === "string" ? new URL(src, fallback) : src;
1662
1803
  }
1663
1804
 
1664
- // src/react/hooks/use-shadow-root.ts
1805
+ // src/react/hooks/use-resolve-client-url.ts
1665
1806
  var import_react = require("react");
1807
+ var import_context = require("#internal/react/context");
1808
+
1809
+ // src/shared/client/default-resolve-client-url.ts
1810
+ function bindResolveClientUrl(prop, remoteSrc) {
1811
+ return prop ? withRemoteSrc(prop, remoteSrc) : void 0;
1812
+ }
1813
+
1814
+ // src/react/hooks/use-resolve-client-url.ts
1815
+ function useResolveClientUrl(prop, urlHref) {
1816
+ const { resolveClientUrl: contextValue } = (0, import_context.useRemoteComponentsContext)();
1817
+ const resolveClientUrl = prop ?? contextValue;
1818
+ return (0, import_react.useMemo)(
1819
+ () => bindResolveClientUrl(resolveClientUrl, urlHref),
1820
+ [resolveClientUrl, urlHref]
1821
+ );
1822
+ }
1823
+
1824
+ // src/react/hooks/use-shadow-root.ts
1825
+ var import_react2 = require("react");
1666
1826
  function useShadowRoot({
1667
1827
  isolate,
1668
1828
  mode,
1669
1829
  keySuffix
1670
1830
  }) {
1671
- const shadowRootContainerRef = (0, import_react.useRef)(null);
1672
- const [shadowRoot, setShadowRoot] = (0, import_react.useState)(() => {
1831
+ const shadowRootContainerRef = (0, import_react2.useRef)(null);
1832
+ const [shadowRoot, setShadowRoot] = (0, import_react2.useState)(() => {
1673
1833
  const self = globalThis;
1674
1834
  const shadowRootKey = `__remote_components_shadowroot_${keySuffix}`;
1675
1835
  const ssrShadowRoot = typeof document !== "undefined" ? document.querySelector(
@@ -1678,7 +1838,7 @@ function useShadowRoot({
1678
1838
  self[shadowRootKey] = null;
1679
1839
  return ssrShadowRoot;
1680
1840
  });
1681
- (0, import_react.useLayoutEffect)(() => {
1841
+ (0, import_react2.useLayoutEffect)(() => {
1682
1842
  if (isolate !== false && typeof document !== "undefined" && (!shadowRoot || !shadowRoot.isConnected)) {
1683
1843
  const self = globalThis;
1684
1844
  const shadowRootKey = `__remote_components_shadowroot_${keySuffix}`;
@@ -1733,11 +1893,12 @@ function getRemoteComponentHtml(html) {
1733
1893
  }
1734
1894
 
1735
1895
  // src/react/index.tsx
1896
+ var import_context2 = require("#internal/react/context");
1736
1897
  var import_jsx_runtime2 = (
1737
1898
  // TODO: remove wrapper div by converting HTML to RSC or React tree
1738
1899
  require("react/jsx-runtime")
1739
1900
  );
1740
- var import_react3 = require("react");
1901
+ var import_react4 = require("react");
1741
1902
  function RemoteComponent({
1742
1903
  src,
1743
1904
  isolate,
@@ -1752,10 +1913,11 @@ function RemoteComponent({
1752
1913
  onError,
1753
1914
  onChange,
1754
1915
  onRequest,
1755
- onResponse
1916
+ onResponse,
1917
+ resolveClientUrl: _resolveClientUrl
1756
1918
  }) {
1757
- const instanceId = (0, import_react2.useId)();
1758
- const name = (0, import_react2.useMemo)(() => {
1919
+ const instanceId = (0, import_react3.useId)();
1920
+ const name = (0, import_react3.useMemo)(() => {
1759
1921
  if (typeof src === "string") {
1760
1922
  const url2 = new URL(
1761
1923
  src,
@@ -1769,23 +1931,26 @@ function RemoteComponent({
1769
1931
  }
1770
1932
  return nameProp;
1771
1933
  }, [src, nameProp]);
1772
- const [data, setData] = (0, import_react2.useState)(null);
1773
- const url = (0, import_react2.useMemo)(() => getClientOrServerUrl(src, DUMMY_FALLBACK), [src]);
1934
+ const [data, setData] = (0, import_react3.useState)(null);
1935
+ const url = (0, import_react3.useMemo)(() => getClientOrServerUrl(src, DUMMY_FALLBACK), [src]);
1936
+ const resolveClientUrl = useResolveClientUrl(_resolveClientUrl, url.href);
1774
1937
  const id = url.origin === (typeof location !== "undefined" ? location.origin : DUMMY_FALLBACK) ? url.pathname : url.href;
1775
- const keySuffix = `${escapeString(id)}_${escapeString(data?.name ?? name)}_${escapeString(instanceId)}`;
1776
- const [remoteComponent, setRemoteComponent] = (0, import_react2.useState)(null);
1938
+ const keySuffix = `${escapeString(id)}_${escapeString(
1939
+ data?.name ?? name
1940
+ )}_${escapeString(instanceId)}`;
1941
+ const [remoteComponent, setRemoteComponent] = (0, import_react3.useState)(null);
1777
1942
  const { shadowRoot, shadowRootContainerRef } = useShadowRoot({
1778
1943
  isolate,
1779
1944
  mode,
1780
1945
  keySuffix
1781
1946
  });
1782
- const htmlRef = (0, import_react2.useRef)(
1947
+ const htmlRef = (0, import_react3.useRef)(
1783
1948
  typeof document !== "undefined" ? document.querySelector(
1784
1949
  `[data-remote-component-id="shadowroot_${keySuffix}"]`
1785
1950
  )?.shadowRoot?.innerHTML ?? document.getElementById(`__REMOTE_COMPONENT${name}`)?.innerHTML ?? document.querySelector(`div[data-bundle][data-route][id^="${name}"]`)?.innerHTML ?? document.querySelector("div[data-bundle][data-route]")?.innerHTML : null
1786
1951
  );
1787
- const endTemplateRef = (0, import_react2.useRef)(null);
1788
- const childrenRef = (0, import_react2.useRef)(
1952
+ const endTemplateRef = (0, import_react3.useRef)(null);
1953
+ const childrenRef = (0, import_react3.useRef)(
1789
1954
  typeof document !== "undefined" ? (() => {
1790
1955
  let el = document.querySelector(`template[id="${name}_start"]`);
1791
1956
  const elements = [];
@@ -1798,20 +1963,20 @@ function RemoteComponent({
1798
1963
  return elements;
1799
1964
  })() : []
1800
1965
  );
1801
- const prevSrcRef = (0, import_react2.useRef)(null);
1802
- const componentHydrationHtml = (0, import_react2.useRef)(null);
1803
- const prevIsRemoteComponentRef = (0, import_react2.useRef)(false);
1804
- const prevUrlRef = (0, import_react2.useRef)(null);
1805
- const prevRemoteComponentContainerRef = (0, import_react2.useRef)(null);
1806
- const unmountRef = (0, import_react2.useRef)(null);
1807
- const prevNameRef = (0, import_react2.useRef)(void 0);
1808
- (0, import_react2.useLayoutEffect)(() => {
1966
+ const prevSrcRef = (0, import_react3.useRef)(null);
1967
+ const componentHydrationHtml = (0, import_react3.useRef)(null);
1968
+ const prevIsRemoteComponentRef = (0, import_react3.useRef)(false);
1969
+ const prevUrlRef = (0, import_react3.useRef)(null);
1970
+ const prevRemoteComponentContainerRef = (0, import_react3.useRef)(null);
1971
+ const unmountRef = (0, import_react3.useRef)(null);
1972
+ const prevNameRef = (0, import_react3.useRef)(void 0);
1973
+ (0, import_react3.useLayoutEffect)(() => {
1809
1974
  const shadowRootKey = `__remote_components_shadowroot_${keySuffix}`;
1810
1975
  return () => {
1811
1976
  delete globalThis[shadowRootKey];
1812
1977
  };
1813
1978
  }, [keySuffix]);
1814
- (0, import_react2.useLayoutEffect)(() => {
1979
+ (0, import_react3.useLayoutEffect)(() => {
1815
1980
  if (childrenRef.current.length > 0 && remoteComponent) {
1816
1981
  childrenRef.current.forEach((el) => {
1817
1982
  el.remove();
@@ -1819,7 +1984,7 @@ function RemoteComponent({
1819
1984
  childrenRef.current = [];
1820
1985
  }
1821
1986
  }, [remoteComponent]);
1822
- (0, import_react2.useLayoutEffect)(() => {
1987
+ (0, import_react3.useLayoutEffect)(() => {
1823
1988
  if (shadowRoot && remoteComponent) {
1824
1989
  const resetStyles = shadowRoot.querySelectorAll(
1825
1990
  "style[data-remote-components-reset]"
@@ -1842,13 +2007,16 @@ function RemoteComponent({
1842
2007
  }
1843
2008
  }
1844
2009
  }, [shadowRoot, remoteComponent, name]);
1845
- (0, import_react2.useEffect)(() => {
2010
+ (0, import_react3.useEffect)(() => {
1846
2011
  if (src && src !== prevSrcRef.current) {
1847
2012
  const previousSrc = prevSrcRef.current;
1848
2013
  const previousName = prevNameRef.current;
1849
2014
  prevSrcRef.current = src;
2015
+ if (previousSrc !== null) {
2016
+ htmlRef.current = null;
2017
+ }
1850
2018
  onBeforeLoad?.(src);
1851
- (0, import_react2.startTransition)(async () => {
2019
+ (0, import_react3.startTransition)(async () => {
1852
2020
  try {
1853
2021
  let html = getRemoteComponentHtml(
1854
2022
  htmlRef.current ?? (endTemplateRef.current?.previousElementSibling?.tagName === "div" ? endTemplateRef.current.previousElementSibling.innerHTML : "")
@@ -1857,41 +2025,18 @@ function RemoteComponent({
1857
2025
  const fetchInit = {
1858
2026
  credentials
1859
2027
  };
2028
+ const resolvedUrl = new URL(
2029
+ resolveClientUrl?.(url.href) ?? url.href,
2030
+ location.href
2031
+ );
1860
2032
  const abortController = new AbortController();
1861
- const res = await fetchWithHooks(url, fetchInit, {
2033
+ const res = await fetchWithHooks(resolvedUrl, fetchInit, {
1862
2034
  onRequest,
1863
2035
  onResponse,
1864
2036
  abortController
1865
2037
  });
1866
2038
  if (!res || !res.ok) {
1867
- let error = failedToFetchRemoteComponentError(
1868
- url.href,
1869
- res ?? new Response(null, { status: 0 })
1870
- );
1871
- try {
1872
- const body = await res.text();
1873
- const parser2 = new DOMParser();
1874
- const doc2 = parser2.parseFromString(body, "text/html");
1875
- const errorTemplate = doc2.querySelector(
1876
- "template[data-next-error-message]"
1877
- );
1878
- const errorMessage = errorTemplate?.getAttribute(
1879
- "data-next-error-message"
1880
- );
1881
- const errorStack = errorTemplate?.getAttribute(
1882
- "data-next-error-stack"
1883
- );
1884
- if (errorMessage) {
1885
- error = new RemoteComponentsError(errorMessage);
1886
- if (errorStack) {
1887
- error.stack = errorStack;
1888
- }
1889
- }
1890
- } catch (parseError) {
1891
- if (isAbortError(parseError))
1892
- throw parseError;
1893
- }
1894
- throw error;
2039
+ throw await errorFromFailedFetch(url.href, resolvedUrl, res);
1895
2040
  }
1896
2041
  const remoteHtml = await res.text();
1897
2042
  htmlRef.current = remoteHtml;
@@ -1952,7 +2097,7 @@ function RemoteComponent({
1952
2097
  prevIsRemoteComponentRef.current = isRemoteComponent;
1953
2098
  prevUrlRef.current = url;
1954
2099
  prevNameRef.current = remoteName;
1955
- applyOriginToNodes(doc, url);
2100
+ applyOriginToNodes(doc, url, resolveClientUrl);
1956
2101
  const links = Array.from(
1957
2102
  doc.querySelectorAll("link[href]")
1958
2103
  ).filter((link) => {
@@ -2072,10 +2217,12 @@ function RemoteComponent({
2072
2217
  shadowRootHtml = `<style data-remote-components-reset="">:host { all: initial; }</style>${shadowRootHtml}`;
2073
2218
  }
2074
2219
  shadowRoot.innerHTML = shadowRootHtml;
2220
+ htmlRef.current = null;
2075
2221
  setRemoteComponent(null);
2076
2222
  const { mount, unmount } = await loadStaticRemoteComponent(
2077
2223
  Array.from(shadowRoot.querySelectorAll("script")),
2078
- url
2224
+ url,
2225
+ resolveClientUrl
2079
2226
  );
2080
2227
  unmountRef.current = unmount;
2081
2228
  await Promise.all(
@@ -2092,9 +2239,11 @@ function RemoteComponent({
2092
2239
  }
2093
2240
  )
2094
2241
  );
2242
+ htmlRef.current = null;
2095
2243
  const { mount, unmount } = await loadStaticRemoteComponent(
2096
2244
  Array.from(component.querySelectorAll("script")),
2097
- url
2245
+ url,
2246
+ resolveClientUrl
2098
2247
  );
2099
2248
  unmountRef.current = unmount;
2100
2249
  await Promise.all(
@@ -2137,7 +2286,8 @@ function RemoteComponent({
2137
2286
  ...userShared
2138
2287
  },
2139
2288
  remoteShared,
2140
- container: shadowRoot
2289
+ container: shadowRoot,
2290
+ resolveClientUrl
2141
2291
  });
2142
2292
  if (rsc) {
2143
2293
  rsc.remove();
@@ -2183,7 +2333,8 @@ function RemoteComponent({
2183
2333
  onError,
2184
2334
  onChange,
2185
2335
  onRequest,
2186
- onResponse
2336
+ onResponse,
2337
+ resolveClientUrl
2187
2338
  ]);
2188
2339
  if (remoteComponent instanceof Error) {
2189
2340
  throw remoteComponent;
@@ -2195,7 +2346,7 @@ function RemoteComponent({
2195
2346
  runtime: prevIsRemoteComponentRef.current ? RUNTIME_SCRIPT : data?.runtime || RUNTIME_WEBPACK
2196
2347
  }) });
2197
2348
  const resetStyle = reset ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { "data-remote-components-reset": "react", children: `:host { all: initial; }` }) : null;
2198
- const linksToRender = data?.links?.map((link) => /* @__PURE__ */ (0, import_react3.createElement)(
2349
+ const linksToRender = data?.links?.map((link) => /* @__PURE__ */ (0, import_react4.createElement)(
2199
2350
  "link",
2200
2351
  {
2201
2352
  ...link,
@@ -2214,7 +2365,8 @@ function RemoteComponent({
2214
2365
  if (prevIsRemoteComponentRef.current) {
2215
2366
  loadStaticRemoteComponent(
2216
2367
  Array.from(shadowRoot.querySelectorAll("script")),
2217
- url
2368
+ url,
2369
+ resolveClientUrl
2218
2370
  ).then(({ mount }) => {
2219
2371
  return Promise.all(
2220
2372
  Array.from(mount).map((mountFn) => mountFn(shadowRoot))
@@ -2297,6 +2449,9 @@ function RemoteComponent({
2297
2449
  ] });
2298
2450
  }
2299
2451
 
2452
+ // src/next/host/client/index.tsx
2453
+ var import_context3 = require("#internal/react/context");
2454
+
2300
2455
  // src/next/host/app-router-compat.tsx
2301
2456
  var import_navigation = require("next/navigation");
2302
2457
  var import_jsx_runtime3 = require("react/jsx-runtime");
@@ -2407,6 +2562,7 @@ function RemoteComponent2(props) {
2407
2562
  }
2408
2563
  // Annotate the CommonJS export names for ESM import in node:
2409
2564
  0 && (module.exports = {
2410
- RemoteComponent
2565
+ RemoteComponent,
2566
+ RemoteComponentsProvider
2411
2567
  });
2412
2568
  //# sourceMappingURL=index.cjs.map