Opens in a new tab
  1. Home
  2. Guides
  3. Utilities
Utilities guide

WordPress Antispambot() vs. Full Email Encoding

Learn how WordPress antispambot() compares with full email encoding, how HTML character references obscure addresses, why neither method is encryption and when a different approach is needed.

  • Updated September 16, 2026
  • 20 min read
  • WordPress guide

WordPress includes a small but useful function called antispambot() that can obscure email addresses before they are sent to the browser.

At first glance, the idea seems straightforward: instead of placing a readable address such as hello@example.com directly in the HTML source, convert some or all of its characters into alternative representations that the browser can still display correctly.

But there are several ways to do this, and they are not equivalent.

WordPress antispambot() uses randomized obfuscation. A custom full-email encoder, by contrast, can encode every character in the address. Both can make basic email harvesting more difficult, but neither makes a public email address secret.

This distinction matters because email encoding is often described as though it were a security boundary. It is not. If a browser can reconstruct an address for a visitor, sufficiently capable automated software can potentially reconstruct it too.

In this guide, we will compare WordPress antispambot() with full email encoding, examine what actually appears in the HTML source, look at mailto: links, discuss accessibility and JavaScript-based alternatives, and explain where TheOneWP Cover Email Address fits into the wider problem of reducing automated email harvesting.

Why public email addresses attract automated harvesting

A normal email link is extremely easy for software to recognize.

Consider this markup:

<a href="mailto:hello@example.com">hello@example.com</a>

The address appears twice:

  • inside the visible anchor text;
  • inside the mailto: URL.

A visitor needs no special processing to understand it, but neither does a crawler.

An automated scraper can download HTML, search for common email patterns, inspect mailto: links and collect addresses at scale.

This is not specifically a WordPress weakness. It is a consequence of publishing machine-readable information in a public HTML document.

For a broader look at where addresses and account identifiers can become public, see How Attackers Collect WordPress Usernames and Email Addresses.

A public email address does not automatically compromise a WordPress account. Even when WordPress accepts an email address as a login identifier, authentication still requires valid credentials. The distinction between an identifier and an authentication secret is covered in WordPress Login: Username vs. Email, Which Is More Secure?.

Publishing an address can nevertheless increase exposure to:

  • unsolicited email;
  • bulk harvesting;
  • phishing attempts;
  • targeted social engineering;
  • credential-stuffing reconnaissance when the same address is used as an account identifier.

Email obfuscation tries to reduce the easiest form of this collection without preventing legitimate visitors from seeing or using the address.

What WordPress antispambot() actually does

WordPress provides the antispambot() function specifically for obscuring email addresses in HTML.

Its basic signature is:

antispambot( string $email_address, int $hex_encoding = 0 ): string

A simple use looks like this:

$email = 'hello@example.com';

echo antispambot( $email );

The important detail is that antispambot() does not simply replace every character with the same type of encoding.

Current WordPress Core processes the address character by character and randomly chooses how individual characters are represented. Without the optional hex mode, a character may remain literal or become a decimal HTML character reference.

The @ character is ultimately replaced with its numeric character reference:

&#64;

So an address might conceptually become something similar to:

hel&#108;o&#64;exam&#112;le.com

The exact result is not fixed because the function deliberately randomizes the representation.

The browser still renders the readable address:

hello@example.com

while the raw HTML contains a less immediately recognizable representation.

WordPress 7.1 improved multibyte handling

The current implementation of antispambot() changed in WordPress 7.1 to obscure multibyte characters rather than treating the function purely as a byte-oriented ASCII transformation.

This matters for internationalized text because characters outside basic ASCII can occupy multiple bytes in UTF-8.

The current WordPress documentation also notes that invalid UTF-8 spans are passed through without obfuscation rather than being incorrectly transformed.

For ordinary ASCII addresses the conceptual purpose remains the same: make the address less obvious in raw markup while preserving the value that a browser can present to the user.

What the hex_encoding option changes

antispambot() accepts a second parameter:

antispambot( $email, 1 )

Setting it to 1 enables an additional representation.

WordPress can then randomly choose between:

  • the original character;
  • a decimal HTML character reference;
  • percent encoding.

A simplified result can therefore contain a mixture such as:

%68&#101;l%6Co&#64;%65xample.com

This makes the source less uniform than applying one deterministic transformation to every address.

It is important not to confuse this with encryption.

The transformation contains enough information for the original address to be recovered. That is necessary because legitimate software eventually needs to interpret the address.

Randomization can frustrate simplistic pattern matching, but it does not create a secret key or prevent decoding.

What full email encoding means

There is no single WordPress Core function named “full email encoding.” The phrase generally describes a strategy where every character of an email address is transformed rather than only a random subset.

For example, the address:

hello@example.com

could be represented using decimal numeric character references.

Conceptually:

h       → &#104;
e       → &#101;
l       → &#108;
l       → &#108;
o       → &#111;
@       → &#64;

The resulting source can therefore contain an encoded representation for every character while the browser displays the normal address.

HTML character references are a standard part of HTML, not a WordPress-specific mechanism. The MDN character reference documentation distinguishes named, decimal numeric and hexadecimal numeric character references.

Decimal references use a structure such as:

&#104;

while hexadecimal references use a structure such as:

&#x68;

Both can represent the character h.

The HTML Standard defines how these character references are parsed by browsers.

Full encoding produces more complete source obfuscation

The obvious advantage is that the plaintext address does not need to appear as one uninterrupted string in the HTML source.

Instead of a partly transformed address, every character can be represented indirectly.

This can defeat a scraper that does little more than apply a basic email regular expression to raw HTML.

But the browser must decode those character references to render the page.

A scraper that understands HTML can do the same thing.

That is the fundamental limitation of full encoding.

Antispambot() vs. full encoding

The two approaches are easier to compare directly.

Characteristic antispambot() Full email encoding
Built into WordPress Core Yes Not as one dedicated Core API
Randomized output Yes Depends on implementation
Encodes every character Not necessarily Typically yes
Supports HTML character references Yes Typically yes
Can use percent encoding Yes, with $hex_encoding = 1 Depends on implementation
Browser can reconstruct address Yes Yes
Stops basic raw-source matching Can reduce it Can reduce it
Stops a decoder-aware scraper No guarantee No guarantee
Encryption No No

The practical difference is therefore not “weak protection versus perfect protection.”

It is a comparison between two forms of reversible obfuscation.

antispambot() has the advantage of being maintained as part of WordPress Core and deliberately varies its output. Full encoding can eliminate literal characters from the address more comprehensively, but a deterministic wall of numeric entities is still straightforward for an HTML-aware parser to decode.

If your wider goal is to reduce public email harvesting in WordPress rather than compare implementation details, see How to Hide Email Addresses from Spam Bots in WordPress.

Why encoding does not make an email address private

This is the most important limitation of the entire technique.

Suppose the HTML source contains:

&#104;&#101;&#108;&#108;&#111;&#64;...

A human looking at raw source may not immediately recognize the address.

A browser does.

That means the transformation follows a documented and reversible standard.

A scraper can:

  1. download the page;
  2. parse the HTML;
  3. resolve character references;
  4. inspect the resulting text and attributes;
  5. search for email-address patterns.

At that point, fully encoded HTML can become ordinary text again.

Rendered-page scraping changes the problem further

Modern automation does not have to inspect raw HTML as an uninterpreted string.

Software can use an HTML parser or browser automation environment and inspect the document after parsing.

If the rendered DOM ultimately contains a usable email address, the encoding has already served its purpose for the browser and can also become visible to automated processing.

The same principle applies to many client-side obfuscation techniques.

If JavaScript reconstructs:

hello@example.com

for a real visitor, a crawler capable of executing that JavaScript may eventually obtain the same result.

Obfuscation still has value

The limitation does not make the technique useless.

Security and privacy controls do not always need to defeat every theoretical adversary to provide value.

If a technique cheaply reduces harvesting by simplistic bots without making the website difficult to use, it can still be a reasonable defensive layer.

The mistake is presenting it as guaranteed protection.

TheOneWP’s own Cover Email Address should be understood in this same context: reducing straightforward automated harvesting, not turning a publicly available contact address into confidential information.

Protect both visible text and mailto links

A common implementation mistake is to obscure only what visitors can see.

Consider:

<a href="mailto:hello@example.com">
    Contact our team
</a>

