Skip to main content

Hugo installation

Hugo Static Site Testimonial Widget

Hugo’s Markdown renderer leaves raw HTML out of your content by default, so pasting the StoryProof div into a .md file quietly produces nothing. The Hugo way is a shortcode: a small template in layouts/_shortcodes that writes the div, called from Markdown with the widget id. The script goes in a partial your base template already includes, so every page loads it once.

  • A storyproof shortcode for Markdown content
  • A partial that loads embed.js once
  • Why raw HTML in Markdown vanishes

Hugo templates

Shortcode, partial and the Markdown call

Enter a widget id. File 1 is the shortcode, File 2 the partial for the script, File 3 the one line to add in baseof.html, and the last block is what an author types in Markdown.

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

Part 1 · File 1: the shortcode

layouts/_shortcodes/storyproof.html

{{- $id := "" -}}
{{- if .IsNamedParams }}{{ $id = .Get "id" }}{{ else }}{{ $id = .Get 0 }}{{ end -}}
<div data-storyproof-widget="{{ $id }}"></div>

Part 2 · File 2: the script partial

layouts/_partials/storyproof-script.html

<script src="https://app.storyproof.io/embed.js" async></script>

Part 3 · File 3: include the partial before </body>

layouts/baseof.html (or your theme’s base template, copied into your project)

    {{ partial "storyproof-script.html" . }}
  </body>
</html>

Part 4 · In any Markdown page

content/about.md

## What clients say

{{< storyproof id="YOUR_WIDGET_ID" >}}

Run hugo server, open the page, and view source: the div should sit in the content and embed.js once near the end of the body. Then build with hugo and deploy as usual.

These templates are produced in your browser. The id is not stored.

The problem, solved

Hugo testimonial snags and how this setup avoids them

  • Problem 1

    My pasted HTML vanished from the page

    Hugo’s Goldmark renderer skips raw HTML in Markdown unless markup.goldmark.renderer.unsafe is turned on, which Hugo describes as unsafe for content you do not control.

  • Problem 2

    Testimonials live in a YAML data file

    Theme blocks read quotes from front matter or data files, so each new one is a commit and a rebuild.

  • Problem 3

    Two shortcodes, two script tags

    A shortcode that prints the script would load it again for every widget on the page.

  • Problem 4

    Theme updates overwrite my edits

    Editing files inside themes/ means losing changes when you pull a new theme version.

  • Problem 5

    Getting video praise into a static site

    Hosting customer clips in static/ bloats the repo and needs a player.

In StoryProof

Add it to a Hugo project

Step 1 of 4

Create the shortcode

Save File 1 as layouts/_shortcodes/storyproof.html. It checks .IsNamedParams, then reads the id by name or as the first positional argument with .Get.

Where each piece lives in Hugo

PieceHugo mechanismWhy
Widget divShortcode in layouts/_shortcodesAuthors can place it in Markdown without raw HTML
embed.js scriptPartial called from baseof.htmlOne copy per page, wherever widgets appear
Fixed site wide widgetPartial called from the footer templateNo content edit needed
Raw HTML in Markdownmarkup.goldmark.renderer.unsafeOff by default; not needed with a shortcode

Before you start

Limits worth knowing

  • Hugo docs as of 2026-11-13

    Directory names, the .Get method, partial calls and the Goldmark setting follow gohugo.io as read on 2026-11-13. The templates have not been built on a live project.

  • Script on every page

    Calling the partial from baseof.html loads embed.js on pages without a widget too. Wrap the call in a condition on a front matter flag if that matters to you.

  • Hosting headers

    If your host adds a Content Security Policy, allow app.storyproof.io in script-src or the script is blocked.

  • No Hugo module or theme

    StoryProof does not ship a Hugo module or theme component. The shortcode is yours to keep in the project.

  • Badge on lower plans

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

FAQ

Questions people ask

Short answers to what usually comes up next.

Should I just turn on unsafe in the Goldmark settings?

You can, and the raw div would then render. A shortcode keeps the setting off, which Hugo recommends unless you control all content, and gives authors a cleaner line to type.

Do I need to rebuild when testimonials change?

Only when the page itself changes, such as adding the shortcode somewhere new. The selection of testimonials is managed in StoryProof.

Can I use positional arguments instead of id=?

Yes. The shortcode reads .Get 0 when the call uses positional arguments, so {{< storyproof abc123 >}} works too. Do not mix both styles in one call.

Does this work with Hugo themes like Hugo Blox?

Yes, as long as your project can add its own layouts. Themes that build pages from blocks may need the partial called from their own base template.

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

Keep your Hugo site static and your testimonials current

Collect and approve in StoryProof, then drop one shortcode into Markdown.

Sources

  1. Shortcode templates, Hugo Documentation. Checked 2026-11-13.
  2. Shortcodes, Hugo Documentation. Checked 2026-11-13.
  3. partials.Include, Hugo Documentation. Checked 2026-11-13.
  4. Base templates, Hugo Documentation. Checked 2026-11-13.
  5. Configure markup, Hugo Documentation. Checked 2026-11-13.

Last updated 2026-11-13.