MBTA Dashboard - Frontend Implementation#
What Was Established#
A portrait-mode (1080x1920) transit dashboard displaying real-time MBTA departures, commuter rail, weather, news, and a static transit map. Hosted on PLT-MBTADisplay (192.168.168.42), served via Nginx with a Node/Express proxy that handles all external API calls server-side. Target display is a 1080p vertical screen driven by Anthias on a Raspberry Pi 3B+.
Design Evolution#
The dashboard went through several major design iterations:
- Initial: Line-based cards with MBTA colors, horizontal layout for 1080p TV
- Minimalist redesign: White background, grey dividers, MBTA colors only on small abbreviated line pills (RL, OL, BL, GL-B/C/D/E), smaller station-only headers with walk time
- Station-based cards: Cards grouped by station (South Station, State Street, Park Street) rather than by line, with all routes listed per station
- Final portrait layout: 2-column CSS Grid, flex column containers, flat time-sorted departure list with line pills, full-width static map image at bottom
Layout (1080x1920 Portrait)#
- 2-column, 3-row card grid above a full-width static map image
- Cards flex with content height (no preset card height)
- CSS Grid with
grid-template-columns: 1fr 1fr
Key Features#
CSS Ticker/Marquee#
- Header text that overflows its container scrolls seamlessly in a ticker
- Uses CSS animation with
transform: translateX()— no JavaScript - Animation speed set slow for readability
Station-Based Grouping#
- Cards grouped by physical station: South Station, State Street, Park Street
- Each station card shows all lines serving that station
- Departures sorted by time, each with abbreviated line pill (RL, OL, BL, GL-B, etc.)
- Filtered to show departures within 10 minutes walking distance
Server-Side Proxy Architecture#
- All API calls proxied through Node/Express on
localhost:3000 - Client fetches single
/api/dataendpoint — no direct browser-to-MBTA calls - API keys stored in environment variables, never exposed to browser
- Server-side caching with TTL to reduce upstream API calls
News Ticker#
- Pulls from multiple RSS feeds (MassLive Boston, State House News)
- Displays first 3 items from each feed as
<title> - <description> - Modular RSS feed configuration for easy addition of new sources
Static Map#
- Originally Leaflet.js with OpenStreetMap and hardcoded markers
- Replaced with static image for performance on Raspberry Pi
- Generated via Snazzy Maps + PowerPoint, served as local
webpfile - Full-width, placed below the card grid
Performance & Optimization#
Memory Constraints (Raspberry Pi 3B+)#
- Total system memory: 788MB
- Dockerized Anthias viewer consumes significant resources
- Strategies employed:
- Server-side proxy: Eliminates duplicate API calls from browser
- Lazy loading: Defer non-critical rendering
- DOM optimization: Remove unused elements, minimize reflows
- Image optimization: Convert to WebP, use static image over dynamic map
- Cache management: Server-side cache with periodic clearing
- Swap avoidance: Swap degrades SD card — keep memory footprint below physical RAM
Font Standardization#
- Default to Arial for cross-platform consistency
- Helvetica Neue as preferred fallback
- Qt WebEngine (Anthias) renders fonts differently than desktop Chrome
Current Configuration#
- Host: PLT-MBTADisplay (
192.168.168.42) - Web root:
/var/www/MBTADisplay/public - Proxy:
/opt/mbta-proxy/server.js(Node/Express, port 3000) - Process manager: pm2 with systemd service (
pm2-administrator) - Deployment: Git push → GitHub → manual pull on server
- Access URLs:
http://transit.intra.plgt.com(internal),https://mbtadash.nbkelley.com(Cloudflare)
Historical Notes#
- Conversation dates: 2026-03-12 to 2026-04-12.
- Collaborative workflow: Claude AI (creative/prompt engineering) → Claude Code (implementation).
- Blue Bikes section was added, then fully removed when GBFS feed deprecated.
- Ferry panel configuration evolved significantly — seasonal routes removed seasonally.
- Several Claude Code UI hallucinations corrected by user during Bambu Studio discussion.
Related Pages#
Sources#
ingested/chats/159-Create MBTA Train Dashboard with API.md- Claude Code conversation: “MBTADashboard - Prompt Maker” (chat 24)