Echtzeit-Tracking von Verspätungen der Deutschen Bahn direkt im Browser. Die App zeigt Abfahrten und Ankünfte beliebiger Bahnhöfe mit farbcodierter Verspätungsanzeige, Zugausfällen und umfangreichen Filtermöglichkeiten.
- Autocomplete-Suche mit Debounce (300ms, ab 2 Zeichen)
- Ergebnisse aus der öffentlichen DB Transport REST API
- Ausgewählter Bahnhof wird im URL-Hash gespeichert (
#8011160), sodass Links teilbar sind
- Alle Abfahrten/Ankünfte der nächsten 60 Minuten
- Automatisches Refresh alle 30 Sekunden mit sichtbarem Countdown
- Anzeige des letzten Aktualisierungszeitpunkts
- Skeleton-Loading während des ersten Ladevorgangs
| Farbe | Bedeutung |
|---|---|
| Grün | Pünktlich (0 min) |
| Gelb | 1–5 Minuten Verspätung |
| Orange | 6–15 Minuten Verspätung |
| Rot | > 15 Minuten Verspätung |
| Roter Badge "Ausfall" | Zug fällt aus |
- Modus: Umschalten zwischen Abfahrten und Ankünften
- Zugtyp: ICE, IC/EC, RE/RB, S-Bahn, Bus (basierend auf
line.product) - Nur verspätete: Blendet pünktliche Züge aus
- Mindest-Verspätung: Numerische Eingabe in Minuten
- Freitextsuche: Suche nach Zugnummer oder Richtung/Herkunft
Kompakte Zusammenfassung über der Zugliste:
- Gesamtanzahl der Züge
- Anzahl pünktlich / verspätet / ausgefallen
- Durchschnittliche Verspätung (nur der verspäteten Züge)
- Retry-Logik mit exponential Backoff (bis 3 Versuche) bei API-Fehlern (z.B. 503)
- Fehlermeldung mit "Erneut versuchen"-Button
- Letzter erfolgreicher Datensatz bleibt bei Folgefehlern sichtbar
| Technologie | Zweck |
|---|---|
| React 19 | UI-Framework |
| Vite 8 | Build Tool & Dev Server |
| Tailwind CSS 4 | Utility-first Styling |
| v6.db.transport.rest | Öffentliche DB API (kein Key nötig) |
Kein Backend nötig – alle API-Aufrufe erfolgen direkt aus dem Browser (CORS-fähig).
- Node.js (v18 oder höher)
- npm (wird mit Node.js mitgeliefert)
# Repository klonen
git clone https://github.com/luckylucab0/DBLateTracker.git
cd DBLateTracker
# Abhängigkeiten installieren
npm install
# Entwicklungsserver starten
npm run devDie App ist dann unter http://localhost:5173 erreichbar.
# Produktions-Build erstellen
npm run build
# Build lokal testen
npm run preview
# Linting
npm run lintsrc/
├── config.js # API-Konstanten (Base-URL, Intervalle, Limits)
├── main.jsx # Entry Point
├── index.css # Tailwind CSS Import
├── App.jsx # Layout, URL-Hash-Synchronisation
├── hooks/
│ ├── useStationSearch.js # Debounced Bahnhofssuche
│ └── useStationDepartures.js # Fetching, Polling, Retry-Logik
└── components/
├── StationSearch.jsx # Autocomplete-Suchfeld
├── DepartureBoard.jsx # Hauptanzeigetafel mit Filterlogik
├── DepartureRow.jsx # Einzelne Abfahrts-/Ankunftszeile
├── FilterBar.jsx # Alle Filteroptionen
├── StatsBar.jsx # Statistik-Zusammenfassung
└── DelayBadge.jsx # Farbcodierte Verspätungsanzeige
- Custom Hooks (
useStationSearch,useStationDepartures) kapseln die gesamte API-Kommunikation, Polling-Logik und Fehlerbehandlung – Komponenten bleiben dadurch rein darstellend - Keine State-Library (kein Redux/Zustand): Der State-Baum ist flach genug für
useState/useEffect - Kein axios: Natives
fetchreicht für die wenigen Endpoints aus config.js: Alle API-Konstanten zentral, damit Anpassungen (z.B. Refresh-Intervall) nur an einer Stelle nötig sind
Die App nutzt die öffentliche DB Transport REST API v6 (inoffiziell, kein API-Key nötig).
| Endpoint | Beschreibung |
|---|---|
GET /locations?query={name}&results=5&stops=true |
Stationssuche |
GET /stops/{id}/departures?duration=60&results=50 |
Abfahrten einer Station |
GET /stops/{id}/arrivals?duration=60&results=50 |
Ankünfte einer Station |
| Feld | Beschreibung |
|---|---|
delay |
Verspätung in Sekunden (null = keine Echtzeitdaten, 0 = pünktlich) |
cancelled |
true bei Zugausfall |
when |
Tatsächliche Abfahrts-/Ankunftszeit |
plannedWhen |
Geplante Zeit laut Fahrplan |
line.product |
Zugtyp (nationalExpress, national, regional, suburban, bus, ...) |
line.name |
Zuglinie (z.B. "ICE 1234") |
direction |
Fahrtrichtung (bei Abfahrten) |
Die API erlaubt maximal 100 Anfragen pro Minute. Durch Debounce (300ms) bei der Suche und das 30-Sekunden-Polling-Intervall bleibt die App deutlich unter diesem Limit.
Alle anpassbaren Werte befinden sich in src/config.js:
| Konstante | Standard | Beschreibung |
|---|---|---|
API_BASE_URL |
https://v6.db.transport.rest |
Basis-URL der API |
REFRESH_INTERVAL_MS |
30000 (30s) |
Auto-Refresh Intervall |
MAX_RETRIES |
3 |
Wiederholungsversuche bei API-Fehlern |
RETRY_BASE_DELAY_MS |
1000 (1s) |
Basis-Wartezeit zwischen Retries (verdoppelt sich) |
SEARCH_DEBOUNCE_MS |
300 |
Debounce für die Suche |
DEPARTURE_DURATION_MIN |
60 |
Zeitfenster in Minuten |
DEPARTURE_RESULTS |
50 |
Max. Ergebnisse pro Abfrage |
Die App ist eine statische Single-Page-Application und kann auf jedem statischen Hosting betrieben werden:
npm run build
# dist/ Ordner deployen oder Vercel-CLI nutzen
npx vercel --prodnpm run build
# dist/ als Publish Directory konfigurierennpm run build
# dist/ Inhalt in den gh-pages Branch pushen- Die verwendete API ist inoffiziell und wird von der Community betrieben – es besteht keine Garantie auf Verfügbarkeit oder Korrektheit der Daten
- Die API kann zeitweise 503-Fehler zurückgeben; die eingebaute Retry-Logik fängt dies ab
- Alle Zeiten werden in der lokalen Zeitzone des Browsers angezeigt
- Die App speichert keine Nutzerdaten und verwendet keine Cookies oder Tracking
MIT