Skip to content

Strava Integration Configuration

To enable Strava integration in Bécik, you need to:

1. Create a Strava Application

Visit https://www.strava.com/settings/api and create a new API application:

  • Application name: Bécik (or your app name)
  • Category: Cycling
  • Website: https://yoursite.com
  • Club: (optional)
  • Description: Automatic odometer tracking for cycling bikes
  • Authorization Callback Domain: yoursite.com (without protocol)

This will give you:

  • Client ID (add to STRAVA_CLIENT_IDNEXT_PUBLIC_STRAVA_CLIENT_ID is supported for backward compatibility)
  • Client Secret (add to STRAVA_CLIENT_SECRET)

2. Environment Variables

Add these to your .env.local:

# Strava OAuth
STRAVA_CLIENT_ID=your_client_id_here
# Optional/backward compatible (the server accepts both):
NEXT_PUBLIC_STRAVA_CLIENT_ID=your_client_id_here
STRAVA_CLIENT_SECRET=your_client_secret_here

# Optional: override pour le callback OAuth en preview Vercel (Strava n'accepte qu'un domaine).
# Si ton app de prod n'est pas www.becik.app, définis ici l'URL canonique pour Strava.
# STRAVA_CALLBACK_BASE_URL=https://ton-domaine.com

# Optional: second Strava app for specific users (e.g. when API rate limits apply per app)
# Users matching these will use STRAVA_CLIENT_ID2 / STRAVA_CLIENT_SECRET2 for OAuth and refresh
STRAVA_CLIENT_ID2=your_second_client_id
STRAVA_CLIENT_SECRET2=your_second_client_secret
# One of:
# STRAVA_APP2_USER_IDS=uuid1,uuid2   # Supabase auth user IDs
# STRAVA_APP2_EMAILS=you@example.com # Emails (comma-separated)

# Strava Webhooks (optional)
# Verify token used by Strava during subscription validation (hub.verify_token)
STRAVA_WEBHOOK_VERIFY_TOKEN=your_verify_token_here

# Optional: if you run the webhook behind a proxy that adds a signature header,
# you can enable signature verification by setting this value.
# (The server also accepts STRAVA_WEBHOOK_SECRET as a fallback verify token.)
STRAVA_WEBHOOK_SECRET=your_webhook_secret_here

3. Create Webhook (Optional, for real-time sync)

In your Strava app settings, create a webhook subscription:

  • Callback URL: https://yoursite.com/api/webhooks/strava/
  • Verify Token: Set this to your STRAVA_WEBHOOK_VERIFY_TOKEN (or STRAVA_WEBHOOK_SECRET)

Strava will POST events here when activities are created, updated, or deleted.

4. Database Setup

Run the migration in /src/lib/supabase/migrations/strava_schema.sql in your Supabase database:

-- This creates:
-- - strava_tokens table (user's OAuth tokens)
-- - strava_activities table (synced activities)
-- - RLS policies (user data isolation)

5. Features

Connect Strava

Users can connect their Strava account via "Connect Strava" button on the bikes page. This stores their access token securely in the database.

Automatic Sync

When configured with webhooks, activities are synced in real-time as they're created on Strava.

Manual Sync

Users can trigger a full sync of historical activities via "Sync Now" button.

Gear Matching (Future)

Once strava_gear_id column is added to bikes table, activities will be automatically matched to bikes based on the Strava gear ID, and odometer values will be updated automatically.

6. Scopes

The integration requests these Strava scopes:

  • read_all - Access to all activities (private and public)
  • profile:read_all - Access to athlete profile

7. Troubleshooting

  • "redirect_uri invalid" en preview Vercel : Strava n’accepte qu’un seul domaine de callback. En preview, l’app utilise automatiquement l’URL de production (https://www.becik.app ou STRAVA_CALLBACK_BASE_URL) pour le redirect. Tu seras redirigé vers la prod après la connexion Strava. Assure-toi que ton domaine de prod est bien configuré dans Strava (« Authorization Callback Domain »).
  • "Strava client ID not configured": Make sure NEXT_PUBLIC_STRAVA_CLIENT_ID is set
  • "State validation failed": User ID mismatch in OAuth flow - clear cookies and try again
  • Webhook not receiving events:
  • Verify callback URL is publicly accessible
  • Check webhook subscription in Strava API application settings
  • Ensure STRAVA_WEBHOOK_VERIFY_TOKEN (or STRAVA_WEBHOOK_SECRET) matches what you set in Strava

8. Local webhook testing with ngrok (dev)

To test real Strava webhooks against your local pnpm dev without extra plumbing:

  1. Start the dev server:
pnpm dev
  1. Expose port 3000 with ngrok:
ngrok http 3000

Copy the HTTPS URL, e.g. https://abc123.ngrok-free.app.

  1. Create a temporary Strava webhook subscription pointing to your local endpoint:
curl -X POST https://www.strava.com/api/v3/push_subscriptions \
  -F client_id=$STRAVA_CLIENT_ID \
  -F client_secret=$STRAVA_CLIENT_SECRET \
  -F callback_url=https://abc123.ngrok-free.app/api/webhooks/strava \
 -F verify_token=$STRAVA_WEBHOOK_VERIFY_TOKEN
  • The route at /api/webhooks/strava will respond to the initial hub_challenge.

  • Trigger an activity on a Strava account that is connected to your dev environment.

  • Create or edit an activity; Strava will POST a webhook to your ngrok URL.
  • The handler will process it and log structured entries like:

    • Strava webhook received (with requestId, object_id, aspect_type, owner_id)
    • Strava activity processed or Strava activity deleted (with userId, bikeId, etc.).
  • When finished, you can delete the temporary subscription from Strava if desired:

  • List subscriptions:

    curl "https://www.strava.com/api/v3/push_subscriptions?client_id=$STRAVA_CLIENT_ID&client_secret=$STRAVA_CLIENT_SECRET"
    
  • Delete a subscription by ID:

    curl -X DELETE \
      "https://www.strava.com/api/v3/push_subscriptions/$ID?client_id=$STRAVA_CLIENT_ID&client_secret=$STRAVA_CLIENT_SECRET"
    

These logs (with the requestId) make it easy to support users by correlating a Strava event (object ID, aspect type, athlete) with what Bécik actually did.