WP Shadow Links
⚠️Pre-Alpha Phase⚠️ Simple plugin for protecting e-mail links from spambots
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/meksone/wp-shadow-links/archive/refs/heads/main.zipReadme
📧 WP Shadow Links
Based on Obfuscated Email Link Generator JS Version 0.1.9
The original script was primarily created for use in WordPress websites, using Elementor Pro or other page builders that make it easy to add "data-attributes" to elements; However, it can be used on any type of website, on plain HTML or Javascript.
This plugin is intended specifically for WordPress, and provides several ways to add email links that are visible only on the frontend and completely absent in the source code of the page. Doing this, crawlers and spambots can't harvest email addresses or, at least, this makes the task more difficult, because parsing the live DOM is required instead of simply searching for email addresses in the raw page source.
⭐ Key features
- Automatic Source Obfuscation - PHP filter scans post content, excerpts, and widgets before output, and obfuscates every
<a href="mailto:...">link and every plain-text email address automatically — no manual configuration needed - Base64 Encoding - Email addresses are Base64-encoded server-side; the raw page source contains no readable
@address. JavaScript decodes them in the live DOM using the nativeatob()function - Manual Data-Attribute Method - Supports the original approach: split an email across
data-email/data-domainattributes for use in page builders like Elementor Pro or plain HTML - Shortcode Support -
[shadow_link]shortcode for inserting obfuscated email links from the WordPress editor - Flexible Targeting - Can target specific elements by class or use the source element
- URL Encoding - Properly encodes subject and body parameters
- Validation - Validates email and domain formats
- Error Handling - Graceful error handling with console warnings
- Accessibility - Adds title attributes for better accessibility
- Dynamic Content Support - Methods for processing dynamically added content
- Optimized Performance - Avoids duplicate processing with processed-element flags
- Avoid Spam Bots - Since the HTML source is free from readable email addresses (links are reconstructed only in the live DOM), most spam bots, crawlers, and data-scraping tools cannot see email addresses, reducing the risk of ending up in spam lists
The script automatically runs when the DOM is loaded and creates functional mailto links from obfuscated data.
🔍 Automatic Email Obfuscation (PHP filter)
This is the easiest way to protect emails — it requires no changes to your existing content.
When a page is rendered, the plugin scans the output of posts, pages, excerpts, and widgets for any exposed email address and obfuscates it before the HTML is sent to the browser:
- Mailto links —
<a href="mailto:user@example.com">Contact us</a>written in the block editor or any page builder is intercepted, the email is Base64-encoded, and the<a>is replaced with an inert<span data-shadow-email="...">. Original link attributes (class,target,title,rel) and inner HTML are preserved and restored by JavaScript. - Plain-text emails — A bare address like
support@example.comappearing in body text is wrapped in the same<span data-shadow-email="...">and converted into a clickable mailto link on the frontend.
In both cases the raw page source contains no literal @ character in the email position — only the Base64 payload is visible:
<!-- What you write in the editor -->
<a href="mailto:contact@example.com">Email us</a>
Write to contact@example.com for info.
<!-- What appears in the page source -->
<span data-shadow-email="Y29udGFjdEBleGFtcGxlLmNvbQ==" data-shadow-inner="RW1haWwgdXM=">Email@us</span>
Write to <span data-shadow-email="Y29udGFjdEBleGFtcGxlLmNvbQ==">contact@example.com</span> for info.
<!-- What the visitor sees in the live DOM (after JS runs) -->
<a href="mailto:contact@example.com" class="mk-mailto-link" title="Send email to contact@example.com">Email us</a>
Write to <a href="mailto:contact@example.com" class="mk-mailto-link">contact@example.com</a> for info.
No-JS fallback: The span fallback text uses the HTML entity
@for@, so the address remains human-readable in browsers without JavaScript but still cannot be harvested by plain-text scrapers.
🏷️ Manual Data-Attribute Method
For fine-grained control — custom icons, copy-to-clipboard buttons, subject/body pre-fill — you can use data attributes directly on any HTML element or via the shortcode. This method works in Elementor Pro, Gutenberg HTML blocks, or plain HTML.
Data attributes
| Data attribute | Required? | Description |
|---|---|---|
| data-email | Yes | the username part of the email (all the text before the @) |
| data-domain | Yes | only the domain part (after the @, and without @ itself) |
| data-subject | No | the subject of the email |
| data-body | No | the body of the email |
| data-class | No | the class of the element that must be converted to email link |
| data-target | No | specify if the link should open in a new tab; any value is valid (true, yes, _blank) because only the presence is checked |
| data-title | No | If present, use the text provided as title on hover (for accessibility); if absent, a default text is used ("Send e-mail to" or "Invia e-mail a" for Italian sites) |
| data-copylink | No | if set to true, adds a copy-to-clipboard button with the default icon (Font Awesome far fa-clipboard);if set to any other value, that value is used as button text; a custom icon is used if data-copylink-icon is also present |
| data-copylink-title | No | Custom tooltip for the copy button; defaults to "Copy e-mail" / "Copia l'e-mail" |
| data-copylink-icon | No | Custom Font Awesome class for the copy button icon (default: far fa-clipboard) |
| data-icon | No | If set to true, adds a default envelope icon (far fa-envelope) to the left of the link; if set to a Font Awesome class, that icon is used instead |
| data-linkwrapper | No | Custom class name for the <div> wrapper that contains the mailto link and copy button; defaults to mk-linkwrapper |
ℹ️ Shortcode attributes
The [shadow_link] shortcode accepts the same attributes without the data- prefix — so data-email becomes email, data-copylink becomes copylink, and so on, with identical behaviour.
CSS classes for custom styling
The link inherits the styling of the element it is attached to. Additional CSS classes are available for custom styling:
| CSS default class name | Customizable? | Purpose |
|---|---|---|
| .mk-icon | No | icon inside the email link (if present) |
| .mk-copylink-btn | No | copy-to-clipboard button (if present) |
| .mk-mailto-link | No | the generated <a> element (applies to both auto-detected and manual links) |
| .mk-linkwrapper | Yes | wrapper <div> around the links; use display:flex for inline/stacked layout control. Customise the class name with data-linkwrapper |
🔐 Security Notes
- When
data-targetis set (or the original link hadtarget="_blank"), the plugin automatically addsrel="noopener noreferrer"to prevent the new page from accessingwindow.opener. - The Base64 encoding used by the automatic PHP filter is not encryption — it is obfuscation. It reliably defeats simple regex scrapers and the vast majority of harvesting bots. A determined attacker running a full headless browser could still decode the address, but that is a significantly higher barrier than scraping raw HTML.
ℹ️ Disclaimer
Please consider I'm not a professional developer, or to say it better: programming is not my main activity.
I'm working in IT since 90's, I've ever loved to create websites and when WordPress appeared I chose it as my main tool. If you plan to use this script in production, please consider personally reviewing the code and making any necessary changes for your case. Or simply, don't use it.
⚠️The script/plug-in is offered "as-is" without any guarantee, use it at your own risk! ⚠️
(sorry, I must say this, there's a lot of bad people out there! 😅)
🤖 AI Disclaimer
As previously stated, I'm not a professional developer and I've used AI (Claude Sonnet) to create and improve this script; though, I've personally tested it on my environment and I'm confident enough to use it on public-facing sites. Feel free to review, modify, fork, suggest, ignore it or whatever else you want.
💾 Implement in your site
WordPress plugin (recommended)
Install and activate the plugin. The automatic PHP filter is enabled immediately — no configuration required. All <a href="mailto:..."> links and plain-text email addresses in posts, pages, excerpts, and widget text areas are obfuscated automatically.
For advanced links (custom icons, copy button, subject/body pre-fill) use the [shadow_link] shortcode or the data-attribute method in a page builder.
Standalone JS (non-WordPress sites)
You can use the JS engine alone on any website. Include the script before </body>:
<script src="path/to/email-link-generator.js" type="text/javascript"></script>
Or paste the contents inside `
Read the full README on GitHub →
Releases
These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.