rank-math-notesRank Math does most of the SEO work for you, but only if every post gets the same few decisions right. Get them wrong and the plugin happily outputs a title that gets cut off, a description Google rewrites, and schema that calls a tutorial a blog post.
This note collects the Rank Math SEO settings we check on every post: one rule for each field, two small schema filters, and a checklist to run before you hit Publish.
One job per field
Most mistakes come from treating the fields as copies of each other. Each one is read by someone different, so each one is written differently:
| Field | Who reads it | The rule |
|---|---|---|
| Focus keyword | You, and Rank Math’s checks | One phrase per post, never reused on another post |
| Post title | Visitors, on the page and in cards | Short and readable; it becomes the H1 |
| SEO title | Searchers, in Google results | Keyword first, about 60 characters with the site name |
| Meta description | Searchers, under the title | 120 to 160 characters, includes the keyword |
| Excerpt | Visitors browsing cards and archives | One line, around 100 characters |
| Permalink | Everyone, and it never changes | The keyword, nothing else |
Pick one keyword, and own it once
Choose the phrase a developer would actually type to find the post, such as “hero image LCP” rather than “making your hero faster”. Add two or three secondary keywords for the related phrases the post also answers.
Each keyword belongs to one post. If two posts target the same phrase, they compete with each other in search and neither ranks as well as one would alone. Keep a simple list of which post owns which keyword, and check it before you start writing.
Then use the keyword where it counts: in the SEO title, once in bold in the first two paragraphs, in the permalink, and naturally in one or two headings. Don’t force it in anywhere else.
Two titles, two audiences
The post title and the SEO title don’t have to match. The post title appears on your site, in the H1 and on cards, so it can be short and conversational. The SEO title appears in Google, so it leads with the keyword.
Set the SEO title in Rank Math with the separator and site name variables, so a change to either updates every post:
Hero Image LCP: Preload It the Right Way %sep% %sitename%
That renders as “Hero Image LCP: Preload It the Right Way – Your Site”. Aim for about 60 characters in total. Google cuts longer titles by pixel width, not a strict count, so put the important words first and the site name last.
Write the description as a promise
The meta description is what makes someone click. Say what the reader will be able to do after reading, include the keyword, and stay between 120 and 160 characters. Much shorter, and Google often fills the gap with text from the page. Much longer, and it gets cut off.
The excerpt is a different job. It sits under the title on a card, so it should be one line that makes someone open the post. Write it separately; don’t paste the description in.
Set the permalink once
Keep the slug to the keyword: /hero-image-lcp/, not /how-to-make-your-hero-image-load-faster-in-wordpress/. Drop the stop words and the dates.
Decide before you publish. Changing a slug later means a redirect, and links shared in the meantime point to the old address. Custom post types keep their base in the URL, such as /note/, so the slug only needs the keyword.
Give social a JPG
Link previews on most social platforms don’t support AVIF, and support for WebP varies. If your featured images are AVIF, upload a JPG version and set it in Rank Math’s Social tab, under Facebook. Rank Math uses it for both Open Graph and the Twitter card.
Use 1200 pixels wide, give it alt text, and check the preview in the Facebook Sharing Debugger once the post is live.
Schema that matches the content
Rank Math outputs a sensible default graph: your Organization, the WebSite, the WebPage, the author, and an Article for the post. Three things are worth correcting with a filter:
- The type. A step-by-step tutorial is a
TechArticle, and it can say who it’s for withproficiencyLevel. - The headline. It should be the post title, not the SEO title with the site name on the end.
- The section.
articleSectiontells search engines which series or category the post belongs to.
One filter handles all three, for posts and for a custom note post type:
add_filter( 'rank_math/json_ld', function ( $data, $jsonld ) {
if ( ! is_singular( array( 'post', 'note' ) ) ) {
return $data;
}
$post_id = get_queried_object_id();
$title = wp_strip_all_tags( html_entity_decode( get_the_title( $post_id ), ENT_QUOTES, 'UTF-8' ) );
// Category slug => schema.org proficiency level (tutorials only).
$levels = array(
'beginner' => 'Beginner',
'intermediate' => 'Intermediate',
'advanced' => 'Expert',
);
// Each post type reads its section from its own taxonomy.
$taxonomy = is_singular( 'note' ) ? 'note-category' : 'category';
$section = get_the_terms( $post_id, $taxonomy );
$article_types = array( 'Article', 'BlogPosting', 'NewsArticle', 'TechArticle' );
foreach ( $data as $key => $entity ) {
if ( ! is_array( $entity ) || empty( $entity['@type'] ) ) {
continue;
}
if ( ! array_intersect( (array) $entity['@type'], $article_types ) ) {
continue;
}
// The headline is the post title, never the SEO title.
$data[ $key ]['headline'] = $title;
$data[ $key ]['name'] = $title;
if ( $section && ! is_wp_error( $section ) ) {
$data[ $key ]['articleSection'] = $section[0]->name;
}
// Tutorials become TechArticle with a proficiency level.
if ( is_singular( 'post' ) ) {
$data[ $key ]['@type'] = 'TechArticle';
foreach ( get_the_category( $post_id ) as $term ) {
if ( isset( $levels[ $term->slug ] ) ) {
$data[ $key ]['proficiencyLevel'] = $levels[ $term->slug ];
break;
}
}
}
}
return $data;
}, 99, 2 );
Change the slugs in $levels to your own category slugs, and the taxonomy names to yours. Leave the article type in Rank Math’s Schema tab set to Article or BlogPosting; the filter changes posts to TechArticle and leaves notes as they are.
Archive and about pages
Pages get a plain WebPage by default. Listing pages are really a CollectionPage, and an about page is an AboutPage. Change the type in Rank Math’s own graph rather than printing a second script, so there’s one WebPage node per page instead of two with the same ID:
add_filter( 'rank_math/json_ld', function ( $data, $jsonld ) {
if ( ! is_page() || is_front_page() ) {
return $data;
}
// Page slug => a more specific type. Every other page stays WebPage.
$types = array(
'tutorials' => 'CollectionPage',
'notes' => 'CollectionPage',
'about' => 'AboutPage',
'contact' => 'ContactPage',
);
$slug = get_post_field( 'post_name', get_queried_object_id() );
if ( ! isset( $types[ $slug ] ) ) {
return $data;
}
foreach ( $data as $key => $entity ) {
if ( is_array( $entity ) && isset( $entity['@type'] ) && 'WebPage' === $entity['@type'] ) {
$data[ $key ]['@type'] = $types[ $slug ];
}
}
return $data;
}, 99, 2 );
Add your own page slugs to $types. Any page not in the list stays a WebPage.
On the page
A few things in the content itself round it out:
- One H1. The post title is the only H1. Sections are H2, and their parts are H3.
- Links that behave. Internal links open in the same tab. External links open in a new tab with
rel="noopener". - Alt text on the featured image. Describe what’s in it, the same way you would to someone who can’t see it.
- A primary category. When a post has more than one category, set the primary one in Rank Math so breadcrumbs and URLs use the right one.
- A featured image that loads first. It’s usually the page’s largest element. Your Hero Image Is Your LCP shows how to preload it.
Before you ship
- The focus keyword isn’t owned by any other post.
- The SEO title leads with the keyword and uses
%sep%and%sitename%. - The description is 120 to 160 characters and includes the keyword.
- The excerpt is written for the card, not copied from the description.
- The permalink is the keyword, and it’s final.
- A JPG or PNG is set in the Social tab, with alt text.
- The page source shows the right schema type, the post title as the headline, and the section.
- There’s one H1, internal links stay in the tab, and external links open a new one.
Every field has one reader. Write it for them. The house rule