svelte: `{@html}` hydration in head duplicates elements

Describe the bug

@html markup in head is being rendered twice. I also noticed that HTML_TAG_END is occurring before HTML_TAG_START, which seems backwards. I believe that @tanhauhau tried to implement / fix this in https://github.com/sveltejs/svelte/pull/4444, but it looks like there may be a kink to work out still

Reproduction

Add this code to a SvelteKit app:

<script>
const item_title = 'Hello world!';

const schema = {
    "@context": "http://schema.org",
    "@type": "Article",
    "@name": item_title
  };
</script>

<svelte:head>
  {@html '<script type="application/ld+json">' + JSON.stringify(schema) + '</script>'}
</svelte:head>

It was originally reported in the SvelteKit repo https://github.com/sveltejs/kit/issues/1035 as there being an issue only on build with adapter-static, but I’m seeing it even with npm run dev. I think that the originally reported issue may have been a bit different perhaps relying on a slightly older version of Svelte before https://github.com/sveltejs/svelte/pull/4444 was merged

Logs

Inspect element in Chrome and see this:

<head>
		<script type="application/ld+json">{"@context":"http://schema.org","@type":"Article","@name":"Hello world!"}</script>

		<!-- HTML_TAG_END --><script type="application/ld+json">{"@context":"http://schema.org","@type":"Article","@name":"Hello world!"}</script><!-- HTML_TAG_START -->
</head>


### System Info

```shell
npmPackages:
    @sveltejs/kit: next => 1.0.0-next.118 
    svelte: ^3.34.0 => 3.38.3

Severity

annoyance

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 2
  • Comments: 19 (10 by maintainers)

Commits related to this issue

Most upvoted comments

hello, I think Severity needs to be change from “annoyance” because google won’t show rich snippets in search results if there are duplicates. Source: https://support.google.com/webmasters/thread/51583675/test-product-on-rich-result-tool-and-found-duplicate-product-do-i-need-to-remove-one-of-them?hl=en Also tested on my personal website where rich snippets is no longer being index.

edit: A work around for this for anyone using google structured data, is to include it the body and not the head, since google doesn’t mind: https://www.youtube.com/watch?v=lI6EtxjoyDU&t=94s

Came here by reference on Discord. Today using a stock sveltekit skeleton app, I’ve found out that including any <meta /> inside <svelte:head> drives things completely crazy causing complete re-render of the <head>, reversing order of the chunks’ CSS and FOUC, in both dev and preview.

Also duplicated stylesheets seem to referenced with different paths, e.g.:

<link rel="stylesheet" href="/./_app/assets/pages/__layout.svelte-4dac632b.css">
<link rel="stylesheet" href="/_app/assets/pages/__layout.svelte-4dac632b.css">

@enda thanks for pointing it out, i’ve opened a PR: https://github.com/sveltejs/svelte/pull/7941

@hbirler I am still having this exact same issue in my Svelte Kit project. We are using Stitches for our CSS framework and they provide an API for handling SSR stylesheets which require a function to be run in svelte:head using the @html template syntax. This results in duplicate tag and style outputs. All styles are loaded twice 🤦‍♂️

My code for __layout.svelte:

<script lang="ts">
	import { getCssText } from '../lib/stitches.config.js';
</script>

<svelte:head>
	{@html `<${'style'} id="stitches">
		${getCssText()}
	</style>`}
</svelte:head>

<slot />

This results in my head output containing 2 style tags with id=stitches and all styles. Note that the second occurs after the HTML comment for HTML_TAG_END. Screen Shot 2022-04-14 at 11 54 48 AM

From my testing… this issue exists both in local dev, preview, and prod.

Svelte & Stitches package versions with Node 16.13.2:

"@stitches/core": "^1.2.7",
"@sveltejs/adapter-vercel": "next",
"@sveltejs/kit": "v1.0.0-next.311",
"svelte": "^3.47.0",
"svelte-check": "^2.6.0",
"svelte-preprocess": "^4.10.5"

I built it locally with the branch from 6449 and uploaded the artifacts manually to my dev stage. Seems to have fixed the fouc issue. Will do some more testing… Edit: Need more time to debug this. Currently i have flaky results for some reason… Edit2: Ok tested this now multiple times with different builds. With better-hydration-src (6449) i get no FOUC anymore for my use case, which is nice. I can see that the head elements are arranged differently now, but i couldn’t find a way yet to check if elements are re-inserted etc. and thus causing fouc in the main branch.