Skip to content

Commit a04a974

Browse files
committed
fix: load page component modules on same-layout navigation
Root cause of both bugs: on client-side navigation within the same layout, the router swapped <main> content but did NOT load the new page's component modules. Components like <new-post> appeared in the DOM as plain HTMLElement — never upgraded, no event handlers, no interactivity. The fix: call mergeHead() on same-layout swaps (previously skipped by design). This adds new <link rel="modulepreload"> and executes new <script type="module"> tags from the target page's <head>, registering the page's components so they upgrade after insertion. Also fixed mergeHead to recreate <script> elements instead of cloning them — cloned scripts don't execute in the browser.
1 parent 2d260dc commit a04a974

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

packages/core/src/router-client.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,8 @@ async function performNavigation(href, isPopState) {
201201
if (currentShell && newShell &&
202202
(currentShell.tagName === newShell.tagName ||
203203
(currentShell.getAttribute('data-layout') && currentShell.getAttribute('data-layout') === newShell.getAttribute('data-layout')))) {
204-
// Same layout — minimal swap: title + page content only.
205-
const newTitle = doc.querySelector('title');
206-
if (newTitle) document.title = newTitle.textContent || '';
204+
// Same layout — swap page content + merge head for new modules.
205+
mergeHead(doc.head);
207206

208207
// For data-layout shells, swap only the <main> element's children
209208
// (header and footer stay mounted). For custom element shells with
@@ -345,7 +344,15 @@ function mergeHead(newHead) {
345344
if (el.tagName === 'BASE') continue;
346345
if (el.tagName === 'TITLE') continue;
347346
if (!currentSet.has(el.outerHTML)) {
348-
currentHead.appendChild(el.cloneNode(true));
347+
if (el.tagName === 'SCRIPT') {
348+
// Scripts must be recreated (not cloned) to execute.
349+
const script = document.createElement('script');
350+
for (const attr of el.attributes) script.setAttribute(attr.name, attr.value);
351+
script.textContent = el.textContent;
352+
currentHead.appendChild(script);
353+
} else {
354+
currentHead.appendChild(el.cloneNode(true));
355+
}
349356
}
350357
}
351358
}

0 commit comments

Comments
 (0)