Skip to content

feat(seo): getSeoMeta accepts defaultTitle/defaultDescription (#1518)#1957

Open
swissky wants to merge 1 commit into
emdash-cms:mainfrom
swissky:feat/seo-meta-defaults
Open

feat(seo): getSeoMeta accepts defaultTitle/defaultDescription (#1518)#1957
swissky wants to merge 1 commit into
emdash-cms:mainfrom
swissky:feat/seo-meta-defaults

Conversation

@swissky

@swissky swissky commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Implements suggestion 2 from #1518 (milestone 1.0): getSeoMeta now accepts defaultTitle and defaultDescription options.

Design discussion: #1956

Today the helper's only fallbacks are data.title / data.excerpt. A page with a computed title (the issue's example: "Maeta — {title} (cover of {artist})") can't use getSeoMeta at all — the author has to drop down to getContentSeo and merge panel-vs-default by hand, or (worse, and this is the footgun) hand-roll <title> and silently bypass the whole SEO panel including the noindex toggle.

The new options slot in between the panel value and the data fallback:

  • title: SEO panel title > defaultTitle > data.title
  • description: SEO panel description > defaultDescription > data.excerpt

Editor-set panel values always win, so the panel stays authoritative. Purely additive; existing callers are unaffected. The siteTitle suffix applies to a default title like any other page title.

Complements the docs fixes for suggestion 1 (#1519 by the reporter, #1900) by removing the main remaining reason to hand-roll <title> in the first place. Suggestion 3 (dev-mode warning) is intentionally out of scope — it needs render-path tracking and is better evaluated once docs + this helper have landed.

Refs #1518

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Translation
  • Documentation
  • Performance
  • Tests
  • Chore

How was this change tested?

  • New unit tests in tests/unit/seo/get-seo-meta.test.ts: defaults beat data.title/data.excerpt, panel values beat defaults, behavior without defaults is unchanged, siteTitle suffix applies to the default title
  • Existing tests/integration/seo/seo.test.ts still passes (67 tests total across both files)
  • pnpm typecheck, pnpm lint, pnpm format all clean

Checklist

  • I have read CONTRIBUTING.md
  • I have added tests that prove my fix/feature works
  • New and existing tests pass locally
  • I have added a changeset (pnpm changeset) if this change affects published packages
  • For features: I have opened a Discussion and linked it here

AI-generated code disclosure

  • Portions of this PR were generated with an AI tool

Which tool? Cursor (Fable 5)

…-cms#1518)

Pages with computed titles/descriptions had to drop down to
getContentSeo and merge panel-vs-default by hand, because getSeoMeta's
only fallbacks were data.title/data.excerpt. The new options rank
between the SEO panel value and the data fallback, so editor-set panel
values still win.
@changeset-bot

changeset-bot Bot commented Jul 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 54caa74

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 16 packages
Name Type
emdash Minor
@emdash-cms/cloudflare Minor
@emdash-cms/sandbox-workerd Patch
@emdash-cms/fixture-perf-site Patch
@emdash-cms/perf-demo-site Patch
@emdash-cms/cache-demo-site Patch
@emdash-cms/do-demo-site Patch
@emdash-cms/do-solo-demo-site Patch
@emdash-cms/admin Minor
@emdash-cms/auth Minor
@emdash-cms/blocks Minor
@emdash-cms/gutenberg-to-portable-text Minor
@emdash-cms/x402 Minor
create-emdash Minor
@emdash-cms/auth-atproto Patch
@emdash-cms/plugin-embeds Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 11, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@1957

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@1957

@emdash-cms/auth-atproto

npm i https://pkg.pr.new/@emdash-cms/auth-atproto@1957

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@1957

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@1957

@emdash-cms/contentful-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/contentful-to-portable-text@1957

emdash

npm i https://pkg.pr.new/emdash@1957

create-emdash

npm i https://pkg.pr.new/create-emdash@1957

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@1957

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/@emdash-cms/plugin-cli@1957

@emdash-cms/plugin-types

npm i https://pkg.pr.new/@emdash-cms/plugin-types@1957

@emdash-cms/registry-client

npm i https://pkg.pr.new/@emdash-cms/registry-client@1957

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/@emdash-cms/registry-lexicons@1957

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/@emdash-cms/sandbox-workerd@1957

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@1957

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@1957

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@1957

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@1957

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@1957

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@1957

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/@emdash-cms/plugin-field-kit@1957

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@1957

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@1957

commit: 54caa74

@emdashbot emdashbot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the right change, implemented in the right place. getSeoMeta is the helper callers already reach for, and adding defaultTitle/defaultDescription as an extra rung in the existing fallback ladder solves the computed-title use case without making anyone drop down to getContentSeo or hand-roll <title>. It is purely additive: the return type is unchanged, the new options are optional, and the precedence (panel value → caller default → content field) matches the PR description exactly.

I checked the helper implementation, the new unit tests, the changeset, and package exports. The precedence chain is correct, siteTitle suffix behavior is preserved, and the fallback to data.title/data.excerpt is unchanged when no defaults are supplied. The changeset is user-facing, present tense, and identifies the migration story. No AGENTS.md conventions are violated: there is no new user-facing UI text, no SQL, no auth/locale/database changes, and a changeset is included.

No issues found.

@github-actions github-actions Bot added review/approved Approved; no new commits since and removed review/needs-review No maintainer or bot review yet labels Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core review/approved Approved; no new commits since size/M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant