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.
With mobile web traffic exceeding 60% globally, clickable phone numbers are essential for business websites. 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 use ,, or ; for pauses
- 3SMS links use sms: scheme instead
- 4Mobile devices dial directly; desktop needs calling software
- 5Remove formatting characters for the URL
"The tel URI defines the URI scheme for 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
# With extension
tel:+15551234567,123 # Pause then dial extension
tel:+15551234567;ext=123 # Extension parameterThe 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.
While tel: URLs require clean numbers without formatting, 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. Tel URLs support two pause mechanisms: comma for timed pauses and semicolon for user-confirmed pauses.
# Pause characters
# Comma (,) - Short pause (2 seconds)
tel:+15551234567,,,123
# Waits 6 seconds, then dials 123
# Semicolon (;) - Wait for user
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 # Preferred
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 2The comma creates a 2-second pause, so ,,, waits 6 seconds. 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) -->
<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.