How OpenSEO Determines Rank Tracking Results: Rank Group vs Rank Absolute Explained

Rank group shows the best (lowest) rank across Desktop and Mobile when tracking both devices, while rank absolute displays the exact position for a single selected device.

OpenSEO's rank tracking feature fetches SERP position data from the DataForSEO service, then presents results in one of two display modes depending on your configuration. The devices field in your rank tracking configuration directly determines whether you see device-specific absolute ranks or a consolidated group rank. This logic is implemented in src/shared/rank-tracking.ts and controlled by the RankTrackingConfig type defined in src/types/schemas/rank-tracking.ts.

How the Devices Setting Controls Rank Display Mode

The rank display mode is not a separate toggle. Instead, it derives automatically from whether you track one device or both.

Single Device: Rank Absolute Mode

When your configuration specifies a single device—either "desktop" or "mobile"—OpenSEO operates in rank absolute mode. The system records and displays the exact position returned for that specific device only, with no aggregation or comparison.

This setting produces a straightforward, unambiguous result: you see precisely where your keyword ranks on your chosen platform.

Both Devices: Rank Group Mode

When the configuration's devices field equals "both", OpenSEO switches to rank group mode. The UI computes the group rank as the minimum of the two absolute ranks—that is, the best (numerically lowest) position achieved across Desktop and Mobile.

This provides a concise, optimistic summary that reflects your keyword's most favorable placement on any device.

Core Implementation in src/shared/rank-tracking.ts

The rank-tracking utilities handle device translation and scheduling. Lines 29-45 define devicesLabel and devicesCount, which convert the raw devices setting into UI-ready values:

// Conceptual flow based on src/shared/rank-tracking.ts
// These utilities prepare device data for the rendering layer

function getDevicesLabel(devices: 'desktop' | 'mobile' | 'both'): string {
  return devices === 'both' ? 'Desktop + Mobile' 
       : devices === 'desktop' ? 'Desktop' 
       : 'Mobile';
}

function getDevicesCount(devices: 'desktop' | 'mobile' | 'both'): 1 | 2 {
  return devices === 'both' ? 2 : 1;
}

The grouping logic itself executes in the client-side component that renders the rank tracking table. When devicesCount equals 2, this component selects Math.min(desktopRank, mobileRank) as the displayed group rank.

The computeNextCheckAt function (lines 78-124) manages crawl scheduling but does not influence the rank group versus rank absolute distinction—it only determines when fresh DataForSEO data is fetched.

Schema Definition in src/types/schemas/rank-tracking.ts

The RankTrackingConfig type governs all rank tracking behavior. Its devices field accepts three literal values that enforce the binary display mode:

// src/types/schemas/rank-tracking.ts
export interface RankTrackingConfig {
  keyword: string;
  devices: 'desktop' | 'mobile' | 'both';  // ← Controls rank display mode
  scheduleInterval: 'daily' | 'weekly' | 'monthly';
  depth: number;
  // Additional configuration fields...
}

Setting devices: 'both' triggers rank group display. Setting either single-device value triggers rank absolute display for that platform.

Practical Code Examples

Creating a Configuration for Rank Group Display

import type { RankTrackingConfig } from '@/types/schemas/rank-tracking';

const groupConfig: RankTrackingConfig = {
  keyword: 'open seo',
  devices: 'both',           // Enables rank group: best of Desktop + Mobile
  scheduleInterval: 'weekly',
  depth: 30,
};

Creating a Configuration for Rank Absolute Display

import type { RankTrackingConfig } from '@/types/schemas/rank-tracking';

const desktopConfig: RankTrackingConfig = {
  keyword: 'open seo',
  devices: 'desktop',        // Shows Desktop rank only
  scheduleInterval: 'weekly',
  depth: 30,
};

Rendering Ranks with Conditional Logic

function renderRank(
  desktopRank: number | null,
  mobileRank: number | null,
  config: RankTrackingConfig
): string {
  if (config.devices === 'both') {
    // Rank group: lowest number is best position
    const ranks = [desktopRank, mobileRank].filter((r): r is number => r !== null);
    const groupRank = Math.min(...ranks);
    return `#${groupRank} (group)`;
  }
  
  // Rank absolute: single device result
  const absoluteRank = config.devices === 'desktop' ? desktopRank : mobileRank;
  return absoluteRank !== null ? `#${absoluteRank}` : 'Not ranked';
}

Scheduling the Next Crawl

import { computeNextCheckAt } from '@/shared/rank-tracking';

// Returns ISO timestamp for next DataForSEO data fetch
const nextCheck = computeNextCheckAt('weekly');
// Example: '2024-01-15T09:00:00.000Z'

File Reference Summary

File Purpose
src/shared/rank-tracking.ts Device handling, cost estimation, scheduling (computeNextCheckAt), and label generation (devicesLabel, devicesCount)
src/types/schemas/rank-tracking.ts RankTrackingConfig type definition including the devices field that determines rank display mode
src/components/.../rank-table.* UI component implementing the Math.min() grouping logic based on devicesCount

Summary

  • Rank absolute displays exact position for one device; triggered by devices: 'desktop' or devices: 'mobile'.
  • Rank group shows the best rank across both devices; triggered by devices: 'both'.
  • The display mode derives from RankTrackingConfig.devices as defined in src/types/schemas/rank-tracking.ts.
  • Device translation utilities in src/shared/rank-tracking.ts (lines 29-45) prepare values for the UI layer.
  • The grouping calculation uses Math.min(desktopRank, mobileRank) in the rank table rendering component when devicesCount === 2.

Frequently Asked Questions

How do I switch between rank group and rank absolute in OpenSEO?

Change your rank tracking configuration's devices field. Set it to 'both' for rank group (best position across Desktop and Mobile), or to 'desktop' or 'mobile' for rank absolute (single-device position). Update the configuration in your project settings or via the API.

Does rank group always show the better of the two ranks?

Yes. Rank group explicitly computes Math.min(desktopRank, mobileRank), selecting the numerically lower value—which represents the better SERP position. If your keyword ranks #5 on Desktop and #12 on Mobile, the group rank displays as #5.

What happens if a keyword has no rank on one device?

The grouping logic filters out null ranks before applying Math.min(). If your keyword ranks #8 on Desktop but is unranked on Mobile, the group rank shows #8. Both ranks must be null for the result to indicate no ranking.

Is the rank group calculation performed server-side or client-side?

The grouping occurs in the client-side component that renders the rank tracking table. The server stores and returns both absolute ranks; the UI layer applies the Math.min() logic based on the configuration's devicesCount value to determine what to display.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →