Wie man eine Kalender-App erstellt - Ein umfassender Leitfaden
Veröffentlicht am
Dieser Artikel ist für Sie, wenn Sie als Entwickler einen Kalender in Ihre Anwendung integrieren sollen, oder wenn Sie als Gründer darüber nachdenken, eine Kalender-App oder ein Produkt mit Kalender-Integrationen zu bauen.
Wir gehen gemeinsam durch, wie man eine Kalender-App entwickelt: Entscheidungen Schritt für Schritt treffen, die passenden Technologien auswählen und die wichtigsten Herausforderungen und Best Practices verstehen.
Was ist der Umfang dieses Artikels?
Das Ziel dieses Artikels ist es, Ihnen beim Bau einer vollständigen Kalender-App zu helfen, oder dabei, Kalenderanbieter in eine bestehende Anwendung zu integrieren, sodass Ihre Nutzer ihre Kalender verbinden und über Ihr Produkt verwalten können.
Der Artikel ist auch dann nützlich, wenn Sie Kalenderanbieter anbinden möchten, ohne überhaupt eine Kalenderoberfläche anzuzeigen. Beispiele sind eine Aufgaben-App, eine Dating-App oder ein Feature, das einfach ein Ereignis in den Kalender eines Nutzers einträgt.
Sie können gerne einzelne Teile dieses Artikels in Ihrem eigenen Code verwenden, inklusive der Technologieentscheidungen, des Unified-API-Ansatzes oder einzelner Code-Ausschnitte.
Überblick über Architektur & Tech-Stack
Als Plattform für dieses Beispiel haben wir das Web gewählt, weil es am schnellsten in Betrieb zu nehmen ist und es viel Community-Support für Kalender-Bibliotheken gibt.
Die Programmiersprache ist TypeScript, das Web-Framework ist Next.js.
Hier ist ein Überblick über den Tech-Stack, den wir verwenden:
- Frontend : Next.js (App Router, TypeScript)
- Backend : Next.js API Routes + tRPC
- Datenbank : PostgreSQL (mit
Prismaals ORM) - Kalender-APIs : Apiroc Unified Calendar API
- Hosting : Anbieterunabhängig, z. B. Vercel oder wo auch immer Sie sich wohlfühlen
- Authentifizierung : OAuth2 (Google, Microsoft) über
better-auth
Unten sehen Sie das Architekturdiagramm, das zeigt, wie die Teile des Tech-Stacks zusammenspielen:
Definitionen:
- Client (1) : Das Endgerät des Nutzers. Die Illustration zeigt ein Mobilgerät, es kann aber auch ein Desktop oder Laptop sein (jedes Gerät mit einem Webbrowser wie Google Chrome). Der Client rendert das Next.js-Frontend, verarbeitet Nutzerinteraktionen und kommuniziert über sichere HTTPS-Anfragen mit dem Backend.
- Webserver (2) : Der Webserver hostet und liefert die Benutzeroberfläche, eine Next.js-(App Router)-Webanwendung. Er stellt optimiertes HTML, CSS und JavaScript bereit und ermöglicht Server-Side Rendering (SSR) sowie Incremental Static Regeneration (ISR) für schnelle Performance und SEO-Vorteile.
- Next.js API (3) : Die Next.js API ist die Backend-Schicht, implementiert mit API Routes und tRPC in derselben Next.js-Anwendung. Sie ist der zentrale Knoten, der Frontend, Datenbank und externe Integrationen wie die Apiroc Unified Calendar API verbindet. Anders als klassische REST-Endpoints bietet tRPC typsichere Ende-zu-Ende-Kommunikation zwischen Frontend und Backend, ohne ein separates API-Schema. Der Client kann Backend-Prozeduren direkt aufrufen, mit vollständiger TypeScript-Typinferenz. Das beschleunigt die Entwicklung und reduziert Laufzeitfehler.
- PostgreSQL (4) : Die PostgreSQL-Datenbank speichert alle persistenten Anwendungsdaten, darunter Nutzer, Sessions, verbundene Kalenderkonten usw. Sie ist das maßgebliche System für alle nutzerbezogenen Daten und Synchronisationszustände. Mit Prisma als ORM-Schicht wird das Schema sauber auf die Datenbank abgebildet, was Migrationen und Abfragen vereinfacht.
- Apiroc Unified Calendar API (5) : Apiroc ist die API, über die wir alle Kalenderanbieter mit einer standardisierten Schnittstelle anbinden. Dadurch müssen wir keine eigene Implementierung pro Anbieter schreiben, keine unterschiedlichen Datenformate behandeln, keine mehreren Integrationen pflegen und nicht auf API-Änderungen der Anbieter reagieren. Unsere API ruft Apiroc mit dem API-Schlüssel und den Kalendern auf, mit denen wir arbeiten möchten (CRUD von Events, Kalendern und mehr), unabhängig vom Anbieter. Apiroc kommuniziert dann mit den Kalenderanbietern und liefert die Antwort für jeden Anbieter im selben standardisierten Format.

Beachten Sie, dass der Webserver (2) und die Next.js API (3) auf demselben Server laufen können (z. B. via Vercel, Docker etc.). Im Diagramm sind sie nur getrennt dargestellt, um zu verdeutlichen, dass es einen UI-Server und einen API-Server gibt, auch wenn beide im selben Next.js-Codebestand leben und in der Regel zusammen gehostet werden.
Das Datenmodell entwerfen
Nachdem Architektur und Tech-Stack klar sind, definieren wir das Datenmodell. Als ORM verwenden wir Prisma.
Dieses Prisma-Schema definiert die Datenstruktur für eine grundlegende Kalender-Anwendung, die Nutzer-Authentifizierung, verbundene Kalenderkonten (Google, Microsoft) und Ereignis-Synchronisation über eine Unified API unterstützt.
Die wichtigsten Modelle sind:
1. User
Repräsentiert einen Endnutzer der App. Jeder Nutzer kann mehrere Sessions, verbundene Konten (OAuth) und Kalenderkonten haben. Felder wie email, name und onboardingCompletedAt helfen, Profil- und Onboarding-Status nachzuverfolgen.
2. CalendarAccount
Repräsentiert ein verknüpftes externes Kalenderkonto (z. B. ein Google- oder Microsoft-Konto). Es speichert provider, email und status (aktiv oder abgelaufen). Jedes CalendarAccount gehört zu genau einem User und kann mehrere Calendar-Einträge enthalten.
3. Calendar
Repräsentiert einen einzelnen Kalender (z. B. „Arbeit“, „Privat“ oder „Familie“) innerhalb eines verknüpften Kontos. Enthält Anzeige-Felder wie name, color, timezone sowie Flags wie isPrimary oder isReadOnly. Jeder Kalender ist sowohl einem User als auch dem zugehörigen CalendarAccount zugeordnet.
4. Account
Verwaltet Daten zu OAuth-Anbietern (Google oder Microsoft). Speichert Access- und Refresh-Tokens, Ablaufzeiten und Scope-Informationen für Authentifizierung und Kalendersynchronisation.
5. Session
Verfolgt aktive Login-Sitzungen der Nutzer. Enthält Felder wie token, expiresAt, ipAddress und userAgent, um aktive Sitzungen zu verwalten und abzusichern.
6. Verification
Wird für einmalige Verifizierungen genutzt, z. B. E-Mail-Login per Magic Link oder Codes für passwortlose Anmeldung. Speichert temporäre Kennungen und Ablaufzeiten.
7. Enums
CalendarAccountProvider: Unterstützte Anbieter (GOOGLE,MICROSOFT)CalendarAccountStatus: Verfolgt, ob ein verbundenes KontoACTIVEoderEXPIREDist
Das ER-Diagramm der Datenbank:
Öffnen Sie die schema.prisma-Datei im Beispiel-Repository, um das vollständige Datenbankschema einschließlich Typen und Beziehungen zu sehen.
Das Backend bauen
Wie erwähnt, verwenden wir Next.js API Routes für die API. Es ist sehr praktisch, UI und API im selben Codebestand und auf demselben Server zu haben, weil Sie beides gleichzeitig ausführen können.
Die Authentifizierung aufbauen
Wir verwenden better-auth als Authentifizierungs-Framework. Better Auth macht Authentifizierung einfach und unkompliziert. Folgen Sie der Better-Auth-Anleitung zur Integration von Better Auth mit Next.js; die Schritte sind nahezu identisch. Sie können auch die Auth-Datei im Beispiel-Repository ansehen.
Die Apiroc Unified Calendar API einrichten, um mit allen Kalenderanbietern zu kommunizieren
Der größte Schmerzpunkt beim Bau einer Kalender-App oder bei der Integration von Kalendern in ein bestehendes Produkt ist der Umgang mit anbieterspezifischen APIs. Das kostet viel Zeit: Man muss jede API separat erlernen und unterschiedliche Datenstrukturen, Requests und Responses handhaben. Außerdem muss man für jeden Anbieter eine eigene Integration bauen und nach der Entwicklung alle pflegen.
Eine gute Lösung für dieses Problem ist eine Unified-Kalender-API, mit der wir alle Kalenderanbieter über eine standardisierte API anbinden. In diesem Beispiel verwenden wir die Apiroc Unified Calendar API.
So starten Sie mit Apiroc:
- Zuerst bei Apiroc registrieren und ein kostenloses Konto anlegen.
- Nach der Registrierung aktivieren Sie die Kalenderanbieter, die Sie integrieren möchten. Wir empfehlen, Google Calendar und Outlook zu aktivieren, damit Sie den Vorteil einer Unified-Kalender-API sehen. Für Sandbox und Entwicklung müssen Sie keinen eigenen Google- oder Microsoft-Client anlegen. Sie können die Google- und Microsoft-Clients von Apiroc verwenden, um Google-Calendar- oder Outlook-Konten mit Ihrer Anwendung zu verbinden.
- Erstellen Sie einen API-Schlüssel und speichern Sie ihn in der Umgebungsvariable
APIROC_API_KEY.
Den Apiroc API-Client bauen
Nachdem Apiroc eingerichtet und der API-Schlüssel erstellt ist, bauen wir den API-Client, der mit der Apiroc Unified Calendar API kommuniziert:
import { env } from "@/env";
import type {
EndUserAccount,
PaginatedResponse,
UnifiedCalendar,
UnifiedEvent as UniversalEvent,
} from "@/server/lib/apiroc/types";
import ky from "ky";
export const apirocApi = ky.create({
prefixUrl: env.NEXT_PUBLIC_APIROC_URL,
headers: {
"x-api-key": env.APIROC_API_KEY,
},
});
export async function getEndUserAccountById(id: string) {
const response = await apirocApi.get<EndUserAccount>(
`endUserAccounts/${id}`,
);
return response.json();
}
export async function getCalendarsForEndUserAccount(endUserAccountId: string) {
const response = await apirocApi.get<
PaginatedResponse<UnifiedCalendar>
>(`calendars/${endUserAccountId}`);
return response.json();
}
interface GetCalendarEventsParams {
pageToken?: string;
pageSize?: number;
syncToken?: string;
startDateTime?: string;
endDateTime?: string;
timeZone?: string;
expandRecurrences?: boolean;
}
export async function getCalendarEvents(
endUserAccountId: string,
calendarId: string,
params: GetCalendarEventsParams = {},
) {
const queryParams = new URLSearchParams(params as Record<string, string>);
const response = await apirocApi.get<
PaginatedResponse<UniversalEvent>
>(`events/${endUserAccountId}/${calendarId}?${queryParams}`);
return response.json();
}
export async function getCalendarEvent(
endUserAccountId: string,
calendarId: string,
eventId: string,
) {
const response = await apirocApi.get<UniversalEvent>(
`events/${endUserAccountId}/${calendarId}/${eventId}`,
);
return response.json();
}
export async function createCalendarEvent(
endUserAccountId: string,
calendarId: string,
event: Partial<UniversalEvent>,
) {
const response = await apirocApi.post<UniversalEvent>(
`events/${endUserAccountId}/${calendarId}`,
{json: event},
);
return response.json();
}
export async function editCalendarEvent(
endUserAccountId: string,
calendarId: string,
eventId: string,
event: Partial<UniversalEvent>,
) {
const response = await apirocApi.put<UniversalEvent>(
`events/${endUserAccountId}/${calendarId}/${eventId}`,
{json: event},
);
return response.json();
}
export async function deleteCalendarEvent(
endUserAccountId: string,
calendarId: string,
eventId: string,
) {
await apirocApi.delete(
`events/${endUserAccountId}/${calendarId}/${eventId}`,
);
}
Sie müssen die Client-Typen nicht selbst definieren. Installieren Sie das offizielle Node.js SDK (@apiroc/unified-calendar-api-node-sdk) und importieren Sie die Typen für Endbenutzerkonten, Kalender und Ereignisse direkt daraus. Das SDK enthält außerdem einen fertigen Client, sodass die obigen Funktionen noch kürzer ausfallen können.
Das folgende Sequenzdiagramm zeigt, wie die Beispiel-Kalender-App mit der Apiroc Unified Calendar API interagiert, um alle Kalenderanbieter anzubinden.
Die API-Routes erstellen
Mit dem Apiroc-Client an Ort und Stelle können wir die API-Routes zum Verwalten von Kalenderkonten und Kalenderereignissen erstellen. Eigene Session-APIs müssen wir nicht definieren, da Better Auth das für uns übernimmt.
Die API enthält Routen-Definitionen für:
- Kalenderkonten : HTTP-Methoden zum Auflisten aller Kalenderkonten und zum Löschen eines Kontos per ID.
- Kalenderereignisse : HTTP-Methoden für CRUD-Operationen auf Ereignissen.
- Kalender : HTTP-Methoden zum Aktualisieren von Kalendern.
Eine Routen-Definition mit tRPC sieht so aus:
export const calendarEventsRouter = createTRPCRouter({
getCalendarEvent: publicProcedure
.input(
z.object({
endUserAccountId: z.string(),
calendarId: z.string(),
eventId: z.string(),
}),
)
.query(async ({ ctx, input }) => {
return await getCalendarEvent(
input.endUserAccountId,
input.calendarId,
input.eventId,
);
}),
});
Die Methode getCalendarEvent stammt aus dem oben gebauten Apiroc-Client.
Öffnen Sie den API-Routes-Ordner im Beispiel-Repository, um die Inhalte jeder API-Route zu sehen. Alles hier einzufügen wäre sehr repetitiv.
Das Frontend bauen
Das Frontend wird mit Next.js + TypeScript gebaut. Beim Erstellen einer Kalender-App ist die wichtigste Komponente, Sie ahnen es, der Kalender.
Aus unserer Erfahrung sind die besten Kalender-UI-Bibliotheken für Next.js und React:
Für dieses Beispiel haben wir react-big-calendar gewählt, weil es sich leicht mit Next.js nutzen lässt. Für Produktions-Apps würden wir jedoch fullcalendar empfehlen, weil es anpassbarer ist und eine größere Community hat.
Fullcalendar ist außerdem für andere Frameworks verfügbar, etwa Svelte, Vue.js usw.
react-big-calendar Verwendung:
<Calendar
culture="en-US"
localizer={localizer}
events={events}
defaultView="week"
eventPropGetter={eventPropGetter}
components={components}
onSelectSlot={(slotInfo) => {
setCreateEventStart(slotInfo.start);
setCreateEventEnd(slotInfo.end);
setCreateEventOpen(true);
}}
onSelectEvent={(event) => {
setSelectedEvent(event);
}}
selectable
onRangeChange={(range) => {
// Week view: range is array of dates
if (Array.isArray(range) && range.length >= 2) {
setDateRange([range[0]!, range[range.length - 1]!]);
return;
}
// Month view: range is object with start/end
if (
range &&
typeof range === "object" &&
"start" in range &&
"end" in range
) {
setDateRange([range.start, range.end]);
return;
}
// Day view: range is a single Date
if (range instanceof Date) {
setDateRange([range, range]);
return;
}
}}
/>
Die vollständige Implementierung finden Sie im Pfad src/app/(protected)/(calendar) im GitHub-Repository. Die Hauptkomponente ist die Seite events-calendar.tsx. Dort gibt es auch Komponenten zum Bearbeiten (inkl. Serientermine), Löschen und Erstellen von Ereignissen.
So sieht der Kalender aus:
Der Nutzer kann in eine Zelle klicken und ein Ereignis erstellen:
Klickt der Nutzer auf ein bestehendes Ereignis, kann er es löschen oder bearbeiten.
Bei Serienterminen kann der Nutzer entscheiden, ob nur die ausgewählte Instanz oder die gesamte Serie bearbeitet werden soll.
So sieht die Bearbeiten-Ansicht aus:
Die UI braucht noch Feinschliff, aber unser Ziel war keine perfekte Kalender-App. Es ging darum, eine funktionierende Kalender-App mit einer funktionierenden Kalender-Integration zu bauen. Die Gestaltung können Sie an Ihre Marke anpassen.
Häufige Herausforderungen und Best Practices
Eine Kalender-App zu bauen oder Kalender-Funktionen hinzuzufügen, ist nicht immer einfach. Selbst wenn die Hauptfunktionalität simpel wirkt, gibt es viele kleine Details, die später Probleme verursachen können. Im Folgenden finden Sie typische Herausforderungen und einige Best Practices, um damit umzugehen.
1. Zeitzonen
Herausforderung:
Ereignisse können zur falschen Zeit erscheinen, wenn Nutzer in unterschiedlichen Zeitzonen sind.
Best Practice:
- Zeiten in der Datenbank immer in UTC speichern. Die Ausnahme sind Kalenderereignisse, denn wir empfehlen nicht, diese überhaupt in Ihrer Datenbank zu speichern. Beim Abrufen über die API des Kalenderanbieters erhalten Sie auch die Zeitzone des Ereignisses.
- Nur für die Anzeige im Frontend in die lokale Zeit des Nutzers umrechnen.
- Eine Bibliothek wie date-fns-tz oder luxon für Konvertierungen nutzen. In diesem Beispiel verwenden wir
date-fnsunddate-fns-tz.
2. Serientermine
Herausforderung:
Wiederholende Ereignisse (täglich, wöchentlich, monatlich) sind komplex, besonders wenn Nutzer eine einzelne Instanz bearbeiten oder löschen möchten.
Best Practice:
- Den Nutzer wählen lassen, ob nur dieses Ereignis oder die gesamte Serie aktualisiert werden soll. So handhaben es Google Calendar, Outlook und viele andere Clients, und so haben wir es auch in unserer Beispiel-App umgesetzt.
3. OAuth-Token-Ablauf
Herausforderung:
Wenn Tokens ablaufen oder widerrufen werden, verlieren Nutzer die Verbindung zu ihren Kalendern.
Best Practice:
- Refresh-Tokens sicher speichern, um automatisch neue Access-Tokens zu erhalten.
- Token-Fehler robust behandeln und Nutzer bei Bedarf auffordern, ihr Konto neu zu verbinden.
4. Daten synchron halten
Herausforderung:
Kalenderdaten veralten, wenn sie nur einmal abgerufen werden.
Best Practice:
- Webhooks der Apiroc Unified Calendar API verwenden, um bei Änderungen in Google- und Microsoft-Kalendern benachrichtigt zu werden.

- Ereignisse dann abrufen, wenn der Nutzer mit der Kalender-App arbeitet. Speichern Sie Ereignisse nicht in Ihrer Datenbank, denn die Synchronisation mit allen Anbietern ist ein schwieriges Problem. Der Mehrwert ist zudem gering, da Sie Ereignisse aller Anbieter jederzeit über Apiroc abrufen können.
5. API-Fehler handhaben
Herausforderung:
Externe APIs (Google, Outlook, iCloud) können Fehler, Rate Limits oder temporäre Ausfälle liefern.
Best Practice:
- Retry-Logik für temporäre Fehler einbauen (Timeouts sind eine Option).
- Rate Limits respektieren und Backoff einsetzen. Beachten Sie, dass sowohl Apiroc als auch die Anbieter (Google Calendar, Outlook Calendar) Limits setzen.
- Fehlgeschlagene Requests protokollieren, um das Debugging zu erleichtern.
6. Große Kalender
Herausforderung:
Manche Nutzer haben Hunderte oder Tausende Ereignisse, was die App verlangsamen kann.
Best Practice:
- Ereignisse seitenweise laden (Pagination). Alle großen Anbieter unterstützen Pagination. Bei Apiroc sind alle Ergebnisse paginiert, sodass dieses Problem gar nicht erst auftritt.
- Nur Ereignisse im sichtbaren Zeitraum abrufen (z. B. diese Woche oder diesen Monat). Grundsätzlich gilt: nur so viele Daten laden, wie benötigt werden. Eine Kalender-App hat Tages-, Wochen-, Monats- und Jahresansicht, rufen Sie die Ereignisse also passend zum sichtbaren Zeitraum ab.
7. Privatsphäre und Sicherheit
Herausforderung:
Kalenderdaten enthalten oft private Informationen.
Best Practice:
- Kalenderereignisse nicht in Ihrer Datenbank speichern. Das Speichern von Access- und Refresh-Tokens genügt.
- Tokens und sensible Felder in der Datenbank verschlüsseln. Wir empfehlen außerdem Verschlüsselung im Ruhezustand; Dienste wie AWS RDS bieten dies von Haus aus.
- Nutzern jederzeit ermöglichen, ihre Kalenderkonten zu trennen. Das ist sehr wichtig. Wenn Nutzer ihre Kalender in Ihrer App nicht trennen oder löschen können, widerrufen sie den Zugriff direkt in ihren Google-Kontoeinstellungen.
FAQ
1. Kann ich anstelle von Next.js API Routes ein anderes Backend verwenden?
Ja. Dieses Beispiel nutzt Next.js API Routes mit tRPC, aber Sie können jedes Backend-Framework einsetzen, z. B. Nest.js, Express oder Django. Entscheidend ist, dass Ihr Backend per HTTPS mit der Apiroc Unified Calendar API kommuniziert. Datenbankstruktur und API-Logik bleiben weitgehend gleich.
2. Muss ich eigene Google- oder Microsoft-Entwickler-Apps erstellen?
Nein, während der Entwicklung können Sie die Google- und Microsoft-Clients von Apiroc verwenden. Für den Produktionsbetrieb bringen Sie eigene OAuth2-Credentials mit, was Ihnen volle Kontrolle und einen eigenen Markenauftritt gegenüber Ihren Nutzern gibt.
3. Kann ich eine andere Datenbank als PostgreSQL nutzen?
Ja. Prisma unterstützt u. a. MySQL, SQLite und MongoDB. Wir haben PostgreSQL gewählt, weil es zuverlässig, skalierbar und für die Produktion leicht einzurichten ist. Je nach Tech-Stack können Sie auch andere Datenbanken und ORMs nutzen.
4. Ist die Apiroc Unified Calendar API kostenlos?
Sie können kostenlos starten, indem Sie ein Apiroc-Konto anlegen. Eine Kreditkarte ist nicht nötig. Der kostenlose Tarif umfasst bis zu 10 End User Accounts und ist ideal zum Testen und für kleine Projekte. Für den Produktionseinsatz können Sie auf den Pro-Tarif upgraden (25 $/Monat, 50 End User Accounts inklusive, danach 0,50 $ pro zusätzlichem End User Account und Monat).
5. Was passiert, wenn ein Nutzer seinen Kalender trennt?
Wenn ein Nutzer trennt, sollte die App das zugehörige CalendarAccount und die Calendars aus Ihrer Datenbank entfernen. Lokale Daten können Sie bei Bedarf zu Analysezwecken behalten, aber getrennte Kalender dürfen nicht mehr synchronisiert oder abgefragt werden.
7. Kann ich Benachrichtigungen oder Erinnerungen hinzufügen?
Ja. Sie können Erinnerungen in Ihrer App bauen oder das native Benachrichtigungssystem des verbundenen Kalenders nutzen (Google, Outlook etc.).
8. Was, wenn die API meine Anfragen wegen Rate Limits begrenzt?
Apiroc hat eingebaute Rate Limits zur Stabilität (20 Anfragen pro Sekunde für Sandbox-Apps und 300 Anfragen pro Sekunde für Produktions-Apps). Wenn Sie das Limit erreichen, reduzieren Sie die Frequenz und versuchen Sie es nach kurzer Zeit erneut. Beachten Sie, dass auch die Anbieter eigene Limits haben; bei Google und Microsoft können höhere Limits beantragt werden.
9. Ist eine bidirektionale Synchronisation möglich?
Ja. Apiroc unterstützt das Lesen und Schreiben von Ereignissen, Sie können also aus verbundenen Kalendern lesen und in sie schreiben. Bei Änderungen auf Anbieterseite erhalten Sie für Google- und Microsoft-Kalender Webhook-Benachrichtigungen. Webhooks für Apple iCloud-Kalender sind geplant, aber noch nicht verfügbar.
10. Wie kann ich dieses Projekt bereitstellen?
Eine Bereitstellung auf Vercel ist einfach. Setzen Sie die Umgebungsvariablen (DATABASE_URL, APIROC_API_KEY, OAuth-Credentials etc.) in den Projekteinstellungen. Alternativ können Sie die App per Docker containerisieren, wenn Sie mehr Kontrolle möchten.
