diff --git a/src/runtime/server/index.ts b/src/runtime/server/index.ts
index 7d7088ad81b6..da510f2fbf99 100644
--- a/src/runtime/server/index.ts
+++ b/src/runtime/server/index.ts
@@ -3,7 +3,7 @@ import type { AstroGlobalPartial, SSRResult, SSRElement } from '../../@types/ast
import type { AstroRequest } from '../../core/render/request';
import shorthash from 'shorthash';
-import { extractDirectives, generateHydrateScript } from './hydration.js';
+import { extractDirectives, generateHydrateScript, serializeProps } from './hydration.js';
import { serializeListValue } from './util.js';
import { escapeHTML, HTMLString, markHTMLString } from './escape.js';
@@ -278,8 +278,8 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
return markHTMLString(html.replace(/\<\/?astro-fragment\>/g, ''));
}
- // Include componentExport name and componentUrl in hash to dedupe identical islands
- const astroId = shorthash.unique(`\n${html}`);
+ // Include componentExport name, componentUrl, and props in hash to dedupe identical islands
+ const astroId = shorthash.unique(`\n${html}\n${serializeProps(props)}`);
// Rather than appending this inline in the page, puts this into the `result.scripts` set that will be appended to the head.
// INVESTIGATE: This will likely be a problem in streaming because the `
` will be gone at this point.
diff --git a/test/fixtures/react-component/src/components/Hello.jsx b/test/fixtures/react-component/src/components/Hello.jsx
index 4b6c416a98e7..4c241162d368 100644
--- a/test/fixtures/react-component/src/components/Hello.jsx
+++ b/test/fixtures/react-component/src/components/Hello.jsx
@@ -1,5 +1,5 @@
import React from 'react';
-export default function ({ name }) {
- return Hello {name}!
;
+export default function ({ name, unused }) {
+ return Hello {name}!
;
}
diff --git a/test/fixtures/react-component/src/pages/index.astro b/test/fixtures/react-component/src/pages/index.astro
index 597a4a546a51..049b5fb6aa48 100644
--- a/test/fixtures/react-component/src/pages/index.astro
+++ b/test/fixtures/react-component/src/pages/index.astro
@@ -17,7 +17,12 @@ const someProps = {
-
+
+
+
+
+
+
diff --git a/test/fixtures/vue-component/src/components/Counter.vue b/test/fixtures/vue-component/src/components/Counter.vue
index 49d2936edcd3..8cbb0f5503c4 100644
--- a/test/fixtures/vue-component/src/components/Counter.vue
+++ b/test/fixtures/vue-component/src/components/Counter.vue
@@ -20,12 +20,17 @@ export default {
start: {
type: String,
required: true
+ },
+ stepSize: {
+ type: String,
+ default: "1"
}
},
setup(props) {
const count = ref(parseInt(props.start))
- const add = () => (count.value = count.value + 1);
- const subtract = () => (count.value = count.value - 1);
+ const stepSize = ref(parseInt(props.stepSize))
+ const add = () => (count.value = count.value + stepSize.value);
+ const subtract = () => (count.value = count.value - stepSize.value);
return {
count,
add,
diff --git a/test/fixtures/vue-component/src/pages/index.astro b/test/fixtures/vue-component/src/pages/index.astro
index eed6624cce9d..7cae724dc9b1 100644
--- a/test/fixtures/vue-component/src/pages/index.astro
+++ b/test/fixtures/vue-component/src/pages/index.astro
@@ -20,6 +20,10 @@ import Counter from '../components/Counter.vue'
SSR Rendered, No Client
SSR Rendered, client:load
+
+ SSR Rendered, client:load
+
+ SSR Rendered, client:load
SSR Rendered, client:idle
SSR Rendered, client:visible
diff --git a/test/react-component.test.js b/test/react-component.test.js
index a05f76cf9170..8e90f88ae420 100644
--- a/test/react-component.test.js
+++ b/test/react-component.test.js
@@ -25,10 +25,10 @@ describe('React Components', () => {
const $ = cheerio.load(html);
// test 1: basic component renders
- expect($('#react-h2').text()).to.equal('Hello world!');
+ expect($('#react-static').text()).to.equal('Hello static!');
// test 2: no reactroot
- expect($('#react-h2').attr('data-reactroot')).to.equal(undefined);
+ expect($('#react-static').attr('data-reactroot')).to.equal(undefined);
// test 3: Can use function components
expect($('#arrow-fn-component')).to.have.lengthOf(1);
@@ -44,6 +44,13 @@ describe('React Components', () => {
// test 7: Can use Pure components
expect($('#pure')).to.have.lengthOf(1);
+
+ // test 8: Check number of islands
+ expect($('astro-root[uid]')).to.have.lengthOf(5);
+
+ // test 9: Check island deduplication
+ const uniqueRootUIDs = new Set($('astro-root').map((i, el) => $(el).attr('uid')));
+ expect(uniqueRootUIDs.size).to.equal(4);
});
it('Can load Vue', async () => {
diff --git a/test/vue-component.test.js b/test/vue-component.test.js
index 46edcfbac376..7b226b91127d 100644
--- a/test/vue-component.test.js
+++ b/test/vue-component.test.js
@@ -29,17 +29,17 @@ describe('Vue component', () => {
.map((el) => $(el).text());
// test 1: renders all components correctly
- expect(allPreValues).to.deep.equal(['0', '1', '10', '100', '1000']);
+ expect(allPreValues).to.deep.equal(['0', '1', '1', '1', '10', '100', '1000']);
// test 2: renders 3 s
- expect($('astro-root')).to.have.lengthOf(4);
+ expect($('astro-root')).to.have.lengthOf(6);
// test 3: all s have uid attributes
- expect($('astro-root[uid]')).to.have.lengthOf(4);
+ expect($('astro-root[uid]')).to.have.lengthOf(6);
- // test 5: all s have unique uid attributes
+ // test 5: components with identical render output and props have been deduplicated
const uniqueRootUIDs = $('astro-root').map((i, el) => $(el).attr('uid'));
- expect(new Set(uniqueRootUIDs).size).to.equal(4);
+ expect(new Set(uniqueRootUIDs).size).to.equal(5);
});
});