A local-first, privacy-first Progressive Web App map viewer β no accounts, no tracking, all data stays on your device.
Maphop is a lightweight map viewer you open in any modern browser. It gives you:
- Zero setup β visit maphop.eu and the map opens instantly.
- Complete privacy β your saved locations live in your browser's IndexedDB only; nothing is sent to a server.
- Offline support β a service worker caches the app shell so it loads even without a network connection.
- Multiple map styles β choose from 7 built-in tile providers, with optional Thunderforest Outdoors support for self-hosted deployments.
| Feature | Description |
|---|---|
| πΊοΈ Base Maps | 7 built-in maps: Bergfex OSM, OpenStreetMap, OpenFreeMap Liberty, OpenTopoMap, CyclOSM, Esri Satellite, basemap.at Grau, plus optional Thunderforest Outdoors when configured |
| π Live Location | Opt-in GPS tracking with an accuracy circle, heading cone, and follow mode |
| β Favorites | Crosshair-based save flow, local-only storage in IndexedDB, and one-tap return to saved places |
| π Favorite Sharing | Share any saved favorite as a deep link; recipients see a pin marker and a banner to add the spot to their own favorites or dismiss |
| π Favorites Overlay | Show all saved favorites as pin markers directly on the map |
| πΎ GeoJSON Backup | Export favorites as GeoJSON and import previously saved favorites from Settings |
| ποΈ 3D Terrain | Toggle hillshade and terrain exaggeration for a three-dimensional view |
| π§ Compass | Appears when the map is rotated or tilted; tap to reset to flat north-up view |
| π Re-center | Appears when you pan away from your live location; tap to fly back |
| Β© Attribution Widget | Compact attribution panel for the active base map and terrain sources |
| π΄ Offline-capable | Service worker caches the app shell for use without connectivity |
| π² Installable PWA | Add to your home screen on Android or iOS for a native app feel |
| π Privacy-first | No accounts, no analytics, explicit CSP allowlists for tile hosts, and strict referrer handling on the live map page |
Visit https://maphop.eu in any modern browser. The map loads immediately β no sign-up required.
- Tap the β° hamburger button (top-right) to open the menu.
- Scroll to the Maps section and tap any style name to switch instantly.
- Maphop remembers the last base map you used and restores it on the next visit.
Available styles:
- Bergfex OSM β detailed street and trail map (default)
- OpenStreetMap β classic community-maintained street map
- OpenFreeMap Liberty β clean, lightweight vector map
- OpenTopoMap β topographic contour map, great for hiking
- Outdoors β Thunderforest outdoor map for hiking and trail context when enabled by the deployment
- CyclOSM β cycling-focused map with route highlights
- Esri Satellite β satellite imagery
- basemap.at Grau β greyscale Austrian base map
- Open the menu and expand the Location section.
- Tap Show My Location to toggle the GPS overlay on or off.
- Your browser will ask for location permission the first time β location data never leaves your device.
Privacy note: The tile provider can infer your approximate area from the map tiles your device requests.
- Pan and zoom the map to the view you want to save.
- Open the menu and expand the Favorites section.
- Tap Add Favorite.
- A crosshair appears in the center of the map; pan or zoom until it sits over the location you want.
- Tap Save This Spot.
- Enter a name in the centered modal and confirm.
- Saved favorites appear in the list; tap any one to fly back to that location.
- Open the Favorites section in the menu.
- Tap the share button beside any saved favorite.
- On supported devices, Maphop opens the native share sheet so you can send the link through apps like WhatsApp.
- If native sharing is unavailable, Maphop copies the share URL to your clipboard instead.
Anyone who opens the shared link will land directly on the same location in Maphop. A pin marker appears at the shared spot and a banner at the top of the screen offers two actions: Add to Favorites (saves the location straight to their own favorites list) or β to dismiss the pin and banner.
- Open the Favorites section in the menu.
- Toggle Show on Map on.
- All saved favorites appear as green pins on the live map.
- Hover over a pin on desktop to see the favorite name.
Open Settings from the menu footer to export favorites as GeoJSON or import a previously saved favorites file.
- Open the menu and expand the Location section.
- Tap 3D Terrain to toggle hillshade and DEM-based exaggeration.
- The map tilts to 45Β° automatically; right-click-drag (desktop) or two-finger gesture (touch) adjusts the tilt further.
Android (Chrome): An install banner appears at the bottom of the screen β tap Install to add Maphop to your home screen.
iOS (Safari): Tap the Share button then Add to Home Screen.
Once installed, Maphop opens in full-screen mode and works offline using cached tiles from previous sessions.
π‘ Visit the live demo at maphop.eu to see the app in action.
- Node.js 20 or later
- npm 10 or later (bundled with Node.js 20)
# Clone the repository
git clone https://github.com/mdiener21/maphop.git
cd maphop
# Install dependencies
npm install
# Optional: enable Thunderforest Outdoors locally
printf 'VITE_THUNDERFOREST_API_KEY=your-key-here\n' > .env.local
# Start the Vite dev server with hot-module replacement
npm run devOpen http://localhost:5173 in your browser. Changes to source files in src/ are reflected immediately without a full reload.
.env.local is gitignored. Do not commit personal API keys.
If you enable Thunderforest Outdoors, keep in mind that this is a browser-rendered tile layer: the key stays out of the repository, but it is still visible to users of a deployed build. Restrict the key in your Thunderforest account to the intended domains and usage limits.
# Run unit tests once
npm test
# Run unit tests in watch mode (re-runs on file save)
npm run test:watch
# Run unit tests with a V8 coverage report
npm run test:coverage
# Run end-to-end tests (Playwright, requires Firefox)
npm run test:e2eUnit tests live in tests/unit/ and currently cover attribution rendering, base-layer switching, install prompts, menu state, favorites transfer/store logic, location tracking, terrain lifecycle, and share-link helpers. End-to-end tests live in tests/e2e/ and exercise the map page, settings page, impressum page, and inter-page navigation.
npm run buildThe production-ready static site is output to the dist/ directory. You can preview it locally before deploying:
npm run previewOpen http://localhost:4173 to verify the built output.
Maphop is a fully static site β dist/ contains only HTML, CSS, JavaScript, and assets. You can host it on any static file host (Netlify, Vercel, GitHub Pages, a plain FTP server, etc.).
Automated deployment is handled by the GitHub Actions workflow in .github/workflows/deploy.yml. On every push to main it:
- Runs
npm cito install dependencies. - Runs
npm run buildto producedist/. - Uploads
dist/to the configured FTP host vialftp.
To use the workflow you need two repository secrets:
| Secret | Description |
|---|---|
FTP_USER |
FTP username for your hosting account |
FTP_PASSWORD |
FTP password for your hosting account |
For a manual deployment, copy the contents of dist/ to the public_html/ (or equivalent) directory on your web server.
Service worker path: The service worker is registered at the root (
/sw.js). Ensure your hosting configuration serves the app from/and does not rewrite the service worker URL.
