Skip to content

frontmatter mapping cannot express a fallback field (seoTitle ?? title) #2

Description

@nahuelsoria

The problem

The frontmatter mapping takes one field name per canonical field. A repo where a field has a documented fallback cannot be expressed, and either choice produces false positives.

My posts have both title (the H1, written for a human) and an optional seoTitle (short, written for the <title> tag). The site does post.seoTitle ?? post.title. Three of ten posts have no seoTitle because their title is already short enough.

Mapping "title": "title" gives 4 title-length errors, on posts whose real <title> is 37 to 43 characters:

automated-newsroom.es    title=87  seoTitle=43
automated-newsroom.en    title=78  seoTitle=38
honest-ai-visibility.es  title=69  seoTitle=37
agent-fleet.es           title=61  seoTitle=43

Mapping "title": "seoTitle" gives 3 missing-title errors instead, on the posts that legitimately do not set it:

{
  "rule": "missing-title",
  "file": "content/blog/agent-guardrails.en.md",
  "message": "mapped title field (seoTitle) is missing or empty",
  "severity": "error"
}

Both readings are wrong about the same 7 posts. There is no third option.

Suggested fix

Let a mapped value be an array of field names, first non empty wins:

"frontmatter": {
  "title": ["seoTitle", "title"],
  "description": "description"
}

A string stays a string, so every existing config keeps working, and null keeps meaning the field is unused. The change is in the resolver in lib/config.mjs, and the rules themselves do not need to know about it. The error message would name the field that actually resolved, or the whole chain when none did.

This is not specific to titles. description with a fallback to an excerpt field, and updatedDate falling back to date, are the same shape. The updatedDate one matters for AEO: a repo that never sets it would get its freshness signal from date instead of dropping the rule entirely.

Related to #1, found in the same run, but independent of it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions