WordPress.org

Plugin Directory

Visibility – Lightweight SEO, AEO and GEO for Search and AI

Visibility – Lightweight SEO, AEO and GEO for Search and AI

Description

Visibility is the SEO essentials without the suite. It covers what most sites actually need (meta tags, canonical URLs, Open Graph, JSON-LD schema, robots directives, redirects, AI discovery with llms.txt and Markdown for agents, robots.txt editor and native XML sitemap control) in about 445 KB, with no Pro tier, no upsell banners and nothing phoning home. It is built on WordPress core APIs (wp_robots, wp_sitemaps_*, register_post_meta, the Block Editor), so most of the work is the platform’s, already optimized.

Coming from Yoast, Rank Math, All in One SEO or SEOPress? Visibility imports your titles, descriptions, robots directives (noindex, nofollow, nosnippet and noimageindex), Open Graph, schema and redirects in one click. The clean metadata it generates is what search engines and AI assistants (ChatGPT, Perplexity, Gemini) read to understand and cite you: the AEO/GEO angle without the bloat. Those same fields are writable by AI agents too: EMCP Tools exposes Visibility’s SEO metadata over MCP, so an agent editing a page in Elementor can update its title, description and schema through the same connection.

Four modules, toggled independently from Overview:

  • Discover — meta title and description, canonical URLs on entries and on every listing, templates for the automatic title and description built from the pieces WordPress already computes, Open Graph and Twitter Cards, Article/BreadcrumbList/Person JSON-LD with a selectable schema type per content type (None included, to leave the structured data of a content type to a specialised plugin), FAQPage from Details and Accordion blocks, and Site Identity, plus AI discovery: llms.txt, Markdown for agents and a robots.txt editor. Author archives get a ProfilePage next to the Person, with the job title, topics and credentials each user fills in on their profile. Each author can pick a page of their own as their profile page, and the Author details block (or the [visibility_author_details] shortcode) shows those fields on the page. A freshness filter flags stale content, and Respect nosnippet keeps content set to nosnippet out of the llms.txt summaries, llms-full.txt, Markdown and FAQPage. Per-post and per-term overrides for all of it.
  • Indexing — bulk or per-item noindex / nofollow / noimageindex / nosnippet by post type and taxonomy, with rules for search, 404, date, paginated, attachment and author archives plus RSS feeds. In the Block Editor, a switch on the Group block and a text format add data-nosnippet to keep part of a page out of Google’s snippets, and the classic editor has a button for it on both tabs. Remove the base of any taxonomy one by one, pick a WooCommerce product URL structure, redirect attachment pages to their parent, all with 301s. Quick Edit, bulk actions and a Visibility column on your post and term lists.
  • Sitemaps — control over the native XML sitemap: exclude post types, taxonomies, users, posts and terms; add URLs of pages served outside WordPress; lastmod dates; 301s from old sitemap URLs; noindexed content stays out automatically. It also keeps /wp-sitemap.xml answering 200 on a site with no blog posts, which older WordPress versions got wrong.
  • Redirects — a lightweight 301 / 302 / 307 / 410 manager resolved in PHP (no .htaccess, no custom table, no 404 log), with CSV import / export, suggested redirects when you delete a post, and WordPress slug-change redirects you can take over.

It builds on the native sitemap instead of walking away from it. The big suites publish a sitemap of their own from their own address, so whatever is wrong with the one WordPress generates stays wrong behind them. Visibility is built on that one: it decides what goes in, sends the old addresses from your previous plugin to it with a 301, and watches the status it answers with. Shops, campuses, service sites and portfolios used to be served /wp-sitemap.xml with a 404 status, which makes Google discard a file that looks perfect in a browser; the fix for that went into WordPress itself, reported from this plugin, and Visibility still covers the versions that came before it.

Per-post controls live in the Block Editor panel and a matching Classic meta box. A Tools tab groups the importers and exports your configuration as JSON for another site.

Visibility replaces a full SEO suite rather than running alongside one (two would fight over the <head>), and warns you if another one is active.

Perfect companions

Visibility is fully independent — these plugins aren’t required — but they pair really well with it:

  • VigIA — AI visibility, crawler analytics, Site Identity JSON-LD on the home page. Visibility coordinates @id references with VigIA so both can add schema without duplicating the Organization or WebSite nodes.
  • Share Buttons & AI-powered Summaries — share buttons for social networks and AI assistants. Helps your content reach both audiences and language models.
  • AI Content Signals — control how AI systems can use your content (training, search, both) through robots.txt directives endorsed by Cloudflare.
  • Vigilante — all-in-one WordPress security: firewall, login protection, security headers, 2FA, file integrity monitoring.

External services

This plugin connects to Gravatar (operated by Automattic Inc.) to check whether the post or page author has a public Gravatar avatar, so it can be exposed in Open Graph tags (og:image) and in Person JSON-LD (image) for E-E-A-T.

What data is sent and when:

  • When a singular view is rendered and the Open Graph module is active, and no other image source exists (per-post og:image, featured image, WooCommerce gallery image, inline content image), the plugin sends an MD5 hash of the lowercased and trimmed author email to https://www.gravatar.com/avatar/{hash}?d=404 via wp_remote_head() (HEAD request, no body).
  • When an author archive is rendered and the Person schema module is active, the same probe is performed for that author.
  • The original email address is never sent — only an MD5 hash, which is the standard Gravatar lookup mechanism.
  • The result (found / not found) is cached for 24 hours in a transient so subsequent page loads do not hit Gravatar again.

This is the same mechanism WordPress itself uses to display Gravatar avatars in comments. Gravatar’s privacy policy: https://automattic.com/privacy/

Performance and security

“Lightweight” should be a measurement, not a slogan. These are the real numbers for this release, refreshed on every update.

Footprint (2.8.0)

  • Download size: about 445 KB zipped.
  • Codebase: 50 PHP files, roughly 34,100 lines of PHP, plus 3,350 lines of JavaScript and 2,500 of CSS, loaded only where they are used.
  • Zero custom database tables. Settings live in a single autoloaded option; per-post, per-term and per-author values use native WordPress meta that is already in the object cache.
  • Zero cron jobs and no scheduled background processes.
  • Zero external HTTP calls, with a single exception: a cached Gravatar HEAD probe (24-hour TTL) that exposes the author avatar for E-E-A-T, the same lookup WordPress already performs for comment avatars.
  • Built on WordPress core APIs (wp_robots, wp_sitemaps_*, register_post_meta, get_canonical_url, the Block Editor), not private reimplementations, so most of the work is the platform’s and already optimized.

Security

  • Every release passes a security audit of the changed code (sanitization, escaping, nonces, capabilities, SQL) before it ships. It is a release gate, not an afterthought.
  • Minimal attack surface by design: no custom tables, no unauthenticated endpoints, output escaped where it is printed, input validated against allowlists, and prepared statements for every database query.
  • No premium tier, no telemetry, no data collection. Nothing phones home.

A smaller surface is a smaller target.

Support

Need private support or custom development?

Do you need one-on-one help, priority troubleshooting, or a custom feature, integration, or tweak built specifically for your site? I offer private support and custom development. Just contact me and tell me what you need.

Need help or have suggestions?

Love the plugin? Please leave us a 5-star review and help spread the word!

About AyudaWP

We are specialists in WordPress security, SEO, AI and performance optimization plugins. We create tools that solve real problems for WordPress site owners while maintaining the highest coding standards and accessibility requirements.

Screenshots

Blocks

This plugin provides 1 block.

  • Author details Shows the job title, topics of expertise, credentials and profile links from the author's user profile.

Installation

  1. Upload the native-aeo-pack folder to /wp-content/plugins/ or install through the Plugins screen.
  2. Activate the plugin.
  3. Open Visibility in the admin sidebar to review the active modules and tune the defaults.
  4. Done. Meta tags, robots directives and sitemap filters are applied automatically based on your settings.

FAQ

Is Visibility an alternative to Yoast, Rank Math, All in One SEO or SEOPress?

For most sites, yes. Visibility covers what 90% of sites actually need: titles, meta descriptions, canonical URLs, Open Graph, schema, robots directives, redirect management and sitemap control — and it imports your per-post data from those plugins in one click. It does not include keyword analysis or content scoring. If you don’t need those, Visibility is a much lighter alternative. If you do, stick with your current SEO plugin — Visibility isn’t meant to run alongside.

How do I migrate from another SEO plugin?

