Rank Math on a 174-Page Affiliate Site: Three Things That Cost Me a Weekend
What actually happened running Rank Math across 174 URLs, 100 posts and 28 WooCommerce affiliate products — including invalid product schema and a focus keyword that silently refuses to save over the REST API.

I have run Rank Math on this site for months. It currently handles the SEO for 174 URLs in the sitemap — published and scheduled posts, 46 browser-based tools, 28 affiliate product pages and the usual scatter of legal, hub and category pages. That is not a huge site, but it is big enough and odd enough to find the edges of a plugin, and this month I found three of them the hard way.
So this is not a feature list. Rank Math’s feature list is excellent and you can read it on their own site. This is what actually happened when I pushed it past the blog-with-twenty-posts use case it is usually reviewed against, including a schema problem that quietly put 33 errors into my site audit and a REST API gap that cost me an evening.
Why I picked it, and would again
The honest reason is the free tier. Rank Math gives away things its competitors charge for — multiple focus keywords, schema types, redirections, 404 monitoring, sitemaps with real control. For a site being built slowly by one person, that mattered more than any single feature.
The second reason took longer to appreciate. Rank Math exposes an unusually large number of PHP filters, and once a site stops being ordinary, that becomes the difference between a plugin you can fix and a plugin you have to fight. Every problem below was solvable precisely because Rank Math let me get at it. I have used SEO plugins where the answer would have been “you cannot”.
Worth saying plainly: nothing here is a reason not to use Rank Math. Two of the three problems are things any affiliate site with WooCommerce will hit, and neither is documented anywhere obvious. That is the gap this review is trying to fill.
Problem one: the focus keyword is missing from the REST API
This is the one that cost me the most time, and it is the most useful thing in this article if you automate anything.
I was creating posts programmatically through the WordPress REST API. Setting the SEO title worked. Setting the meta description worked. Both saved and both came back correctly when I read the post again.
The focus keyword silently did not. No error, no warning, a clean 200 OK response — and reading the post back returned null every time. I checked it against Rank Math’s own data through a separate route and the field was genuinely empty.
The cause is that rank_math_title and rank_math_description are registered for REST, and rank_math_focus_keyword is not. So WordPress accepts your write, discards the unregistered key, and reports success. That combination — silent, successful-looking failure — is the worst possible shape for a bug, because nothing tells you to look.
The fix is four lines:
register_post_meta( 'post', 'rank_math_focus_keyword', array(
'type' => 'string',
'single' => true,
'show_in_rest' => true,
) );Add an auth_callback checking current_user_can( 'edit_posts' ) and a sanitize_callback of sanitize_text_field, and it behaves exactly as you would expect from then on. I now set focus keywords on every post through the API without touching the editor.
If you schedule posts in bulk, or publish from anything other than the WordPress admin, check this before you assume your keywords are saving. Mine were not, across thirty posts, and everything looked fine.
Problem two: automatic product schema that cannot be valid
This is the one with real consequences, and it applies to every Amazon affiliate site running WooCommerce.
My site audit came back with 33 invalid structured data items. All of them were product pages. Rank Math adds WooCommerceProduct schema automatically, which is normally exactly what you want — except my products are WooCommerce external products. They are affiliate links out to Amazon. They carry no price, because I am not the seller.
Google’s Product schema requires offers, review or aggregateRating. Without one of those, the entity is invalid. Mine had none, so every product page was emitting a broken entity.
The obvious fix is to add a price. I cannot. Amazon’s Operating Agreement does not permit publishing price data you have not pulled from their API and refreshed inside 24 hours. Putting a static price in schema would trade a structured data error for an Associates policy violation, which is a considerably worse trade.
So the correct answer is to remove the entity rather than ship it broken:
add_filter( 'rank_math/json_ld', function ( $data, $jsonld ) {
if ( ! is_singular( 'product' ) ) {
return $data;
}
$product = wc_get_product( get_the_ID() );
if ( ! $product || ! $product->is_type( 'external' ) ) {
return $data;
}
if ( '' !== (string) $product->get_price() ) {
return $data;
}
foreach ( $data as $key => $entity ) {
if ( ! empty( $entity['@type'] ) && in_array( 'Product', (array) $entity['@type'], true ) ) {
unset( $data[ $key ] );
}
}
return $data;
}, 99, 2 );The pages keep their breadcrumb and page schema and lose the invalid product entity. You give up nothing real, because an invalid entity was never going to produce a rich result — it was only ever producing an error.
What I would like from Rank Math is for it to notice this itself. It knows the product is external and it knows there is no price. Emitting Product schema in that situation is a decision it could make better, and I suspect a large number of affiliate sites are carrying this error without knowing.
Problem three: a noindexed page in the sitemap
Smaller, and still worth knowing. Rank Math normally keeps noindexed content out of the sitemap automatically, and it does this correctly for anything you have noindexed through Rank Math itself.
My WooCommerce account page carried a noindex applied from elsewhere. Rank Math did not see it as its own, and listed the URL in the page sitemap anyway. A noindexed URL in a sitemap is a direct contradiction — you are asking Google to crawl something you have told it to ignore — and audit tools flag it immediately.
The fix is the sitemap entry filter, which lets you drop a URL by returning false:
add_filter( 'rank_math/sitemap/entry', function ( $url, $type, $object ) {
$drop = array( '/my-account/', '/home/' );
$path = wp_parse_url( $url['loc'], PHP_URL_PATH );
return in_array( $path, $drop, true ) ? false : $url;
}, 10, 3 );The same filter set solved two related annoyances in one pass — a duplicate front page at /home/ and an old page that now redirects elsewhere, both of which were still being listed.
There is also rank_math/sitemap/exclude_post_type, which I used to remove an entire custom post type that had no business being indexed at all. Nine form-definition pages were in my sitemap, two of them carrying over two megabytes of markup each. That was not Rank Math’s fault — the form plugin registered the post type as public — but Rank Math is where you fix it.
What is genuinely good
The filter surface. I have now written four filters against Rank Math and every one did exactly what the name suggested, first time, with no surprises. That is rarer than it should be.
The free tier is not crippled. Everything above, and everything I do day to day, is free-tier functionality. The paid tier adds things I have not needed yet.
Redirections and 404 monitoring being built in. On a site where URLs move, having this in the same plugin rather than a second one is worth more than it sounds.
Sitemap control. Once you know the filters exist, you can make the sitemap say exactly what you want, which is not true of every plugin in this category.
What I would change
Scoring is client-side only. The content analysis that produces the SEO score runs in the browser, in the editor. You cannot get a score programmatically, which means you cannot audit a hundred posts without opening a hundred posts. For a site of any size this is the single most frustrating limitation.
The REST surface is incomplete. Covered above. If two of the three main SEO fields are exposed, the third should be.
It should notice impossible schema. An external product with no price cannot produce valid Product schema. The plugin has both facts and emits it anyway.
The interface has a lot of surface. Rank Math does a great deal, and the settings reflect that. Finding the right toggle is occasionally an exercise in patience.
What it does well
- A free tier that is genuinely complete rather than a trial
- Extensive, well-named PHP filters that work as documented
- Redirections and 404 monitoring built in
- Fine-grained sitemap control once you find the filters
- Schema handling that is right for ordinary content
What to watch for
- Focus keyword is not exposed over the REST API
- Emits invalid Product schema on priceless external products
- Can list externally-noindexed pages in the sitemap
- SEO scoring cannot be run outside the editor
- A large and occasionally confusing settings surface
Who it suits
Anyone building a content site who does not want to pay a subscription to get started. The free tier is the strongest argument and it is not close.
People comfortable writing a filter. This is where Rank Math pulls ahead. Every problem in this article was fixable in a few lines. If you would never touch PHP, you will hit these same walls and have no way through them.
Affiliate sites running WooCommerce external products — with the schema caveat above understood before you launch rather than discovered in an audit three months later, which is what happened to me.
It suits you less if you need programmatic SEO scoring across many posts, or if you want a plugin that makes every decision correctly without supervision. It does not, and neither does anything else I have used.
Related reading
The audit that surfaced two of these problems is written up step by step in how to do an SEO audit. The page-weight problem it also flagged is covered in cutting 39 KB of HTML from every page.
Frequently asked questions
Is the free version actually enough?
Why is my focus keyword not saving via the API?
rank_math_focus_keyword is not registered for REST, unlike the title and description fields. Your write returns 200 and is silently discarded. Register the meta yourself with show_in_rest set to true and it works.Why does my audit show invalid product schema?
rank_math/json_ld filter instead.Can I audit SEO scores across all my posts at once?
Rank Math or Yoast?
Does any of this apply to a normal blog?
The verdict
Still what I run, and I would install it again tomorrow. The free tier is the most generous in its category and the filter surface means problems stay solvable. But it is not a plugin that gets everything right unattended — it will hand invalid product schema to an affiliate site, quietly refuse a focus keyword over the API, and occasionally list a page it should not. All three are a few lines to fix, and none of them are documented anywhere I could find, which is why they are written down here.
How this review was made
Everything described here happened on this site during August 2026, across 174 URLs, 100 posts and 28 WooCommerce external products. The code shown is running in production here. Figures like the 33 invalid schema items come from my own site audit. I have not tested Rank Math on a multisite install, on a WooCommerce store selling its own products, or against the paid tier’s features, and I have not run Yoast on the same site for comparison — so this covers one real site in depth rather than the plugin in general.