Using the Script Tag in Svelte Files for 3rd Party Code
Summary
Currently svelte files can only have one instance-level <script> element
.
So when you want to add 3rd party script tags in your svelte files, things go wrong. There are a few options. This article by Adam Tuttle covers most of the options pretty well (except the focus is for sveltekit). This How-To offers a few more options and my thoughts on them.
The Problem
So when you try to do this:
<script>
// js logic
</script>
<p>Check out this cool 3rd party form I embedded</p>
<iframe id="iFrameResizer0" src="https://not-my-site.com/bookingform"></iframe>
<script src="https://not-my-site.com/my/3rd/party/script.js"></script>
Svelte errors out like this.
The 5 Solutions
1. Use svelte:element
<script>
export let src = undefined
</script>
<svelte:element this="script" {src} {...$$restProps} />
Notice in the example above I am wrapping this in its own component for reuse. This is also a simplified version of what would be passed in.
2. Wrap it in something
If you wrap the script
tag in another html element or a javascript block, that will work:
Wrap it in a div
element
<div>
<script async defer data-website-id="my-id" src="https://my.cloud/umami.js"></script>
</div>
Wrap it in a if
block
{#if evalsToTrue}
<script async defer data-website-id="my-id" src="https://my.cloud/umami.js"></script>
{/if}
3. Throw the script element in svelte:head
<svelte:head>
<script async defer data-website-id="my-id" src="https://my.cloud/umami.js"></script>
</svelte:head>
4. Use onMount and append the script element to body
<script>
import { onMount } from 'svelte'
import { appendScripts } from '@/core/frontier'
import scriptsHTMLString from '@settings/FooterScripts.md?raw'
// Creates a script element and appends to <body>
onMount(() => appendScripts(document, scriptsHTMLString))
</script>
5. Using vite to import the script as raw text and inject as html
<script>
import SiteHead from '@/components/SiteHead.svelte'
import FooterHtml from '@settings/footer.html?raw'
</script>
<SiteHead {...$$restProps} />
<slot />
{@html FooterHtml}
Where footer.html looks like this:
<script async defer data-website-id="my-id" src="https://my.cloud/umami.js"></script>
Conclusion
All these have their pros and cons. I don’t have time to write on that now.
References
https://adamtuttle.codes/blog/2021/adding-3rd-party-script-tags-in-sveltekit/