SvelteKit installation
SvelteKit Site Testimonial Widget Embed
SvelteKit renders pages on the server by default, which is good news for embeds: the empty widget div is already in the HTML when the browser arrives, so a plain async script finds it. The only part that needs thought is SvelteKit’s client side router, which swaps pages without reloading them.
- A tiny component for the widget div
- The script in svelte:head or app.html
- Links that load widget pages fresh
Code generator
SvelteKit files with your widget id
Enter the widget id. Use the component and the route page for testimonials on a few pages. Use app.html instead of svelte:head if most pages carry a widget. Add the reload attribute to links that lead to widget pages.
Part 1 · Component: the widget div
src/lib/StoryProofWidget.svelte
<!-- src/lib/StoryProofWidget.svelte -->
<script>
// Svelte 5 props. In Svelte 4 write: export let id;
let { id } = $props();
</script>
<!-- Server rendered and left empty. embed.js fills it in the browser. -->
<div data-storyproof-widget={id}></div>Part 2 · Route: render it and load the script
src/routes/customers/+page.svelte
<!-- src/routes/customers/+page.svelte -->
<script>
import StoryProofWidget from '$lib/StoryProofWidget.svelte';
</script>
<svelte:head>
<script src="https://app.storyproof.io/embed.js" async></script>
</svelte:head>
<h1>What our customers say</h1>
<StoryProofWidget id="YOUR_WIDGET_ID" />Part 3 · Alternative: script on every page
src/app.html
<!-- src/app.html: only if widgets appear on most pages -->
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
<script src="https://app.storyproof.io/embed.js" async></script>
</body>Part 4 · Links into widget pages
nav, footer or anywhere you link
<!-- Any link that leads to a page with a widget -->
<a href="/customers" data-sveltekit-reload>Customer stories</a>Run npm run build and npm run preview, open the widget route directly, then click through to it from another page to confirm both arrivals work.
Assembled in your browser; nothing you type is sent.
The problem, solved
SvelteKit and embedded widgets: what goes wrong and how to set it up
- Problem 1
Empty widget after clicking a link
SvelteKit’s router handles links to your own routes by importing the next page’s code instead of loading a new document, so a script that runs on page load does not run again.
How StoryProof solves it
Add data-sveltekit-reload to links that lead to widget pages. SvelteKit then does a full page navigation and the StoryProof script finds the div on arrival.
- Problem 2
Where does the script go?
A component, svelte:head and app.html all look plausible, and the wrong pick loads the script on every page or not at all.
How StoryProof solves it
For a few pages, put it in the route’s svelte:head. For most pages, put it in app.html. Either way one copy fills every StoryProof div on the page.
- Problem 3
Will this break prerendering?
Code that touches document during a server render fails the build.
How StoryProof solves it
The component outputs only an empty div with the widget id, which renders fine on the server and in prerendered HTML. The script does its work in the browser.
- Problem 4
Different proof on different routes
A pricing page and a features page need different quotes, but hard coding them means a deploy for every change of mind.
How StoryProof solves it
Pass a different widget id per route. Each widget has its own chosen, approved testimonials and its own layout.
In StoryProof
Add it to a SvelteKit project
Step 1 of 5
Create the component
Add StoryProofWidget.svelte from the generator. It takes the id as a prop and renders an empty div; keep it empty.
Step 2 of 5
Choose where the script loads
Per route: add the svelte:head block to each page that uses the component. Site wide: add the script once to app.html, inside body after the sveltekit.body placeholder.
Step 3 of 5
Render the widget
Import the component in the route and pass the widget id.
Step 4 of 5
Mark the links into widget pages
Add data-sveltekit-reload to nav and footer links pointing at routes that show a widget. Links to other routes keep fast client navigation.
Step 5 of 5
Check both arrivals
In a production preview, load the widget route directly, then reach it by clicking a link from the homepage. Both should show the widget.
Before you start
SvelteKit caveats
Reload costs some speed
data-sveltekit-reload gives up the instant client navigation for that link. Use it only on links into widget pages.
Client only pages
If a route turns off server rendering, the div is not in the first HTML. Load the script from that route after it mounts, or keep server rendering on for it.
svelte:head placement
Svelte requires svelte:head at the top level of a component, never inside a block or element. Put it in the route file, not deep in the markup.
No Svelte package
There is no StoryProof npm package for Svelte; the component above is the integration. Widgets show a "Powered by StoryProof" badge until Pro.
Svelte docs as of 2026-11-13
The steps follow svelte.dev as read on 2026-11-13. Nobody has run them against a live StoryProof widget yet.
FAQ
Questions people ask
Short answers to what usually comes up next.
Can I load the script in onMount instead?
You can append it from the component in the browser, which also covers client only routes. A widget reached later by client navigation may still need the reload link.
Does this work with adapter-static?
It should, since a prerendered page carries the empty div and the script tag in its HTML. Check the built output with npm run preview before you deploy.
Will the testimonials be crawled as part of my page?
The built HTML holds only the empty div. The testimonials are added in the browser by the script.
Is there a way to show testimonials with no code at all?
Every plan includes a hosted Wall of Love page with its own link, which you can link from your nav.
Still have a question? Ask the StoryProof team or book a demo.
Get a widget id for your SvelteKit site
Approve a few testimonials in StoryProof and pass the id to the component.
Sources
- Link options, SvelteKit documentation. Checked 2026-11-13.
- Project structure, SvelteKit documentation. Checked 2026-11-13.
- <svelte:head>, Svelte documentation. Checked 2026-11-13.
Last updated 2026-11-13.