> ## Documentation Index
> Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Bauen Sie Ihr eigenes Verknüpfungs-Popup

> Direct Mode — verbinden Sie ein Netzwerk nach dem anderen über Ihre eigene Schaltfläche, mit einem Popup, das Sie selbst öffnen und überwachen.

export const PlansAvailable = ({plans = [], maxPackRequired}) => {
  let displayPlans = plans;
  if (plans && plans.length === 1) {
    const lowerCasePlan = plans[0].toLowerCase();
    if (lowerCasePlan === "business") {
      displayPlans = ["Launch", "Business", "Enterprise"];
    } else if (lowerCasePlan === "premium") {
      displayPlans = ["Premium", "Launch", "Business", "Enterprise"];
    }
  }
  return <Note>
Available on {displayPlans.length === 1 ? "the " : ""}
{displayPlans.join(", ").replace(/\b\w/g, l => l.toUpperCase())}{" "}
{displayPlans.length > 1 ? "plans" : "plan"}.

{maxPackRequired && <span onClick={() => window.open('https://www.ayrshare.com/docs/additional/maxpack', '_self')} className="flex items-center mt-2 cursor-pointer">
 <span className="px-1.5 py-0.5 rounded text-sm" style={{
    backgroundColor: '#C264B6',
    color: 'white',
    fontSize: '12px'
  }}>
   Max Pack required
 </span>
</span>}
</Note>;
};

<PlansAvailable plans={["business"]} maxPackRequired={true} />

Direct Mode verbindet **ein soziales Netzwerk nach dem anderen**, über eine Schaltfläche in Ihrem
eigenen Dashboard. Sie erstellen eine Link Session für dieses Netzwerk, öffnen die zurückgegebene
URL in einem Popup, und Ihre Seite erfährt, was passiert ist. Ihr Nutzer sieht nie eine Seite, die
alle Netzwerke auflistet, und verlässt Ihre App nie länger, als das Login des Netzwerks selbst
dauert.

## Welche Oberfläche Sie möchten

Drei Varianten, und die ersten beiden sind dieselbe Integration. Diese Seite ist die, die Sie
selbst bauen.