Install and activate Visibility. If data from Yoast SEO, Rank Math, All in One SEO, SEOPress, The SEO Framework, Slim SEO or SureRank exists in your database (the suite can be active or already deactivated), the Tools tab shows an import card with a per-field breakdown: titles, meta descriptions, canonical URLs and robots overrides on posts and on taxonomy terms, plus Open Graph images, social titles and descriptions, the default social image, the per-content-type schema type and the webmaster tools verification codes. Your existing 301, 302, 307 and 410 redirects come over too, from Rank Math, All in One SEO, SEOPress and the Redirection plugin. One click copies it all into Visibility without touching the source plugin, skipping anything you already set here. Titles and descriptions built from the suite’s template variables (%%title%%, %title%, #post_title, {{ title }}), the site-wide templates and the ones typed on an entry or a term alike, are converted to Visibility’s own placeholders and imported, so the title tag and the description keep their shape after the switch; a value that needs a variable Visibility does not resolve, such as a custom field or a date, is left where it is. Each suite imports what it actually stores; the per-field breakdown always shows exactly what was found before you import, and the import is non-destructive and idempotent: your existing Visibility values win and re-running never duplicates. Review a few entries, then deactivate the suite.

I used Native SEO Meta Tags, NoIndexer or Sitemap Customizer. How do I migrate?

Install and activate Visibility. If it finds data from any of those plugins, the Tools tab shows an import card with a per-plugin breakdown and an “Import now” button (and Overview points you there). The import is non-destructive (it copies, never deletes) and your existing Visibility values win on any conflict, so you can run it safely. Once you’ve imported and checked everything, deactivate the old plugins.

Is Visibility free? Is there a Pro version?

It is free, and there is no Pro version, no add-ons, no credit packs and no upsell banners in your admin. Everything described on this page is in the plugin you just downloaded, including the redirect manager, the one-click importers, the WooCommerce URL structures and the AI discovery files, which several SEO suites keep behind a paid tier. There is nothing to buy, no account to create and no key to paste. That is a deliberate product decision, not a launch promotion: the plugin has no premium tier to protect, so nothing in it is deliberately limited to sell you the next step.

Will Visibility slow down my site?

It is built not to. Visibility is about 445 KB zipped, adds no database tables, schedules no cron jobs and makes no external HTTP calls, with one documented exception: a cached lookup that checks whether an author has a public Gravatar, the same one WordPress already performs for comment avatars. Settings live in a single autoloaded option and per-content values use native post, term and user meta, which WordPress already keeps in the object cache. Most of the actual work is done by core APIs (wp_robots, wp_sitemaps_*, register_post_meta, get_canonical_url), not by private reimplementations, so it is code the platform already runs and has already optimized. The “Performance and security” section above publishes the real numbers for each release, refreshed on every update.

Does Visibility track me or send my data anywhere?

No. There is no telemetry, no usage analytics, no “improve the plugin” opt-in, no account and no server of ours that your site talks to. Visibility never phones home, and deactivating it does not notify anyone. The single outbound request it can make is the cached Gravatar check described in “External services” above, which sends a hash of the author email and never the address itself, so an author avatar can be included in Open Graph and Person schema. Everything else happens inside your WordPress install.

Are there any database tables?

No. Visibility stores its settings in a single WordPress option and uses native post, term and user meta tables for per-content overrides. Deleting the plugin removes the option; per-content overrides remain so reinstalling does not lose your work.

Can I disable individual modules?

Yes. The Overview tab lets you toggle Discover (meta tags), Indexing (robots), Sitemaps and Redirects independently. You can run only what you need.

What are AEO and GEO, and does Visibility do them?

AEO (answer engine optimization) and GEO (generative engine optimization) are two names for the same goal: being findable, understandable and citable by AI assistants such as ChatGPT, Perplexity, Claude and Google’s AI answers, not only by a classic results page. In practice it is less exotic than the acronyms suggest. Nobody outside the AI companies knows exactly how they choose their sources, so Visibility works on what you can check yourself: how recently your content was updated, who wrote it, and the questions and answers you have actually published. For those three it gives you a freshness filter and a sortable Last updated column on your content lists, author details that feed Person structured data and can be shown with the Author details block, and FAQPage built from Q&A you have actually published. What no plugin can do, including this one, is promise you a citation.

How does Visibility help with AI (AEO / GEO)?

It generates the signals AI search and assistants can read about your site: Site Identity JSON-LD (who is behind it), llms.txt and llms-full.txt (a Markdown index of your content, with taxonomy sections and WooCommerce-aware data), a clean Markdown version of every page at its .md URL, and a robots.txt editor to allow or block AI crawlers by name. No plugin can guarantee a citation, but Visibility makes your content easy for AI systems to find, read and attribute. The companion plugin VigIA can then measure which AI crawlers actually visit.

Does Visibility generate llms.txt and a Markdown version of my pages?

Yes, both, and neither one writes a file to your server. /llms.txt is a Markdown index of your site for language models, with sections per content type and taxonomy and WooCommerce-aware entries, and /llms-full.txt is the long form. Every entry also answers at its own .md URL, so an agent following a link gets clean Markdown instead of a full HTML page. All of it is generated on the fly from your real content: no files written, no cron job, nothing to regenerate when you publish. An honest note on expectations, because this gets sold louder than the evidence supports: llms.txt is a proposed convention, not a standard. Adoption is still low, Google has said it ignores it, and no major AI vendor has confirmed support. Including it costs you nothing and positions you if that changes, but do not expect it to get you cited on its own.

Does Visibility add schema markup and structured data?

Yes, as a single JSON-LD graph rather than a pile of separate blocks: the Article family with a selectable type per content type (BlogPosting, NewsArticle and the rest), BreadcrumbList, Person including author expertise fields, FAQPage built from your Details and Accordion blocks, and Site Identity (Organization and WebSite) on the home page, with per-post and per-term overrides for all of it. What is deliberately missing is a visual builder for rich types such as Recipe, Product, Event or HowTo. Those need properties your content does not hold in structured form (ingredients, prices, dates, steps), and adding the type without its required properties generates errors in Search Console, which is worse than not adding it at all. The plugins that own that data already handle it: WooCommerce adds Product, recipe plugins add Recipe, event plugins add Event. And if you would rather write your structured data elsewhere, the type selector has a None option that applies to a whole content type or to a single entry; see the next question.

Can I stop Visibility from writing schema and use a specialised plugin instead?

Yes, at three levels. To drop everything at once, uncheck JSON-LD: Article and BreadcrumbList in the Discover tab: the generator is not even loaded after that. To hand over one content type, set its schema type to None in “Schema type per content type”, and to hand over a single entry, pick None in its Schema type field in either editor. None is a full withdrawal, not a missing node: no Article or WebPage, no BreadcrumbList and no FAQPage are added to that content, so the other plugin owns the document with no second graph competing with it, and a single entry can still opt back in by choosing a real type. Site Identity is a separate setting, so the Organization and WebSite markup on your home page keeps working whichever of the three you use. For anything more selective, the native_aeo_pack_schema_graph filter receives the nodes before they are printed.

Does Visibility mark up author pages as ProfilePage?

Yes: the author archive of anyone with at least one published post gets a ProfilePage with their Person (job title, topics, credentials, profiles and post count). A user who can write entries can pick a page such as About me as their profile page; that page becomes the ProfilePage and the author URL of their posts points to it. The Author details block or the [visibility_author_details] shortcode shows those fields on the page, because Google asks that structured data describe what people can see.

Does Visibility control the XML sitemap?

It customizes the sitemap WordPress already generates at /wp-sitemap.xml instead of building a second one alongside it, which is why there is no cache to clear and nothing to rebuild. You can exclude whole post types and taxonomies, individual posts and terms by ID or slug, and users by role; control lastmod dates; and set the maximum number of URLs per sitemap. Anything set to noindex stays out automatically, so the two modules can never contradict each other, and you can also exclude something from the sitemap while leaving it indexable. Pages that are not WordPress content (a static landing page, a microsite on a subdomain, a headless front end) can be added as a list of URLs, listed in their own sub-sitemap under the index. Arriving from another SEO plugin, its old sitemap URLs (sitemap.xml, post-sitemap.xml and the rest) are 301-redirected to the native one, so nothing search engines already know about breaks.

My sitemap looks fine in the browser but Google says it could not be read. Why?

Because it is answering with a 404 status while showing you the right file, and Google discards any sitemap that does not answer 200. It happens on any site with no published entries of the Posts type: a shop, a campus, a portfolio, a site of services and pages. WordPress decides the 404 before the sitemap is rendered, and on an ordinary blog what keeps it away is only that the query behind the page happened to find entries, which has nothing to do with the sitemap being served. Publish one post and it goes away; delete it and it comes back. Pages, products and courses make no difference.

This is the one answer here that names a version, because whether it affects you depends on which one you run: it was fixed in WordPress 7.1.1, from a report that came out of this plugin. Below that, Visibility answers /wp-sitemap.xml with a 200 itself, with a switch for it in the Sitemaps tab. Either way, sitemaps that genuinely have nothing behind them still answer 404, which is the honest status for them, and so does every other address on the site.

My old sitemap URLs redirect to a page that does not exist. What is wrong?

Something on the site has switched off the sitemap WordPress generates, and that is what the old addresses point at. WordPress keeps those URLs routed even when the feature is off, so that /wp-sitemap.xml can answer a clean 404 instead of a broken page, and a redirect sent there lands on that 404. Two causes account for nearly all of it: a snippet filtering wp_sitemaps_enabled to false, left in a child theme or in Code Snippets by a migration tutorial and still running long after the plugin it was written for is gone, and another SEO plugin serving sitemaps of its own, which switches the native one off and redirects the native addresses to its own while Visibility redirects them back, so the two end up in a loop. Visibility checks before redirecting and leaves the old address alone, so it answers a plain 404 rather than a redirect to one. To get the sitemap itself back, look for that filter in functions.php and in your snippets plugin, and check that “Discourage search engines from indexing this site” is unticked in Settings > Reading, which switches the sitemap off as well.

Does Visibility manage redirects? Do I need .htaccess or a separate plugin?

Redirects are included and you need neither. The Redirects module handles 301, 302, 307 and 410 responses, resolved in PHP with no .htaccess editing, no server configuration and no custom database table. It imports and exports CSV, offers you a redirect for any post you delete so the URL does not become a 404, and lets you take over or remove the slug-change redirects WordPress creates silently on its own. One thing it does not do, on purpose: log every 404 your site receives. That needs a dedicated table and a scheduled cleanup job, which is the kind of weight this plugin exists to avoid. If you want that view, the companion plugin VigIA already records the 404s that crawlers run into.

Does Visibility work with Elementor, Divi and other page builders?

Yes. The Visibility panel appears in the Block Editor sidebar and, on any screen where a builder replaces the block editor, as a matching meta box on the classic editing screen, so you get the same title, description, social, schema and robots controls whichever editor your builder leaves in place. Elementor gets one extra piece of handling worth knowing about: it keeps its layout in post meta and substitutes the content at render time, so the stored post content is close to empty. Visibility renders the Elementor document when it builds the Markdown version of a page, which means AI agents reading your .md URL get the real text instead of a blank page.

Does Visibility work with WooCommerce?

Yes, and it treats a shop as a first-class case rather than an afterthought. Products, product categories, tags and attributes are covered like any other content for titles, descriptions, social tags, schema and robots rules; the product gallery image is part of the og:image fallback chain; and the llms.txt index is WooCommerce-aware. It also fixes product URLs in ways WooCommerce blocks on its own permalinks screen, which has its own answer below. What Visibility does not add is Product schema: WooCommerce already generates it with the price, stock and review data it owns, and a second copy would only contradict the first.

Does it work with custom post types and custom taxonomies?

Yes. All public post types and taxonomies are supported — including WooCommerce product categories, tags and attributes (the latter requires “Enable Archives?” in the WooCommerce attribute settings).

Can I preview how my page will look on Google, social networks and AI answers?

Yes. The Visibility panel — in the Block Editor sidebar and in the Classic Editor meta box — includes a live preview with three views: your Google result snippet, your shared social card and an AI Overview citing your page. It updates as you type, following the exact fallback chains the plugin generates (post title, excerpt, featured image, site fallbacks). It is an honest render of what goes into your HTML, not a score: the final appearance always depends on each platform.

Can I change how the automatic title tag is composed?

Yes, with a template on the Discover tab. It is a line of text with up to six placeholders, all of them values WordPress already holds for the page: %%title%%, %%sep%% (the separator chosen above it), %%sitename%%, %%page%%, %%tagline%% and %%taxonomy%% (the first term of the main taxonomy of the entry: its category on a post, its product category on a product). Put them in the order you want, add words between them (%%sitename%% » %%title%%, %%taxonomy%%: %%title%% %%sep%% %%sitename%%), and that is the title tag on every page that has no Meta title of its own. The front page has its own template, because there the page title is the site name, and a content type or a taxonomy can have one that replaces the general template. The page number is added on paginated pages even when the template leaves it out, so page 2 never repeats the title of page 1. The Meta title typed on an entry or a term wins over all of them, and may use the same placeholders (Guide: %%title%%); one without placeholders is used exactly as typed.

The meta description works the same way, with one more placeholder, %%excerpt%%, which is the automatic description Visibility already builds: the excerpt or the opening of the content on an entry, the term description on an archive, the tagline on the front page. With no template, the automatic description is used on its own, as before; a template such as %%excerpt%% %%sep%% %%sitename%% or %%taxonomy%%: %%excerpt%% adds to it, and a Meta description typed on an entry or a term may use the same placeholders.

What it does not do, on purpose: variables that need a query on every page, such as a custom field, the parent page or a date. Those are what make title templates in the big suites both slow and impossible to leave, and the editor previews would not be able to show them honestly. Themes that never adopted the modern title API and print their own title tag are not reached by the template either, only by a per-entry Meta title.

How do I set noindex on a single post?

In the Block Editor, open the Visibility panel in the post sidebar and tick the noindex toggle. In the Classic Editor, the same toggle is in the Visibility meta box. You can also use Quick Edit or Bulk Actions from the post list, and from the category, tag and custom taxonomy lists for a term archive.

How do I keep part of a page out of Google’s snippets?

In the block editor, turn on Keep out of search snippets in the Advanced panel of a Group block (it shows for div and section groups, the only two Google reads), or apply the format of the same name to selected words. In the classic editor, the Visual toolbar has a button of that name, and the Text tab a nosnippet one. Google uses it for search snippets; Visibility also leaves that text out of the descriptions and summaries it generates, while the Markdown version and llms-full.txt keep the whole page. A Group’s mark is added when the page is displayed and stops if you deactivate Visibility; the one on words stays in the content.

What does Respect nosnippet do?

With nosnippet, Google shows no snippet and does not use the text as direct input for AI Overviews and AI Mode. With Respect nosnippet on (Discover tab), Visibility also lists the entry in llms.txt by title and link only, gives no text for it in llms-full.txt, serves no Markdown version and adds no FAQPage. It is on in new installs. On an update it turns on only if that changes nothing the site serves; otherwise it stays off and nothing changes until you switch it on.

Does my robots.txt always work, even on a subdirectory install?

Yes, and this is an SEO safeguard worth knowing about. WordPress only serves its virtual /robots.txt on root installs once the rewrite rules have been flushed; on a subdirectory install, or when the rules go stale, /robots.txt can return a 404 while the same directives still answer at /?robots=1 — so crawlers asking for the canonical /robots.txt get nothing. Visibility takes ownership of the endpoint: it serves /robots.txt itself when there is no physical file (independent of the rewrite rules, so it works on any install), and when another plugin writes a physical robots.txt that the web server would serve instead, it merges its own directives into that file in a BEGIN/END block, leaving every other block untouched, so its rules prevail there too. It also 301-redirects WordPress’s internal /?robots=1 to /robots.txt. The result is a single canonical /robots.txt that always loads your AI-crawler and indexing rules, even behind a static file.

Does Visibility work on WordPress Multisite?

Yes, and each site keeps its own rules. Every site in the network has its own Visibility settings, so on a subdomain or mapped-domain network each one serves its own /robots.txt and /llms.txt from its own directives, with nothing to wire up by hand — something WordPress does not do on its own and most SEO plugins leave as a single global file. This matters because a physical robots.txt or llms.txt in the site root is one file shared by the whole install: Visibility writes it only where it genuinely belongs — a single-site install, or the main site of a subdirectory network — so one site can never overwrite another’s rules, and everywhere else the always-served virtual endpoints answer per site. On a subdirectory network (every site under one domain) the robots.txt standard allows only one file at the domain root, owned by the main site, and the Discover tab makes that clear wherever the physical-file option does not apply. Activate Visibility per site or network-activate it.

There is one case that used to have no way out: a physical robots.txt already sitting in the network root. The web server hands that one file to crawlers before WordPress runs, so every site in the network answers with the same rules and no plugin can override a static file the server sends first. The Discover tab offers a way past it on Apache and LiteSpeed: one button adds a single rewrite to the .htaccess, in its own BEGIN/END block, that routes /robots.txt into WordPress even though the file exists. Every host then answers with its own directives and its own Sitemap: line, and the physical file is left untouched on disk. Nothing is written without the click, removing it puts the .htaccess back exactly as it was, and only a network administrator sees the button, because the .htaccess belongs to the whole network. On nginx there is no equivalent a plugin can perform, so the screen says so plainly and hands you the directive for whoever administers the server.

Where does Visibility store per-post overrides?

In standard WordPress post meta (_native_aeo_pack_* keys). Term overrides go to term meta, user social URLs to user meta. Nothing leaves the standard WordPress tables.

Can I copy my configuration to another site?

Yes. The Tools tab exports every Visibility setting plus the per-entry and per-term values (meta titles and descriptions, canonical URLs, social overrides, schema types, robots flags) as a single JSON file, and imports it back on another site. Content is matched by slug, not by database ID, so it works between sites that were never clones: staging to production, or a starter configuration across several sites. On import you choose whether the file only fills in what is empty (the default, safe on a site that already has its own values) or replaces what is there. Everything goes through the same validation as the settings screen, only known keys are read, and nothing is ever created: values land on content that already exists, and the result tells you how many entries were not found. Redirects are not in the file because they have their own CSV export on the Redirects tab, and author profile fields stay out because they belong to each user account.

How do I know which content has gone stale?

AI assistants tend to cite recently updated pages: an Ahrefs analysis of 17 million citations found that the pages they cite were updated more recently, on average, than the ones ranking in Google’s organic results, with Google’s AI Overviews as the exception. With the threshold set in the Discover tab (90 days by default), your content lists get a “Not updated in 90 days” filter link with a count, and a sortable Last updated column. That is all it does: no score, no traffic light, no “SEO health” number, because which article deserves a rewrite is an editorial call. Set the threshold to 0 to leave your list tables untouched.

Can I clean up my WooCommerce URLs?

Yes, including the parts WooCommerce itself refuses to do. In the Indexing tab you can remove the base of each taxonomy independently, so a store can drop /product-category/, /product-tag/ and /brand/ while keeping /category/ on its blog, which the single toggle of earlier versions did not allow. And you can choose a product URL structure WooCommerce blocks on its own permalinks screen: the product slug alone (/my-product/), the category and the slug (/t-shirts/my-product/), or the full category path (/clothing/t-shirts/my-product/). WooCommerce puts the /product/ base back whenever you empty it and forces a base in front of a category structure, which is why those three need a plugin.

Old URLs are 301-redirected to the new ones, and so is any other combination that still resolves (a leftover base, a category the product no longer belongs to), so a product never ends up reachable at two URLs. The redirects are included: no premium tier for them. If you are running Premmerce Permalink Manager, Visibility detects it, tells you in the Indexing tab that both plugins are rewriting the same URLs, and takes precedence (its filters run last). Import its structure from the Tools tab first, check your product URLs, and then you can deactivate it, premium included. Two honest notes. Whatever already exists at a path wins, so a page or a term keeps its URL and the product stays on the one WooCommerce gave it. And a base-less taxonomy URL costs one rewrite rule per term, five counting feeds and pagination, so the settings screen tells you how many rules your selection adds before you commit to it: fine for a blog or a normal shop, worth a thought on a store with thousands of attribute terms.

Does Visibility generate FAQ structured data?

Yes, from the content you already have. Switch on JSON-LD: FAQPage in the Discover tab and Visibility reads the native Details and Accordion blocks in your entries, taking the question from the block heading and the answer from its content, and adds FAQPage to the same JSON-LD block as the rest of the schema. There is no separate builder or duplicate fields to fill in, so the markup can only ever describe Q&A that is genuinely visible on the page. It is off by default on purpose: a Details block is not always a question (“Show technical details”), and describing something that is not a FAQ is worse than not describing it. Honest expectation: this helps AI assistants pick up your Q&A structure. It does not bring back Google’s FAQ rich results, which were retired in 2023.

Is there an API for plugins and themes?

Yes, and it stays stable. Read the robots state Visibility resolved with Native_AEO_Pack_Frontend_Robots::is_noindex( $post_id ), is_nofollow( $post_id ), is_term_noindex( $term_id, $taxonomy ) and is_term_nofollow( $term_id, $taxonomy ); read any setting with Native_AEO_Pack_Settings::get( $group, $key, $default ); and check the AI-crawler rules with Native_AEO_Pack_Settings::is_robots_ai_blocking() and get_robots_ai_agents(), which is how the companion plugin VigIA reads them.

To change what is emitted, six filters:

  • native_aeo_pack_schema_graph ($graph, $context, $object) — the JSON-LD nodes before they are printed. $context is article, person or identity. Add, edit or drop nodes; return an empty array to print nothing.
  • native_aeo_pack_document_title ($title) — the Meta title of the current entry, term or posts page before it reaches <title>, or an empty string when none is set. Return your own text to have the last word over any hook priority, or an empty string to hand the title back to the theme. Return plain text: it is escaped after the filter.
  • native_aeo_pack_canonical_url ($url, $object) — the canonical of a listing (term, author, post type and date archives, the blog), printed as rel=canonical and as og:url alike. Return an empty string to print neither. Single entries keep the core get_canonical_url filter.
  • native_aeo_pack_meta_description ($description) — the resolved description, after the whole fallback chain. It feeds the meta tag, og:description, the Twitter card, the Article node and the preview alike.
  • native_aeo_pack_og_image ($image, $post) — the image chosen for a singular, after the per-post, featured, WooCommerce, inline and site-fallback chain.
  • native_aeo_pack_schema_faq_pairs ($pairs, $post) — the question/answer pairs read from the blocks, before they become FAQPage. Return an empty array to skip it on a page where Details blocks are not questions.

Reviews

September 22, 2026 1 reply
Finally a lightweight SEO plugin that does it's job properly without bloating.Using it on our main domain and default for all new sites.Compatible with EMCP Tools to do mass SEO audits and changes using IA 🙂 Only small suggestion, maybe add an optional setting to move Visibility under Settings, as for example Slim SEO does by default, to keep visual impact minimal hehe
September 19, 2026 1 reply
Después de años de uso, decidí quitar Rank Math después de leer el amplio y detallado estudio que el autor de Visibility recién publicó en su sitio web, titulado: "¿Qué plugin de SEO es más ligero y que consume menos recursos?" (recomiendo leerlo). Allí se puede constatar, a través de datos reales, cuales son las sustanciales diferencias que hay entre Visibility y otros conocidos plugins de SEO. Visibility es un plugin liviano y veloz, con funcionalidades Pro, que aporta todo lo necesario para el SEO en estos tiempos de IA. ¡Mil gracias y muchas bendiciones!
July 30, 2026 1 reply
Para que quede claro lo que me ha gustado, he quitado Rankmath SEO pro y he puesto este sencillo y práctico plugin de Fernando Tellado. 100% optimizado para el SEO sin recargar ni agregar cosas innecesarias. Y, lo mejor, no veía el mapa del sitio y utilicé el soporte y Fernando me contestó a los 5 minutos. Más no se puede pedir. Al final no era problema del plugin sino de mi cahé. ¡Bravo por todo!
July 1, 2026 1 reply
Llevo como 15 años en el tema de marketing y desarrollo web, y después de trabajar con Yoast y otros plugins que al final es un lío de opciones que cada vez valen menos, este plugin pone lo que es útil y necesario en tu web para que sea entendible y te puedes dedicar a lo importante. Además, el soporte es muy rápido si necesitas algo.
June 23, 2026
Perfect SEO plugin for anyone who wants essential SEO features without bloat. Lightweight, fast, and fully integrated with WordPress core. Includes everything needed for modern SEO, AEO, and AI visibility.
June 23, 2026
From what i've seen it has a lot already and apparently it plans to be a bigger one having pro features from other plugins for free so definitely giving it a try and prob gonna be my new SEO plugin from now on
Read all 6 reviews

Contributors & Developers

“Visibility – Lightweight SEO, AEO and GEO for Search and AI” is open source software. The following people have contributed to this plugin.

Contributors

“Visibility – Lightweight SEO, AEO and GEO for Search and AI” has been translated into 2 locales. Thank you to the translators for their contributions.

Translate “Visibility – Lightweight SEO, AEO and GEO for Search and AI” into your language.

Interested in development?

Browse the code, check out the SVN repository, or subscribe to the development log by RSS.

Changelog

2.8.0

Author archives gain a ProfilePage, and users with no published posts no longer get a Person. New Author details block, a profile page per author and data-nosnippet controls in the editor. The new Respect nosnippet setting stays off on sites already serving llms.txt, Markdown or FAQPage.

  • New: Author archives now describe the author with a ProfilePage next to the Person, on the first page of the archive of any user with at least one published post; an author who picks a profile page (see below) gets the ProfilePage on that page instead. It has the author as its main entity, the date the account was created, the date the profile last changed and, on the Person, the number of entries written as a WriteAction count. The date of the last change is noted from now on, whenever the biographical info, the job title, topics, credentials, social links, profile page, display name, website or email change, so an author whose profile predates this update has no such date until something changes. In the person context of the native_aeo_pack_schema_graph filter, the graph of an archive now holds the ProfilePage as a second node.
  • New: Choose a profile page for each author. Users who can write entries get a Profile page field in their user profile, to pick the page that presents them, such as an About page. In the structured data, that page becomes the address of the Person and of the author of each entry, and it is described as a ProfilePage with the author as its main entity, together with the full Person. It has to be a published page the user can edit, and a page can belong to one user only; in a network, each site keeps its own choice. Each choice is checked when saving, with an error on the profile screen, and again every time it is read: a page that stops being public sends everything back to the author archive. A page that stops being published stays in the list with its status in brackets, so saving the profile does not take the choice away without a word, and a line under the field says the author archive is used meanwhile. The block editor and the classic editor say, next to the schema type, whose profile a page is and, on a page marked as ProfilePage that nobody picked, whose profile it is described as.
  • New: Author details, to show on the page what the user profile holds about the author: job title, topics of expertise, credentials and links to their profiles, as a description list with a term for each section and a line for each value. Add it with the Author details block, which is rendered on the server and takes the color, typography and spacing controls of the block, with the [visibility_author_details] shortcode, or with native_aeo_pack_author_details() in the author.php of a classic theme. There is no user to choose and the shortcode ignores any attribute: on an author archive it shows the author of the archive, on the profile page a user picked it shows that user, and anywhere else the author of the entry. It shows nothing for a user who cannot write entries. The links carry rel="me" only on the author archive and on the profile page of that same user, sections with nothing in them are left out, and nothing is added by itself: where nobody places it, the fields stay in the structured data alone. The Markdown version of the page includes it, and llms-full.txt does not.
  • New: Keep a group out of search snippets from the block editor, without writing HTML. The Advanced panel of the Group block has a “Keep out of search snippets” switch that adds data-nosnippet to the group, so Google does not use its text in search result snippets, and Visibility leaves it out of the descriptions and summaries it generates too. It shows when the HTML element of the group is a div, the default, or a section, the only two Google reads on a group, and it also works on the Row, Stack and Grid variations. It does not depend on any module. The switch is saved as a block setting and the attribute is added when the page is displayed, so with Visibility deactivated the group stops carrying it, and it comes back when you activate the plugin again.
  • New: Keep a few words out of search snippets. Select them and choose “Keep out of search snippets” in the More menu of the formatting toolbar: the text is wrapped in a span with data-nosnippet, which stays in the content, so it keeps applying if Visibility is deactivated, and it is underlined with dots in the editor only.
  • New: Keep text out of search snippets from the classic editor too, on both tabs. The Visual tab has a “Keep out of search snippets” button in its toolbar that puts a span with data-nosnippet on the selected words and takes it off with the cursor inside. It lights up over marked words, which are underlined with dots in the editor only, and over a selection that crosses paragraphs it marks each paragraph on its own, so the HTML stays valid. The Text tab (called Code in recent WordPress versions) has a nosnippet button that wraps the selection in <span data-nosnippet>, or in <div data-nosnippet> with each tag on its own line when the selection has line breaks; with nothing selected it adds the opening and closing tags with the cursor between them. The Classic block of the block editor gets the Visual button too. Clear formatting removes the mark, like any other format. It is saved in the content, so it keeps applying if Visibility is deactivated.
  • Improved: The author fields of the user profile (job title, topics, credentials, social links and profile page) are now offered, saved and used only for users who can write entries. The condition is on the user whose profile it is, not on who is editing it, so an administrator editing a customer or a subscriber no longer sees them, and somebody who loses the role stops publishing them: the Person in their structured data leaves out the job title, topics, credentials and the social links of Visibility, and their profile page is ignored, so everything goes back to their author archive. What they had saved is kept, and comes back if the role does. Name, biographical info and website are fields of WordPress and are not affected. When someone changes their profile, the cached Markdown of their profile page is rebuilt right away.
  • Improved: The importer for Yoast SEO, Rank Math, All in One SEO and SEOPress now also brings over nosnippet and noimageindex, from entries and, except in Yoast SEO, which has none, from terms. They land in the same robots flags as noindex and nofollow, with the same rules: what you have already set in Visibility is kept, and running the import again never copies a value twice. A site that imported before sees the import card again if its old plugin holds either directive, and importing then copies only those. A max-snippet of 0 in All in One SEO, which it adds to the page and Google reads as nosnippet, is imported as nosnippet; Rank Math never added its own zero to the page, so it is left out. The SEO Framework, Slim SEO and SureRank store neither directive, so there is nothing to bring over from them. The import card now says so.
  • Improved: Under each SEO plugin, the importer now lists what it found and cannot bring over because Visibility has no equivalent: noarchive (Yoast SEO, Rank Math, All in One SEO, The SEO Framework and SureRank), a max-snippet limit above 0, a max-image-preview below large and a max-video-preview limit (Rank Math and All in One SEO). Only what the plugin was really serving is counted. It only counts them: nothing is imported or changed. The note shows in the import card, in the result of the import and, when there is nothing left to import, in the migration block of the Tools tab, so a site whose only leftovers are noarchive or a limit does not get silence.
  • Improved: The help under the nosnippet checkbox, in the block editor sidebar, the classic editor and the term editor, now says what nosnippet does. Google shows no snippet of the page and does not use its text as direct input for AI Overviews and AI Mode. With the new Respect nosnippet setting on, Visibility also keeps the text out of llms.txt, llms-full.txt and FAQPage, and serves no Markdown version.
  • Fix: The Person no longer appears on the author archive of a user with no published posts, such as the customers of a store (WordPress answers 200 for every member of the site), nor on page 2 and beyond of an archive, and the native_aeo_pack_schema_graph filter is no longer called there. Only posts of the Posts type count, so an author who publishes only products or other content types does not get it either.
  • Fix: Content set to nosnippet was still summarised and reproduced by the files Visibility generates. The new Respect nosnippet setting (Discover tab, llms.txt section) fixes that. With it on, an entry or archive set to nosnippet is listed in llms.txt with its title and link but no summary, the link going to the page and not to its Markdown version; is listed in llms-full.txt with its title and URL but no text; is listed by title and link, with no summary, in the latest entries of the Markdown of the blog and of the term archives; has no Markdown version (its .md answers 404 and is no longer advertised in the page head, in the Link header or in llms.txt, which includes the posts page); and gets no FAQPage, so the native_aeo_pack_schema_faq_pairs filter is not called for it. The setting starts on for new installs, and for sites that update while serving none of llms.txt, llms-full.txt, Markdown or FAQPage and with no author archive set to nosnippet, where it changes nothing. A site that updates with any of those in use keeps it off, so nothing changes until you switch it on, and a notice on the admin screens says where to find it until you do.
  • Fix: Text inside an element marked with data-nosnippet (a span, div or section, with any value or none) no longer reaches the automatic meta description, and so neither og:description, twitter:description, the Article description or the editor preview, nor the llms.txt summary of an entry, nor the answers of a FAQPage, nor the summaries Visibility writes inside a Markdown version: the description in its frontmatter and the one-line summary of each entry in the latest entries of the blog and of the term archives. Google leaves that text out of its snippets, and Visibility was still cutting fragments out of it. A whole block wrapped in one, such as a Group, goes too. A summary you wrote by hand is left as you wrote it, and the body of the Markdown versions and llms-full.txt keep the marked text, because they hand over the whole page.
  • Fix: llms.txt, llms-full.txt and the Markdown of the blog are rebuilt as soon as an entry or a term is set or unset as nosnippet from a list-table bulk action, which saves the flag without going through the post save that used to refresh them. Every cached AI document is rebuilt when Respect nosnippet is switched on or off.
  • Fix: A page whose schema type is ProfilePage said nothing about who it describes and pointed its mainEntityOfPage at itself. It now names its author as its main entity, adds the author’s Person to its graph and no longer carries that self-reference. With the Person schema switched off, that person is reduced to its name and address.
  • Fix: The worksFor of the Person now points to the site identity whenever Visibility’s own Site Identity is on. It used to look only at VigIA’s, so with the own identity the Person declared a second Organization inline. And when that identity is a Person, the worksFor is left out.
  • Fix: With Respect nosnippet on, the Person of an author archive set to nosnippet, and the one of a profile page set to nosnippet, are generated without their description, the biographical info.
  • Fix: Some texts gave figures about AI citations with no source to back them: how much more often recently updated pages get cited, and how much weight author expertise carries. The descriptions in the user profile and in the Discover tab, and the readme, now say what Visibility does, and the readme cites the Ahrefs analysis of 17 million citations that the freshness filter rests on.
  • Fix: In the Markdown version of a page, every description list (a <dl>, in the Author details or anywhere else in the content) ran its terms and values into one word, like “Job titleDeveloper”. Each term is now a bold line and each value a bullet under it. This changes the Markdown of any content that already had a description list.
  • Fix: The X button of the admin notice about the store archives set to noindex did not dismiss it: it asked for its address with an HTML entity in the middle, so the request lost its security token. The Dismiss link beside it worked.

For older changelog entries, please check the changelog.txt file