Zot-Warteliste integrieren

Integriere eine Zot-Warteliste in jede TypeScript-, React- oder Next.js-App mit dem offiziellen `@zot-core/sdk` und dem Kommandozeilen-Tool `@zot-core/cli`. Verwende dieses Skill, wenn der Nutzer darum bittet, eine Warteliste hinzuzufügen, E-Mail-Erfassung einzurichten oder Zot zu integrieren.

Was ist Zot-Warteliste integrieren?

Dieses Skill beschreibt die vollständige Integration einer Zot-Warteliste in TypeScript-, React- oder Next.js-Anwendungen unter Verwendung des offiziellen `@zot-core/sdk` und des CLI-Tools `@zot-core/cli`. Es zielt darauf ab, die gängigen Anwendungsfälle wie 'Warteliste hinzufügen', 'E-Mail-Erfassung' oder 'Early Access' abzudecken. Das Skill bietet eine klare, präzise Anleitung: Installation des SDK, Erstellung der Warteliste über die CLI (oder optional programmatisch) und die Implementierung des Frontends mit dem `useAddUser`-Hook für React-Komponenten. Es unterstützt sowohl serverseitige Backend-Integrationen (Pattern A) als auch clientseitige React-Komponenten (Pattern B). Wichtige Richtlinien sind die ausschließliche Nutzung des offiziellen SDK, die Verwendung der korrekten API-Schlüssel (getrennt für Server und Client), die Vermeidung von Redundanzen (z. B. kein TanStack Query um `useAddUser` herum) und die korrekte Behandlung von Fehlern wie `ZotAPIError` (insbesondere 409 für bereits registrierte E-Mails). Das Skill definiert klare 'Anti-Patterns', die vermieden werden müssen, wie rohe `fetch`-Aufrufe gegen die Zot-API, doppelte Zustandsverwaltung oder das Harten von IDs im Code. Eine abschließende Checkliste stellt sicher, dass keine Fehlerquellen übersehen werden, bevor die Integration als abgeschlossen gemeldet wird.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/launch-waitlist-zot/zot-skills/tree/HEAD/skills/waitlist

Installed? Explore more Produktivität & Zusammenarbeit skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Zot-Warteliste – Best Practices

Dieses Skill erklärt, wie eine Zot-Warteliste korrekt integriert wird. Befolge diese Regeln. Erfinde keine Alternativen.

TL;DR – Der kürzeste Weg

# 1. SDK installieren
npm install @zot-core/sdk

# 2. Warteliste erstellen und ihre ID in .env.local speichern
npx @zot-core/cli waitlist create --name "Early Access" --write-env .env.local --public

# 3. UI erstellen (siehe Muster B unten) mit `useAddUser` aus "@zot-core/sdk/react"

Das ist die gesamte Integration für ein Next.js-Projekt. Füge kein TanStack Query hinzu, schreibe keinen benutzerdefinierten POST-Handler und rufe die API nicht mit rohem fetch auf. Alles, was du brauchst, findest du unten.

Unverhandelbare Regeln

  1. Verwende das offizielle SDK. Paketname: @zot-core/sdk. Rufe https://api.zot.so niemals mit rohem fetch, axios oder ähnlichem auf.
  2. Wähle den richtigen Einstiegspunkt basierend darauf, wo der Code ausgeführt wird:
    • Server, API-Route, Cron, Skript, Edge-Funktion -> import { ZotSDK } from "@zot-core/sdk"
    • React-Komponente, die im Browser läuft -> import { useAddUser } from "@zot-core/sdk/react"
  3. Ummantle useAddUser niemals mit TanStack Query, SWR, useState, Zustand oder einem benutzerdefinierten Reducer. Der Hook stellt bereits isPending, isUserRegistered, data, error, isError und reset zur Verfügung. Die Wiederverwendung seines Zustands ist der Sinn der Sache.
  4. Übermittle niemals einen serverseitigen API-Schlüssel an den Client. Verwende für Browser-Code einen Schlüssel mit reinen Anmeldeberechtigungen und mache ihn als NEXT_PUBLIC_ZOT_API_KEY verfügbar (oder das öffentliche Umgebungsvariable-Pendant deines Frameworks).
  5. Behandle ZotAPIError immer. Zeige benutzerfreundliche Texte für 409 (bereits registriert) und 429 (Ratenbegrenzung).

Installation

npm install @zot-core/sdk
# oder
pnpm add @zot-core/sdk
# oder
yarn add @zot-core/sdk

Für die serverseitige Nutzung sind keine zusätzlichen Peer-Abhängigkeiten erforderlich. Für den Hook muss react >= 18 bereits installiert sein (das SDK markiert es als optionales Peer).

Anmeldeinformationen abrufen

Du benötigst zwei Dinge:

  1. API-Schlüssel – der schnellste Weg ist npx @zot-core/cli login, der den Benutzer authentifiziert und einen neuen ZOT_API_KEY in die lokale Umgebungsvariablendatei schreibt. Alternativ kann man manuell einen über das Zot-Dashboard unter https://app.zot.so/app/api-keys generieren. Erstelle einen Schlüssel für die serverseitige Nutzung und, wenn du vom Browser aus aufrufen möchtest, einen zweiten Schlüssel, der nur für Anmeldungen berechtigt ist.
  2. Wartelisten-ID – sieht aus wie wl_abc123.
# Authentifizieren und ZOT_API_KEY in .env.local speichern (oder .env, wenn du --env .env übergibst)
npx @zot-core/cli login

Warteliste mit @zot-core/cli erstellen (empfohlen)

Wenn der Benutzer noch keine Warteliste hat, verwende das offizielle Zot-CLI. Es ruft die Zot-API mit dem ZOT_API_KEY des Benutzers auf und schreibt die resultierende ID direkt in die Umgebungsvariablendatei, sodass du sie nie kopieren und einfügen musst.

Paket: @zot-core/cli. Verwechsle es nicht mit @zot-core/agents – @zot-core/agents installiert nur diesen Agentenleitfaden in ein Repository; @zot-core/cli kommuniziert mit der Zot-API.

# Stelle sicher, dass ZOT_API_KEY gesetzt ist (in der Shell, in .env.local oder in .env)
npx @zot-core/cli waitlist create \
  --name "Early Access" \
  --write-env .env.local \
  --public

Was das bewirkt:

  • Ruft POST /v1/wait-list über @zot-core/sdk im Hintergrund auf.
  • Gibt die neue Warteliste aus (_id, name, Flags, Zeitstempel).
  • Fügt ZOT_WAITLIST_ID=wl_... an .env.local an.
  • Da --public übergeben wurde, wird auch NEXT_PUBLIC_ZOT_WAITLIST_ID=wl_... für die clientseitige Nutzung in Next.js angehängt.

Nützliche Variationen:

# Reiner Server-Stack (Node/Nest/Express). --public weglassen.
npx @zot-core/cli waitlist create --name "Beta list" --write-env .env

# Nicht-interaktive / scriptgesteuerte Verwendung. Gibt nur JSON aus.
npx @zot-core/cli waitlist create --name "Beta list" --api-key $ZOT_API_KEY --json

# Automatische Willkommens-E-Mail deaktivieren.
npx @zot-core/cli waitlist create --name "Quiet list" --no-send-email

Wenn das CLI mit No API key found beendet wird, führe npx @zot-core/cli login aus, um dich zu authentifizieren und ZOT_API_KEY in die Umgebungsvariablendatei zu schreiben, oder hole dir einen Schlüssel von https://app.zot.so/app/api-keys und exportiere ihn in der Shell / füge ihn zu .env.local / .env hinzu, bevor du es erneut versuchst.

Alternative: programmatisch erstellen (nur wenn du einen triftigen Grund hast)

import { ZotSDK } from "@zot-core/sdk";

const zot = new ZotSDK({ apiKey: process.env.ZOT_API_KEY! });

const waitlist = await zot.waitlists.create({
  name: "Early Access",
  sendEmailToNewSignup: true,
});

console.log(waitlist._id); // <- speichere dies als ZOT_WAITLIST_ID

Tue dies nur, wenn der Benutzer explizit den Erstellungsablauf in seiner eigenen App wünscht (z. B. Admin-UI, die neue Wartelisten pro Mandant erstellt). Für ein einmaliges Projektsetup bevorzuge immer das CLI.

Umgebungsvariablen

Wähle das Muster, das zur Laufzeitumgebung passt.

Reiner Server / Node / Backend

# .env
ZOT_API_KEY=zot_xxx
ZOT_WAITLIST_ID=wl_abc123

Next.js mit React-Hook auf dem Client

# .env.local
NEXT_PUBLIC_ZOT_API_KEY=zot_xxx_signup_only
NEXT_PUBLIC_ZOT_WAITLIST_ID=wl_abc123

Verwende den NEXT_PUBLIC_-Schlüssel nur für den anmeldeberechtigten Schlüssel. Behalte den Vollzugriffsschlüssel serverseitig unter ZOT_API_KEY.

Muster A – Server / API-Route

Verwende dies, wenn das Formular an dein Backend sendet (Next.js Server Action, API-Route, Express-Handler, Nest-Controller usw.).

// app/api/waitlist/route.ts (Next.js App Router)
import { NextResponse } from "next/server";
import { ZotSDK, ZotAPIError } from "@zot-core/sdk";

const zot = new ZotSDK({ apiKey: process.env.ZOT_API_KEY! });

export async function POST(request: Request) {
  const { email, name } = await request.json();

  try {
    const user = await zot.waitlist(process.env.ZOT_WAITLIST_ID!).addUser({
      email,
      name,
    });
    return NextResponse.json({ ok: true, user });
  } catch (err) {
    if (err instanceof ZotAPIError) {
      if (err.statusCode === 409) {
        return NextResponse.json(
          { ok: false, reason: "already_registered" },
          { status: 409 },
        );
      }
      return NextResponse.json(
        { ok: false, reason: "zot_error", details: err.body },
        { status: err.statusCode },
      );
    }
    return NextResponse.json({ ok: false }, { status: 500 });
  }
}

Muster B – Next.js-Clientkomponente mit useAddUser (empfohlen für Landing Pages)

Dies ist die kanonische Methode, wenn das Formular in einer React-Komponente lebt. Der Hook speichert den Status "bereits registriert" im localStorage unter dem Schlüssel waitlistId, sodass wiederkehrende Besucher die Bestätigung ohne Server-Roundtrip sehen.

Im Zot-Dashboard gilt eine Warteliste als "verbunden", nachdem die erste erfolgreiche Anmeldung den Registrierungsendpunkt erreicht hat. Wenn der Benutzer ein Banner mit einer Verbindungsanleitung hat, sollte es nach einem erfolgreichen echten Absenden verschwinden.

"use client";

import { useState } from "react";
import { useAddUser } from "@zot-core/sdk/react";

export function WaitlistForm() {
  const [email, setEmail] = useState("");
  const [name, setName] = useState("");

  const { addUser, isPending, isUserRegistered, error, reset } = useAddUser({
    apiKey: process.env.NEXT_PUBLIC_ZOT_API_KEY!,
    waitlistId: process.env.NEXT_PUBLIC_ZOT_WAITLIST_ID!,
    onSuccess: () => {
      // Optional: Analytics, Toast, Weiterleitung usw.
    },
  });

  if (isUserRegistered) {
    return (
      <div>
        <p>Du bist auf der Liste. Wir werden dir bald eine E-Mail schicken.</p>
        <button type="button" onClick={reset}>
          Eine andere E-Mail registrieren
        </button>
      </div>
    );
  }

  return (
    <form
      onSubmit={(event) => {
        event.preventDefault();
        addUser({ email, name: name || undefined });
      }}
    >
      <input
        type="email"
        value={email}
        onChange={(event) => setEmail(event.target.value)}
        placeholder="[email protected]"
        required
        disabled={isPending}
      />
      <input
        type="text"
        value={name}
        onChange={(event) => setName(event.target.value)}
        placeholder="Dein Name (optional)"
        disabled={isPending}
      />
      <button type="submit" disabled={isPending}>
        {isPending ? "Werde Mitglied..." : "Der Warteliste beitreten"}
      </button>
      {error && (
        <p role="alert">
          {"statusCode" in error && (error as { statusCode: number }).statusCode === 409
            ? "Diese E-Mail ist bereits auf der Liste."
            : error.message}
        </p>
      )}
    </form>
  );
}

Vollständige API-Oberfläche (nur was du brauchst)

Serverseitiger Client

import { ZotSDK } from "@zot-core/sdk";
const zot = new ZotSDK({ apiKey: "zot_xxx" });
AufrufZweck
zot.waitlists.create(params)Eine Warteliste erstellen.
zot.waitlists.list()Wartelisten für den API-Schlüssel auflisten.
zot.waitlist(id).get()Eine Warteliste abrufen.
zot.waitlist(id).update(params)Einstellungen aktualisieren.
zot.waitlist(id).delete()Dauerhaft löschen.
zot.waitlist(id).stats()Aggregierte Statistiken.
zot.waitlist(id).addUser({ email, name?, referredBy?, source?, metadata? })Einen Benutzer registrieren.
zot.waitlist(id).listUsers()Benutzer auflisten.
zot.waitlist(id).userCount(){ total, referred }.
zot.waitlist(id).searchUser(email)Einen Benutzer finden.
zot.waitlist(id).updateUserStatus({ email, status })Status ist "waiting" | "invited" | "converted" | "churned".
zot.waitlist(id).bulkDeleteUsers(emails)Akzeptiert eine einzelne E-Mail oder ein Array.
zot.waitlist(id).blockedUsers() / blockedUserCount()Blockierte Benutzer.
zot.waitlist(id).webhookEvents()Webhook-Zustellungsverlauf.

