Zum Inhalt springen
    WingoUI
    KomponentenVorlagenDokuPreiseKI-AgentenBlogChangelogKontakt
    1. Startseite
    2. Blog
    3. Praxis: Screens und Apps
    4. SaaS Website Template: 7 Seiten neben der Startseite
    Read in English
    1. Blog
    2. Praxis: Screens und Apps
    3. SaaS Website Template: 7 Seiten neben der Startseite
    Praxis: Screens und Apps
    Praxis: Screens und Apps

    SaaS Website Template: 7 Seiten neben der Startseite

    SR
    Serban Rusu · Gründer von Wingo UI
    5. Nov. 2026 · 19 Min. Lesezeit

    Auf dieser Seite

    0%
    1. Welche Seiten braucht eine SaaS-Website neben der Startseite?
    2. Wie richte ich alle Seiten als eine Next.js-Website ein?
    3. Was braucht eine SaaS-Preisseite, um zu konvertieren?
    4. Was gehört auf die About-Seite eines SaaS?
    5. Wie geht eine Karriereseite mit offenen Stellen um?
    6. Warum braucht ein SaaS einen öffentlichen Changelog?
    7. Wann lohnt sich eine Kontaktseite?
    8. Welche Rechtsseiten braucht eine SaaS-Website?
    9. Wann lohnt sich eine Vergleichsseite?
    10. Welche Seiten kommen später dazu?
    11. Mit welchem SaaS Website Template solltest du starten?
    12. Wie prüfe ich die ganze Website vor dem Launch?
    13. Wie geht es weiter?
    14. Häufige Fragen
      1. Welche Seiten braucht eine SaaS-Website?
      2. Gibt es ein kostenloses Next.js SaaS Website Template?
      3. Braucht ein SaaS eine Changelog-Seite?
      4. Welche Rechtsseiten braucht eine SaaS-Website?
      5. Sollte eine Startup-Website Vergleichsseiten haben?

    Kurz gesagt

    Ein SaaS Website Template sollte neben der Startseite sieben Seiten abdecken: Preise, Kontakt, Rechtliches, Changelog, About, Karriere und eine Vergleichsseite pro echtem Wettbewerber, jede mit genau einer Aufgabe. In Next.js legst du sie in eine Route Group, deren Layout Header und Footer einmal rendert, und renderst jede Seitenvorlage mit abgeschaltetem eigenem Header und Footer. Vor dem Launch verbindest du jedes Formular und jeden Plan-Button mit einem echten Handler und entfernst alle Beispielinhalte.

    Veröffentlicht am 5. Nov. 2026

    Ein SaaS Website Template heißt meistens: eine Startseite, ein Preisabschnitt und ein Footer voller Links, die ins Leere führen. Dann klickt jemand auf Karriere, Changelog oder Datenschutz und landet auf einer 404 oder auf einer Seite, auf der noch Acme steht. Dieser Guide behandelt die Seiten, die deine SaaS-Website neben der Startseite braucht: wofür jede da ist, was sie enthalten muss, damit aus einem Besucher eine Registrierung wird, und wie du das ganze Set in Next.js aus Seitenvorlagen zusammensetzt, sodass sich die Website wie ein Produkt liest und nicht wie sieben Experimente.

    Wir bauen Wingo UI, eine React-Komponentenbibliothek mit 50 Seitenvorlagen. Wir sind also nicht neutral, und der Code unten nutzt unsere Vorlagen. Die Struktur funktioniert aber mit jedem React-Kit und auch mit Seiten, die du von Hand schreibst. Brauchst du nur die Startseite, deckt die Vorlage Landing Page sie ab, und unser Tutorial zur Next.js SaaS Landing Page baut sie Abschnitt für Abschnitt. Für den oberen Teil der Seite zeigt unser Beitrag zur Shadcn Hero Section sechs Layouts, und ein KI-Produkt bekommt sein eigenes AI SaaS Landing Page Template. Dieser Beitrag setzt dort an, wo die beiden aufhören.

    Welche Seiten braucht eine SaaS-Website neben der Startseite?

    Sieben: Preise, Kontakt und Rechtliches zum Launch, dann ein Changelog, eine About-Seite, eine Karriereseite und eine Vergleichsseite pro echtem Wettbewerber, während das Unternehmen wächst. Die meisten Vorlagen zeigen dir diese Seiten, ohne zu sagen, wofür jede einzelne da ist.

    Such nach einem Startup Website Template, einer SaaS Website Vorlage oder einem Next.js SaaS Starter, und du bekommst zwei Arten von Ergebnissen (geprüft am 5. November 2026). Minimale Starter wie Vercels Minimal Next.js SaaS Website Starter (opens in a new tab) (Next.js 14, Tailwind CSS, next-themes) und das kostenlose Startup (opens in a new tab) von NextJSTemplates liefern eine Startseite und ein paar Grundabschnitte. Bezahlte Themes wie Copper (opens in a new tab) von Themefisher ($77 für eine Einzellizenz, Next.js 16) listen 17 Seiten auf, darunter Career, Career Single, Changelog, zwei Preis-Layouts, Terms und Privacy. Beide Arten zeigen dir die Seiten. Keine sagt dir, was jede Seite leisten muss.

    Das ist das Set, das ein SaaS aus unserer Sicht braucht, mit der einen Aufgabe jeder Seite:

    SeiteIhre eine AufgabeMuss enthaltenWann sie dazukommt
    Preise„Was kostet mich das?“ beantwortenPläne, einen Umschalter für den Zeitraum, eine Vergleichstabelle, ein FAQ zur AbrechnungZum Launch
    KontaktDen Käufer auffangen, der nicht im Alleingang kauftEin Formular, das bei einem Menschen ankommt, eine Antwortzeit, direkte KanäleZum Launch
    Rechtliches„Kann ich dir meine Daten anvertrauen?“ beantwortenAGB, Datenschutz, Cookies, ein DPA für B2B, DatumsangabenZum Launch
    ChangelogBeweisen, dass das Produkt lebtDatierte Releases, gruppierte Änderungen, RSSNach ein paar Releases
    AboutNamen und eine Geschichte hinter das Produkt stellenGründer, eine Zeitleiste, Werte, einen KontaktwegSobald es eine Geschichte gibt
    KarriereEinstellen und zeigen, dass das Unternehmen wächstOffene Stellen mit Gehalt, den Ablauf, ein BewerbungsformularWenn du einstellst
    VergleichDen Käufer gewinnen, der zwischen dir und X wähltEin ehrliches Fazit, eine Feature-Tabelle, Preise mit QuellenPro echtem Wettbewerber

    Zwei Regeln gelten für jede Seite. Erstens: eine Hauptaktion auf der ganzen Website. Wenn die Startseite „Kostenlos starten“ sagt, sagen die Preisseite, die About-Seite und das Abschlussband einer Vergleichsseite dasselbe und führen auf dieselbe Route. Zweitens: Keine Seite geht mit Beispielinhalten live. Jede Vorlage, von der du startest, unsere eingeschlossen, kommt mit einer fiktiven Firma, ihren Kunden, ihren Zahlen und ihren Zitaten. Eine Karriereseite mit „42 Leute in 11 Ländern“, wenn ihr zwei Gründer seid, kostet mehr Vertrauen als eine fehlende Seite.

    Wie richte ich alle Seiten als eine Next.js-Website ein?

    Behandle die Marketingseiten als eine Route Group mit einem Layout. Das Layout rendert Header und Footer einmal, also teilen alle Seiten dieselbe Navigation, denselben Anmelde-Link und dieselben Footer-Spalten. Jede Seite rendert dann ihre Vorlage mit header={false} und footer={false}.

    txt
    app/
    (marketing)/
    layout.tsx Header, Footer und Router-Link, einmal
    providers.tsx LinkProvider mit next/link
    site-nav.tsx Navigationspunkte und Footer-Spalten
    page.tsx die Startseite
    pricing/page.tsx
    about/page.tsx
    careers/page.tsx
    careers/[slug]/page.tsx
    changelog/page.tsx
    changelog/rss.xml/route.ts
    contact/page.tsx
    contact/actions.ts
    legal/[doc]/page.tsx
    compare/[competitor]/page.tsx
    sitemap.ts

    Dieser Baum ist das komplette Next.js Website Template: eine Route Group, ein Layout, ein Ordner pro Seite. Installier, was er braucht, mit der CLI. Jede Vorlage holt die Abschnitte, aus denen sie besteht, als Quelldateien, die dir gehören:

    bash
    npx wingo-ui@latest add marketing-header marketing-footer pricing-page about-page careers-page changelog-page contact-page legal-page compare-page

    Die Vorlagen und ihre Links rendern über LinkProvider. Eine kleine Client-Komponente leitet also jeden internen Link auf jeder Seite über next/link und sagt dem Header, welcher Punkt aktiv ist:

    tsx
    // app/(marketing)/providers.tsx
    "use client";
    import type { ReactNode } from "react";
    import Link from "next/link";
    import { usePathname, useRouter } from "next/navigation";
    import { LinkProvider } from "@/lib/navigation";
    export function Providers({ children }: { children: ReactNode }) {
    const router = useRouter();
    return (
    <LinkProvider component={Link} currentPath={usePathname()} navigate={router.push}>
    {children}
    </LinkProvider>
    );
    }
    tsx
    // app/(marketing)/layout.tsx
    import type { ReactNode } from "react";
    import { MarketingFooter } from "@/components/blocks/marketing-footer";
    import { MarketingHeader } from "@/components/blocks/marketing-header";
    import { Providers } from "./providers";
    import { footerColumns, legalLinks, navItems } from "./site-nav";
    export default function MarketingLayout({ children }: { children: ReactNode }) {
    return (
    <Providers>
    <MarketingHeader items={navItems} labels={{ brand: "Acme" }} />
    {children}
    <MarketingFooter
    columns={footerColumns}
    legalLinks={legalLinks}
    socials={[]}
    status={false}
    labels={{ brand: "Acme", tagline: "Pläne, Docs und Automationen für kleine Teams." }}
    />
    </Providers>
    );
    }

    Drei Details in diesem Layout zählen. Pack children nicht in ein <main>: Jede Vorlage rendert ihr eigenes <main id="main">, auf das auch der Skip-Link des Headers zeigt, und eine Seite mit zwei main-Landmarks verwirrt Screenreader. socials={[]} blendet die Social-Icons aus, bis du Accounts hast, die einen Link wert sind. Und status={false} blendet das Badge „All systems operational“ im Footer aus, das auf /status verlinkt, bis eine echte Statusseite dahintersteht.

    Der Marketing Header zeigt die Links auf dem Desktop in Dropdown-Panels und klappt sie unter 1024px in ein Bottom Sheet, und der Marketing Footer nimmt deine Link-Spalten und Rechtslinks. Beide sind kostenlos. Halte die Navigation kurz: Produkt, Preise, Changelog und Unternehmen (Über uns, Karriere, Kontakt) reichen für die meisten SaaS-Websites. Rechtsseiten gehören in den Footer. Unser Guide zur shadcn Navbar baut so einen Header im Detail, mit Mega-Menü-Panels, einem Menü fürs Smartphone und einer Sticky-Leiste.

    Zum Schluss listest du jede Seite in app/sitemap.ts, auch jedes Rechtsdokument und jede Vergleichsseite, damit Crawler die dynamischen Routen kennen, ohne auf Footer-Links angewiesen zu sein.

    Was braucht eine SaaS-Preisseite, um zu konvertieren?

    Die Preisseite beantwortet eine Frage, „Was kostet mich das?“, und räumt dann jeden Grund aus dem Weg, nicht anzufangen. In dieser Reihenfolge: Pläne mit Umschalter zwischen monatlich und jährlich, der empfohlene Plan hervorgehoben, eine Vergleichstabelle für den Besucher, der zwischen zwei Plänen schwankt, ein FAQ zur Abrechnung und ein abschließender Call to Action. Unser Tutorial zur shadcn Pricing Page geht tief auf die Vergleichstabelle und die Jahresrechnung ein; hier geht es darum, wie die ganze Seite in die Website passt.

    Der Block Pricing Page rendert all das. Er ist eine Client-Komponente mit eigenem Prop linkComponent, lebt also in einer kleinen Client-Datei, die auch den gewählten Plan und Zeitraum an die Registrierung weitergibt:

    tsx
    // app/(marketing)/pricing/pricing-view.tsx
    "use client";
    import Link from "next/link";
    import { useRouter } from "next/navigation";
    import { PricingPage } from "@/components/blocks/pricing-page";
    import { comparison, faqs, plans } from "./pricing-data";
    export function PricingView() {
    const router = useRouter();
    return (
    <PricingPage
    header={false}
    footer={false}
    linkComponent={Link}
    plans={plans}
    comparison={comparison}
    faqs={faqs}
    currencies={["USD"]}
    showLogos={false}
    showTestimonials={false}
    labels={{ yearlySaving: "2 Monate gratis" }}
    onSelectPlan={(planId, period) => router.push(`/sign-up?plan=${planId}&period=${period}`)}
    />
    );
    }
    ts
    // app/(marketing)/pricing/pricing-data.ts
    import type { PricingComparisonGroup, PricingPlan } from "@/components/ui/pricing-table";
    // yearly ist der Preis für das ganze Jahr
    export const plans: PricingPlan[] = [
    { id: "free", name: "Free", price: 0, features: ["Bis zu 3 Personen", "2 Projekte"], cta: { label: "Kostenlos starten", href: "/sign-up" } },
    { id: "pro", name: "Pro", price: { monthly: 12, yearly: 120 }, priceSuffix: "/Nutzer/Monat", featured: true, features: ["Unbegrenzte Projekte", "Automationen"], cta: { label: "14 Tage testen" }, note: "14 Tage gratis, ohne Karte" },
    { id: "business", name: "Business", price: { monthly: 24, yearly: 240 }, priceSuffix: "/Nutzer/Monat", features: ["SSO und Audit-Logs", "Priorisierter Support"], cta: { label: "14 Tage testen" } },
    ];
    export const comparison: PricingComparisonGroup[] = [
    {
    label: "Workspace",
    rows: [
    { label: "Personen", values: { free: "Bis zu 3", pro: "Unbegrenzt", business: "Unbegrenzt" } },
    { label: "Automationen", values: { free: false, pro: true, business: true } },
    { label: "SSO", hint: "SAML-Anmeldung mit Google Workspace oder Microsoft Entra ID.", values: { free: false, pro: false, business: true } },
    ],
    },
    ];
    export const faqs = [
    { question: "Kann ich den Plan später wechseln?", answer: "Ja. Upgrades gelten sofort, Downgrades zur nächsten Verlängerung." },
    { question: "Was passiert, wenn die Testphase endet?", answer: "Du wechselst in den Free-Plan, außer du hinterlegst eine Karte. Nichts wird gelöscht." },
    ];

    page.tsx bleibt eine Server Component, die die Metadaten exportiert und <PricingView /> rendert. Vier Props in dieser View entscheiden, ob die Seite die Wahrheit sagt. Ein Plan, dessen cta ein href hat, navigiert einfach; ein Plan ohne href ruft onSelectPlan mit dem Zeitraum auf, und so trägt der Pro-Button „yearly“ in die Registrierung. Ohne onSelectPlan zeigen die Buttons nur einen Toast: gut für eine Demo, nutzlos auf einer Live-Website. currencies={["USD"]} blendet den Umschalter zwischen Dollar und Euro aus. Die Vorlage rechnet mit einem festen eurRate in Euro um, also lass den Umschalter nur an, wenn du wirklich in Euro abrechnest. Und das Badge „2 Monate gratis“ ist nur ein Label: Ist der Jahrespreis in deinen Plänen nicht das Zehnfache des Monatspreises, ändere es.

    Schalte zwischen Monthly und Yearly um und öffne dann den Vergleich unter den Plänen. Mach den Rahmen schmaler als 768px: Die Pläne werden zu einem wischbaren Karussell, das beim empfohlenen Plan startet
    $ npx wingo-ui@latest add pricing-page
    ProDoku: Pricing Page

    Lass Logos und Zitate weg, bis sie echt sind. Ein Käufer, der ein erfundenes Logo entdeckt, zweifelt auch an den Preisen. Pläne, eine Tabelle und fünf ehrliche FAQ-Antworten sind die stärkere Seite.

    Was gehört auf die About-Seite eines SaaS?

    Auf der About-Seite prüft ein Käufer, ob echte Menschen hinter dem Produkt stehen, und Bewerber schauen dort vorbei, bevor sie ihre Unterlagen schicken. Sie braucht Namen und Gesichter, die Geschichte in ein paar datierten Meilensteinen, woran dein Team glaubt, und einen Weg, euch zu erreichen oder mitzumachen. Die Vorlage About Page hat all das plus Kennzahlen, Investoren, Presse und Büros, und genau das ist die Falle: Die Standardwerte beschreiben Acme, mit 12.000 Teams, 42 Leuten und drei Studios.

    tsx
    // app/(marketing)/about/page.tsx
    import type { Metadata } from "next";
    import { AboutPage } from "@/components/templates/about-page";
    import { roles } from "../careers/roles";
    import { milestones, team, values } from "./about-content";
    export const metadata: Metadata = {
    title: "Über Acme",
    description: "Wer Acme baut, warum wir angefangen haben und was wir über kleine Teams denken.",
    };
    export default function About() {
    return (
    <AboutPage
    header={false}
    footer={false}
    heroLayout="stacked"
    heroMedia={null}
    milestones={milestones}
    values={values}
    team={team}
    openRoles={roles.length}
    showStats={false}
    showInvestors={false}
    showPress={false}
    showOffices={false}
    labels={{
    heroTitle: "Zwei Entwickler, die genug von Status-Meetings hatten",
    heroDescription: "Wir haben Acme 2025 gestartet, damit kleine Teams Pläne, Docs und Entscheidungen an einem Ort haben.",
    }}
    />
    );
    }

    heroMedia={null} blendet die gezeichnete Collage aus, deren Beschriftungen Acmes Gründer und Teamgröße zeigen; gib stattdessen ein echtes Teamfoto mit, sobald du eins hast. openRoles={roles.length} liest dieselbe Liste wie die Karriereseite, also stimmen die Kachel „We're hiring“ und ihre Zahl, und bei null verschwindet die Kachel. Schalte Abschnitte wieder ein, sobald sie echt sind: Kennzahlen, wenn du Zahlen veröffentlichen kannst, Presse, wenn jemand über euch geschrieben hat.

    Wie geht eine Karriereseite mit offenen Stellen um?

    Eine Karriereseite hat zwei Leser: den Bewerber, der überlegt, ob er sich bewirbt, und den Käufer, der prüft, ob das Unternehmen wächst. Beide wollen dasselbe: Stellen mit Ort, Arbeitsmodell und Gehaltsspanne, eine Beschreibung des Bewerbungsprozesses und ein kurzes Bewerbungsformular, das auf dem Smartphone funktioniert. Die Vorlage Careers Page filtert Stellen nach Text, Abteilung und Ort, öffnet jede Stelle in einem Seitenpanel (auf Smartphones in einem Bottom Sheet) und endet mit einem Bewerbungsformular samt Lebenslauf-Upload.

    Das Formular ruft onApply mit der Stelle, den Feldern und der Datei auf. Fehlt der Handler, wartet die Vorlage kurz und zeigt trotzdem ihre Bestätigung. Eine Live-Karriereseite kann so jede Bewerbung verlieren und dabei völlig in Ordnung aussehen. Schick sie an ein echtes Ziel:

    tsx
    // app/(marketing)/careers/careers-view.tsx
    "use client";
    import { CareersPage, type CareersApplication } from "@/components/templates/careers-page";
    import { roles } from "./roles";
    async function apply(application: CareersApplication) {
    const body = new FormData();
    body.set("role", application.role?.slug ?? "open-application");
    body.set("name", application.name);
    body.set("email", application.email);
    body.set("linkedin", application.linkedin);
    body.set("note", application.note);
    if (application.resume) body.set("resume", application.resume);
    const response = await fetch("/api/apply", { method: "POST", body });
    // ein abgelehntes Promise zeigt statt der Bestätigung die Fehlermeldung des Formulars
    if (!response.ok) throw new Error("Die Bewerbung konnte nicht gesendet werden");
    }
    export function CareersView() {
    return (
    <CareersPage
    header={false}
    footer={false}
    roles={roles}
    onApply={apply}
    showStats={false}
    showTeam={false}
    labels={{
    heroEyebrow: "Karriere bei Acme",
    heroDescription: "Wir sind zwei Entwickler, bauen Acme für kleine Teams und suchen unseren ersten Designer.",
    }}
    />
    );
    }

    Der Hero-Text zählt so viel wie der Handler: Die Standardbeschreibung sagt, Acme habe 42 Leute in 11 Ländern, und stats, values, perks und steps beschreiben dieselbe fiktive Firma, bis du eigene Arrays übergibst oder die Abschnitte abschaltest.

    Jede Stellenzeile ist außerdem ein Link auf /careers/<slug>, und ein Klick mit Cmd oder Strg öffnet ihn in einem neuen Tab. Diese Route muss also existieren. Bau sie mit der Vorlage Job Detail Page und ergänze dort strukturierte Daten vom Typ JobPosting. Die Richtlinien von Google für Stellenanzeigen (opens in a new tab) verlangen das Markup auf der Seite einer einzelnen Stelle und werten es auf einer Seite mit mehreren Stellen als Richtlinienverstoß. Die Detailroute ist also der einzige Ort dafür. Unser Guide zu JSON-LD in Next.js zeigt, wie du es renderst.

    Der Guide zum Karriereseite Template behandelt diese Seite ausführlich: Filter für Stellen, ein Job Drawer, das Bewerbungsformular und wohin die JobPosting-Daten gehören.

    Warum braucht ein SaaS einen öffentlichen Changelog?

    Ein Changelog beweist, dass das Produkt lebt. Ein Käufer, der zwei Tools vergleicht, öffnet ihn, um zu sehen, wann das letzte Release kam, ein bestehender Nutzer findet das Feature, um das er gebeten hat, und jedes Release wird zu einem Link, den du posten kannst. Er braucht datierte Releases, Änderungen gruppiert nach neu, verbessert und behoben, einen Permalink pro Release und einen Weg, ihm zu folgen: RSS und eine E-Mail-Anmeldung.

    Der Guide zur Changelog-Vorlage geht weiter als dieser Abschnitt: eine Seite pro Release, der RSS-Feed und die E-Mail-Anmeldung.

    Die Vorlage Changelog Page nimmt ein Array releases, das neueste zuerst. Leg es in eine einfache Datendatei, damit Seite und Feed dieselbe Liste lesen:

    ts
    // app/(marketing)/changelog/releases.ts
    import type { ChangelogRelease } from "@/components/templates/changelog-page-data";
    export const releases: ChangelogRelease[] = [
    {
    version: "1.4.0",
    date: "2026-11-03",
    title: "Wiederkehrende Aufgaben",
    summary: "Wiederhol jede Aufgabe täglich, wöchentlich oder nach eigenem Zeitplan.",
    changes: [
    { type: "new", text: "Wiederkehrende Aufgaben mit täglichem, wöchentlichem und eigenem Zeitplan.", href: "/docs/recurring-tasks" },
    { type: "improved", text: "Boards mit 500 Karten öffnen schneller." },
    { type: "fixed", text: "Fälligkeitsdaten verschieben sich über Zeitzonen hinweg nicht mehr um einen Tag." },
    ],
    },
    ];

    Die Seite rendert <ChangelogPage header={false} footer={false} releases={releases} onSubscribe={subscribe} />, wobei subscribe eine Server Action ist, die die E-Mail-Adresse annimmt, wie die Kontakt-Action weiter unten. Ein Haken: Ohne eigenen Header reserviert die Vorlage keinen Platz mehr für eine Sticky-Leiste. Ab 768px klebt ihre Versionsleiste dann 24px unter dem oberen Rand und rutscht unter den Header deines Layouts. Gib die Header-Höhe über style={{ "--topbar-offset": "65px" } as CSSProperties} zurück (65px ist der Standard des Marketing Headers). Ihr RSS-Button verlinkt standardmäßig auf /changelog/rss.xml (rssHref), also bau diese Route, statt einen toten Link auszuliefern:

    ts
    // app/(marketing)/changelog/rss.xml/route.ts
    import { releases } from "../releases";
    export const dynamic = "force-static";
    const SITE = "https://acme.com";
    const escape = (text: string) => text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
    // changelogAnchor der Vorlage, kopiert, weil ihr Modul nur im Client läuft. 1.4.0 wird zu #v1-4-0
    const anchor = (version: string) => `v${version.replace(/[^a-z0-9]+/gi, "-")}`;
    export function GET() {
    const items = releases
    .map(
    (release) => `<item>
    <title>${escape(`${release.version}: ${release.title}`)}</title>
    <link>${SITE}/changelog#${anchor(release.version)}</link>
    <guid>${SITE}/changelog#${anchor(release.version)}</guid>
    <pubDate>${new Date(`${release.date}T12:00:00Z`).toUTCString()}</pubDate>
    <description>${escape(release.summary)}</description>
    </item>`,
    )
    .join("\n");
    const xml = `<?xml version="1.0" encoding="UTF-8"?>
    <rss version="2.0"><channel>
    <title>Acme Changelog</title><link>${SITE}/changelog</link><description>Neue Features, Verbesserungen und Fixes.</description>
    ${items}
    </channel></rss>`;
    return new Response(xml, { headers: { "Content-Type": "application/rss+xml; charset=utf-8" } });
    }
    Filtere nach New, Improved oder Fixed und schau, wie sich die Zahl ändert, dann scroll: Ab 768px klebt die Versionsleiste neben dem Release, das du gerade liest
    $ npx wingo-ui@latest add changelog-page
    ProDoku: Changelog Page

    Schreib die Einträge für Nutzer, nicht für das Commit-Log: „Fälligkeitsdaten verschieben sich über Zeitzonen hinweg nicht mehr um einen Tag“ sagt einem Kunden etwas, „fix tz offset in date util“ nicht. Die Seite zeigt zuerst vier Releases (pageSize) und lädt ältere bei Bedarf nach. Stell also das Release nach oben, das eine Ankündigung wert ist.

    Wann lohnt sich eine Kontaktseite?

    Manche Käufer wollen nicht im Alleingang kaufen: Sie brauchen ein Angebot, einen ausgefüllten Sicherheitsfragebogen oder ein Gespräch. Die Kontaktseite fängt sie auf. Sie braucht ein kurzes Formular, das bei einem Menschen ankommt, eine genannte Antwortzeit, die du auch einhältst, die direkten Kanäle (E-Mail für Sales und Support, eine Telefonnummer, wenn du rangehst) und einen Link zur Datenschutzerklärung neben der Einwilligungs-Checkbox.

    Die Vorlage Contact Page ist kostenlos und passt gut zu einer Server Action: Eine Action ist die einzige Art von Funktion, die eine Server Component an eine Client-Komponente übergeben darf. Die Seite braucht also keinen Client-Wrapper.

    ts
    // app/(marketing)/contact/actions.ts
    "use server";
    import type { ContactFormValues } from "@/components/templates/contact-page";
    export async function sendContact(values: ContactFormValues) {
    // auf dem Server erneut prüfen: Die Prüfung im Browser hilft dem Nutzer, sie schützt dich nicht
    if (!values.consent || !values.name.trim() || !values.email.includes("@") || !values.message.trim()) {
    throw new Error("Ungültige Nachricht");
    }
    const response = await fetch(process.env.LEADS_WEBHOOK_URL!, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(values),
    });
    if (!response.ok) throw new Error("Die Nachricht konnte nicht zugestellt werden");
    }
    tsx
    // app/(marketing)/contact/page.tsx
    import type { Metadata } from "next";
    import { ContactPage } from "@/components/templates/contact-page";
    import { sendContact } from "./actions";
    export const metadata: Metadata = {
    title: "Kontakt zu Acme",
    description: "Sprich mit Sales, hol dir Support oder frag nach Sicherheit. Wir antworten innerhalb eines Werktags.",
    };
    export default function Contact() {
    return (
    <ContactPage
    header={false}
    footer={false}
    onSubmit={sendContact}
    channels={[
    { kind: "email", title: "Sales", value: "sales@acme.com" },
    { kind: "email", title: "Support", value: "support@acme.com" },
    ]}
    showHours={false}
    showOffices={false}
    showLogos={false}
    />
    );
    }

    Wirft die Action einen Fehler, zeigt das Formular seine Fehlermeldung und behält, was der Besucher eingegeben hat; läuft sie fehlerfrei durch, wird das Formular zu einem Panel „Message sent“. Wie bei der Karriereseite gilt: Ohne onSubmit sieht jede Nachricht gesendet aus und landet nirgends. Schalte die Öffnungszeiten erst wieder ein, wenn du deine echte Zeitzone und deine echten Zeiten einträgst, und ersetz das Beispiel-FAQ durch die drei Fragen, die in deinem Postfach wirklich ankommen. Unser Tutorial zum Next.js-Kontaktformular geht weiter, mit zod-Validierung, einer Server Action, die die E-Mail sendet, einem Honeypot und einem Rate Limit; das hier ist das Minimum, das funktioniert.

    Welche Rechtsseiten braucht eine SaaS-Website?

    AGB und eine Datenschutzerklärung ab dem ersten Tag, eine Cookie-Richtlinie, wenn du mehr als notwendige Cookies setzt, und einen Auftragsverarbeitungsvertrag (DPA), sobald Geschäftskunden dir personenbezogene Daten schicken. Erhebst du personenbezogene Daten von Menschen in der EU, listet Artikel 13 der DSGVO (opens in a new tab) auf, was die Datenschutzhinweise ihnen mitteilen müssen, darunter wer du bist, warum du die Daten verarbeitest, die Rechtsgrundlage, wie lange du sie speicherst und welche Rechte sie haben. Wir sind keine Anwälte, und eine Vorlage ist auch keiner: Sie liefert das Layout, die Formulierungen sollten von einem Anwalt oder einem geprüften Generator für deine Rechtsordnung kommen.

    Das Layout zählt trotzdem, denn Leute lesen diese Seiten tatsächlich, bevor sie kaufen. Die Vorlage Legal Page legt alle Dokumente hinter einen Umschalter, beginnt jedes mit Aktualisierungs- und Gültigkeitsdatum und einer Zusammenfassung in einfacher Sprache, nummeriert die Abschnitte, verlinkt jede Überschrift und macht aus Tabellen (Unterauftragsverarbeiter, Aufbewahrungsfristen, Cookies) auf Smartphones Karten. Gib jedem Dokument mit einer dynamischen Route eine eigene URL:

    tsx
    // app/(marketing)/legal/[doc]/page.tsx
    import type { Metadata } from "next";
    import { notFound } from "next/navigation";
    import { LegalPage } from "@/components/templates/legal-page";
    import { documents } from "./documents";
    type Props = { params: Promise<{ doc: string }> };
    export const dynamicParams = false;
    export function generateStaticParams() {
    return documents.map((document) => ({ doc: document.id }));
    }
    export async function generateMetadata({ params }: Props): Promise<Metadata> {
    const document = documents.find((item) => item.id === (await params).doc);
    return document ? { title: document.title, description: document.description } : {};
    }
    export default async function Legal({ params }: Props) {
    const { doc } = await params;
    if (!documents.some((item) => item.id === doc)) notFound();
    return (
    <LegalPage
    header={false}
    footer={false}
    documents={documents}
    doc={doc}
    contact={{ email: "legal@acme.com", company: "Acme Inc.", address: ["100 Main Street", "New York, NY 10001"] }}
    />
    );
    }

    documents ist eine einfache Datendatei mit { id, label, title, description, href, updated, effective, summary, sections }, in der jeder Abschnittstext eine Liste aus Absätzen, Listen, Definitionen, Tabellen und Hinweisen ist. Jedes href muss zur Route passen (/legal/privacy für die id privacy), weil der Umschalter und die Links im Text es verwenden. Setz updated bei jeder Textänderung neu und lass die Rechtslinks im Footer auf dieselben Routen zeigen. Setzt du Analytics-Cookies, behandelt der Guide zum Cookie-Consent in Next.js das Banner, das zur Cookie-Richtlinie gehört.

    Wann lohnt sich eine Vergleichsseite?

    Wenn Käufer in Calls, E-Mails oder Suchanfragen einen Wettbewerber nennen. Eine Vergleichsseite trifft jemanden genau im Moment der Entscheidung. Das macht sie zu einer der wertvollsten Seiten der Website und zu der, die man am leichtesten falsch macht. Die Erklärung der FTC von 1979 zu vergleichender Werbung (opens in a new tab) befürwortet Vergleiche, solange sie wahr und nicht irreführend sind. Leser legen einen strengeren Maßstab an und gehen bei der ersten Behauptung, die sie widerlegen können.

    Was die Seite enthalten muss: ein Fazit in einer Zeile, das sagt, für wen welches Produkt passt, eine Feature-Tabelle, gruppiert so, wie Käufer denken, einen Preisvergleich für eine realistische Teamgröße mit datiertem Link zur Preisseite des Wettbewerbers, die Schritte für den Umstieg und ein FAQ. Die Vorlage Compare Page macht das pro Wettbewerber, mit einem Regler für die Teamgröße, der beide Jahreskosten neu berechnet und es offen sagt, wenn das andere Tool günstiger ist. Ihre Wettbewerberdaten enthalten Icon-Komponenten und ihre Labels sind Funktionen, also rendert sie aus einer Client-Datei, und der Umschalter führt auf /compare/<id>:

    tsx
    // app/(marketing)/compare/[competitor]/compare-view.tsx
    "use client";
    import { useRouter } from "next/navigation";
    import { ComparePage } from "@/components/templates/compare-page";
    import { competitors } from "./competitors";
    export function CompareView({ id }: { id: string }) {
    const router = useRouter();
    return (
    <ComparePage
    header={false}
    footer={false}
    competitors={competitors}
    competitor={id}
    onCompetitorChange={(next) => router.push(`/compare/${next}`)}
    acmePricing={{ plan: "Pro", perSeat: 12 }}
    showTestimonials={false}
    />
    );
    }

    Die Server-page.tsx daneben exportiert generateStaticParams aus derselben Liste competitors (jeweils { competitor: id }), setzt den Metadaten-Titel auf „Acme vs Taskly“ und rendert <CompareView id={competitor} />. Ändere labels.brand und die Titel-Labels von Acme auf deinen Produktnamen.

    Wähl im Umschalter einen anderen Wettbewerber und zieh dann den Regler für die Teamgröße: Beide Jahreskosten rollen auf neue Summen, und das Band darunter sagt, welches Tool günstiger ist
    $ npx wingo-ui@latest add compare-page
    ProDoku: Compare Page

    Schreib eine Seite pro Wettbewerber und füll die Tabelle aus dessen öffentlicher Doku und Preisseite, mit dem Datum deiner Prüfung. Sag offen, wo der andere besser ist: Ein skeptischer Käufer glaubt dem Rest der Tabelle mehr, wenn eine Zeile gegen dich spricht. Unser Guide zur SaaS-Vergleichsseite geht Fazit, datierte Tabelle und Umstiegsweg Schritt für Schritt durch.

    Welche Seiten kommen später dazu?

    Die meisten Websites bekommen einen zweiten Ring von Seiten, sobald das erste Set live ist. Zu jeder gibt es einen eigenen Beitrag:

    • Eine Statusseite, sobald Kunden während der Arbeitszeit auf dich angewiesen sind.
    • Ein Blog für die Suchanfragen, die dein Produkt beantwortet.
    • Eine 404-Seite, die verirrte Besucher zur Suche und zu den Seiten oben schickt.
    • Eine Waitlist-Seite, wenn du startest, bevor das Produkt offen ist.
    • Eine App Landing Page mit Store-Buttons und QR-Code, sobald du eine App fürs Smartphone veröffentlichst.
    • Ein Help Center, sobald jede Woche dieselben Support-Fragen ankommen.
    • Die Anmelde- und Registrierungsseiten, zu denen jeder Preis-Button führt, und der Onboarding-Flow danach.

    Die Vorlagen-Galerie hat außerdem Seiten für FAQ, Sicherheit, Kunden, Integrationen und Roadmap. Nimm sie dazu, wenn du die Inhalte hast, nicht damit der Footer voll aussieht.

    Mit welchem SaaS Website Template solltest du starten?

    Nimm einen kostenlosen Starter, wenn du die meisten Seiten selbst schreibst, ein bezahltes Theme, wenn dir sein Design gefällt, und Komponentenvorlagen, wenn sich die Seiten ständig ändern werden. Ein Vergleich der Optionen, die wir am 5. November 2026 geprüft haben:

    OptionPreisWas du bekommstNimm es, wenn
    Vercel Minimal SaaS Starter (opens in a new tab)KostenlosEine minimale Next.js-14-Startseite mit Tailwind CSS und Dark Modedu einen sauberen Start willst und jede weitere Seite selbst schreibst
    Startup von NextJSTemplates (opens in a new tab)Kostenlos (bezahlte Pro-Stufe)Eine Next.js-14-Startup-Website mit den üblichen Abschnittendu eine kostenlose, fertige Startseite und einen Preisabschnitt willst
    Copper von Themefisher (opens in a new tab)$77, Einzellizenz17 Seiten auf Next.js 16, darunter Karriere, Changelog und Rechtlichesdu jede Seite als fertiges Theme mit einem Kauf willst
    Wingo UI VorlagenKontakt- und FAQ-Seite kostenlos; der Rest in Pro für $8 im Monat, $80 im Jahr oder $150 einmalig50 Seitenvorlagen, per CLI als Quellcode installiert, mit Props für die Inhalte und Schaltern für jeden Abschnittdu jede Seite als Komponente konfigurieren willst, mit gemeinsamem Header, Footer und denselben Tokens

    Ein Theme ist der schnellere Start, wenn sein Design genau das ist, was du willst. Komponentenvorlagen passen besser, wenn sich die Website ständig ändert: Jede Seite bekommt ihre Inhalte als Props, also ist ein neuer Plan oder ein neues Release eine Datenänderung statt eines Eingriffs in eine Datei mit 600 Zeilen, und die CLI kann die Vorlage später aktualisieren und deine Änderungen dabei behalten.

    Wie prüfe ich die ganze Website vor dem Launch?

    Klick dich als Käufer auf dem Smartphone durch, dann als Crawler. Diese Liste fängt das meiste ab, was schiefgeht:

    1. Jeder Link in Header und Footer funktioniert: keine 404 für Karriere-, Changelog-, Status- oder Rechtsseiten, die du noch nicht gebaut hast. Entferne den Link stattdessen.
    2. Kein Beispielinhalt hat überlebt: Durchsuch das gerenderte HTML nach „Acme“, „Emma Carter“, „12,000“ und den anderen Standardwerten der Vorlagen.
    3. Jedes Formular und jeder Button erreicht einen echten Handler: onSubmit beim Kontakt, onApply bei der Karriere, onSubscribe beim Changelog und onSelectPlan oder Plan-Links bei den Preisen. Schick jedes einmal ab und prüf, ob die Nachricht ankommt.
    4. Die Hauptaktion lautet auf jeder Seite gleich und führt zur selben Route.
    5. Jede Seite hat ihren eigenen Titel und ihre eigene Beschreibung, und sitemap.ts listet die Rechtsdokumente, die Vergleichsseiten und die Stellenseiten.
    6. Bei 390px scrollt nichts seitwärts, Menüs und Filter öffnen sich als Bottom Sheets, und die Preispläne lassen sich wischen.
    7. Light und Dark Mode sind auf jeder Seite lesbar, auch die grauen Bänder zwischen den Abschnitten.

    Unser Guide zu Mobile-first React-Komponenten erklärt die Smartphone-Regeln hinter den Punkten 6 und 7, und die Kategorie Praxis: Screens und Apps hat die anderen Screens, vom Admin-Dashboard hinter dem Registrierungs-Button bis zum Checkout. Diese Tutorials bauen die App hinter der Website:

    • React Settings Page: Navigation zwischen Bereichen, eine Save Bar für Textfelder und eine Danger Zone.
    • API Key Management UI: Keys anlegen, einmal zeigen, rotieren und widerrufen, für Produkte mit einer API.
    • Onboarding Checkliste UI: die Get-started-Karte, die neue Nutzer zuerst sehen.
    • Shadcn Profile Page: das öffentliche Profil mit Follow, Tabs und einem Sheet zum Bearbeiten, für Produkte mit einer Community.
    • Role Management UI: Mitglieder und Einladungen mit Plätzen, eine Rechtematrix und ein Audit-Log.
    • React CRM Template: eine Deal-Pipeline mit gewichteter Prognose und einer Firmenseite.
    • React Invoice Template: ein Rechnungseditor mit einer einzigen Summenfunktion für Client und Server.
    • React Marketplace Template: Suche, Facetten und Angebotskarten, wobei die ganze Suche in der URL bleibt.
    • Shadcn Ecommerce Template: ein Shop von der Startseite bis zum Checkout.
    • Bestellhistorie UI: Bestellungen nach Monat mit Track, Buy again und Invoice, für Produkte, die etwas verkaufen.
    • React Terminbuchung: Datum, Zeitslot und Angaben, mit sauber behandelten Zeitzonen.
    • React Workflow Builder: Trigger, Verzweigungen und KI-Schritte auf React Flow.
    • Mehrwertsteuer für e-Factura und das rumänische Adressformat: für Produkte, die rumänische Kunden abrechnen.

    Du baust gar kein SaaS? Dieselbe Kategorie deckt auch andere Websites ab: ein Nextjs Portfolio Template für Freelancer, ein Agentur Website Template, das Briefings einsammelt, eine Restaurant Website Vorlage mit Öffnungszeiten und Tischreservierung und ein Immobilien Website Template mit Suche, Karte mit Preis-Pins und Kreditschätzung.

    Wie geht es weiter?

    Fang mit den Seiten an, die ein Käufer am ersten Tag braucht: Startseite, Preise, Kontakt und die beiden Rechtsdokumente. Die Vorlage Contact Page ist mit einem kostenlosen Konto gratis, also ist npx wingo-ui@latest add contact-page eine gute erste Installation, um zu sehen, wie die Vorlagen Props annehmen. Die anderen Vorlagen in diesem Guide gehören zu Wingo UI Pro. Egal, welches SaaS Website Template du wählst: Liefer lieber weniger Seiten mit echten Inhalten aus als mehr Seiten mit Beispieltext.

    Komponenten in diesem Artikel

    • Landing Page

      A SaaS home page: hero with a drawn product shot, logos, bento features, product tour, numbers, quotes, pricing teaser, FAQ and CTA.

      Pro
    • Pricing Page

      A React SaaS pricing page: plans with monthly or yearly and USD or EUR switches, a comparison table, quotes, an FAQ and a closing call.

      Pro
    • About Page

      A React about page template for a SaaS: hero collage, mission, stats, a timeline, values, team, investors, press, offices and careers.

      Pro
    • Careers Page

      A React careers page template: mission, team mosaic, values, benefits, filterable open roles with a job drawer and apply form.

      Pro
    • Changelog Page

      A React changelog page template: email and RSS subscribe, releases on a sticky version rail with drawn covers and New, Improved and Fixed groups.

      Pro
    • Contact Page

      A React contact page template: a validated form, copyable channels with live office hours, offices on a drawn map, a short FAQ and logos.

      Free
    • Legal Page

      Terms, privacy, cookie and data processing pages in one template: a document switcher, a plain-English summary and numbered sections.

      Pro
    • Compare Page

      A React comparison page template (Acme vs a competitor): a verdict hero, a feature table, price comparison, migration steps and FAQ.

      Pro
    • Marketing Header

      A React marketing header for a SaaS site: a sticky navbar with logo, dropdown panels, Sign in, Get started, a news strip and a phone menu.

      Free
    • Marketing Footer

      The bottom of a SaaS website: brand and tagline, link columns, a newsletter signup, a status dot, legal links and social icons.

      Free
    • Job Detail Page

      A React job posting page template: the role, benefits, interview steps, team, a sticky apply card, an application form and similar roles.

      Pro

    Häufige Fragen

    Welche Seiten braucht eine SaaS-Website?

    Zum Launch: eine Startseite, Preise, Kontakt, AGB und Datenschutz. About und Changelog kommen dazu, sobald es eine Geschichte und eine Release-Historie zu zeigen gibt, Karriere, wenn du einstellst, und eine Vergleichsseite für jeden Wettbewerber, mit dem deine Käufer dich wirklich vergleichen.

    Gibt es ein kostenloses Next.js SaaS Website Template?

    Ja. Stand 5. November 2026 listet Vercel einen kostenlosen, minimalen Next.js SaaS Website Starter, und NextJSTemplates bietet Startup als kostenlose Open-Source-Vorlage an, beide auf Next.js 14. Sie decken die Startseite und ein paar Grundlagen ab; bezahlte Kits wie Copper von Themefisher ($77) bringen Karriere-, Changelog- und Rechtsseiten mit.

    Braucht ein SaaS eine Changelog-Seite?

    Sie bringt mehr, als ihr Traffic vermuten lässt. Käufer prüfen dort, ob das Produkt gepflegt wird, bestehende Nutzer finden neue Features, und jedes Release liefert dir einen Link zum Teilen. Liefer sie mit einem RSS-Feed aus, damit man ihr ohne Konto folgen kann.

    Welche Rechtsseiten braucht eine SaaS-Website?

    Mindestens AGB und eine Datenschutzerklärung, dazu eine Cookie-Richtlinie, wenn du nicht notwendige Cookies setzt, und einen Auftragsverarbeitungsvertrag (DPA), wenn Geschäftskunden dir personenbezogene Daten schicken. Eine Vorlage liefert das Layout; den Text sollte ein Anwalt oder ein geprüfter Generator für deine Rechtsordnung liefern.

    Sollte eine Startup-Website Vergleichsseiten haben?

    Nur für Wettbewerber, die deine Käufer in Calls, E-Mails oder Suchanfragen tatsächlich nennen. Jede Seite sollte offen sagen, wo das andere Produkt die bessere Wahl ist, Preise mit Datum und Quelllink nennen und Umsteigern einen Importweg anbieten.

    In deinem Projekt ausprobieren

    Landing Page

    Pro

    A SaaS home page: hero with a drawn product shot, logos, bento features, product tour, numbers, quotes, pricing teaser, FAQ and CTA.

    75 Komponenten kostenlos, ohne Konto. Pro ab 8 $ im Monat.

    Landing Page live öffnenPreise ansehen
    • Next.js
    • SaaS
    • Vorlagen
    • Marketing-Website
    • Tailwind CSS

    Teilen

    SR

    Über den Autor

    Serban Rusu

    Gründer von Wingo UI

    Serban Rusu hat Wingo UI gegründet. Er baut die Komponenten, die CLI und den MCP-Server und schreibt über React-UIs für Smartphones und KI-Agents.

    Mehr von Serban
    Weiterlesen

    Ähnliche Artikel

    Alle Artikel
    Praxis: Screens und Apps

    Karriereseite Template in React: Bewerbung und JobPosting

    Ein Karriereseite Template in React, das Bewerbungen bringt: Mission, Team, Benefits, filterbare Stellen, Drawer, Bewerbungsformular und JobPosting für Google.

    SRSerban Rusu·6. Nov. 2026·12 Min. Lesezeit
    Vergleiche und Alternativen

    Beste shadcn Templates 2026: kostenlos und bezahlt, getestet

    Beste shadcn Templates für SaaS-Sites, Dashboards, Shops und Doku, geprüft am 6. November 2026: Lizenz, Preis, Tailwind v4 und jede Demo bei 390px Breite.

    SRSerban Rusu·6. Nov. 2026·11 Min. Lesezeit
    Vergleiche und Alternativen

    Shadcn Blocks vs Components: Womit du anfangen solltest

    Shadcn Blocks vs Components vs Vorlagen: was dir jede Ebene abnimmt, was spätere Anpassungen kosten und eine einfache Regel, womit du neue Screens startest.

    SRSerban Rusu·16. Okt. 2026·11 Min. Lesezeit
    Newsletter

    Neue Artikel per E-Mail

    Neue Artikel, Produktneuheiten und gelegentlich Angebote von Wingo UI. Wir zählen Klicks, damit es relevant bleibt.

    Kein Spam. Du kannst dich jederzeit abmelden.

    WingoUI

    Animierte, konfigurierbare, mobile-first React-Komponenten und Blöcke. Kopier den Quellcode, pass ihn an und lass deinen Coding-Agenten damit bauen.

    Produkt

    • Komponenten
    • Vorlagen
    • Preise
    • KI-Agenten
    • Für Teams
    • Theme-Generator

    Ressourcen

    • Doku
    • Kontakt
    • Programme
    • Blog
    • Changelog
    • Changelog-RSS
    • llms.txt

    Vergleiche

    • Wingo UI vs. Premium-Kits
    • Wingo UI vs. shadcn/ui
    • shadcn/ui-Alternativen
    • MUI-Alternativen
    • Tailwind-Plus-Alternativen
    • Magic-UI-Alternativen
    • Kostenlose Komponenten

    Rechtliches

    • AGB
    • Datenschutz
    • Rückerstattung
    • Lizenz
    • Impressum

    Komponenten-Kategorien

    • Buttons & Actions
    • Inputs
    • Forms
    • Navigation
    • Overlays
    • Feedback
    • Data Display
    • Tables & Lists
    • Charts & Stats
    • Layout
    • Media
    • AI Kit
    • Text & Effects
    • Mobile
    • Commerce
    • Marketing Sections
    • Blocks
    • Hooks & Utilities

    © 2026 Wingo UI

    Wingo UI