How Target Detection Works for Identifying Tracked Domains in Open-SEO

The detectTarget function uses a deterministic four-step heuristic—trimming whitespace, checking for dots without spaces, normalizing via the URL constructor, and validating hostnames—to classify user input as either a tracked domain or a brand keyword.

Open-SEO, an open-source SEO analytics platform, relies on precise input classification to separate domain-based tracking from keyword-based tracking. The target detection system serves as the gatekeeper for the "Add tracked domain" feature, ensuring only valid hostnames enter the rank-tracking pipeline while routing free-text brand queries to the appropriate keyword analysis workflows.

The Target Detection Algorithm

The detection logic resides in src/shared/targetDetection.ts and follows a strict, side-effect-free process that prioritizes speed and reliability.

Step 1: Input Sanitization

First, the raw input undergoes rawInput.trim() to eliminate leading and trailing whitespace, preventing accidental spaces from breaking domain validation.

Step 2: Quick Domain Heuristic

The algorithm performs a rapid preliminary check: the trimmed string must contain no spaces and must include a dot (.). This filters out obvious brand keywords like "Acme Widgets" before expensive parsing operations begin.

Step 3: Domain Normalization and Validation

If the heuristic passes, the system invokes normalizeDomain from src/types/schemas/domain.ts. This helper:

  • Adds a dummy protocol if missing to satisfy the URL constructor
  • Extracts the hostname using the browser-compatible URL API
  • Strips leading www. prefixes
  • Returns the lower-cased hostname

If this normalization throws an error (invalid URL structure) or the resulting hostname lacks a dot, the input is rejected as a domain and classified as a keyword instead.

Step 4: Type Classification

Finally, detectTarget returns a discriminated union:

  • For valid domains: { type: "domain", value: hostname }
  • For all other inputs: { type: "keyword", value: trimmed }

Domain Validation in the Rank-Tracking Pipeline

This detection mechanism is critical for the tracked domains feature, where each stored domain associates with specific location and city settings. When users enter competitors for AI-driven searches or add new properties to monitor, the application calls detectTarget before any external API requests (such as DataForSEO).

This architecture provides:

Practical Implementation Examples

The detectTarget function handles various input formats uniformly:

import { detectTarget } from '@/shared/targetDetection';

// Valid domain without protocol
console.log(detectTarget('example.com'));
// → { type: 'domain', value: 'example.com' }

// Domain with protocol, www, and path
console.log(detectTarget('https://www.Example.com/page'));
// → { type: 'domain', value: 'example.com' }

// Brand keyword with spaces
console.log(detectTarget('Acme Widgets'));
// → { type: 'keyword', value: 'Acme Widgets' }

// Malformed input fails normalization
console.log(detectTarget('not a real domain.'));
// → { type: 'keyword', value: 'not a real domain.' }

These patterns are validated in the comprehensive test suite located at src/shared/targetDetection.test.ts.

Key Source Files

Understanding the target detection flow requires familiarity with these specific modules:

Summary

  • Target detection in Open-SEO relies on the detectTarget helper to classify user input as either a domain or keyword before processing.
  • The algorithm uses a deterministic heuristic: no spaces, contains a dot, and successfully parses through normalizeDomain using the standard URL constructor.
  • Valid domains return with type "domain" and a cleaned hostname; all other inputs receive type "keyword".
  • This pure function operates safely in both server-side API handlers and client-side React components, ensuring consistent behavior across the stack.
  • Early validation prevents invalid URLs from reaching external SEO data providers like DataForSEO.

Frequently Asked Questions

How does target detection handle URLs containing paths or query parameters?

The normalizeDomain function in src/types/schemas/domain.ts utilizes the browser-compatible URL constructor to extract only the hostname component, automatically discarding paths, query strings, and hash fragments. For example, https://example.com/blog/post resolves to example.com.

Does the system treat subdomains differently from root domains?

The detection algorithm preserves subdomains during normalization, only stripping the specific www. prefix. Inputs like blog.example.com return as type "domain" with value blog.example.com, maintaining distinct tracking for subdomain-specific SEO strategies.

Can detectTarget be safely called from server-side Node.js environments?

Yes, the function is deliberately pure and side-effect-free, making it safe for server-side services like brandLookup.ts. It relies only on standard JavaScript APIs (String methods and the global URL constructor) available in both Node.js and browser runtimes.

What happens when a user enters an invalid domain-like string?

If the input passes the initial heuristic (contains a dot, no spaces) but fails normalizeDomain validation—such as not a real domain.—the function catches the thrown error and returns { type: "keyword", value: "not a real domain." }, routing the input to keyword tracking instead of domain tracking.

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 →