The visible text does not contain an email address.

The HTML source still does.

A scraper looking specifically for:

mailto:

does not care whether the anchor says “Contact our team,” “Email us” or anything else.

The address remains directly available in the href.

The opposite mistake is possible too:

<a href="mailto:encoded-value">
    hello@example.com
</a>

Now the link target may be obscured while the visible text exposes the original address.

When an email address is intentionally obfuscated, review every place where the address appears.

Build the mailto link carefully

A simple WordPress implementation can start with:

$email = 'hello@example.com';
$safe_email = antispambot( $email );

printf(
    '<a href="%1$s">%2$s</a>',
    esc_attr( 'mailto:' . $safe_email ),
    esc_html( $safe_email )
);

However, output handling deserves attention because encoding and escaping are different operations.

antispambot() obscures the address. Escaping functions protect output according to the HTML context in which a value is being inserted.

Do not assume that calling an obfuscation function eliminates the need to think about output safety.

The WordPress Escaping Data documentation explains why values should be escaped according to their final output context.

Obfuscation is not email validation

antispambot() also does not answer the question:

Is this a valid email address?

WordPress provides separate APIs for email handling.

sanitize_email(), for example, removes characters that WordPress does not allow in its sanitized email representation.

Validation, sanitization, escaping and obfuscation solve different problems. Treating them as interchangeable tends to produce code that appears secure while quietly doing the wrong job.

Should you use JavaScript instead?

Another common approach is to avoid placing the complete address in the initial HTML and reconstruct it with JavaScript.

For example, a script might combine:

hello

with:

example.com

and insert the @ symbol at runtime.

This can defeat a scraper that downloads HTML but never executes JavaScript.

It also introduces additional considerations:

  • the contact method may depend on JavaScript;
  • accessibility must be tested;
  • caching and optimization can affect execution;
  • content may not exist in the initial document;
  • modern crawlers can execute JavaScript;
  • the implementation becomes more complex than HTML character references.

JavaScript therefore changes the harvesting threshold rather than creating guaranteed secrecy.

Do not damage usability to hide a public contact address

A technically clever obfuscation mechanism can become counterproductive if visitors can no longer:

  • select the address;
  • copy it;
  • activate the email link;
  • use it with assistive technology;
  • access it when JavaScript fails.

If the purpose of publishing the address is to let people contact the organization, the protection should not make that task unreliable.

This is one reason server-generated HTML character references remain attractive for simple use cases: browsers understand them natively without requiring a custom client-side decoding application.

When not publishing the address is stronger

If an email address genuinely must remain private, reversible obfuscation is the wrong security model.

The strongest way to prevent a public page from revealing an address is not to publish that address to the visitor in the first place.

A website could instead provide:

  • a contact form;
  • a support ticket interface;
  • a role-based contact alias;
  • a server-side message relay;
  • a dedicated public address separated from privileged accounts.

The server can receive the visitor’s message and route it internally without exposing the destination mailbox in the page source.

This changes the architecture rather than merely changing the representation of the address.

A contact form introduces its own spam problem

Replacing a public email address with a form does not eliminate automated abuse.

It changes what attackers target.

The form may then require:

  • rate limiting;
  • bot detection;
  • server-side validation;
  • spam filtering;
  • submission logging;
  • CSRF protections appropriate to the implementation.

The important distinction is that the destination email address no longer needs to be disclosed to every visitor merely to make contact possible.

Separate public addresses from privileged WordPress accounts

If a company intentionally publishes:

info@example.com

there is usually little reason for that same address to be the identifier of the most privileged WordPress administrator account.

Separating public contact identities from administrative identities reduces unnecessary coupling between marketing information and authentication information.

This does not make an administrator account secure by itself, but it supports a more deliberate exposure model.

For the wider authentication strategy, see A WordPress Login Hardening Checklist.

Choosing the right approach in WordPress

There is no need to turn every public email address into an elaborate anti-scraping project.

The appropriate approach depends on why the address exists and how sensitive its exposure is.

Situation Reasonable approach
Ordinary public business address Obfuscation can reduce basic harvesting while preserving usability
Address displayed by custom PHP antispambot() provides a native WordPress mechanism
Need to obscure every literal character Full encoding can provide more complete source transformation
Address must remain genuinely undisclosed Do not send the address to the public page
Contact must work without exposing destination mailbox Use an appropriately protected server-side form or messaging workflow
Public address is also a privileged login identifier Consider separating public and administrative identities

