Navio is a Safari web extension for iOS and macOS that automatically redirects Google Maps links to Apple Maps, providing a seamless one-tap navigation experience.
- Auto-redirect Google Maps links: Any link on Google Search that would normally open Google Maps will instead launch Apple Maps with the corresponding location
- Support all Google domains: Works on every regional Google domain (google.com, google.co.uk, google.ca, etc.) for both iOS and macOS Safari
- Smart fallback mechanism: If Navio cannot immediately resolve a particular link, it will allow the Google Maps web page to load and then automatically attempt the redirect from there
- Zero data storage: Navio does not collect or store personal data. It only examines page content for map links and uses on-device URL schemes to open Apple Maps
- Native integration: Uses native messaging for optimal user experience on both platforms
Navio/
├── Navio/ # iOS/macOS container app
│ ├── Resources/
│ │ └── Base.lproj/
│ │ └── Main.html # Splash screen with setup instructions
│ ├── ViewController.swift # Main app view controller
│ ├── AppDelegate.swift
│ └── SceneDelegate.swift
├── Navio Extension/ # Safari Web Extension
│ ├── Resources/
│ │ ├── manifest.json # Extension manifest (Manifest v3)
│ │ ├── content.js # Content script for link interception
│ │ ├── background.js # Background script for native messaging
│ │ ├── popup.html # Toolbar popup UI
│ │ └── _locales/en/
│ │ └── messages.json # Localized strings
│ └── SafariWebExtensionHandler.swift # Native message handler
├── NavioTests/ # Unit tests
├── NavioUITests/ # UI tests
├── README.md # This file - comprehensive documentation
├── TESTING.md # Testing procedures and test cases
├── URL_PATTERNS.md # URL conversion patterns and examples
├── ICONS.md # Icon requirements and generation
└── generate-icons.sh # Script to generate missing icon sizes
- TESTING.md - Comprehensive testing guide with 20+ test cases covering functional, performance, UX, and edge case testing
- URL_PATTERNS.md - Detailed documentation of all supported Google Maps URL patterns and their Apple Maps conversions
- ICONS.md - Icon requirements, design guidelines, and generation instructions
- generate-icons.sh - Automated script to generate missing icon sizes using ImageMagick
When you visit a Google Search results page, Navio's content script (content.js) runs automatically and:
- Detects all links that point to Google Maps (searches for patterns like
/maps/place,/maps/dir,maps.google.com, etc.) - Converts each Google Maps URL to the equivalent Apple Maps URL
- Rewrites the link's
hrefattribute to point to Apple Maps - Adds a click interceptor as a backup to ensure the redirect happens
The googleToAppleMapsURL() function handles different types of Google Maps links:
- Place/Address searches: Converts to Apple Maps search queries using the
qparameter - Directions links: Extracts origin and destination, converts to Apple Maps using
saddranddaddrparameters - Coordinates: Extracts latitude/longitude and uses the
llparameter - Edge cases: Handles various Google Maps URL formats and patterns
Example conversions:
Google: https://www.google.com/maps/place/Empire+State+Building/@40.748,-73.985
Apple: https://maps.apple.com/?q=Empire%20State%20Building&ll=40.748,-73.985
Google: https://www.google.com/maps/dir/Current+Location/Central+Park
Apple: https://maps.apple.com/?daddr=Central%20Park
If a Google Maps link is missed on the search page, Navio has a fallback mechanism:
- When a Google Maps page (
google.com/maps) loads, the content script detects it - After a short delay (500ms) to allow the URL to stabilize, it extracts the location from the page URL
- Automatically redirects to Apple Maps
- This ensures even complex or unusual links eventually open in Apple Maps
For the best user experience (especially on macOS), Navio uses native messaging:
- When a link is clicked, the content script sends a message to the background script
- The background script forwards it to the native app via
browser.runtime.sendNativeMessage() SafariWebExtensionHandler.swiftreceives the message and opens Apple Maps using:- iOS:
UIApplication.shared.open() - macOS:
NSWorkspace.shared.open()
- iOS:
- This avoids Safari creating blank tabs or showing repeated permission prompts
- Xcode 14+ (for Manifest v3 support)
- macOS 12+ and/or iOS 16+ for testing
- Safari with extension support enabled
- Apple Developer account (for running on physical iOS devices)
-
Clone the repository:
git clone <repository-url> cd Navio
-
Open in Xcode:
open Navio.xcodeproj
-
Select your target:
- For macOS: Select "Navio (macOS)" scheme
- For iOS: Select "Navio (iOS)" scheme
-
Build and run:
- Press
Cmd+Ror click the Run button - The app will launch and show the setup instructions
- Press
- Run the Navio app from Xcode
- Open Safari → Preferences → Extensions
- Enable "Navio"
- Allow "All Websites" permission
- Close the preferences and test on a Google search
- Run the Navio app from Xcode
- Open Settings app → Safari → Extensions
- Enable "Navio"
- Allow "All Websites" permission
- Open Safari and test on a Google search
The extension requires icon assets in multiple sizes. Place them in Navio Extension/Resources/images/:
icon-16.png(16x16)icon-19.png(19x19) - iOS toolbaricon-32.png(32x32)icon-38.png(38x38) - iOS toolbar @2xicon-48.png(48x48)icon-64.png(64x64)icon-96.png(96x96)icon-128.png(128x128)icon-256.png(256x256)icon-512.png(512x512)
Note: Currently, the project references these icons but placeholder assets need to be created. Use a simple compass or map pin icon design.
- Open Safari with Navio enabled
- Search for "Empire State Building" on Google
- Click the map result or "Directions" link
- Expected: Apple Maps opens with the location
- Visit
google.co.ukorgoogle.ca - Search for a local place
- Click a map link
- Expected: Works the same as google.com
- Search for a restaurant or business on Google
- Click the "Directions" or "Get there" button
- Expected: Apple Maps opens in directions mode to that destination
- Temporarily disable the extension
- Click a Google Maps link (it will load maps.google.com)
- Re-enable the extension
- Reload the Google Maps page
- Expected: Auto-redirects to Apple Maps after ~500ms
- Coordinates-only links: Links with
@lat,lngformat - Plus codes: Links using Google Plus Codes
- Complex queries: Multi-word addresses with special characters
- Direct maps.google.com URLs: Opening a Google Maps URL directly (not from search)
- Enable Navio alongside other extensions (ad-blockers, etc.)
- Ensure link rewriting happens quickly (< 100ms)
- Check Safari console for any errors
- Verify no memory leaks or excessive resource usage
To enable debug logging:
- Edit
content.js - Change
const DEBUG = false;toconst DEBUG = true; - Rebuild the extension
- Open Safari's Web Inspector on a Google Search page
- Check the Console tab for
[Navio]log messages
Navio uses Manifest V3 for future compatibility and improved performance:
- Non-persistent background script: Lightweight service worker
- Host permissions:
<all_urls>to support all Google country domains - Native messaging permission: For seamless Apple Maps opening
Page Load (Google Search)
↓
Content Script Initialization
↓
Detect Google Search Page?
↓ Yes
Scan for Map Links (querySelectorAll)
↓
For each map link:
├─ Convert to Apple Maps URL
├─ Rewrite href attribute
└─ Add click interceptor
↓
Start DOM Observer (for dynamic content)
↓
User Clicks Link
↓
Click Interceptor Fires
↓
Send message to background script
↓
Background forwards to native app
↓
Native app opens Apple Maps
User lands on maps.google.com
↓
Content Script Detects Maps Page
↓
Wait 500ms (for URL to stabilize)
↓
Extract location from current URL
↓
Convert to Apple Maps URL
↓
Redirect via native messaging
Navio is designed with privacy in mind:
- No data collection: No user data, location data, or search queries are collected or transmitted
- No external servers: All processing happens on-device
- No analytics: No tracking or analytics code
- Minimal permissions: Only requests necessary permissions for functionality
- Open source: All code is transparent and auditable
The extension only examines page content to find Google Maps links and uses standard URL schemes to open Apple Maps. All operations are performed locally on the user's device.
- First-time permission prompt: Users must allow "All Websites" permission for the extension to work on all Google domains
- Safari prompts: On first use, Safari may show a permission dialog to open Apple Maps
- Dynamic content: Some dynamically loaded Google results may have a slight delay before links are converted (handled by DOM observer)
- macOS tab behavior: Depending on Safari version, a blank tab might briefly appear when opening Apple Maps (mitigated by native messaging)
- Check if the extension is enabled in Safari settings
- Verify "All Websites" permission is granted
- Try disabling and re-enabling the extension
- Check Safari's Web Inspector console for errors
- Ensure you've allowed the extension on the current website
- Try refreshing the Google Search page
- Check if another extension is interfering
- Enable debug logging and check console
- Verify the native app is properly installed
- Check Xcode console for native app logs
- Ensure bundle identifiers match in manifest and app
- Try rebuilding the entire project
This is a reference implementation following the comprehensive plan. Contributions are welcome for:
- Additional URL pattern support
- Performance improvements
- Icon design
- Bug fixes
- Documentation improvements
See the LICENSE file for details.
- Implementation based on comprehensive Safari Web Extension development best practices
- Inspired by similar extensions like Mapper for Safari
- Built using Apple's Safari Web Extension APIs
For issues, questions, or feedback, please open an issue on the repository or contact the developer.
Built with ❤️ for iOS and macOS Safari users who prefer Apple Maps