PHPackages                             wppack/sanitize-characters-plugin - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. wppack/sanitize-characters-plugin

ActiveWordpress-plugin

wppack/sanitize-characters-plugin
=================================

Sanitize invisible and control characters (zero-width spaces, BOM, bidi controls, C0/C1 controls, soft hyphens) out of posts, ACF fields and search terms, plus a WP-CLI command to clean existing data.

v1.0.1(1mo ago)0266↓75%MITPHPPHP ^8.2CI passing

Since Jul 16Pushed 1mo agoCompare

[ Source](https://github.com/wppack-io/sanitize-characters-plugin)[ Packagist](https://packagist.org/packages/wppack/sanitize-characters-plugin)[ RSS](/packages/wppack-sanitize-characters-plugin/feed)WikiDiscussions 1.x Synced 1w ago

READMEChangelogDependencies (23)Versions (3)Used By (0)

WPPack Sanitize Characters
==========================

[](#wppack-sanitize-characters)

[![CI](https://camo.githubusercontent.com/6fdd6c2acf178b24e395a746d054329a571bdb8fa1d089ce5e169a2c9ac8e51f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f77707061636b2d696f2f73616e6974697a652d636861726163746572732d706c7567696e2f63692e796d6c3f6272616e63683d312e78)](https://github.com/wppack-io/sanitize-characters-plugin/actions/workflows/ci.yml)[![License: MIT](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![PHP Version](https://camo.githubusercontent.com/c2588b5670f2c910b8cc849ace22a22efda8956b7c2f797d11d2096bbfc7b1f5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d3737374242342e737667)](https://php.net)[![WordPress](https://camo.githubusercontent.com/64babe529b54d28abac0e1bd2d50aad20cc7e96787fbc49998ee3221c4385896/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f576f726450726573732d362e372532422d3231373539422e737667)](https://wordpress.org)

[日本語版 README](README.ja.md)

Sanitizes invisible and control characters out of content on its way into WordPress and out of search terms on their way into a query. No settings screen, no options in the database.

The problem
-----------

[](#the-problem)

Word processors and note-taking tools (Google Docs, Notion, …) inject zero-width characters into text as soft line-break hints; PDFs and terminals leak control characters and odd separators. Pasted into WordPress they survive invisibly inside titles, body text and search boxes. Search then fails on strings that look identical on screen: a title containing `Broad​way` (with a hidden U+200B) never matches a typed `Broadway`, and a pasted search term with a trailing zero-width space matches nothing — in the admin search, in ACF relationship fields and in the front-end `?s=` search alike. As a bonus, MySQL's utf8mb4 collations treat these characters as ignorable, which makes the corruption invisible to SQL too.

What gets sanitized
-------------------

[](#what-gets-sanitized)

CharactersTreatmentC0 controls except TAB/LF/CR, DEL, C1 controls (U+0000–U+001F, U+007F–U+009F)removedU+00AD SOFT HYPHENremovedZero-width: U+200B, U+2060, U+FEFF (BOM)removedBidirectional controls: U+061C, U+200E/U+200F, U+202A–U+202E, U+2066–U+2069 (trojan-source vectors)removedU+2028 LINE SEPARATOR, U+2029 PARAGRAPH SEPARATORrewritten to `\n`Deliberately kept: TAB/LF/CR, U+200C ZWNJ and U+200D ZWJ (they glue emoji sequences — 👨‍👩‍👧 — and shape several scripts), U+00A0 NBSP, variation selectors. Sites that rely on bidi control characters for mixed RTL text should not use this plugin.

What it does
------------

[](#what-it-does)

**On save**

- `wp_insert_post_data` — sanitizes post title, content and excerpt on every save path (editor, REST, XML-RPC, WP-CLI).
- `acf/update_value` — sanitizes ACF field values (arrays recursively). Registered unconditionally; without ACF it simply never fires.

**On search**

- `pre_get_posts` — normalises the `s` query var of every `WP_Query`: admin searches, ACF relationship lookups and the front-end search.

**Existing data**

- `wp sanitize-characters` — scans `wp_posts` (title, content, excerpt; revisions excluded) and `wp_postmeta`, dry-run by default; pass `--apply`to persist. Posts are updated in place: `post_modified` stays untouched and no revision is created. Serialized meta is unserialized and rebuilt; object values are skipped. Revisions are excluded on purpose — restoring one goes through `wp_insert_post_data`, where the save filter sanitizes again.

WP-CLI usage
------------

[](#wp-cli-usage)

```
# List affected rows without changing anything (dry-run is the default).
$ wp sanitize-characters
post 42 [post] post_title,post_content: Example post title
meta 137 (post 42, subtitle)
Success: Would clean 2 posts and 1 meta rows (dry-run; pass --apply to persist).

# Persist the changes.
$ wp sanitize-characters --apply
Success: Cleaned 2 posts and 1 meta rows.

# Verify: a second run finds nothing.
$ wp sanitize-characters
Success: Would clean 0 posts and 0 meta rows (dry-run; pass --apply to persist).

```

One line is printed per affected row — `post  [] : `for posts, `meta  (post , )` for post meta. Meta rows whose value is a serialized object are reported and skipped. `wp help sanitize-characters` shows the full synopsis. Running it periodically is harmless: the save-time filters keep new content clean, so the command only finds rows written while the plugin was inactive.

Background and related work
---------------------------

[](#background-and-related-work)

- WordPress core removes invisible characters from **slugs only** when building permalinks ([Trac #47912](https://core.trac.wordpress.org/ticket/47912), [Trac #42951](https://core.trac.wordpress.org/ticket/42951)); titles, body text and search terms are untouched — the gap this plugin fills.
- [invisible-characters.com](https://invisible-characters.com/) — a reference list of the characters involved.
- [Insert Special Characters](https://wordpress.org/plugins/insert-special-characters/)serves the opposite purpose (inserting such characters deliberately).

Requirements
------------

[](#requirements)

PHP 8.2+, WordPress 6.7+.

License
-------

[](#license)

MIT

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance90

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

45d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/578548?v=4)[TSURU](/maintainers/ttsuru)[@ttsuru](https://github.com/ttsuru)

---

Top Contributors

[![ttsuru](https://avatars.githubusercontent.com/u/578548?v=4)](https://github.com/ttsuru "ttsuru (4 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/wppack-sanitize-characters-plugin/health.svg)

```
[![Health](https://phpackages.com/badges/wppack-sanitize-characters-plugin/health.svg)](https://phpackages.com/packages/wppack-sanitize-characters-plugin)
```

###  Alternatives

[helsingborg-stad/municipio

A bootstrap theme for creating municipality sites.

4028.8k10](/packages/helsingborg-stad-municipio)[wp-media/wp-rocket

Performance optimization plugin for WordPress

7691.4M4](/packages/wp-media-wp-rocket)[october/rain

October Rain Library

1611.7M109](/packages/october-rain)[drupal/recommended-project

Project template for Drupal projects with a relocated document root

1623.0M1](/packages/drupal-recommended-project)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45945.2k1](/packages/pressbooks-pressbooks)[mediawiki/maps

Adds various mapping features to MediaWiki

84157.7k3](/packages/mediawiki-maps)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
