`@html` content in `<svelte:head>` is duplicated
winston0410 opened this issue ยท 25 comments
Describe the bug
simple json object of json-ld
will be duplicated with injecting into the document with <svelte:head>
. The tag will be rendered twice.
I use a function like this:
export const mkSchema = (thing: Schema) => {
return `<script type="application/ld+json">${JSON.stringify(thing, null, 2)}</script>`;
};
And render like this:
<svelte:head>
{@html mkSchema(orgSchema)}
</svelte:head>
Reproduction
https://github.com/winston0410/duplicate-head
Logs
No response
System Info
System:
OS: macOS 11.4
CPU: (8) arm64 Apple M1
Memory: 123.59 MB / 8.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 17.8.0 - /opt/homebrew/bin/node
Yarn: 1.22.17 - /opt/homebrew/bin/yarn
npm: 8.5.5 - /opt/homebrew/bin/npm
Browsers:
Brave Browser: 99.1.36.119
Safari: 14.1.1
npmPackages:
@sveltejs/adapter-auto: next => 1.0.0-next.34
@sveltejs/kit: next => 1.0.0-next.310
svelte: ^3.44.0 => 3.47.0
Severity
blocking all usage of SvelteKit
Additional Information
It will greatly affect the SEO of sveltekit as structured data cannot be used
Does it also happen when you put the script tag into <svelte:head>
directly without using @html
?
note: to avoid potential security issues/rendering errors, you should escape the content of the script tag ( see eg. https://github.com/sveltejs/kit/blob/01221d30a78483a212ccb2d3e9b2ee0094b916cb/packages/kit/src/utils/escape.js#L44)
@dominikg It will not happen if you do that directly, but then the content of the object cannot be expanded.
A repro for that behavior:
looks like you already found #1607 and posted there before opening this issue.
This information should have been included in your original report.
Yup I have found that. Should I proceed this issue here, or do it over that one? Because that one is closed right now.
Let's use this issue since the other one is closed. I think that issue was fixed, but some issues remain.
@hbirler you had looked at hydration stuff a decent amount earlier. I'm not sure if you're still interested in these, but this might be an interesting case to take a look at. I confirmed that there's a bug here
@benmccann Thank you so much for your effort in moderating the issue.
@benmccann @dominikg I just added a comment to issue #6463 that seems to relate to this as well.
A workaround for now is to add the json-ld in the body since it's doesn't make a difference for search engine bots.
@abdo643-HULK that works if you are working with json-ld but there are any other things you may want to render in the head with @html. In my case, I'm trying to inject server side css into the head with the <style> tag.
@abdo643-HULK that works if you are working with json-ld but there are any other things you may want to render in the head with @html. In my case, I'm trying to inject server side css into the head with the <style> tag.
Yes that's why I said json-ld :). But you can also inject a style tag into the body and it's still global and valid html. If it's a link tag than you are correct and it isn't valid.
Edit: I don't think it's ideal, but a workaround for now
@abdo643-HULK that works if you are working with json-ld but there are any other things you may want to render in the head with @html. In my case, I'm trying to inject server side css into the head with the <style> tag.
Yes that's why I said json-ld :). But you can also inject a style tag into the body and it's still global and valid html. If it's a link tag than you are correct and it isn't valid.
Edit: I don't think it's ideal, but a workaround for now
Sveltekit doesn't offer an out-of-the-box solution for adding custom tags to the body... but they do give you their svelte:head component which makes head injection straightforward.
I suppose I could make a custom body component and pull all of my custom html out of the base html file and put it in that component, including the style injection. ๐คทโโ๏ธ
@abdo643-HULK that works if you are working with json-ld but there are any other things you may want to render in the head with @html. In my case, I'm trying to inject server side css into the head with the <style> tag.
Yes that's why I said json-ld :). But you can also inject a style tag into the body and it's still global and valid html. If it's a link tag than you are correct and it isn't valid.
Edit: I don't think it's ideal, but a workaround for nowSveltekit doesn't offer an out-of-the-box solution for adding custom tags to the body... but they do give you their svelte:head component which makes head injection straightforward.
I suppose I could make a custom body component and pull all of my custom html out of the base html file and put it in that component, including the style injection. ๐คทโโ๏ธ
I think you are thinking a little bit complicated if you fetch the resource for example in your layout and just do:
<script>
export let style;
</script>
{@html style}
<slot/>
This should inject the style tag into your body
I can confirm that the tricks mentioned by @abdo643-HULK works! Just tried that and Google seems to be happy with it
There don't seem to be any duplicates here: https://svelte.dev/repl/ffd783c9b8e54d97b6b7cac6eadace42?version=3.48.0
There don't seem to be any duplicates here: https://svelte.dev/repl/ffd783c9b8e54d97b6b7cac6eadace42?version=3.48.0
The duplication happens when you use SSR.
In a component i define some content in svelte.head. If i use this component multiple times on a page. It will add the content multiple times
The duplication happens when you use SSR.
Very critical issue for me. For now, I'm forced to use this dirty temporary workaround to remove duplicates.
hooks/index.js:
export async function handle({event, resolve}) {
let response = await resolve(event, {
transformPage: ({ html }) => {
return html
.replace(/<link\s+rel="canonical"[^>]*>/, '')
.replace(/<meta\s+name="description"[^>]*>/, '')
.replace(/<meta\s+name="keywords"[^>]*>/, '')
.replace(/<meta\s+property="og:url"[^>]*>/, '')
.replace(/<meta\s+property="og:title"[^>]*>/, '')
.replace(/<meta\s+property="og:image"[^>]*>/, '')
.replace(/<meta\s+property="og:description"[^>]*>/, '')
}
})
return response
}
Any update when this is going to be fixed?
I have a project that depends on it, the workaround mensioned here doesn't work in my use case.
Also depending on this fix.
This should be fixed now in 3.51.0.
@Conduitry using 3.52, the problem persists with latest kit
@thousandsofraccoons thanks for pointing that out.
Could you care to help create a new issue with a repro? Comments on a closed issue will be easily missed out.
@tanhauhau, related issue - #7879
related svelte-meta-tags#556