---
title: "Eine Shopify-Sidekick-App-Erweiterung bauen: was die Doku untertreibt"
description: "Entwicklerleitfaden zu Shopify-Sidekick-App-Erweiterungen: die drei Ebenen, der Vertrag für Ressourcenlinks und Deeplinks – und die teuren Fallen."
url: "https://www.quotway.com/de/blog/building-shopify-sidekick-app-extensions"
type: "blog post"
category: "Engineering"
published: "2026-07-04"
updated: "2026-10-07"
verified: "2026-10-07"
shopify_api_version: "2026-10"
audience: "Shopify-App-Entwickler, die eine Sidekick-Erweiterung bauen"
scope: "Sidekick-App-Erweiterungen in API 2026-10: die drei Schichten, der Vertrag aus Ressourcenlink und Deep Link, das Budget je App (20 Werkzeuge, 5 Intents, 4.000 Token, 1 Sekunde für Daten und 3 für Aktionen) und das Intent-Vokabular im heutigen Stand"
locale: "de"
source: "QuotWay - B2B Quote & Negotiation App for Shopify"
---

# Eine Shopify-Sidekick-App-Erweiterung bauen: was die Doku untertreibt

**Kurzfassung:** Eine Sidekick-App-Erweiterung besteht aus drei Ebenen – einer Deklaration (`tools.json` plus eine einzeilige Zusammenfassung auf App-Ebene), einer dünnen Laufzeit, die Werkzeuge registriert und Ihr Backend aufruft, und Ihrer bestehenden API. Die Doku erklärt die Formen; sie untertreibt die betriebliche Realität. Die beiden Dinge, die uns die meiste Zeit kosteten: Sidekick leitet nur dann an Ihre Werkzeuge weiter, wenn die `extensions_summary` auf App-Ebene in ein hartes Limit passt, und ein Ergebnis wird nur dann *öffenbar*, wenn sein Deeplink ein erstklassiges `url`-Feld ist – nicht in `_meta` versteckt. Dieser Beitrag ist die Anleitung, die wir gern zuerst gelesen hätten, aus dem Ausliefern der Integration in [QuotWay](/features/shopify-sidekick), unserer B2B-Angebots-App.

## Was eine Sidekick-App-Erweiterung tatsächlich ist

Sidekick ist der KI-Assistent im Shopify-Adminbereich. Eine **App-Erweiterung** lässt Sidekick *Ihre* App aufrufen, um die Frage einer Händlerin zu beantworten – „Welche Angebote warten auf Freigabe?“ – und das Ergebnis inline darzustellen, ohne dass die Händlerin die Seite verlässt.

Es gibt zwei Arten, und die Unterscheidung zählt, bevor Sie eine Zeile Code schreiben:

| | **Datenerweiterung** | **Aktionserweiterung** |
|---|---|---|
| Ziel | `admin.app.tools.data` | `admin.app.intent.link` / `admin.app.intent.render` |
| Tut | Lesen: suchen, nachschlagen, zusammenfassen | Schreiben: eine Änderung vorbereiten, die die Händlerin bestätigt |
| Intent-Vokabular | Keines – freie Werkzeuge | **Festes** Shopify-Vokabular (E-Mail, Ticket, Bewertung, …) |
| Heute lieferbar? | Ja, für jede App | Nur, wenn ein passender Intent-`type` existiert |

> **Update, 31. August 2026.** Die unten beschriebene Einschränkung bei Aktionserweiterungen gibt es nicht mehr. Wir haben einen RFC eingereicht, und Shopify hat den Intent-Typ `application/quote` im August 2026 zur Plattform hinzugefügt – ein Angebot in einer Sidekick-Antwort ist jetzt also öffenbar. Die Fortsetzung, samt dem, was wir über Intents falsch verstanden hatten, steht in [Wir haben Shopify um einen neuen Sidekick-Intent-Typ gebeten](/blog/shopify-sidekick-intent-types). Der Rest dieses Beitrags bleibt, wie er im Juli 2026 geschrieben wurde.

Wir haben eine **Datenerweiterung** mit 15 nur lesenden Werkzeugen ausgeliefert (Angebote suchen, Pipeline-Kennzahlen, offene Freigaben, Unternehmenseinblicke und so weiter). Damals haben wir *keine* Aktionserweiterung ausgeliefert – eine Einschränkung, die man früh verstehen sollte (dazu unten mehr) und die inzwischen aufgehoben ist.

## Das Denkmodell: drei Ebenen

Fast jeder Fehler, den wir gemacht haben, kam daher, diese zu vermischen. Halten Sie sie getrennt:

**1. Deklaration (was Sidekick liest, um zu entscheiden, ob es Sie aufruft).** Zwei Dateien plus ein String auf App-Ebene:

- `shopify.app.toml` bekommt einen `[sidekick]`-Block mit einer `extensions_summary` – einer Beschreibung in normaler Sprache, *was Ihre App beantworten kann*. Das ist der **Router**. Sidekick liest ihn, um zu entscheiden, ob eine Frage überhaupt zu Ihrer App gehört.
- `tools.json` deklariert jedes Werkzeug: `name`, `description`, `inputSchema`. Die Beschreibungen sind der Weg, auf dem Sidekick auswählt, *welches* Werkzeug es aufruft.
- `instructions.md` ist eine Anleitung, die Sidekick zur Nutzung der Ergebnisse bekommt.

```toml
# shopify.app.toml
[sidekick]
extensions_summary = "QuotWay answers questions about B2B quotes: search and filter by status/buyer/company/amount, look up a quote's status and next step, list quotes pending approval, report pipeline analytics, and summarize B2B companies."
```

```toml
# extensions/sidekick-data/shopify.extension.toml
api_version = "2026-04"

[[extensions]]
name = "QuotWay quote tools"
handle = "quotway-sidekick-data"
type = "ui_extension"

  [[extensions.targeting]]
  module = "./src/index.js"
  target = "admin.app.tools.data"
  tools = "./tools.json"
  instructions = "./instructions.md"
```

**2. Laufzeit (der abgeschottete Klebstoff).** Ihr `module` läuft ohne Oberfläche in Shopifys Sandbox. Es registriert jedes deklarierte Werkzeug und ruft, wenn Sidekick eines aufruft, Ihr Backend ab und bildet die Antwort auf Sidekicks Ergebnisform ab. Halten Sie es dünn – keine Geschäftslogik hier:

```js
export default () => {
  shopify.tools.register("pending_approvals", async () => {
    const res = await fetch("/api/sidekick/quotes?status=awaiting_approval", {
      headers: { Accept: "application/json" },
    });
    const data = res.ok ? await res.json() : null;
    return { results: (data?.quotes ?? []).map(quoteLink) };
  });
};
```

**3. Backend (die echte API Ihrer App).** Die Sandbox ruft per `fetch` Ihre eigenen Endpunkte auf derselben Domain auf, und Shopify hängt das Sitzungstoken der Händlerin an – Ihre bestehende Authentifizierung, Mandantenabgrenzung und Berechtigungsprüfung gelten also unverändert. Wir haben eine kleine Familie von `/api/sidekick/*`-Routen ergänzt, die dieselbe Sitzungstoken-Authentifizierung und Rollensteuerung wiederverwenden wie der Rest der App:

```ts
export const loader = async ({ request }) =>
  withAdminShopContext(request, async ({ shopId, staff }) => {
    requirePermission(staff.role, "quote.view");
    // ...abfragen, ein schlichtes DTO formen, JSON mit CORS zurückgeben
  });
```

Die Sandbox-Aufrufe sind **ursprungsübergreifend**, jede Route beantwortet also einen CORS-Preflight (`OPTIONS → 204`) und gibt CORS-Header zurück. Shopifys Leitfaden bittet Sie, den Ursprung der Sandbox, `https://extensions.shopifycdn.com`, in Ihre CORS-Allowlist aufzunehmen; ein `Access-Control-Allow-Origin` mit Platzhalter funktioniert ebenfalls und ist hier unbedenklich, weil die Authentifizierung an einem Bearer-Sitzungstoken hängt, nicht an Cookies.

## Der Ergebnisvertrag – und das eine Feld, das Links öffnen lässt

Datenwerkzeuge geben **Ressourcenlinks** nach dem Model Context Protocol zurück:

```json
{
  "results": [
    {
      "type": "resource_link",
      "uri": "gid://application/quotway.quote/123",
      "name": "QW-1042 — Acme Co.",
      "mimeType": "application/vnd.quotway.quote",
      "_meta": { "status": "Proposal sent", "total": "USD 5,000.00" }
    }
  ]
}
```

Hier das Wichtigste, das wir gelernt haben, und es ist in der Doku kaum ein Satz: **`_meta` sind reine Anzeigedaten zur Zusammenfassung. Es ist kein Navigationsziel.** Wir hatten den Deeplink zuerst in `_meta.url` – die Karte wurde sauber dargestellt, aber ein Klick tat nichts. Sidekick hatte keine Möglichkeit, die Ressource zu *öffnen*, weil unser `uri` ein künstliches `gid://application/...` war, das es nicht auflösen kann, und die echte URL in Metadaten steckte, die es als Zierde behandelt.

Die Lösung ist ein **erstklassiges `url`-Feld** am Ergebnis, mit dem `app:`-Protokoll für eine eingebettete App:

```js
function quoteLink(q) {
  return {
    type: "resource_link",
    uri: `gid://application/quotway.quote/${q.id}`,
    name: `${q.reference} — ${q.buyerName}`,
    mimeType: "application/vnd.quotway.quote",
    url: `app://app/quotes/${q.id}`, // ← erstklassig, öffenbar
    _meta: { status: q.statusLabel, total: q.total },
  };
}
```

Shopify löst `app://<pfad>` gegen die Basis-URL Ihrer eingebetteten App auf und navigiert direkt in Ihre App – ohne Shop-Handle, ohne API-Schlüssel, ohne absolute URL zu bauen. (Ein absolutes `admin.shopify.com/store/<store>/apps/<client_id>/<pfad>` funktioniert ebenfalls, aber `app:` ist einfacher und shopunabhängig.) Mit der aus `_meta` herausgehobenen `url` liefert „Zeig mir Angebot QW-1007“ jetzt die Zusammenfassung *und* einen Link, der genau dieses Angebot in der App öffnet.

Shopifys Leitfaden zu Datenerweiterungen, erneut gelesen am 7. Oktober 2026, dokumentiert inzwischen zwei getrennte Ergebnisformen: einen Ressourcen-Link (`uri`, `name`, `mimeType`), der handlungsfähig wird, wenn sein `mimeType` zu einem registrierten Intent-Typ passt, und einen Link in die eingebettete App, der allein aus einer `url` besteht. Das kombinierte Ergebnis oben ist das, was wir ausgeliefert haben, als dieser Beitrag entstand; seit es `application/quote` gibt, ist der Intent-Weg der dokumentierte – [der Beitrag zu Intent-Typen](/blog/shopify-sidekick-intent-types) zeigt die Änderung in zwei Zeilen.

## Die Fallen (das, was uns einen Tag kostete)

| Symptom | Ursache | Lösung |
|---|---|---|
| Sidekick antwortet aus allgemeinem Wissen; **null Aufrufe erreichen Ihr Backend** | `extensions_summary` überschreitet das Limit des Deploy-Prüfers und wird still verworfen, der `[sidekick]`-Block wird also nie registriert | Halten Sie die Zusammenfassung innerhalb der durchgesetzten Größe (bei uns lag die reale Obergrenze bei **500 Zeichen**, nicht bei den „256 Token“, die die Doku nahelegt). Prüfen Sie es, indem Sie Ihre Serverprotokolle nach `/api/sidekick`-Treffern durchsehen – null Treffer heißt *nicht weitergeleitet*, kein Backend-Fehler. |
| Die Ergebniskarte erscheint, aber der Link öffnet nicht | Der Deeplink steht in `_meta`, oder `uri` ist ein nicht auflösbares `gid://application/...` | Setzen Sie eine `app://<pfad>`-URL (oder eine absolute) in ein **erstklassiges `url`**-Feld |
| „Es ist kaputt“ direkt nach dem Deployen | Die Verfügbarkeit von Sidekick-Werkzeugen ist **sitzungsbezogen und verzögert** | Versuchen Sie es in einem **brandneuen Sidekick-Chat**; schließen Sie aus einer alten Sitzung nicht auf einen Defekt |
| Backend-Werkzeugaufrufe geben in Produktion 404 oder scheitern an CORS | Sie haben die Erweiterung deployt, aber nicht die Backend-Routen (oder umgekehrt) | Deployen Sie **beides gemeinsam**: die Erweiterung per `shopify app deploy`, die Backend-Routen über Ihren Host |
| Ein Push zu Ihrem Host deployt still nicht | (Hostabhängig) etwa bricht eine Einstellung „nur verifizierte Commits“ unsignierte Pushes ab | Signieren Sie Ihre Commits, damit das Backend tatsächlich zusammen mit der Erweiterung ausgeliefert wird |
| Die CLI-Vorschau verhält sich anders als erwartet | Die Werkzeuge laufen über den echten Adminbereich | **Testen Sie im Sidekick des Adminbereichs, nicht in der CLI-Vorschau** |

