Ein einfaches Testimonial-Widget für Next.js (ohne npm-Paket, ein iframe)
Du baust dein Portfolio oder eine Kunden-Website mit Next.js und willst echte Bewertungen darauf. Du könntest eine Tabelle für Kundenstimmen, eine Admin-Oberfläche und einen Moderationsablauf bauen, oder du setzt einfach ein iframe ein. Dieser Guide zeigt die zweite Option mit SimplerFeedback: das reine HTML-Snippet, eine kleine App-Router-Komponente, die Leisten-Variante für eine Startseite und was ein iframe ehrlich gesagt nicht kann.
Die Idee: Deine Bewertungen leben auf einer Wand, die dir gehört, deine Website rahmt sie nur ein
Mit SimplerFeedback werden Bewertungen über deine Formulare gesammelt und auf deiner Wand veröffentlicht, einer öffentlichen Seite unter simplerfeedback.com/wall/your-slug. Diese Seite ist die Single Source of Truth: Du gibst eine Bewertung frei, sie erscheint auf der Wand, und jede Website, die die Wand einbindet, zeigt sie ebenfalls.
Deine Next.js-Website speichert nichts. Sie rahmt die Wand in einem iframe ein. Die Wand ist statisches HTML, ausgeliefert über ein CDN: kein API-Key, den du geheim halten musst, kein npm-Paket zu installieren und kein Build, den du neu anstoßen musst, wenn eine neue Bewertung reinkommt. Veröffentliche eine Bewertung in der App und die Einbindung ist aktuell.
Das reine HTML-Snippet
Öffne in der App Meine Wand, dann Teilen, und kopier den Einbettungscode. Er besteht aus zwei Teilen: dem iframe und einem optionalen Skript, das die Größe anpasst.
<iframe
src="https://simplerfeedback.com/wall/your-slug?embed=wall"
title="Your name"
style="width:100%;height:900px;border:0"
loading="lazy"
></iframe>
<script src="https://simplerfeedback.com/embed.js" async></script>Die Höhe von 900px ist nur ein Fallback. embed.js wartet auf eine Nachricht, die die Wand mit der tatsächlichen Höhe ihres Inhalts schickt (sf-embed-height), und passt die Höhe des iframes daran an, sodass die Wand nie eine innere Scrollleiste oder eine leere Lücke zeigt. Ohne das Skript behält das iframe einfach die Höhe aus seinem style-Attribut. Ein einziges script-Tag reicht für alle Wand-iframes auf der Seite.
Eine Next.js-App-Router-Komponente
Rohes HTML in JSX einzufügen funktioniert, aber eine kleine Komponente hält den Slug in einer Prop und lädt das Skript nur einmal. next/script mit strategy="lazyOnload" lädt embed.js, wenn der Browser im Leerlauf ist, und dedupliziert es, sodass zweimaliges Rendern der Komponente auf einer Seite das Skript nicht zweimal hinzufügt (das Skript schützt sich außerdem selbst).
// components/TestimonialWall.tsx
'use client';
import Script from 'next/script';
type Props = {
slug: string;
title: string;
variant?: 'wall' | 'strip';
featured?: boolean; // strip only, Premium
};
export function TestimonialWall({ slug, title, variant = 'wall', featured = false }: Props) {
const params = new URLSearchParams({ embed: variant });
if (variant === 'strip' && featured) params.set('featured', '1');
const src = `https://simplerfeedback.com/wall/${encodeURIComponent(slug)}?${params}`;
return (
<>
<iframe
src={src}
title={title}
loading="lazy"
style={{ width: '100%', height: variant === 'strip' ? 320 : 900, border: 0 }}
/>
<Script src="https://simplerfeedback.com/embed.js" strategy="lazyOnload" />
</>
);
}Zwei Attribute sind wichtig. title gibt dem iframe einen zugänglichen Namen, den Screenreader vorlesen; nimm etwas Aussagekräftiges wie „Kundenbewertungen“, nicht „iframe“. loading="lazy" sorgt dafür, dass eine Wand unterhalb des sichtbaren Bereichs erst geladen wird, wenn der Besucher in ihre Nähe scrollt, sie kostet beim ersten Rendern also nichts.
Die Leiste für eine Startseite, und nur angeheftete Bewertungen
Eine volle Wand passt gut auf eine /testimonials-Seite. Auf einer Startseite willst du meist ein kurzes Band mit Belegen unter dem Hero. Nutze ?embed=strip: eine horizontale Leiste mit Bewertungen, standardmäßig 320px hoch. Mit Premium fügst du der Leiste featured=1 hinzu, um nur die Bewertungen zu zeigen, die du angeheftet hast (bis zu drei), sodass die Startseite immer mit deinen besten beginnt.
// app/page.tsx — a strip of pinned reviews under the hero
import { TestimonialWall } from '@/components/TestimonialWall';
export default function Home() {
return (
<main>
{/* ...hero... */}
<TestimonialWall slug="your-slug" title="What clients say" variant="strip" featured />
</main>
);
}
// app/testimonials/page.tsx — the full wall
// <TestimonialWall slug="your-slug" title="Client reviews" />Styling und Layout
Behandle das iframe wie ein Bild: Es füllt die Breite seines Containers, und embed.js kümmert sich um die Höhe. Pack es in den Wrapper, den dein Layout ohnehin nutzt (einen Container mit max-width, eine Grid-Zelle), und es passt sich an.
- Breite: 100 % des Elternelements. Begrenze das Elternelement, nicht das iframe.
- Höhe: wird von embed.js anhand des Inhalts gesetzt; die Inline-Höhe ist nur der Fallback.
- Farben sowie Dark oder Light Mode kommen vom Wand-Stil, nicht von deiner Website. Dein CSS kommt nicht in ein Cross-Origin-iframe hinein, und du solltest es auch nicht versuchen.
- Wähl einen Wand-Stil, der zur Seite passt (Terminal passt zu einem Entwickler-Portfolio), oder nutz Eigener Stil mit Premium, um Hintergrund-, Akzent- und Textfarbe an deine Marke anzupassen.
Die Grenzen, ehrlich gesagt
Es ist ein iframe, mit allem, was dazugehört. Die Bewertungen werden nicht serverseitig in dein DOM gerendert, Suchmaschinen rechnen den Bewertungstext also nicht deiner Seite zu; dieser Text wird unter der URL der Wand indexiert, auf die du auch direkt verlinken kannst. Es gibt kein React-Komponentenpaket und keine öffentliche API, um Bewertungen als JSON abzurufen: Die Komponente oben kannst du kopieren, und das iframe ist die Integration.
Für die meisten Portfolios und Kunden-Websites ist das der richtige Kompromiss: zwei Minuten zum Einbauen, nichts zu warten und Bewertungen, die von selbst aktuell bleiben.