Use antispambot() when native WordPress integration is enough

For custom WordPress PHP, antispambot() has several practical advantages:

  • it is part of WordPress Core;
  • it requires no custom decoder;
  • its output is randomized;
  • it can optionally include percent encoding;
  • WordPress maintains the implementation as Core evolves.

It is a sensible lightweight choice when the objective is simply to make raw-source harvesting less trivial.

Use full encoding when complete literal transformation matters

A full encoder may be useful when you specifically want every character transformed in the generated source.

But do not describe that as fundamentally stronger secrecy.

It is still an encoding that standards-aware software can reverse.

Use TheOneWP when you want the behavior managed centrally

If the goal is to reduce exposure without maintaining custom snippets across a site, TheOneWP Cover Email Address provides a dedicated control for making publicly displayed addresses less straightforward for basic automated harvesting.

This fits particularly well when the requirement is operational rather than developmental: you want email exposure handled as a site configuration concern instead of scattering custom obfuscation code across templates.

The same principle appears elsewhere in WordPress administration. Centralized controls are easier to audit than unrelated snippets whose existence depends on somebody remembering why they were added three years earlier.

Common mistakes with email obfuscation

Email encoding is simple enough that the most serious problems usually come from incorrect assumptions rather than difficult code.

Calling encoding encryption

HTML character references are not encryption.

There is no secret key involved, and the browser is expected to recover the represented characters.

Encoding only the visible address

If the plaintext address remains inside href="mailto:...", a scraper can ignore the visible text completely.

Encoding only the mailto target

If the visible anchor still says hello@example.com, the address remains available in the document text.

Assuming JavaScript defeats all crawlers

Some crawlers execute JavaScript. Client-side reconstruction raises the effort required for simplistic harvesting but does not guarantee that the reconstructed address remains hidden.

Using a public contact address as a security secret

If an address must be shown to every visitor, design security as though that address can eventually become known.

That principle is particularly relevant when email addresses can also function as WordPress login identifiers.

See How Attackers Collect WordPress Usernames and Email Addresses for the wider reconnaissance problem.

Breaking accessibility or copy-and-paste behavior

Visitors should not have to solve a puzzle to contact a business.

Test the final result as a real interactive element rather than checking only whether the source code looks sufficiently scrambled.

Forgetting cached HTML

If obfuscated output is generated server-side and then cached, the same generated representation may be served repeatedly until the cache is refreshed.

This does not make the output invalid, but it can reduce the practical variation produced by a randomized function such as antispambot().

That is another reason not to treat randomization itself as the security boundary.

Related guides

Final recommendation

WordPress antispambot() and full email encoding solve the same general problem at different levels of completeness: they make an email address less obvious in the raw page source while preserving a usable address for legitimate visitors.

antispambot() is the native WordPress option. It randomly varies the representation of characters and can optionally mix HTML character references with percent encoding. In WordPress 7.1, its implementation was updated to handle multibyte characters more deliberately.

Full encoding can transform every character of an address, producing source code with no continuous plaintext email address. That can make simplistic regular-expression harvesting less effective.

Neither technique should be treated as encryption or guaranteed anti-spam protection.

HTML character references are standardized and reversible. A browser can decode them, and an HTML-aware scraper can potentially do the same. JavaScript-based reconstruction follows the same general rule: if client-side software can recover the address for a visitor, sufficiently capable automation may also recover it.

For ordinary public business addresses, lightweight obfuscation can still be worthwhile because it raises the cost of basic harvesting without significantly harming usability.

For addresses that genuinely must remain private, use a different architecture. Do not deliver the address to the public page at all. Route communication through a server-side contact mechanism or another controlled interface instead.

And when an address must remain public, treat it as public information. Protect WordPress authentication independently with strong credentials, appropriate login controls and additional authentication layers rather than relying on the email address remaining undiscovered.

Simplify your WordPress stack

A modular WordPress toolkit. 104 focused tools.

Ultimately, you can build cleaner workflows, maintain fewer plugins and enable only the features each website actually needs.