Zwei davon lohnen eine Ausführung.

**Diagnostizieren Sie das Routing mit Ihren eigenen Protokollen.** Wenn Sidekick „nicht funktioniert“, ist das schnellste Signal, ob Ihr Backend überhaupt aufgerufen wurde. Wir haben die Produktionsprotokolle nach `/api/sidekick` durchsucht und **null Treffer** gesehen – was CORS, Authentifizierung und Backend-Fehler sofort ausschloss und uns auf den Router (`extensions_summary`) wies. Stille am Backend heißt, die Frage wurde nie an Ihre App geleitet.

**Die Beschreibungen sind das Produkt.** Sidekicks Routing ist eine Entscheidung eines Sprachmodells über Ihre `extensions_summary` und die `description`s Ihrer Werkzeuge. Vage Beschreibungen werden übersprungen. Laden Sie sie mit genau den Wörtern, die eine Händlerin benutzen würde („Angebote“, „RFQs“, „wartet auf Freigabe“, „Abschlussquote“, „Pipeline“) – bleiben Sie aber sachlich. Shopifys Inhaltsrichtlinie prüft diese beim Deployen *und* zur Laufzeit und verbietet Verkaufsanpreisungen, Wettbewerbsvergleiche und **Anweisungen, die Sidekicks Verhalten steuern wollen**. Wir mussten eine Zeile aus `instructions.md` löschen, die Sidekick vorschrieb, was es sagen soll; beschreiben Sie Ihre Daten, schreiben Sie dem Assistenten kein Drehbuch.

## Lesen ist heute lieferbar, Schreiben ist gesperrt

Das ist die strategische Einschränkung, um die herum Sie planen sollten. Eine **Daten**erweiterung (lesen) funktioniert für jede App schon jetzt. Eine **Aktions**erweiterung (schreiben – erstellen, bearbeiten, senden, umwandeln) bindet an ein *festes* Shopify-Intent-Vokabular, und `shopify app deploy` lehnt einen Intent-`type` ab, der nicht darin enthalten ist. Als dies geschrieben wurde, gab es keinen Typ `application/quote`, wir konnten also keine native Aktion „dieses Angebot aus Sidekick öffnen“ ausliefern. Shopify hat ihn nach unserem RFC im August 2026 hinzugefügt, und am 7. Oktober 2026 führt Shopifys Leitfaden zu App-Aktionen fünfzehn Typen – elf `application/*` (ad, campaign, email, faq, loyalty-program, optimization-plan, quote, return, review, shipment, ticket) und vier `shopify/*` (Customer, Discount, Order, Product). `application/*`-Typen unterstützen genau `create` und `edit`; `shopify/Customer`, `shopify/Order` und `shopify/Product` nehmen `import` und `import+bulk`, und `shopify/Discount`, am 30. September 2026 für Rabatt-Apps auf Basis einer Shopify Function hinzugekommen, nimmt `create` und `edit`.

