What is a URL Scheme?
The scheme is the first part of a URL, appearing before the ://. It tells the browser (or operating system) which protocol or application should handle the URL.
While http and https are the most common schemes for web browsing, URLs can use many different schemes to trigger different behaviors:
mailto:— Opens email clienttel:— Initiates phone callsms:— Opens messaging appfile:— Accesses local filesftp:— File transfer protocol- App-specific schemes like
slack:,spotify:
The mailto: Scheme
The mailto: scheme opens the user's default email client with a new message. It's essential for contact pages and support links.
Basic Usage
<a href="mailto:contact@example.com">Email Us</a>
Clicking this link opens the email client with the "To" field pre-filled.
Adding Parameters
You can pre-fill other fields using query parameters:
| Parameter | Purpose | Example |
|---|---|---|
subject |
Email subject line | ?subject=Support%20Request |
body |
Email body text | ?body=Hello%2C%0A%0A |
cc |
Carbon copy recipients | ?cc=manager@example.com |
bcc |
Blind carbon copy | ?bcc=archive@example.com |
Complete Example
<a href="mailto:support@example.com?subject=Support%20Request&body=Hi%20Support%20Team%2C%0A%0AI%20need%20help%20with...&cc=sales@example.com"> Contact Support </a>
This creates a link that:
- Sends to:
support@example.com - Subject: "Support Request"
- Body: "Hi Support Team,\n\nI need help with..."
- CC:
sales@example.com
Multiple Recipients
Separate multiple addresses with commas:
<a href="mailto:one@example.com,two@example.com?subject=Team%20Update"> Email Team </a>
The tel: Scheme
The tel: scheme initiates a phone call. On mobile devices, it opens the phone dialer. On desktop, it may open a communication app like Skype or FaceTime.
Basic Usage
<a href="tel:+1-555-123-4567">Call Us</a>
International Format
Always use the international format (E.164) for maximum compatibility:
- Start with
+followed by the country code - No spaces, parentheses, or dashes in the number itself
- Visual formatting should only be in the link text
<!-- Recommended: International format --> <a href="tel:+15551234567">+1 (555) 123-4567</a> <!-- Works but not recommended: Local format --> <a href="tel:555-123-4567">555-123-4567</a>
Extensions
Some systems support dialing extensions after connecting:
<!-- Using pause (,) before extension --> <a href="tel:+15551234567,123">+1 (555) 123-4567 ext. 123</a> <!-- Using wait (;) for manual continue --> <a href="tel:+15551234567;123">+1 (555) 123-4567 ext. 123</a>
The sms: Scheme
The sms: scheme opens the default messaging app to send a text message.
Basic Usage
<a href="sms:+15551234567">Text Us</a>
Pre-filled Message Body
You can include a pre-filled message, though syntax varies by platform:
<!-- iOS uses &body= --> <a href="sms:+15551234567&body=Hello%20from%20website">Text Us (iOS)</a> <!-- Android uses ?body= --> <a href="sms:+15551234567?body=Hello%20from%20website">Text Us (Android)</a>
Geographic Coordinates: geo:
The geo: scheme specifies a geographic location, typically opening a maps application.
<!-- Coordinates for the Eiffel Tower --> <a href="geo:48.8584,2.2945">Open in Maps</a> <!-- With a label --> <a href="geo:48.8584,2.2945?q=Eiffel%20Tower">Eiffel Tower</a>
Note: Browser support is limited. On iOS, consider using maps: or Apple Maps URLs. On Android, geo: works directly.
App-Specific Schemes (Deep Links)
Applications can register custom URL schemes to enable "deep linking"—opening the app directly to specific content.
Common App Schemes
| App | Scheme | Example |
|---|---|---|
| Slack | slack:// |
slack://channel?team=T123&id=C456 |
| Spotify | spotify: |
spotify:track:4PTG3Z6ehGkBFwjybzWkR8 |
| Twitter/X | twitter:// |
twitter://user?screen_name=example |
instagram:// |
instagram://user?username=example |
|
| Zoom | zoommtg:// |
zoommtg://zoom.us/join?confno=123456 |
Handling Missing Apps
If the app isn't installed, custom scheme links fail silently or show an error. Common patterns include:
- Universal Links (iOS) / App Links (Android): Use regular HTTPS URLs that the app can intercept if installed
- Fallback URLs: Redirect to app store or web version if app isn't available
- Smart App Banners: Prompt users to install the app
<!-- Better: Use universal link that falls back to web --> <a href="https://open.spotify.com/track/4PTG3Z6ehGkBFwjybzWkR8"> Listen on Spotify </a>
Registering Custom Protocol Handlers
Web applications can register themselves as handlers for specific URL schemes using the registerProtocolHandler() API.
// Register your web app to handle "web+myapp:" URLs navigator.registerProtocolHandler( 'web+myapp', 'https://myapp.com/handle?url=%s', 'My App' );
Restrictions
- Custom schemes must start with
web+followed by at least one letter - The handler URL must be on the same origin as the registering page
- User permission is required
- Only works with user gesture (click, etc.)
Standard schemes that web apps can handle include:
mailto:— Email clientirc:/ircs:— IRC chatxmpp:— XMPP messaging
Security Considerations
URL schemes can be exploited for malicious purposes. Be aware of these risks:
The Dangerous javascript: Scheme
The javascript: scheme executes JavaScript code:
<!-- DANGEROUS - Never allow user-provided javascript: URLs -->
<a href="javascript:alert('XSS!')">Click me</a>
This is a major Cross-Site Scripting (XSS) vector. Never:
- Allow users to input URLs that could be
javascript: - Use
javascript:for navigation - Put user data in
javascript:URLs
Scheme Validation
When accepting user-provided URLs, validate the scheme:
function isAllowedUrl(url) {
try {
const parsed = new URL(url);
const allowedSchemes = ['http:', 'https:', 'mailto:', 'tel:'];
return allowedSchemes.includes(parsed.protocol);
} catch {
return false; // Invalid URL
}
}
Data: Scheme Risks
The data: scheme (covered in the next tutorial) can also be exploited. Be cautious with user-provided data URLs, especially those containing HTML or JavaScript.
Practical Contact Card Example
Here's a complete contact section using multiple URL schemes:
<address>
<h2>Contact Us</h2>
<p>
<strong>Email:</strong>
<a href="mailto:hello@example.com?subject=Website%20Inquiry">
hello@example.com
</a>
</p>
<p>
<strong>Phone:</strong>
<a href="tel:+15551234567">+1 (555) 123-4567</a>
</p>
<p>
<strong>Text:</strong>
<a href="sms:+15551234567">Send SMS</a>
</p>
<p>
<strong>Location:</strong>
<a href="https://maps.google.com/?q=123+Main+St,+City,+State">
123 Main Street, City, State
</a>
</p>
</address>