diff --git a/CHANGELOG.md b/CHANGELOG.md
index 25c0aa2093..8d69c6194b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
* Fix reactive assignments with destructuring and stores where the destructured value should be undefined ([#4170](https://github.com/sveltejs/svelte/issues/4170))
* Fix hydrating `{:else}` in `{#each}` ([#4202](https://github.com/sveltejs/svelte/issues/4202))
* Do not automatically declare variables in reactive declarations when assigning to a member expression ([#4212](https://github.com/sveltejs/svelte/issues/4212))
+* Only render one `
` in SSR mode when multiple components provide one ([#4250](https://github.com/sveltejs/svelte/pull/4250))
## 3.16.7
diff --git a/src/compiler/compile/render_ssr/handlers/Title.ts b/src/compiler/compile/render_ssr/handlers/Title.ts
index 62d49d461a..f1f458ed5b 100644
--- a/src/compiler/compile/render_ssr/handlers/Title.ts
+++ b/src/compiler/compile/render_ssr/handlers/Title.ts
@@ -1,10 +1,16 @@
import Renderer, { RenderOptions } from '../Renderer';
import Title from '../../nodes/Title';
+import { x } from 'code-red';
export default function(node: Title, renderer: Renderer, options: RenderOptions) {
+ renderer.push();
+
renderer.add_string(``);
renderer.render(node.children, options);
renderer.add_string(``);
+ const result = renderer.pop();
+
+ renderer.add_expression(x`($$result.title = ${result}, "")`);
}
diff --git a/src/runtime/internal/ssr.ts b/src/runtime/internal/ssr.ts
index 274006f243..b032284d52 100644
--- a/src/runtime/internal/ssr.ts
+++ b/src/runtime/internal/ssr.ts
@@ -103,12 +103,13 @@ export function create_ssr_component(fn) {
on_destroy = [];
const result: {
+ title: string;
head: string;
css: Set<{
map: null;
code: string;
}>;
- } = { head: '', css: new Set() };
+ } = { title: '', head: '', css: new Set() };
const html = $$render(result, props, {}, options);
@@ -120,7 +121,7 @@ export function create_ssr_component(fn) {
code: Array.from(result.css).map(css => css.code).join('\n'),
map: null // TODO
},
- head: result.head
+ head: result.title + result.head
};
},
diff --git a/test/server-side-rendering/samples/head-multiple-title/A.svelte b/test/server-side-rendering/samples/head-multiple-title/A.svelte
new file mode 100644
index 0000000000..b139b4ff77
--- /dev/null
+++ b/test/server-side-rendering/samples/head-multiple-title/A.svelte
@@ -0,0 +1,3 @@
+
+ A
+
diff --git a/test/server-side-rendering/samples/head-multiple-title/B.svelte b/test/server-side-rendering/samples/head-multiple-title/B.svelte
new file mode 100644
index 0000000000..4a29ecb04c
--- /dev/null
+++ b/test/server-side-rendering/samples/head-multiple-title/B.svelte
@@ -0,0 +1,3 @@
+
+ B
+
diff --git a/test/server-side-rendering/samples/head-multiple-title/_expected-head.html b/test/server-side-rendering/samples/head-multiple-title/_expected-head.html
new file mode 100644
index 0000000000..af5c5feba4
--- /dev/null
+++ b/test/server-side-rendering/samples/head-multiple-title/_expected-head.html
@@ -0,0 +1 @@
+B
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/head-multiple-title/_expected.html b/test/server-side-rendering/samples/head-multiple-title/_expected.html
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/server-side-rendering/samples/head-multiple-title/data.json b/test/server-side-rendering/samples/head-multiple-title/data.json
new file mode 100644
index 0000000000..eab238e816
--- /dev/null
+++ b/test/server-side-rendering/samples/head-multiple-title/data.json
@@ -0,0 +1,3 @@
+{
+ "adjective": "custom"
+}
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/head-multiple-title/main.svelte b/test/server-side-rendering/samples/head-multiple-title/main.svelte
new file mode 100644
index 0000000000..fb9a70b923
--- /dev/null
+++ b/test/server-side-rendering/samples/head-multiple-title/main.svelte
@@ -0,0 +1,10 @@
+
+
+
+ Main
+
+
+