Embed System
The /embed route is the core of the project β it renders interactive GPX maps inside iframes on the WordPress blog.
Query parameters
| Parameter | Required | Description |
|---|---|---|
gpx | Yes | URL to the GPX file (must be on bttpirineus.org) |
chart | No | Elevation chart behavior: auto (default), show, hide |
page | No | WordPress page URL (used for sharing and analytics) |
anchor | No | Anchor ID for deep-linking (e.g. map-bassegoda) |
title | No | Custom display title (defaults to GPX filename) |
Example:
/embed?gpx=http://www.bttpirineus.org/wp-content/uploads/Falda%20Bassegoda.gpx&chart=autoData flow
page.tsxextracts query params and passes them toEmbedClientEmbedClientfetches the GPX via/api/gpx?url=...(server-side proxy)- Parses XML with
parseGpx()(DOMParser-based, handles missing elevation/time) - Enriches with
enrichGpxData(): haversine distances, cumulative elevation, smoothed speeds, gradients, waypoint snapping - Renders the UI components
UI layout
ββββββββββββββββββββββββββββββββββββββββ
β β
β LeafletMap β
β (track in red, hover marker) β
β β
β ββββββββ ββββββββ ββββββββ β
β βπ 42 β ββ¬ 12 β ββ 3 β β β Analytics HUD (bottom-left)
β ββββββββ ββββββββ ββββββββ β
β ββββββββββββββββ β
β ββ² Veure perfilβ β β Chart toggle (when collapsed)
β ββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββ€
β ElevationChart (SVG) β β Collapsible
ββββββββββββββββββββββββββββββββββββββββ€
β Title βπ Inici ββ¬ Descarregarββ Compartir β β Bottom bar
ββββββββββββββββββββββββββββββββββββββββChart auto-collapse
When chart=auto (the default), the chart behavior depends on the device:
- Mobile devices (touch, small screen, or mobile UA): chart starts collapsed
- Very short embeds (
innerHeight < 360px): chart starts collapsed - Desktop: chart starts expanded
Users can toggle the chart at any time. The chart=show and chart=hide params override auto-detection.
Mobile detection
Uses multiple signals: CSS media queries (hover: none, max-width: 767px), navigator.maxTouchPoints, user agent string, and userAgentData.mobile.
Map features
- Track rendering: Red polyline (
#e74c3c) with start (green) and end (red) circle markers - Waypoints: Blue circles with emoji icons based on semantic categories (font, coll, ermita, etc.)
- Hover sync: Hovering the elevation chart moves a marker along the track on the map
- Cyclist icon: Animated emoji that flips direction based on track heading
- Base layers: Hybrid (Esri satellite), Topo (OpenTopoMap), IGN Raster β preference persisted in localStorage
- Responsive: Full viewport height layout, adapts to compact viewports
Bottom bar
- Title: Derived from GPX filename or explicit
titleparam - Inici de ruta: Opens Google Maps directions to the track start point
- Descarregar el track: Downloads GPX via
/api/gpx?url=...&dl=1 - Compartir: ShareDropdown with Facebook, X, WhatsApp, email, Garmin Connect, QR code, copy link
Analytics
On mount, the embed:
- Fetches current view/download/share counts from Supabase (displayed in HUD)
- Fires a
track_viewedevent (deduplicated per session via sessionStorage) - Subsequent actions (download, share, route start) are tracked via dual-write to Supabase + PostHog
Cross-origin iframe considerations
When embedded on bttpirineus.org, the iframe is cross-origin. This means:
- localStorage may be blocked β the layer preference hook fails gracefully
- PostHog uses
persistence: "memory"in iframe contexts (loses cross-page identity, which is acceptable) - sessionStorage is used for view deduplication β works within the iframe session