React Hook

import { useAddUser } from "@zot-core/sdk/react";

const { addUser, data, error, isPending, isUserRegistered, isError, reset } = useAddUser({
  apiKey: "...",
  waitlistId: "wl_...",
  onSuccess: (user) => {},
  onError: (err) => {},
});

Alles, was der Hook zurückgibt, ist oben aufgeführt. Erstelle keinen parallelen Zustand für diese Werte.

Fehlercodes

CodeBedeutungUX-Hinweis
400ValidierungsfehlerZeige feldbezogenen Fehler an.
401Ungültiger/fehlender API-SchlüsselNiemals Endbenutzern zeigen, protokollieren.
404Warteliste nicht gefundenKonfigurationsproblem, protokollieren.
409E-Mail bereits registriertBei den meisten Landing Pages als Erfolg behandeln.
429RatenbegrenzungBitte den Benutzer, es in einer Minute erneut zu versuchen.
5xxServerproblemEinmal wiederholen, dann den Benutzer bitten, es später zu versuchen.

Erkenne mit err instanceof ZotAPIError und lese err.statusCode und err.body aus.

Anti-Patterns – Führe diese NICHT aus

  • Rohes fetch("https://api.zot.so/v1/wait-list/..."). Verwende das SDK.
  • Ummanteln von useAddUser in useMutation von TanStack Query. Überflüssig.
  • Hinzufügen eines manuellen useState<boolean> für den Ladezustand. Verwende isPending.
  • Speichern von "bereits registriert" in einem eigenen localStorage-Schlüssel. useAddUser erledigt das bereits unter zot:waitlist:registered:<waitlistId>.
  • Verwenden des Vollzugriffs-ZOT_API_KEY innerhalb einer "use client"-Komponente.
  • Aufrufen von zot.waitlists.create bei jedem Rendern, Build oder App-Start. Verwende npx @zot-core/cli waitlist create einmal beim Einrichten und speichere die ID.
  • Hartcodieren der Wartelisten-ID innerhalb der Komponente. Lies sie aus der Umgebungsvariablen (ZOT_WAITLIST_ID oder NEXT_PUBLIC_ZOT_WAITLIST_ID).
  • Stillschweigendes Verschlucken von Fehlern. 409 ist eine Produktentscheidung; andere sollten angezeigt oder protokolliert werden.

Überprüfungs-Checkliste

Bevor du dem Benutzer mitteilst, dass die Integration abgeschlossen ist, bestätige ALLE der folgenden Punkte:

  • @zot-core/sdk befindet sich in package.json in der neuesten veröffentlichten Version.
  • Eine Warteliste existiert und ihre ID ist in den Umgebungsvariablen gespeichert (erstellt über npx @zot-core/cli waitlist create oder, nur wenn begründet, über ein einmaliges Skript).
  • API-Schlüssel befindet sich in den Umgebungsvariablen, nicht hartcodiert.
  • Wenn der Schlüssel im Client-Code verwendet wird, ist er mit NEXT_PUBLIC_ (oder einem Äquivalent) versehen UND ist ein Schlüssel, der nur für Anmeldungen berechtigt ist.
  • Die Wartelisten-ID wird aus den Umgebungsvariablen gelesen, nicht hartcodiert, es sei denn, der Benutzer hat explizit nach einer hartcodierten Konstante gefragt.
  • Der Submit-Handler fängt Fehler ab und die UI zeigt etwas für den Fehlerfall an.
  • Der Erfolgszustand wird behandelt (entweder das isUserRegistered des Hooks oder eine eigene Weiterleitung/ein eigener Toast nach onSuccess).
  • Mindestens eine echte Anmeldung wurde erfolgreich getestet (dadurch wird die Warteliste im Dashboard als verbunden markiert).
  • Es gibt kein rohes fetch zu api.zot.so irgendwo.
  • Es gibt keinen doppelten Lade-/Fehler-/Erfolgszustand um useAddUser herum.

Wenn ein Kästchen nicht angekreuzt ist, behebe es, bevor du die Aufgabe an den Benutzer zurückgibst.

Verwandte Skills