Skip to main content

SEO & Schema Markup

Goal​

Give a WooCommerce store the SEO basics without a separate SEO plugin: per-object meta titles and descriptions, product structured data, Open Graph tags, an XML sitemap, redirects with 404 logging, and a per-page score that says what is missing.

Tier and entitlement​

FieldValue
TierFree core
Entitlement keyseo
Admin tabseo
Module keyseo
Settings prefixaiowc_seo_

This is one of the two modules in this group that ship in the free tier. Hooks still register only when aiowc_module_enabled_seo is true.

What the code does​

Meta tags and titles​

Frontend/MetaTagHandler.php writes the meta tags on wp_head at priority 1, and overrides the document title through both pre_get_document_title and document_title_parts at priority 20. Meta is stored per object, keyed by object type and object ID, so a product, post, page or term can each carry its own.

Structured data​

Frontend/SchemaHandler.php writes JSON-LD on wp_head at priority 5, emitting Product (with nested Offer, Brand and AggregateRating), Organization, WebSite and BreadcrumbList.

It disables WooCommerce's own equivalents so the page does not carry two competing graphs:

add_filter('woocommerce_structured_data_product', '__return_empty_array');
add_filter('woocommerce_structured_data_breadcrumblist', '__return_empty_array');

That is worth knowing before enabling the module alongside another SEO plugin that also emits product schema.

Sitemap​

Two rewrite rules, added on init, served on template_redirect:

URLServes
/aiowc-sitemap.xmlThe sitemap index
/aiowc-sitemap-{type}-{page}.xmlOne paginated sitemap per object type

Which post types are included comes from the sitemap_post_types setting. The cached sitemap is invalidated on save_post, delete_post, edited_term and delete_term, all at priority 20.

Note the filenames: this is the plugin's own sitemap at aiowc-sitemap.xml, not WordPress's core wp-sitemap.xml.

Redirects and 404s​

Frontend/RedirectHandler.php processes redirects on template_redirect at priority 1, and logs 404s at priority 99. It watches post_updated so that a changed permalink can produce a redirect, and adds an allowed_redirect_hosts filter so an off-site target is permitted where one is configured. Each redirect row carries its own redirect_type, so the status code is per redirect rather than global.

Score​

Service/ScoreService.php grades an object out of 100 and returns a letter grade. The checks are meta title length (30–60 characters), meta description length (120–160), presence of a focus keyword, the keyword appearing in the title, in the description and in the content, content length, a featured image for social sharing, Open Graph tags, and the presence of internal links.

Settings​

Read through ModuleSettings with the aiowc_seo_ prefix; defaults come from SeoModule::defaults(). Three of them are stored as JSON.

SettingDefaultMeaning
enable_schematrueEmit JSON-LD structured data
enable_ogtrueEmit Open Graph tags
enable_sitemaptrueServe the XML sitemap
enable_redirectstrueProcess redirects and log 404s
default_og_imageemptyImage used when an object has none
schema_organizationJSON: site name, home URL and an empty logoThe Organization graph node
sitemap_post_typesJSON: ["product","post","page"]Which types the sitemap covers
auto_redirect_404falseWhether a logged 404 becomes a redirect automatically

Admin screen​

Admin tab seo. It lists per-object meta with its score, manages redirects, previews the schema for a product, triggers a sitemap regeneration, and carries the settings form.

Database schema​

Created by Schema/DatabaseSchema.php at schema version 1.0.0.

TableHolds
{prefix}aiowc_seo_metaPer-object meta title, description, focus keyword and score
{prefix}aiowc_seo_redirectsSource URL, target URL and redirect type

REST endpoints​

Namespace aiowc/v1. All responses use the shared envelope, and every route requires the manage permission.

Meta and score​

MethodPathPurposeRequired args
GET/seo/metaList meta rows, filterable by object_type, paginated—
GET/seo/meta/{object_type}/{object_id}Read one object's meta—
POST/seo/meta/{object_type}/{object_id}Save one object's meta—
DELETE/seo/meta/{object_type}/{object_id}Delete one object's meta—
GET/seo/score/{object_type}/{object_id}Score and per-check detail for one object—
GET/seo/overviewAggregate figures for the admin overview—

Redirects​

MethodPathPurposeRequired args
GET/seo/redirectsList redirects, paginated—
POST/seo/redirectsCreate a redirect; redirect_type is optionalsource_url, target_url
PUT / PATCH / POST/seo/redirects/{id}Update a redirect—
DELETE/seo/redirects/{id}Delete a redirect—

Schema, sitemap and settings​

MethodPathPurposeRequired args
GET/seo/schema/preview/{product_id}The JSON-LD that would be emitted for a product—
POST/seo/sitemap/regenerateRebuild the sitemap now—
GET/seo/settingsRead settings—
PUT / PATCH / POST/seo/settingsUpdate settings—

WordPress and WooCommerce integration​

HookPriorityEffect
wp_head1Meta tags and Open Graph
wp_head5JSON-LD structured data
pre_get_document_title20Replaces the document title
document_title_parts20Adjusts the title parts
woocommerce_structured_data_product—Emptied, so WooCommerce does not also emit product schema
woocommerce_structured_data_breadcrumblist—Emptied, likewise for breadcrumbs
template_redirect1Applies a matching redirect
template_redirect99Logs a 404
post_updated10Notices a permalink change
init—Adds the two sitemap rewrite rules
query_vars—Registers aiowc_sitemap and aiowc_sitemap_page
save_post / delete_post / edited_term / delete_term20Invalidates the cached sitemap

No shortcode and no block are registered.

Background jobs​

Both run through Action Scheduler in the aiowc-seo group.

HookSchedulePurpose
aiowc_seo_sitemap_regenerateDaily, from midnightRebuilds the sitemap
aiowc_seo_score_recalculateWeekly, from Sunday midnightRecalculates scores across objects

Entitlement limits​

seo is a free-tier entitlement, so the module is available without a premium licence. No cap on meta rows, redirects or sitemap entries is implemented; sitemap size is handled by pagination.