Segment · Next.js · Vercel KV · Strava API
Training log
A calendar of every training day, weekly distance, the year to date and my latest activities per sport, read from Strava and updated when I upload a new activity.
All sports this week: 0 kcal
- Active days
- 189
- Training
- 256 h
- Sessions
- 278
- Streak
- 12 wk
| Sport | Activity | Dist. | Time |
|---|---|---|---|
| Running | Afternoon Run | 8.0 | 44m |
| Cycling | Zwift - Mishmash | 12.6 | 30m |
| Sport | Sessions | Dist. | Time | Share |
|---|---|---|---|---|
| Running | 107 | 964 | 87h 53m | 34% |
| Cycling | 77 | 2,061 | 78h 7m | 31% |
| Strength | 55 | – | 47h 15m | 18% |
| Skiing | 20 | – | 24h 13m | 9% |
| Other | 17 | – | 17h 23m | 7% |
| Swimming | 2 | 3 | 42m | 0% |
- Mon
- Tue
- Wed
- Thu
- Fri
- Sat
- Sun
Synced from Strava Oct 24, 2026
About Training log
Why I built it
I wanted the site to show something I do every week, from live data instead of a screenshot.
Key decision
Push, not polling. A Strava webhook updates a stored snapshot of my activities, so a page never waits on Strava or spends its rate limit. Strava doesn't sign webhook events, so the app only takes the activity id from them and fetches the activity itself. A missed event can leave the snapshot stale, which a protected resync route repairs.
Stack
Next.js App Router with a server-only data layer, Vercel KV for tokens and the activity snapshot, deployed on Vercel.