Rank positions: report organic rank (rank_group), not absolute SERP slot (#429)

A user's #1 organic result showed as position 3-4 because rank_absolute
counts SERP features (local pack, PAA, AI overviews) as positions. Rank
tracker, keyword-research SERP list, and onboarding market snapshot now
prefer rank_group; MCP get-serp-results keeps rank_absolute since it
returns all SERP item types.
This commit is contained in:
Ben Senescu 2026-07-29 10:46:15 -04:00 committed by GitHub
parent 72c1cf0b8e
commit c81fd7a130
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 7 additions and 4 deletions

View File

@ -41,7 +41,7 @@ function mapOrganicSerpItems(items: SerpLiveItem[]): SerpResultItem[] {
return items
.filter((item) => item.type === "organic")
.map((item) => ({
rank: item.rank_absolute ?? item.rank_group ?? 0,
rank: item.rank_group ?? item.rank_absolute ?? 0,
title: item.title ?? "",
url: item.url ?? "",
domain: item.domain ?? "",

View File

@ -87,7 +87,7 @@ export function marketTools(ctx: ToolContext): ToolSet {
.filter((item) => item.type === "organic")
.slice(0, 10)
.map((item) => ({
rank: item.rank_absolute ?? item.rank_group ?? null,
rank: item.rank_group ?? item.rank_absolute ?? null,
domain: item.domain ?? null,
title: item.title ?? null,
url: item.url ?? null,

View File

@ -168,7 +168,7 @@ describe("rank check task queue", () => {
result: {
keywordId: "kw-1",
keyword: "alpha",
position: 4,
position: 3,
url: "https://www.example.com/page",
serpFeatures: ["organic"],
},

View File

@ -129,8 +129,11 @@ function buildRankCheckResult(
return {
keywordId: input.keywordId,
keyword: input.keyword,
// rank_group = position among organic results only (what users count as
// "my ranking"). rank_absolute would also count SERP features (local
// pack, PAA, AI overviews) and reads as worse than what users see.
position: organicMatch
? (organicMatch.rank_absolute ?? organicMatch.rank_group ?? null)
? (organicMatch.rank_group ?? organicMatch.rank_absolute ?? null)
: null,
url: organicMatch?.url ?? null,
serpFeatures: [...new Set(items.map((item) => item.type).filter(Boolean))],