Skip to main content

Astro installation

Astro Site Testimonial Widget Embed

Astro bundles and rewrites script tags by default, and a script pointing at another domain has to be marked is:inline to be left alone. So the StoryProof script goes once in your base layout with is:inline, and the widget itself is a one-line .astro component that ships no JavaScript of its own. If your site uses Astro’s ClientRouter, read the navigation note before you ship.

  • Layout with the script marked is:inline
  • A props-only StoryProofWidget component
  • The ClientRouter caveat and the fix

Code generator

Layout, component and page for Astro

Type your widget id. The layout loads embed.js once; the component outputs only the div, so it adds nothing to your JavaScript budget.

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

Part 1 · Base layout: the script, once

src/layouts/BaseLayout.astro

---
// src/layouts/BaseLayout.astro
---
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <slot name="head" />
  </head>
  <body>
    <slot />
    <!-- is:inline: Astro outputs this tag exactly as written.
         It lives in the layout, so it appears once per page. -->
    <script is:inline src="https://app.storyproof.io/embed.js" async></script>
  </body>
</html>

Part 2 · The widget component

src/components/StoryProofWidget.astro

---
// src/components/StoryProofWidget.astro
interface Props {
  id: string;
}
const { id } = Astro.props;
---
<div data-storyproof-widget={id}></div>

Part 3 · Using it on a page

src/pages/index.astro

---
// src/pages/index.astro
import BaseLayout from '../layouts/BaseLayout.astro';
import StoryProofWidget from '../components/StoryProofWidget.astro';
---
<BaseLayout>
  <h2>What customers say</h2>
  <StoryProofWidget id="YOUR_WIDGET_ID" />
</BaseLayout>

Run astro build and open the built page in dist, or run astro preview. View source: you should see one embed.js tag, untouched, before the closing body tag.

The files are generated in your browser from the id you enter.

The problem, solved

Astro gotchas with hosted widgets, solved

  • Problem 1

    Astro rewrote my script tag

    Without a directive, Astro processes script tags, bundling them and turning them into modules, which is not what a script from another domain needs.

  • Problem 2

    Script repeated for every widget

    Astro duplicates an is:inline script for each instance of the component that contains it.

  • Problem 3

    I picked Astro to ship less JavaScript

    Adding a framework component just to show testimonials would undo the reason the site is fast.

  • Problem 4

    Content collections need a review step

    Hard-coding quotes into Markdown means each new testimonial waits for a commit, with no record of approval.

  • Problem 5

    Blog posts need a quote image

    A static post sometimes wants a single striking quote as an image rather than a live widget.

In StoryProof

Add it to an Astro site

Step 1 of 4

Copy the widget id

Build the widget in StoryProof and copy the data-storyproof-widget value from its embed code.

Which Astro script option for the StoryProof embed

From Astro’s scripts and view transitions guides, read 2026-11-13.
OptionWhat Astro doesUse for StoryProof?
Plain <script> with only srcProcesses and bundles it as a moduleNo, it is a third-party file
<script is:inline> in the layoutOutputs it exactly as written, once per pageYes
<script is:inline> in the componentRepeats it for every instanceNo
data-astro-rerunForces an inline script to run after every transitionNot documented for embed.js; prefer data-astro-reload links

Before you start

Limits for Astro

  • Client-side navigation

    Under ClientRouter, Astro runs bundled scripts once and may re-run inline ones. StoryProof has not documented how embed.js behaves there, so use full loads for widget pages.

  • Content Security Policy

    If your host sends a CSP header, add the StoryProof script host to script-src.

  • No Astro integration

    StoryProof is not an Astro integration package. The files above are plain Astro code in your repo.

  • Badge on lower plans

    Widgets show a small "Powered by StoryProof" badge until Pro.

  • Astro docs, not a live run

    The code follows Astro’s documentation as read on 2026-11-13. It has not been run against a live StoryProof widget on an Astro site for this guide.

FAQ

Questions people ask

Short answers to what usually comes up next.

Do I need a React or Vue island for this?

No. The widget is a div and a script. An .astro component outputs the div with no client framework.

Why not import embed.js into a bundled script?

It is a hosted file from StoryProof, not a module in your project. Astro’s docs point scripts outside src to is:inline.

Does this work on a fully static Astro build?

Yes. The div and script are in the built HTML, and the widget is filled in the visitor’s browser.

Can I use it inside MDX posts?

Yes. Import StoryProofWidget into the MDX file and use it like any other component, as long as the post uses the layout with the script.

Still have a question? Ask the StoryProof team or book a demo.

Add real testimonials to your Astro site

Collect testimonials with one link and render them with a zero-JS component.

Sources

  1. Scripts and event handling, Astro Docs. Checked 2026-11-13.
  2. View transitions, Astro Docs. Checked 2026-11-13.

Last updated 2026-11-13.