Die pragmatische Brücke – von Shopify-Mitarbeitenden im Entwicklerforum bestätigt – ist das obige `url`-Feld: Sie können aus Sidekick heraus nicht *handeln*, aber Sie können ihm einen öffenbaren Deeplink geben, sodass die Händlerin genau auf der Seite landet, auf der sie handeln kann, einen Klick entfernt. Wenn Sie im selben Boot sitzen, ist der richtige Zug, einen Vorschlag für Ihren Intent-Typ in Shopifys RFC-Repository [`app-intent-types`](https://github.com/Shopify/app-intent-types) einzureichen und das Erlebnis aus Lesen und Deeplink jetzt auszuliefern. Wir haben beides getan.

## Einschränkungen, die man sich merken sollte

- **Antwortbudget:** Halten Sie jede Werkzeugantwort unter **4.000 Token**. Eine Datenerweiterung muss innerhalb von **1 Sekunde** antworten, eine Aktion bekommt **3 Sekunden**. Das sind lesende Werkzeuge, die eine Chatrunde beantworten – geben Sie zurück, was gefragt wurde, nicht Ihren gesamten Objektgraphen.
- **Budget je App: 20 Werkzeuge über alle Erweiterungen hinweg und 5 Intents.** Das ist das gesamte Kontingent, und die Werkzeuge gehen zuerst aus – eine reiche Datenerweiterung plus ein paar Werkzeuge zum Vorbereiten von Aktionen bringt Sie in die hohen Zehner. Modellieren Sie sie um echte Händlerfragen herum, nicht um Ihre Datenbanktabellen, und planen Sie die Werkzeuge vor den Intents.
- **Authentifizierung ist gratis:** Die Sandbox nutzt die Sitzung Ihrer App wieder, stützen Sie sich also auf Ihre bestehende Mandantenabgrenzung und Berechtigungsprüfung. Ein lesendes Werkzeug sollte genauso abgesichert sein wie die Seite, die es spiegelt.

## Ein vernünftiger erster Meilenstein

1. Eine Datenerweiterung mit **zwei Werkzeugen**, die echten Fragen entsprechen („X suchen“, „ein X nachschlagen“).
2. Eine `[sidekick] extensions_summary` innerhalb des Größenlimits, dazu schlagwortreiche, sachliche Werkzeugbeschreibungen.
3. Dünner Sandbox-Klebstoff, der zwei `/api/*`-Endpunkte per `fetch` aufruft und Ihre bestehende Authentifizierung samt CORS-Preflight wiederverwendet.
4. Eine erstklassige `url` an jedem Ergebnis, sodass es die richtige Seite in der App öffnet.
5. Deployen Sie Erweiterung **und** Backend gemeinsam; testen Sie im **echten Adminbereich** in einem frischen Chat.

Das ist ein Tag Arbeit für eine wirklich nützliche Integration – der größte Teil davon ist die Wiederverwendung der API, die Sie ohnehin haben. Der schwierige Teil ist nicht der Code, sondern die drei, vier betrieblichen Tatsachen oben.

Wenn Sie Händler statt Entwickler sind: Die hier beschriebene Erweiterung steckt in QuotWay als [Shopify Sidekick für B2B-Angebote](/features/shopify-sidekick), in jedem Tarif – siehe [Tarife und Preise](/pricing).

## Weiterführendes

Am 7. Oktober 2026 erneut gegen Shopifys Seiten geprüft (die Budgets oben stammen von der ersten, das Vokabular aus dem Leitfaden zu App-Aktionen):

- Shopify: [Sidekick-App-Erweiterungen](https://shopify.dev/docs/apps/build/sidekick) und [App-Daten bereitstellen](https://shopify.dev/docs/apps/build/sidekick/build-app-data)
- Shopify: [App-Aktionen für Sidekick bauen](https://shopify.dev/docs/apps/build/sidekick/build-app-actions) (die unterstützten Intent-Typen und die zwei Intent-Targets)
- Shopify: das RFC-Repository [`app-intent-types`](https://github.com/Shopify/app-intent-types) (schlagen Sie Ihren Aktions-Intent-Typ vor)
- Der händlerseitige Begleitbeitrag: [Shopify Sidekick für Ihre B2B-Angebote nutzen](/blog/shopify-sidekick-b2b-quotes)