| Oberfläche                                                                                                                     | Ihr Nutzer sieht                                                                         | White-Labeling                                                                           | Wählen Sie sie, wenn                                                                                                          |
| ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **Widget — eingebettete Frames** ([mount](/docs/multiple-users/connect-widget#mount-a-slot))                                        | unsere Schaltflächen inline in Ihrem eigenen Layout; kein Popup bis zu dem des Netzwerks | **Am stärksten.** Ihre Seite, Ihre Schriften und Farben, und Ihr Nutzer verlässt sie nie | Sie haben ein Dashboard mit einer Zeile pro Netzwerk und möchten, dass die Verknüpfung an Ort und Stelle geschieht. Max Pack. |
| **Widget — Ihre eigene Schaltfläche** ([popup](/docs/multiple-users/connect-widget#your-own-button))                                | Ihre Schaltfläche, dann ein Popup für das Netzwerk                                       | **Stark.** Das Popup ist unseres, aber es ist kurz und übernimmt Ihr Erscheinungsbild    | Sie möchten Ihre eigene Schaltfläche und Ihr eigenes Styling, und keine Frames in Ihrem Layout. Max Pack.                     |
| **Gehostete Verknüpfungsseite** ([Anleitung](/docs/multiple-users/api-integration-business#single-sign-on-with-jwt-authentication)) | eine von uns gehostete Seite mit Ihrem Logo, Ihren Farben und eigenem CSS                | **Am schwächsten.** Es ist unsere Seite, und Ihr Nutzer verlässt Ihre, um sie zu nutzen  | Sie möchten einen Link zum Weitergeben, oder Sie onboarden per E-Mail. Nichts zu bauen, kein Max Pack.                        |

<Note>
  **Direct Mode ist das Popup der zweiten Zeile ohne unser Skript.** Wenn Ihre Seite das Skript
  laden kann, erledigt das [Widget](/docs/multiple-users/connect-widget) alles auf dieser Seite für
  Sie — es öffnet und überwacht das Popup selbst und kann außerdem Frames einbetten. Direct Mode
  ist das Richtige, wenn Ihre Seite kein Drittanbieter-Skript laden kann oder die Oberfläche eine
  native App statt eines Browsers ist.
</Note>

<Frame caption="Ihre Schaltfläche, Ihre Seite. Das Popup ist das Einzige von uns, das Ihr Nutzer sieht, und nur so lange, wie das Netzwerk es braucht.">
  <img src="https://mintcdn.com/ayrshare-docs/-2tpx3mFy9vWIObd/images/multiple-users/connect-widget-popup.webp?fit=max&auto=format&n=-2tpx3mFy9vWIObd&q=85&s=b68021d477703d97a5994ee85d299be6" alt="Ein Kunden-Dashboard mit eigenen Connect-Schaltflächen und einem Ayrshare-Popup mit dem Facebook-Übergabebildschirm" width="2880" height="1317" data-path="images/multiple-users/connect-widget-popup.webp" />
</Frame>

## Was Sie bauen

Vier Schritte. Der erste läuft auf Ihrem Server, der Rest in Ihrer Seite.

<Steps>
  <Step title="Erstellen Sie eine Session für ein Netzwerk">
    Rufen Sie aus Ihrem Backend
    [Eine Link Session erstellen](/docs/apis/profiles/create-link-session) mit `mode: "connect"`, dem
    `network` und der `origin` auf, auf der Ihre Seite läuft.

    ```javascript Your backend theme={"system"}
    const response = await fetch("https://api.ayrshare.com/api/profiles/link-sessions", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${process.env.AYRSHARE_API_KEY}`,
        "Profile-Key": profileKey,
      },
      body: JSON.stringify({
        mode: "connect",
        network: "reddit",
        origin: "https://app.example.com",
      }),
    });

    const { url } = await response.json();
    ```

    Sie erhalten eine `url` zurück, die auf eine Connect-Seite für ein einzelnes Netzwerk zeigt,
    und kein `token` — das Token steckt in der URL. Behandeln Sie die gesamte URL wie ein
    Passwort: Sie meldet Ihren Nutzer in seinem User Profile an.

    <Warning>
      Erstellen Sie die Session auf Ihrem Server, nie im Browser. Der Aufruf benötigt Ihren API
      Key.
    </Warning>
  </Step>

  <Step title="Öffnen Sie sie im Click-Handler, synchron">
    Das Popup muss von `window.open` **im Click-Handler selbst** geöffnet werden. Ein Browser
    erlaubt ein Popup nur, solange er den Klick Ihres Nutzers noch verarbeitet, und diese
    Erlaubnis überlebt kein `await` — die URL erst zu laden und im Callback zu öffnen, wird also
    zuverlässig vom Popup-Blocker gestoppt.

    Laden Sie die URL, wenn Sie die Schaltfläche rendern, oder wenn Ihr Nutzer darüber hovert.
    Zum Zeitpunkt des Klicks sollten Sie sie bereits haben.

    ```javascript Your page theme={"system"}
    // `url` was fetched earlier. Nothing async between the click and window.open.
    button.addEventListener("click", () => {
      const popup = window.open(url, "ayrshare-connect", "width=600,height=800");
      if (!popup) {
        showError("Allow popups for this site to connect an account.");
        return;
      }
      listenForOutcome(popup, url);
    });
    ```
  </Step>

  <Step title="Warten Sie auf das Ergebnis">
    Weil Sie `origin` übergeben haben, sendet das Popup für alles, was darin passiert, ein Event an
    Ihre Seite: `connect:success`, `connect:error`, `connect:cancelled` und dazwischen
    Fortschritts-Events. Genau eines dieser drei kommt pro Verbindung an.

    [Link-Completion-Events](/docs/multiple-users/link-completion-events) enthält die vollständige
    Event-Tabelle und einen Listener zum Kopieren — `listenForOutcome` oben ist genau dieses
    Snippet. Zwei Teile davon werden leicht vergessen, und beide verursachen echte Bugs:

    * **Prüfen Sie `event.origin`** gegen die Origin der URL, die Sie geöffnet haben. Jede Seite
      kann eine Message an Ihr Fenster senden, und die Origin ist der einzige Teil einer Message,
      der nicht gefälscht werden kann.
    * **Pollen Sie `popup.closed`**, mit einem kurzen Puffer, bevor Sie einen Schluss ziehen. Ein
      von Ihrem Nutzer von Hand geschlossenes Popup sendet gar nichts, und ohne den Puffer kann
      eine erfolgreiche Verbindung als abgebrochen gemeldet werden.
  </Step>

  <Step title="Behandeln Sie jede Endung">
    | Endung              | Bedeutung                                                                                                        | Was zu tun ist                                                                                                        |
    | ------------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
    | `connect:success`   | das Konto ist verbunden **und gespeichert**                                                                      | aktualisieren Sie diese Zeile. Ein [`GET /user`](/docs/apis/user/profile-details) direkt danach zeigt es bereits.          |
    | `connect:error`     | die Verbindung ist fehlgeschlagen                                                                                | zeigen Sie `message` an. `code` ist vorhanden, wenn der Fehler einen katalogisierten Code hat, und fehlt, wenn nicht. |
    | `connect:cancelled` | Ihr Nutzer hat abgebrochen oder das Fenster geschlossen                                                          | lassen Sie die Zeile, wie sie war. `reason` ist `popupClosed`, `scopesDenied` oder `userCancelled`.                   |
    | nichts kommt an     | der Link war abgelaufen, widerrufen oder unbekannt, die Seite hat also nie erfahren, wohin Events zu senden sind | pollen Sie [Eine Link Session abrufen](/docs/apis/profiles/get-link-session), das diese Zustände verbindlich meldet.       |
  </Step>
</Steps>

<Tip>
  Hängen Sie während der Entwicklung `&autoClose=false` an die URL an. Das Popup bleibt dann nach
  jedem Ergebnis geöffnet, statt sich zu schließen, sodass Sie lesen können, was es anzeigt.
</Tip>

## Hinweise pro Netzwerk

Die meisten Netzwerke sind ein Popup und sonst nichts: Ihr Nutzer klickt, autorisiert beim
Netzwerk, und das Popup schließt sich. Dies sind die Ausnahmen, die Sie vor dem Bauen kennen
sollten.

<AccordionGroup>
  <Accordion title="X erfordert Ihre eigenen API Keys">
    X in Direct Mode verwendet **Ihre** Zugangsdaten Ihrer X Developer App, übergeben beim
    Erstellen der Session als Header `X-Twitter-OAuth1-Api-Key` und `X-Twitter-OAuth1-Api-Secret`
    auf [Eine Link Session erstellen](/docs/apis/profiles/create-link-session).

    Eine für `twitter` oder `x` **ohne** diese Header erstellte Session wird beim Öffnen des
    Popups verweigert: Ihrem Nutzer wird mitgeteilt, dass die Verbindung nicht verfügbar ist, ohne
    Formular, und Ihre Seite erhält `connect:error` mit einer `message` und **ohne `code`**. Das
    ist beabsichtigt. Die fehlenden Zugangsdaten sind Ihre, nicht die Ihres Nutzers, und Endnutzer
    dürfen nie aufgefordert werden, Ihre API Keys einzugeben.

    Anders bei Bluesky, wo das App-Passwort die eigene Zugangsinformation des Endnutzers ist —
    dieses sammelt die Connect-Seite sehr wohl ein, in einem Formular im Popup.
  </Accordion>

  <Accordion title="Facebook zeigt vor Metas Login eine Schaltfläche">
    `network: "facebook"` zeigt eine einzelne Schaltfläche im Popup, und Metas eigenes Login
    öffnet sich aus diesem Klick — Meta verlangt, dass sein Login durch einen Klick innerhalb der
    Seite gestartet wird, die sein SDK hostet. Ihr Nutzer klickt zweimal statt einmal; sonst
    ändert sich nichts.

    Instagram verhält sich genauso, wenn es **über eine Facebook-Seite** verknüpft wird — also
    wenn die Session `instagramLinkMethod: "facebook"` trägt oder die
    [Instagram-Login](/docs/multiple-users/manage-user-profiles#instagram-login)-Einstellung Ihres
    Accounts diesen Ablauf wählt. Beim direkten Instagram Login gibt es keine zusätzliche
    Schaltfläche.
  </Accordion>

  <Accordion title="Bluesky und Telegram zeigen Seiteninhalt, keine Weiterleitung">
    Keines der beiden schickt Ihren Nutzer zu einem Netzwerk-Login. Das Popup rendert stattdessen
    Inhalt: ein Handle- und App-Passwort-Formular für Bluesky und einen Code zur Verwendung für
    Telegram. Die Ergebnis-Events sind in beiden Fällen dieselben.

    X gehört nicht in diese Gruppe. Mit Ihren Keys auf der Session schließt es ab, ohne Ihren
    Nutzer nach irgendetwas zu fragen, und ohne sie wird es verweigert — siehe oben.
  </Accordion>

  <Accordion title="Telegram schließt außerhalb des Browsers ab">
    Telegram zeigt einen Code, statt irgendwohin weiterzuleiten, und die Verbindung wird
    abgeschlossen, wenn Ihr Nutzer diesen Code verwendet — nachdem das Popup weg ist. Es gibt kein
    Browser-Event, auf das gewartet werden könnte, pollen Sie also
    [Eine Link Session abrufen](/docs/apis/profiles/get-link-session) und beobachten Sie
    `completedNetworks`.
  </Accordion>

  <Accordion title="Facebook Groups lassen sich auf diesem Weg nicht verbinden">
    Facebook Groups ist kein Verknüpfungsziel, `network: "fbg"` gibt also beim Erstellen der
    Session `code: 508` zurück.

    WhatsApp **ist** in Direct Mode verfügbar. Es öffnet Metas Embedded Signup im Popup, und die
    Ergebnis-Events sind dieselben wie bei jedem anderen Netzwerk.
  </Accordion>
</AccordionGroup>

## Native Apps

Eine native App öffnet dieselbe `url`, im **Systembrowser**, und erfährt das Ergebnis durch Pollen
von [Eine Link Session abrufen](/docs/apis/profiles/get-link-session). Setzen Sie `origin` auf Ihr
eigenes Custom Scheme (`myapp://connected`), damit die Seite einen Rückweg in Ihre App hat; ein
Custom Scheme kann keine Events empfangen, weil es kein Browserfenster gibt, an das sie gesendet
werden könnten.

* **iOS** — `ASWebAuthenticationSession` oder `SFSafariViewController`.
* **Android** — Chrome Custom Tabs.

<Warning>
  **Öffnen Sie eine Linking-URL nie in einer eingebetteten WebView** (`WKWebView`, `UIWebView`,
  Android `WebView`). Die sozialen Netzwerke verweigern darin die Authentifizierung: Google lehnt
  die Anmeldung mit `disallowed_useragent` ab, und Meta blockiert sie vollständig. Ihr Nutzer sieht
  die Fehlerseite des Netzwerks, nicht unsere, und nichts, was Sie auf Ihrer Seite ändern können,
  behebt das. Die oben genannten Systembrowser-Komponenten existieren genau aus diesem Grund und
  halten den Nutzer in Ihrer App.
</Warning>

## Was Direct Mode erfordert

<ul className="custom-bullets">
  <li>
    Der **[Max Pack](/docs/additional/maxpack)**. Das Erstellen einer Connect-Mode-Session ohne ihn gibt
    `code: 504` zurück, was auch immer der Rest der Anfrage sagt.
  </li>

  <li>
    Ein **`origin`** auf jeder Session. Es gibt keine Allowlist und keinen Registrierungsschritt —
    Sie senden ihn pro Aufruf. Weglassen gibt `code: 505` zurück; ein Wert, der keine
    `https`-Origin, kein Custom Scheme und nicht `http://localhost` ist, gibt `code: 506` zurück.
  </li>

  <li>
    Ein **`network`**, das Ihr Account aktiviert hat. Ein unbekannter Name gibt `code: 508`
    zurück; ein bekannter, den Ihr Account nicht aktiviert hat, gibt `code: 509` zurück — das
    können Sie auf Ihrer Seite
    [Soziale Netzwerke](/docs/multiple-users/manage-user-profiles#set-social-networks-access) beheben.
  </li>

  <li>
    **Kein** `allowedSocial`. Es kann nicht mit `network` kombiniert werden (`code: 507`) — eine
    Session für ein einzelnes Netzwerk ist bereits ihre eigene Allowlist.
  </li>
</ul>

Jeder dieser Codes steht in der Referenz
[Link-Session-Fehler](/docs/errors/errors-ayrshare#link-session-errors), mit der Meldung, die die API
zurückgibt.

## Nächste Schritte

<Card title="Link-Completion-Events" icon="tower-broadcast" href="/docs/multiple-users/link-completion-events" horizontal>
  Jedes Event, das das Popup sendet, und der Listener, um sie zu empfangen.
</Card>

## Verwandte Themen

<Card title="Eine Link Session erstellen" icon="link" href="/docs/apis/profiles/create-link-session#connect-mode" horizontal>
  Die Parameter `mode`, `origin` und `network` sowie die Antwortformen.
</Card>

<Card title="Eine Link Session abrufen" icon="magnifying-glass" href="/docs/apis/profiles/get-link-session" horizontal>
  Pollen Sie auf Abschluss, wenn Sie kein Popup verwenden können.
</Card>
