Skip to main content

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.

Shown in StoryProof when you copy a widget’s embed code.

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.

  • 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.

  • Problem 3

    Will this break prerendering?

    Code that touches document during a server render fails the build.

  • 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.

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.

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

  1. Link options, SvelteKit documentation. Checked 2026-11-13.
  2. Project structure, SvelteKit documentation. Checked 2026-11-13.
  3. <svelte:head>, Svelte documentation. Checked 2026-11-13.

Last updated 2026-11-13.