Skip to content

Commit

Permalink
Fix hydration scripts missing from dynamic slot usage (#10219)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewp committed Feb 26, 2024
1 parent fd7453b commit afcb9d3
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/dirty-boats-suffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"astro": patch
---

Fix dynamic slots missing hydration scripts
2 changes: 1 addition & 1 deletion packages/astro/src/core/render/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class Slots {
const slot = async () =>
typeof expression === 'function' ? expression(...args) : expression;
return await renderSlotToString(result, slot).then((res) => {
return res != null ? String(res) : res;
return res;
});
}
// JSX
Expand Down
2 changes: 2 additions & 0 deletions packages/astro/src/runtime/server/escape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ export function unescapeHTML(
return Promise.resolve(str).then((value) => {
return unescapeHTML(value);
});
} else if(str[Symbol.for('astro:slot-string')]) {
return str;
} else if (Symbol.iterator in str) {
return unescapeChunks(str);
} else if (Symbol.asyncIterator in str || hasGetReader(str)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
const getHtml = async () => {
if(Astro.slots.has("default")) {
let output = await Astro.slots.render("default", [{
foo: "bar"
}]);
return output;
} else {
return "";
}
};
---


<Fragment set:html={getHtml()} />
34 changes: 34 additions & 0 deletions packages/astro/test/fixtures/hydration-race/src/pages/slot.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
// Component Imports
import Demo from '../components/One.jsx';
import WithSlot from '../components/WithSlot.astro';
// Full Astro Component Syntax:
// https://docs.astro.build/core-concepts/astro-components/
---

<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<style>
html,
body {
font-family: system-ui;
margin: 0;
}
body {
padding: 2rem;
}
</style>
</head>
<body>
<main>
<WithSlot>
{(foo) => <Demo client:load />}
</WithSlot>
</main>
</body>
</html>
11 changes: 11 additions & 0 deletions packages/astro/test/hydration-race.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,15 @@ describe('Hydration script ordering', async () => {
assert.equal($('style').length, 1, 'hydration style added once');
assert.equal($('script').length, 1, 'only one hydration script needed');
});

it('Hydration script included when inside dynamic slot', async () => {
let html = await fixture.readFile('/slot/index.html');
let $ = cheerio.load(html);

// First, let's make sure all islands rendered
assert.equal($('astro-island').length, 1);

// There should be 1 script
assert.equal($('script').length, 1);
});
});

0 comments on commit afcb9d3

Please sign in to comment.