0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-20 22:12:38 -05:00

Fix hydration scripts missing from dynamic slot usage (#10219)

This commit is contained in:
Matthew Phillips 2024-02-26 03:38:11 -05:00 committed by GitHub
parent fd7453bc0d
commit afcb9d3311
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 69 additions and 1 deletions

View file

@ -0,0 +1,5 @@
---
"astro": patch
---
Fix dynamic slots missing hydration scripts

View file

@ -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

View file

@ -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)) {

View file

@ -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()} />

View file

@ -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>

View file

@ -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);
});
});