DEV Community

Wabbiyo
Wabbiyo

Posted on

wa.me Links Explained: Formats, Encoding and Gotchas for Pre-Filled WhatsApp Messages

Click-to-chat links (https://wa.me/?text=) look trivial, but they break in surprisingly common ways. Here’s what to get right.

The number format

Full international format: country code + number
No +, spaces, dashes or brackets
Drop the national leading zero: UK 07700 900123 becomes 447700900123

A quick JavaScript helper:

js
function waLink(number, message = '') {
const digits = String(number).replace(/\D/g, '');
const text = message ? ?text=${encodeURIComponent(message)} : '';
return https://wa.me/${digits}${text};
}

waLink('+91 98765 43210', 'Hi, I need help with order #1042');
// https://wa.me/919876543210?text=Hi%2C%20I%20need%20help%20with%20order%20%231042

Note: stripping non-digits removes + and spaces, but not a national leading zero. Store numbers in international format from the start.

Encoding the message
Always encode the whole message, not just the spaces. Characters that break links when left raw:

Character Encoded
space %20
new line %0A
& %26

%23

? %3F

  • %2B

In JS use encodeURIComponent(). In PHP use rawurlencode(), which turns spaces into %20. Plain urlencode() turns them into +.

Gotchas

On desktop, the link opens WhatsApp Web, not the app.
The pre-filled text is editable; the user can change or delete it.
The link can’t send anything by itself. For automated messages (order updates, reminders) you need the WhatsApp Business API.
The number must be registered on WhatsApp, or the user sees an error.

We wrote up five ways to add WhatsApp to a WordPress site, from these links to full API automation: How to add WhatsApp to WordPress

No-plugin floating button for WordPress: read on Hashnode

Top comments (1)

Collapse
 
srkdan_writes profile image
SRKDAN •

good catch on the leading zero. stripping non-digits isn't enough for numbers like 0700... that still need the country code swap. we shoved libphonenumber (or a thin E.164 helper) in front of waLink and that fixed the UK/NL cases. also the code blocks in the post lost their backticks in the rendered version, so the template literals won't run as shown.