1. Warum wir Vercel für die ChatGPT App nutzen
In den vorherigen Vorlesungen haben wir GiftGenius lokal gestartet und über den Dev Mode und einen Tunnel mit ChatGPT verbunden. Jetzt ist es Zeit für den nächsten Schritt in Richtung echten Produktivbetriebs und wir bringen denselben Code auf Vercel.
An diesem Punkt haben Sie bereits eine funktionierende Anwendung GiftGenius (unsere Lern‑App). Lokal läuft sie auf Next.js 16 mit einem MCP‑Endpoint (zum Beispiel /api/mcp) und basiert auf dem offiziellen ChatGPT Apps SDK Next.js Starter.
Man könnte den Weg gehen: „Ich miete mir einen VPS, installiere Node und Nginx von Hand und konfiguriere alles selbst“, aber bei Next.js ist das ungefähr so, als würde man 2025 Frontend mit purem document.write schreiben. Es funktioniert, aber Sie machen sich das Leben unnötig schwer.
Vercel ist aus mehreren Gründen gut geeignet.
Erstens versteht Vercel Next.js nativ: Build, SSR, Static Assets, Edge‑Schicht und Serverless‑Funktionen werden automatisch eingerichtet. Für eine ChatGPT App ist das besonders praktisch, weil Widget und MCP‑Endpoint mit einem Klick ausgerollt werden und in derselben Infrastruktur leben.
Zweitens liefert Vercel CI/CD out of the box: Sie verbinden ein Git‑Repository — und jeder Push erzeugt ein neues immutable Deployment mit einer einzigartigen URL. Aus dem Branch main gilt es als Production, aus anderen Branches als Preview.
Drittens hat Vercel eine angenehme Geschichte bei Umgebungen und Secrets. Env‑Variablen sind klar getrennt in Development, Preview und Production, werden verschlüsselt gespeichert und lassen sich bequem in Next.js injizieren. Genau das, was eine ChatGPT App braucht, wo Keys und die URL des MCP‑Servers je Umgebung variieren.
Viertens bietet Vercel komfortable Rollbacks: Wenn ein neuer Release schiefgeht, können Sie schnell den vorherigen erfolgreichen Deploy promoten und das System wieder in einen stabilen Zustand versetzen. Das senkt die „Deployment‑Angst“ und fördert kleine, häufige Releases.
Und schließlich ist Vercel das Unternehmen hinter Next.js. Sie haben Next.js auf ihre Server zugeschnitten und ihre Server auf Next.js. Mit Vercel werden Sie noch oft spüren, wie reibungslos alles in ein paar Klicks funktioniert. Ich garantiere, es wird Ihnen gefallen.
2. Ausgangspunkt: Projektstruktur von GiftGenius
Laut Kursplan lebt unser GiftGenius in einem Repository. Es gibt zwei Organisationsvarianten, beide sind für Vercel geeignet:
1) Monorepo mit mehreren Anwendungen — zum Beispiel:
giftgenius/
apps/
web/ # Next.js (Widget + MCP)
mcp/ # separater MCP-Server (falls ausgelagert)
2) Ein einziges Next.js‑Projekt, in dem sowohl das Widget als auch MCP zusammen leben (das ist anfangs einfacher und genau so ist der offizielle Starter aufgebaut):
giftgenius/
app/
page.tsx # Widget
api/
mcp/route.ts # MCP Endpoint
next.config.mjs
package.json
...
Im Modul 2 haben Sie bereits den Apps SDK Starter geklont, Dependencies installiert und npm run dev gestartet. Wir gehen jetzt davon aus, dass:
- das Projekt bereits in Git liegt (GitHub / GitLab / Bitbucket);
- Sie lokal .env.local mit Keys verwenden (OPENAI_API_KEY u.a.);
- der ChatGPT Dev Mode mit Ihrem Tunnel verbunden ist.
Unser Ziel: derselbe Code soll auf Vercel bauen und laufen, und ChatGPT soll nicht mehr über den Tunnel gehen, sondern über eine stabile HTTPS‑Domain wie https://giftgenius.vercel.app.
3. Repository für das Deployment vorbereiten
Bevor Sie in Vercel auf „New Project“ klicken, bringen Sie das Repository kurz in Ordnung. Einfache Schritte, die später viel Zeit sparen.
Erstens: Stellen Sie sicher, dass .env.local und .vercel nicht ins Repository gelangen. Im .gitignore des Next.js Starters ist das in der Regel schon enthalten, aber prüfen Sie es besser nach:
node_modules
.next
.env.local
.vercel
.env.local ist Ihre lokale Konfiguration und Ihre Secrets. Diese Datei hat in Git nichts verloren, insbesondere wenn dort OPENAI_API_KEY oder Datenbank‑Keys liegen. Auf Vercel speichern wir Secrets separat im UI.
Zweitens: Werfen Sie einen Blick auf package.json. Für Vercel sind korrekte scripts wichtig:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
Vercel ruft standardmäßig npm run build auf (oder pnpm build, wenn Sie pnpm verwenden). Das muss Ihr Projekt fehlerfrei bauen.
Drittens: Stellen Sie sicher, dass die Node‑Version angegeben ist und zu Next.js 16 passt. Laut Release Notes von Next.js 16 ist die minimale Version 18.18.0. Meist genügt ein Feld in der package.json:
{
"engines": {
"node": ">=18.18.0"
}
}
Vercel wählt eine LTS‑Version von Node, die zu Ihrer App kompatibel ist.
Wenn das alles erledigt ist, pushen Sie den aktuellen Code in Git und wechseln zu Vercel.
4. Erster Import des Projekts in Vercel
Wechseln Sie jetzt ins Vercel‑Webinterface. Falls Sie dort noch keinen Account haben — jetzt ist der richtige Zeitpunkt.
Sie loggen sich bei Vercel ein, klicken „New Project“ und wählen in der Liste Ihr Repository giftgenius aus. Vercel prüft unter der Haube den Inhalt des Repos und erkennt fast immer selbst, dass es ein Next.js‑Projekt ist, und setzt das passende Preset.
In den Projekteinstellungen schlägt Vercel vor:
- Framework = Next.js;
- Build Command = npm run build (oder pnpm build/yarn build);
- Output Directory — standardmäßig .next (muss nicht geändert werden).
Für das erste Deployment können Sie Env‑Variablen zunächst weglassen (wir fügen sie im nächsten Schritt hinzu). Klicken Sie „Deploy“ — Vercel klont das Repo, installiert Dependencies, startet npm run build und erstellt bei Erfolg einen ersten Deploy mit einer Adresse wie https://giftgenius-xyz.vercel.app.
Wichtig: Jeder Deploy ist immutable. Wenn Sie später Änderungen pushen, entsteht ein neuer Deploy mit neuer URL, der alte bleibt in der Historie. Die Produktions‑Domain (zum Beispiel giftgenius.vercel.app oder Ihre eigene Domain) zeigt auf einen konkreten Deploy und kann für einen Rollback wieder auf einen früheren umgeschaltet werden.
Schematisch sieht das so aus:
flowchart LR
A[GitHub-Repository
giftgenius] -->|git push| B[Vercel Build]
B --> C[Preview‑Deploy #1
eindeutige URL]
B --> D[Preview‑Deploy #2
eindeutige URL]
D --> E[Production‑Alias
giftgenius.vercel.app]
Der Git‑Branch main gilt üblicherweise als Produktions‑Branch, alles andere als Preview. Das lässt sich aber anpassen.
5. Umgebungsvariablen in Vercel
Ihr erster Deploy ist jetzt wahrscheinlich nicht besonders funktionsfähig: Es gibt keinen OPENAI_API_KEY, der MCP‑Server erreicht keine externen APIs usw. Zeit für die Env‑Variablen.
In Vercel werden Env‑Variablen unter Settings → Environment Variables verwaltet. Dort sieht man auch die Trennung in die drei Scopes: Development, Preview und Production.
Gedankliche Zuordnung in einer Tabelle:
| Scope | Wo verwendet | Lokales Pendant |
|---|---|---|
| Development | vercel dev und lokales Dev über die Vercel CLI | .env.local |
| Preview | alle Deployments aus Branches außer dem Produktions‑Branch | Staging / Test |
| Production | Deployments aus dem Produktions‑Branch (meist main) | „produktive“ .env.prod |
Im Unterschied zur lokalen .env.local speichert Vercel die Werte verschlüsselt und stellt sie Ihrem Next.js‑Code automatisch als process.env.MY_VAR bereit.
Sehr wichtig ist der Präfix NEXT_PUBLIC_. Alles, was mit NEXT_PUBLIC_ beginnt, landet im Browser‑Bundle und ist für jeden Nutzer sichtbar (über die DevTools einsehbar). Das ist gut für öffentliche Konfiguration (NEXT_PUBLIC_ENV=preview, NEXT_PUBLIC_API_BASE_URL=https://giftgenius.vercel.app), aber strikt ungeeignet für Keys wie OPENAI_API_KEY.
Für Secrets verwenden wir Namen ohne NEXT_PUBLIC_ und lesen sie ausschließlich auf der Serverseite: in Route‑Handlern, MCP‑Tools usw.
6. Env‑Konfiguration für GiftGenius: Beispiel
Schauen wir, welche Env‑Variablen unsere Lern‑App GiftGenius braucht.
Ein minimales Set könnte so aussehen:
- OPENAI_API_KEY — Schlüssel für Modellaufrufe / MCP‑Client;
- APP_BASE_URL — Basis‑URL der App (https://giftgenius.vercel.app oder Preview‑URL);
- ggf. GIFTDATA_API_URL oder PRODUCTS_API_URL, falls Sie einen externen Katalog haben.
In der lokalen Entwicklung liegt das in .env.local:
OPENAI_API_KEY=sk-local-...
APP_BASE_URL=http://localhost:3000
PRODUCTS_API_URL=https://dev-api.gifts.example.com
Auf Vercel gehen Sie zu Settings → Environment Variables und fügen dieselben Keys und Werte hinzu — allerdings im jeweils passenden Scope.
Ein Beispiel, wie das im Code des MCP‑Endpoints aussieht:
// app/api/mcp/route.ts
import { NextRequest } from 'next/server';
const apiKey = process.env.OPENAI_API_KEY!; // In echtem Code nicht ohne Checks machen :)
export async function POST(req: NextRequest) {
if (!apiKey) {
return new Response('Missing OPENAI_API_KEY', { status: 500 });
}
// Aufruf von OpenAI oder eines anderen Dienstes mit apiKey...
}
Das Widget kann APP_BASE_URL auf der Serverseite nutzen, z. B. um absolute Links zu bauen — unter Berücksichtigung des ChatGPT‑iframes und der Konfiguration assetPrefix/basePath aus dem Starter‑Template.
Wenn es eine öffentliche API‑URL braucht (z. B. für window.fetch zu Ihrem Backend), können Sie dafür NEXT_PUBLIC_API_BASE_URL verwenden. Aber niemals NEXT_PUBLIC_OPENAI_API_KEY.
7. Preview‑Deploys: Staging auf Steroiden
Jetzt zum Angenehmsten: den Preview‑Deploys. Sobald Sie das Git‑Repository verbunden haben, erzeugt Vercel automatisch für jeden Push in einen Nicht‑Produktion‑Branch bzw. für jeden Pull Request einen Preview‑Deploy. Jeder dieser Deploys hat eine eindeutige URL, etwa:
https://giftgenius-git-feature-new-layout-username.vercel.app
Diese Deploys verwenden den Scope Preview für Env‑Variablen, sodass Sie zum Beispiel setzen können:
# Preview‑Env in Vercel
APP_BASE_URL=https://giftgenius-staging.vercel.app
PRODUCTS_API_URL=https://staging-api.gifts.example.com
— und das nicht mit Production verwechseln.
Aus Sicht des ChatGPT Dev Mode ist die Preview‑URL ein idealer Staging‑Kandidat. In den Einstellungen Ihrer Dev‑App können Sie den Endpoint vorübergehend vom Tunnel auf die Preview‑URL umstellen und sehen, wie sich die bereits gebaute Version von GiftGenius verhält — aber noch nicht der Production‑Deploy.
Ein häufiges Vorgehen: Für ein Feature erstellen Sie den Branch feature/smart-recommendations, pushen Änderungen — Vercel liefert eine Preview‑URL. Sie gehen in den Dev Mode, ändern die URL auf diese Adresse, prüfen die Szenarien mit GPT (Geschenke‑Empfehlung, Kartenanzeige, Aufrufe von MCP‑Tools). Erst wenn alles passt, mergen Sie in main. Production läuft derweil ruhig weiter.
Mentales Pipeline‑Schema:
flowchart TD
A[Lokale Entwicklung
localhost + Tunnel] --> B[git push
feature/*]
B --> C[Preview‑Deploy
Preview‑URL]
C --> D[ChatGPT Dev Mode
App → Preview‑URL]
C --> E[Code‑Review / Tests]
E --> F[Merge in main]
F --> G[Production‑Deploy
Prod‑URL]
G --> H[ChatGPT Prod App
App → Prod‑URL]
8. Production‑Deploy und Rollback
Wenn Sie in main (oder einen anderen von Ihnen gewählten Produktions‑Branch) mergen, erstellt Vercel einen Production‑Deploy und hängt den Production‑Alias daran: giftgenius.vercel.app oder Ihre eigene Domain.
Zu diesem Zeitpunkt sollte die ChatGPT Prod‑App (die Sie gleich erstellen) auf die Production‑URL konfiguriert sein. Im Dev Mode experimentieren Sie weiter mit Tunnel oder Preview‑URL; reguläre Nutzer im ChatGPT Store greifen auf Production zu.
Der Vorteil der immutable Deploys: Rollback ist sehr einfach. Wenn der neue Release missglückt (z. B. stürzt ein MCP‑Tool mit Live‑Daten ab), müssen Sie nicht in Eile „auf Prod“ reparieren. Öffnen Sie die Deploy‑Liste in Vercel, wählen Sie den letzten stabilen aus und klicken sinngemäß „Promote to Production“ — irgendwo weit weg schalten K8s und Lambda um, und Ihre Domain zeigt wieder auf die stabile Version.
Auch per CLI lässt sich das mit vercel rollback automatisieren, aber für unseren Kurs genügt die Idee: Jeder Deploy ist ein eigenständiges Artefakt, und den Production‑Alias können Sie auf jeden davon richten.
9. Besonderheiten von Next.js 16 + MCP auf Vercel
Aus Sicht von Vercel ist Ihr MCP‑Endpoint in Next.js eine Serverless‑Funktion (oder Edge‑Funktion, falls so konfiguriert). Sie lebt nur kurz: wacht beim Request auf, verarbeitet ihn und beendet sich. Zwischen Aufrufen lässt sich kein Zustand halten, es sei denn, Sie nutzen eine externe Datenbank oder ein Storage.
Das ist für MCP kritisch: Wenn Sie z. B. die Dialoghistorie in ein globales Array let history = [] in route.ts legen, wird es bei jedem Kaltstart zurückgesetzt. Für Zustand brauchen Sie ein externes System (KV, Postgres usw.) — das behandeln wir in späteren Modulen.
Der zweite Aspekt sind Ausführungs‑Timeouts. In kostenlosen Plänen haben Vercel‑Serverless‑Funktionen eine Laufzeitbegrenzung (zum Zeitpunkt der Erstellung dieser Unterlagen etwa 10 Sekunden im Hobby‑Plan, mehr im Pro‑Plan). Für LLM‑Requests und insbesondere für Ketten von MCP‑Tools kann das knapp sein.
In Next.js 16 können Sie für Route‑Handler maxDuration setzen, um Vercel explizit um mehr Zeit zu bitten (im Rahmen des Plans):
// app/api/mcp/route.ts
export const maxDuration = 60; // Sekunden; im Pro‑Plan bis zu 300
export async function POST(req: Request) {
// lang andauernde Operation: Request an OpenAI, externe DB usw.
}
Das ist kein magischer „unendlich laufen“-Schalter, aber der korrekte Weg, Vercel wissen zu lassen: „Diese Funktion kann länger laufen, bitte nicht zu früh beenden.“
Denken Sie außerdem an die Besonderheiten des ChatGPT‑iframes. Im Apps SDK Starter sind assetPrefix und basePath bereits so konfiguriert, dass Static Assets und Routen in den verschachtelten iframes von web-sandbox.oaiusercontent.com korrekt funktionieren. Dadurch gehen alle Requests an Ihre Domain, nicht an die Sandbox. Beim Deployment auf Vercel bleibt diese Konfiguration bestehen, sodass das Widget „out of the box“ korrekt funktioniert.
10. Integration mit ChatGPT nach dem Deployment
Auch wenn das eher in die Module zu Store und Produktion gehört, ist die Integrationslogik mit ChatGPT nach dem Deployment recht einfach und passt gut schon jetzt.
Zuerst deployen Sie GiftGenius auf Vercel und erhalten die Production‑URL. Dann erstellen Sie in ChatGPT im Dev Mode eine separate App, zum Beispiel GiftGenius Prod, und tragen in deren Einstellungen als Endpoint diese URL ein (konkret den MCP‑Endpoint wie https://giftgenius.vercel.app/api/mcp gemäß dem OpenAI Apps SDK Deploy Guide).
Für die Entwicklung verwenden Sie weiterhin die Dev App, die auf den Tunnel oder die Preview‑URL zeigt. Für Tages‑/Wochen‑Builds können Sie eine Staging‑App anlegen und sie an einen stabilen Preview‑Alias binden. Daraus ergibt sich ein dreistufiges Schema:
Dev App → lokaler Tunnel oder Dev‑URL (instabil)
Staging App → stabile Preview/Staging‑URL auf Vercel
Prod App → Production‑URL auf Vercel
Zur Orientierung fassen wir alles in einer Tabelle zusammen:
| Was | URL / Deployment auf Vercel | Scope in Vercel | Wer greift zu |
|---|---|---|---|
| Dev App | lokaler Tunnel / vercel dev | Development | Sie / Team |
| Staging App | stabiler Preview‑Alias | Preview | Team / QA |
| Prod App | giftgenius.vercel.app / eigene Domain | Production | Nutzer |
Das ist dasselbe Local/Staging/Prod‑Modell, über das wir zu Beginn des Moduls gesprochen haben — jetzt mit Bezug zu Vercel und ChatGPT Apps. Das ist die Architektur eines erwachsenen Projekts, nicht der ewige localhost.
11. Häufige Fehler beim Deployment auf Vercel
Fehler Nr. 1: Secrets existieren nur in .env.local, auf Vercel fehlen sie.
Sehr häufig: Lokal funktioniert alles, Sie klicken selbstbewusst „Deploy“, die App baut, aber die MCP‑Tools liefern in Production 500 mit „Missing OPENAI_API_KEY“. Der Grund ist einfach: Vercel kennt Ihre lokale .env.local nicht. Sie müssen die Variablen separat in den Projekteinstellungen auf Vercel anlegen (und im richtigen Scope: Preview, Production).
Fehler Nr. 2: Verwendung von NEXT_PUBLIC_ für sensible Daten.
Der Wunsch „Hauptsache es funktioniert“ verleitet manchmal dazu, NEXT_PUBLIC_OPENAI_API_KEY zu setzen, um im Client‑Code Zugriff auf den Key zu haben. Ergebnis: Der Key landet im JS‑Bundle und ist für jeden Nutzer sichtbar. Das ist nicht nur schlechte Praxis, sondern ein direkter Weg zu Leaks und Key‑Sperrungen. Alle Secrets — nur ohne Präfix und ausschließlich auf der Serverseite.
Fehler Nr. 3: Inkonsistente Umgebungen zwischen Lokal und Vercel.
Lokal haben Sie vielleicht eine URL für Produkte (http://localhost:4000), auf Vercel eine andere (https://api.gifts-staging.com) und in Production eine dritte. Wenn Sie keine saubere Liste der Env‑Variablen pflegen und nicht prüfen, dass sie in Preview/Production korrekt gesetzt sind, passiert es leicht, dass das Production‑Widget auf das Staging‑Backend zeigt und das Staging‑Widget auf Prod. Disziplin hilft: Alle nötigen Variablen dokumentieren und in jeder Umgebung prüfen.
Fehler Nr. 4: Ignorieren der Laufzeitlimits für MCP‑Endpoints.
Lokal können Sie auf die Antwort eines langsamen externen Systems 30 Sekunden warten, ohne Probleme zu bemerken. Auf Vercel bekommt dieselbe Funktion nach 10–15 Sekunden ein Timeout, und ChatGPT sieht einen Fehler. Wenn Sie maxDuration nicht konfigurieren und die Laufzeit der MCP‑Tools nicht im Blick behalten, führt das in Production zu sporadischen Ausfällen.
Fehler Nr. 5: Versuch, MCP‑Zustand im Speicher der Serverless‑Funktion zu halten.
Manchmal ist die Versuchung groß, die Dialoghistorie oder einen Empfehlungscache in eine globale Variable let cache = {} direkt im Route‑Handler zu legen. Lokal, solange der Dev‑Server lange läuft, kann das sogar „funktionieren“. Auf Vercel lebt jede Serverless‑Funktion nur kurz und wird oft neu erstellt. Dadurch „sehen“ manche Requests einen alten Cache, andere einen neuen und wieder andere einen leeren. Das erzeugt schwer reproduzierbare Bugs. Für Zustand braucht es eine externe DB oder ein KV‑Store; auf dem Niveau dieser Vorlesung sollten Sie den MCP‑Endpoint als stateless betrachten.
GO TO FULL VERSION