SEO Meta Tags (seo-meta-tags)
Summary
Title, meta description, H1, canonical, Open Graph, JSON-LD; multi-page when crawl data exists; optional keyword coverage.
Classification
- Category:
SEO - Plugin id:
seo-meta-tags - Version:
2.0.0 - Target types:
WEBSITE,WEBSHOP - Weight class:
LIGHT - Risk level: not set on plugin object
- Browser required: No (HTTP / Node / other — see source)
- Tier / group: Tier 1 — HTTP-only
Schedule
- scheduleHints:
{ defaultInterval: '0 */6 * * *', priority: 5 } - Prerequisites: None declared on this plugin.
Configurable inputs
Public keys are derived from inputSchema: z.object({ ... }) (underscore-prefixed keys are runtime-only and omitted here).
| Field | Notes |
|---|---|
timeout |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
titleMinLength |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
titleMaxLength |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
descMinLength |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
descMaxLength |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
samplePages |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
url |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
pageType |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
_keywords |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
keyword |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
isPrimary |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
pageScope |
Zod field in inputSchema — see source for defaults, min/max, and .describe(). |
Runtime / injected config
- Worker may inject
_keywordsfrom target keyword configuration. - Worker may inject extra sample page URLs from the latest crawl snapshot.
Checks that produce findings
These checks run inside this plugin during a single test run. They are not separate tests in the database — each becomes a Finding linked to the Run for seo-meta-tags.
In multi-page mode (when a crawl snapshot exists), the same checks run across up to 10 sample pages and findings list affected URLs. Severity is higher on product/category pages for missing description, H1, and canonical.
| Check | Typical severity | Why |
|---|---|---|
Missing <title> |
WARNING | SERP snippets and browser tabs fall back to URL or generic text — click-through and brand recognition drop sharply. |
| Very short / too long title | INFO | Titles under ~15 chars are often placeholders; titles over ~60 display chars truncate in Google results. Clear short titles are fine — there is no mandatory 30–60 range. |
| Missing meta description | WARNING on product/category/homepage; INFO elsewhere (multi-page) | Auto-generated snippets from random on-page text hurt CTR; commerce pages lose control of offer messaging. |
| Description too short / too long | INFO | Descriptions outside ~120–160 chars truncate in SERPs or look thin compared to competitors. |
| Missing H1 | INFO (homepage exempt in multi-page) | Missing primary heading weakens topical relevance; homepage-only H1 gaps are common on hero layouts. |
| Multiple H1 tags | INFO | Several H1s dilute the main topic signal and confuse accessibility “document outline” heuristics. |
| Missing canonical URL | WARNING on product/category; INFO on other pages (multi-page) | Duplicate URLs (filters, tracking params) compete in the index without a canonical — especially costly on PDP/category pages. |
Missing og:title / og:description / og:image |
INFO | Social shares show bland link previews — lower engagement when links are pasted in Slack, LinkedIn, or messaging apps. |
| No JSON-LD structured data | INFO | Rich results (products, breadcrumbs, org info) require structured data; absence limits enhanced SERP features. |
| Primary keyword missing from title | WARNING when primary + important page type | Target keywords absent from titles reduce relevance for tracked queries on revenue-critical templates. |
| Keyword missing from description / H1 / body | INFO (WARNING for primary on H1 when important page) | Gaps in description, H1, or body weaken alignment with the configured keyword strategy. |
| Keyword stuffing in title (3+ repeats) | WARNING | Three or more exact keyword repeats in <title> mimic spam patterns and can trigger quality demotion. |
How each check works
- Pages loaded — Always fetches target URL as homepage. Up to 10 additional
samplePages(from crawl injection or config) are fetched with cheerio (fetchAndParse, default timeout 15s). Failed page fetches are skipped; all failures → runfailed. - Thresholds — Title stub floor 15 / display soft max 60 (
titleMinLength/titleMaxLength), description 120–160 (descMinLength/descMaxLength), all configurable. Short precise titles (≥15) are not flagged. - Multi-page aggregation — When >1 page succeeds,
aggregateMultiPageFindings()buckets affected URLs per issue type. Important page types (product,category,homepage) elevate missing description, H1 (non-homepage), and canonical to WARNING. Homepage missing H1 is excluded from H1 findings. - Single-page mode — Same checks on homepage only; missing H1 is INFO with note that hero homepages often omit H1; missing meta description is always WARNING.
- Keywords — When
_keywordsis injected, each keyword is scoped bypageScopeglob. Checks title (case-insensitive substring), description (only pages that have one), H1 (only pages with H1 text), URL path/slug, and visible body text. Stuffing = keyword appears ≥3 times in title. Primary keywords escalate missing title/H1 on important pages to WARNING. - JSON-LD — Parsed for metrics (
jsonLdTypessummary with per-type validation), but invalid JSON-LD does not emit findings — only “no JSON-LD” when zero blocks are found. - Score —
(checksPassed / checksTotal) × 100across all emitted check dimensions (including keyword checks when configured).
Caveats and concerns
- Static HTML only — Client-rendered title/meta (SPA, tag managers) are not visible unless present in the initial HTML response.
- No duplicate title/description detection — Unlike deep-404-scanner SEO phase, this plugin does not flag duplicate tags across pages in one run (except via multi-page lists in evidence).
- Keyword heuristics — Substring match, not stemmed/lemmatized Norwegian/English variants;
pageScopeuses simple glob→regex. - Hreflang counted in metrics only — Alternate links are not finding-producing checks.
Source
packages/test-plugins/src/plugins/seo-meta-tags.ts