Repository: sveltejs/svelte (JavaScript)
Date: 2020-01-23 14:56:21+00:00
Task type: Bug Fix

Issue:
Hydration removes <title> element
**Describe the bug**
When starting from SSR generated HTML with `hydratable: true`, hydration will remove the `<title>` element along with the other appropriate `<head>` elements, but will not add it back.

**Logs**
None.

**To Reproduce**
https://github.com/johnmuhl/svelte-hydrate-head

**Expected behavior**
The `<title>` should remain after hydration.

**Stacktraces**
None.

**Information about your Svelte project:**
Independent of browser.
Svelte 3.17.0+

**Severity**
Pretty bad.

**Additional context**
This was introduced in #4082. The compiled component sets `document.title` first and then later removes elements matching `[data-svelte="svelte-..."]`, and so the title is lost. The simplest way to handle this would probably be to not add the special SSR attribute to the `<title>` element at all, since as of #4250 we don't need to worry about there being more than one of that anyway.

cc @johnmuhl @tanhauhau 


Issue discussion:

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,7 @@
 * Fix updating a `<slot>` inside an `{#if}` or other block ([#4292](https://github.com/sveltejs/svelte/issues/4292))
 * Fix using RxJS observables in `derived` stores ([#4298](https://github.com/sveltejs/svelte/issues/4298))
 * Add dev mode check to disallow duplicate keys in a keyed `{#each}` ([#4301](https://github.com/sveltejs/svelte/issues/4301))
+* Fix hydration of `<title>` when starting from SSR-generated code with `hydratable: true` ([#4310](https://github.com/sveltejs/svelte/issues/4310))
 
 ## 3.17.2
 
diff --git a/src/compiler/compile/render_ssr/handlers/Title.ts b/src/compiler/compile/render_ssr/handlers/Title.ts
--- a/src/compiler/compile/render_ssr/handlers/Title.ts
+++ b/src/compiler/compile/render_ssr/handlers/Title.ts
@@ -5,11 +5,7 @@ import { x } from 'code-red';
 export default function(node: Title, renderer: Renderer, options: RenderOptions) {
 	renderer.push();
 
-	renderer.add_string('<title');
-	if (options.hydratable && options.head_id) {
-		renderer.add_string(` data-svelte="${options.head_id}"`);
-	}
-	renderer.add_string('>');
+	renderer.add_string(`<title>`);
 
 	renderer.render(node.children, options);
 


Test patch:
diff --git a/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html b/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html
--- a/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html
+++ b/test/hydration/samples/head-meta-hydrate-duplicate/_before_head.html
@@ -1,4 +1,4 @@
-<title data-svelte="svelte-1s8aodm">Some Title</title>
+<title>Some Title</title>
 <link rel="canonical" href="/" data-svelte="svelte-1s8aodm">
 <meta name="description" content="some description" data-svelte="svelte-1s8aodm">
 <meta name="keywords" content="some keywords" data-svelte="svelte-1s8aodm">
\ No newline at end of file
diff --git a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html
--- a/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html
+++ b/test/server-side-rendering/samples/head-meta-hydrate-duplicate/_expected-head.html
@@ -1,4 +1,4 @@
-<title data-svelte="svelte-1s8aodm">Some Title</title>
+<title>Some Title</title>
 <link rel="canonical" href="/" data-svelte="svelte-1s8aodm">
 <meta name="description" content="some description" data-svelte="svelte-1s8aodm">
 <meta name="keywords" content="some keywords" data-svelte="svelte-1s8aodm">
\ No newline at end of file