The tel: scheme creates clickable phone links. On mobile devices, these trigger a call; on desktop, they may open calling apps like Skype or FaceTime.
On phones, a clickable phone number saves visitors from copying digits by hand. A properly formatted tel: link lets users call you with a single tap, removing friction from the conversion process.
Key Takeaways
- 1Use international format (+1234567890) for universal compatibility
- 2Extensions: ;ext= (RFC 3966) or a dialer pause (,)
- 3SMS links use sms: scheme instead
- 4Mobile devices dial directly; desktop needs calling software
- 5Strip spaces from the URL (RFC 3966 forbids them)
"This document defines the URI scheme "tel", which describes resources identified by telephone numbers. A telephone number is a string of decimal digits that uniquely indicates the network termination point."
Tel URL Structure
Tel URLs have a simple structure: the scheme followed by the phone number. The key is formatting the number correctly—always use international format with the country code to ensure the link works for visitors worldwide.
# Basic tel URL
tel:+15551234567
# Format:
tel:+{country}{number}
# Examples by country:
tel:+15551234567 # USA: +1 (555) 123-4567
tel:+442071234567 # UK: +44 20 7123 4567
tel:+33123456789 # France: +33 1 23 45 67 89
tel:+4930123456 # Germany: +49 30 123456
tel:+81312345678 # Japan: +81 3 1234 5678
# Without country code (local only)
tel:5551234567 # May not work internationally
# (RFC 3966: local numbers MUST carry ;phone-context=...)
# With extension
tel:+15551234567,123 # Pause then dial extension (dialer convention)
tel:+15551234567;ext=123 # Extension parameter (RFC 3966)The examples above show phone numbers from different countries, all using the international E.164 format (plus sign, country code, national number with no spaces). Omitting the country code may work for local users but will fail for international visitors.
RFC 3966 allows the visual separators -, ., ( and ) but forbids spaces; stripping all formatting is the simplest safe choice. Either way, you'll want to display phone numbers in a human-readable format. Let's look at how to handle this.
Phone Number Formatting
The table below shows the relationship between display formatting and tel: URL formatting. Users see the readable version; the URL contains the machine-readable version.
| Format | Display | Tel URL |
|---|---|---|
| US local | (555) 123-4567 | tel:+15551234567 |
| US full | +1 555-123-4567 | tel:+15551234567 |
| UK | +44 20 7123 4567 | tel:+442071234567 |
| With ext | +1 555-123-4567 x123 | tel:+15551234567,123 |
| Toll-free | 1-800-123-4567 | tel:+18001234567 |
Notice how the display format includes parentheses, dashes, and spaces for readability, while the tel: URL strips all of these. The link text can use any format—only the href needs to be clean.
Let's see how to implement phone links in HTML, including accessibility and SEO best practices.
HTML Examples
These examples demonstrate progressively more sophisticated phone links, from basic click-to-call to accessible, SEO-optimized business listings with schema markup.
<!-- Basic phone link -->
<a href="tel:+15551234567">+1 (555) 123-4567</a>
<!-- With visual formatting -->
<a href="tel:+15551234567">(555) 123-4567</a>
<!-- With extension -->
<a href="tel:+15551234567,123">Call Sales (ext. 123)</a>
<!-- International -->
<a href="tel:+442071234567">+44 20 7123 4567</a>
<!-- Business listing -->
<div itemscope itemtype="https://schema.org/LocalBusiness">
<span itemprop="name">Example Business</span>
<a itemprop="telephone" href="tel:+15551234567">
+1 (555) 123-4567
</a>
</div>
<!-- Accessible phone link -->
<a href="tel:+15551234567" aria-label="Call us at 555-123-4567">
<span aria-hidden="true">📞</span>
(555) 123-4567
</a>The Schema.org markup in the business listing example helps search engines understand and display your phone number in rich results. The accessible version uses aria-label to provide context for screen readers.
For business phone systems, you often need to dial an extension after the main number. Tel URLs support this with pause characters.
Dial Pauses and Extensions
When calling automated systems, you need to wait for prompts before entering extensions or menu choices. Phone dialers commonly support two pause mechanisms: comma for timed pauses and semicolon for user-confirmed pauses. These are dialer conventions, not part of RFC 3966, which removed the pause characters of its predecessor RFC 2806 (and uses ; to start parameters such as ;ext=).
# Pause characters
# Comma (,) - Short timed pause (length is device-dependent)
tel:+15551234567,,,123
# Waits three pauses, then dials 123
# Semicolon (;) - Wait for user (not valid RFC 3966 syntax)
tel:+15551234567;123
# Dials number, shows 123 to dial manually
# DTMF tones
tel:+15551234567,1,2,3
# Dials number, pauses, sends 1, pauses, sends 2, etc.
# Extension formats
tel:+15551234567,123 # Dialer pause (widely used)
tel:+15551234567;ext=123 # RFC 3966 format
tel:+15551234567p123 # Some systems
# Automated menu navigation
tel:+18001234567,,1,,3,,2
# Calls, waits, presses 1, waits, presses 3, waits, presses 2Each comma adds one timed pause (its length depends on the phone), so ,,, waits three times as long as ,. The automated menu example shows how to pre-program a call that navigates through an IVR menu—useful for links that need to reach a specific department.
Beyond phone calls, you may also want to let users send text messages. The sms: scheme works similarly but has some platform differences.
SMS Links
The sms: scheme opens the user's messaging app. While the basic format is simple, pre-filling the message body has platform-specific quirks you need to handle.
<!-- SMS link (different scheme) -->
<a href="sms:+15551234567">Send SMS</a>
<!-- With body (iOS) -->
<a href="sms:+15551234567&body=Hello">Text with message</a>
<!-- With body (Android; also the RFC 5724 standard form) -->
<a href="sms:+15551234567?body=Hello">Text with message</a>
<!-- Cross-platform (may not work everywhere) -->
<a href="sms:+15551234567?&body=Hello">Send SMS</a>
<!-- Group SMS -->
<a href="sms:+15551234567,+15559876543">Group Text</a>
<!-- Note: SMS body support varies by device/OS -->Unfortunately, iOS and Android use different syntaxes for the body parameter (&body= vs ?body=). The cross-platform version with ?&body= works on most devices but isn't guaranteed. For critical functionality, consider detecting the platform or using a two-step flow.
Let's look at how to build phone links dynamically in JavaScript, including handling formatted input and conditional rendering.
JavaScript Phone Link
When building phone links programmatically, you need to clean formatting characters from the input. The functions below handle this conversion and provide a reusable React component.
// Build tel URL from formatted number
function cleanPhoneNumber(phone) {
// Remove all non-numeric except +
return phone.replace(/[^\d+]/g, '');
}
function buildTelUrl(phone, extension) {
const cleaned = cleanPhoneNumber(phone);
if (extension) {
return `tel:${cleaned},${extension}`;
}
return `tel:${cleaned}`;
}
// Usage
buildTelUrl('+1 (555) 123-4567'); // tel:+15551234567
buildTelUrl('+1 (555) 123-4567', 123); // tel:+15551234567,123
// Phone link component
function PhoneLink({ number, extension, children }) {
const href = buildTelUrl(number, extension);
return (
<a href={href}>
{children || number}
</a>
);
}
// Detect mobile for click-to-call
function isMobileDevice() {
return /Android|iPhone|iPad|iPod|webOS/i.test(navigator.userAgent);
}
// Conditional rendering
{isMobileDevice() ? (
<a href="tel:+15551234567">Call Now</a>
) : (
<span>+1 (555) 123-4567</span>
)}The cleanPhoneNumber function strips everything except digits and the plus sign, making it safe to pass user-formatted numbers. The mobile detection at the end shows a common pattern: making numbers clickable on mobile but showing plain text on desktop where click-to-call is less reliable.