Add OG Image field to content editor#328
Conversation
The `_emdash_seo` table and content API already support `seo_image`, but the admin UI had no way to set it. This adds: - `SeoImageField` component using the existing `MediaPickerModal` - 2-column grid layout placing the OG Image next to the Featured Image - `description` prop on `ImageFieldRenderer` for helper text below images - Preserve `seo.image` in `SeoPanel.emitChange` so sidebar edits don't clear the image Closes emdash-cms#327 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: e30369e The changes in this PR will be included in the next version bump. This PR includes changesets to release 10 packages
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 |
There was a problem hiding this comment.
Pull request overview
This PR exposes per-content Open Graph (OG) image selection in the admin content editor for SEO-enabled collections, aligning the UI with existing seo.image support in the API/database.
Changes:
- Adds a new
SeoImageFieldcomponent that reusesMediaPickerModalto set/clearseo.image. - Updates
ContentEditorto render the OG Image picker next to an image field and adds helper-text support toImageFieldRenderer. - Updates
SeoPanel.emitChangeto includeseo.imagein the emitted SEO payload.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| packages/admin/src/components/SeoPanel.tsx | Includes image when emitting SEO updates from the sidebar. |
| packages/admin/src/components/SeoImageField.tsx | New OG Image picker field built on MediaPickerModal. |
| packages/admin/src/components/ContentEditor.tsx | Renders OG Image alongside an image field and adds description support for image fields. |
Comments suppressed due to low confidence (1)
packages/admin/src/components/SeoPanel.tsx:44
emitChangenow always includesimage: seo?.image || null. Becauseseocomes from props and is only refreshed after the update mutation + query invalidation, this value can be stale; editing title/description/canonical shortly after changing the OG image can sendimage: nulland clear the newly-selected image on the server. Prefer leavingimageundefined unless the panel is actually editing it (let the backend preserve existing values), or liftseointo shared local state so both components read the same up-to-date value before emitting changes.
const emitChange = (patch: Partial<ContentSeoInput>) => {
onChange({
title: title || null,
description: description || null,
image: seo?.image || null,
canonical: canonical || null,
noIndex,
...patch,
});
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add changeset for @emdash-cms/admin patch release - Remove image from SeoPanel.emitChange to avoid overwriting a freshly-selected OG image with a stale prop value Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Thank you!! Could you look at the copilot reviews. |
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/blocks
@emdash-cms/cloudflare
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
- Fix emdash-cms#1: Use @phosphor-icons/react instead of lucide-react - Fix emdash-cms#2: Send minimal patch { image } instead of spreading stale seo props - Fix emdash-cms#3: Only show OG Image next to the featured_image field, not all image fields - Fix emdash-cms#4: Only add description text for the featured_image field - Fix emdash-cms#5: Add responsive breakpoint (grid-cols-1 md:grid-cols-2) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Done. |
|
I'm looking forward to this one! Will be great to have. Thanks @jdevalk for the PR |
Summary
MediaPickerModaldescriptionprop toImageFieldRendererso both image fields show helper text below the imageseo.imageinSeoPanel.emitChangeso sidebar edits don't accidentally clear itThe
_emdash_seotable and content API already fully supportseo_image— this change exposes it in the admin UI.Screenshot
Closes #327
Test plan
hasSeoenabledseo.imageis set on the content API responseseo.imageis clearedhasSeo🤖 Generated with Claude Code