Repository navigation
feat(blog): ✨ add blog post preview page and related functionality - #914
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d6904aa967
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const editorWindows = (): Window[] => { | ||
| const windows: Window[] = []; | ||
| if (window.parent !== window) windows.push(window.parent); | ||
| if (window.opener instanceof Window) windows.push(window.opener); |
There was a problem hiding this comment.
Accept the opener without a cross-realm instanceof check
When the preview is opened through “Open in a new tab”, its opener belongs to a different JavaScript realm and does not pass instanceof Window against the preview's constructor. Since this tab also has no parent frame, sources is empty and the effect returns before registering its message listener. The popped-out preview therefore never follows edits. Check for a non-null opener instead, retaining the existing origin and source checks when receiving messages.
Useful? React with 👍 / 👎.
| findLangValue(content, locale) ?? | ||
| findLangValue(content, DEFAULT_LOCALE) ?? | ||
| item.content, | ||
| coverImage: values.coverImage === null ? null : item.coverImage, |
There was a problem hiding this comment.
Resolve the selected cover image for live preview
When an editor uploads or selects a different cover image, the form sends its numeric file ID, but this expression ignores every non-null value and always retains the saved image. Consequently, adding a cover to an article without one still displays no cover, and replacing an existing cover continues to display the old one. Resolve the selected ID to a file descriptor and apply it to the preview rather than handling only removal.
Useful? React with 👍 / 👎.
| const ids = numericIds(value); | ||
| if (!ids) return saved; | ||
|
|
||
| return ids.flatMap(id => saved.filter(author => author.id === id)); |
There was a problem hiding this comment.
Resolve newly selected authors instead of dropping them
When the editor adds an author who was not in the saved article, saved.filter cannot find that user's descriptor, so the selected author is silently omitted from the live preview. Replacing all saved authors makes the byline disappear entirely despite the form containing valid authors. Fetch or supply descriptors for newly selected user IDs so the preview reflects additions as well as removals and reordering.
Useful? React with 👍 / 👎.
| return windows; | ||
| }; | ||
|
|
||
| export const useContentLivePreview = (): ContentLivePreviewPayload | null => { |
There was a problem hiding this comment.
Document the exported live-preview APIs at their declarations
The newly exported useContentLivePreview hook and ContentLivePreview component are developer-facing entry points, but neither has declaration-level JSDoc. Add their runtime, same-origin and embedding constraints, return or configuration semantics, and minimal import examples at the original declarations; the MDX tutorial does not replace this requirement. AGENTS.md explicitly requires these contracts for APIs consumed by app and plugin authors.
AGENTS.md reference: AGENTS.md:L134-L138
Useful? React with 👍 / 👎.
|
React Doctor found 1 new issue in 1 file · 1 warning · score 84 / 100 (Needs work) · 0 fixed · vs 1 warning
Reviewed by React Doctor for commit |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 820671cb56
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| coverImageAlt: | ||
| localizedText(values.coverImageAlt, locale) ?? item.coverImageAlt, |
There was a problem hiding this comment.
Preserve explicitly cleared text in the live preview
When an editor clears the default-language cover alt text, localizedText returns null, so this fallback restores the saved alt text instead of previewing its removal. Saving the same form converts the empty nullable field to null (contentFormValuesToTranslations), allowing BlogArticle to use the file's own alt text instead. The preview therefore differs from the saved result. Distinguish an explicitly empty value from missing or malformed input rather than falling back to the saved value in both cases.
Useful? React with 👍 / 👎.
| export const parseContentLivePreviewValues = ( | ||
| data: unknown, | ||
| ): ContentLivePreviewPayload | null => { |
There was a problem hiding this comment.
Document the exported live-preview protocol helpers
The new parseContentLivePreviewValues and isContentLivePreviewReady helpers are re-exported through @vitnode/core/content, but neither has declaration-level JSDoc. Document their universal runtime, accepted message shapes, return semantics, and validation limits—particularly that parsing does not authenticate the message's origin or source. The hook and component now have documentation, but these additional public protocol APIs still violate the declaration-documentation requirement in AGENTS.md.
AGENTS.md reference: AGENTS.md:L134-L135
Useful? React with 👍 / 👎.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ec18d0d to
fc80226
Compare
| key={frameKey} | ||
| ref={frameRef} | ||
| // oxlint-disable-next-line @eslint-react/dom-no-unsafe-iframe-sandbox -- the preview reads the editor's origin and session | ||
| sandbox="allow-forms allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts" |
There was a problem hiding this comment.
React Doctor · react-doctor/iframe-missing-sandbox (warning)
Combining allow-scripts & allow-same-origin lets the iframe remove its own sandbox, defeating the protection.
Fix → Add sandbox="" or a curated value so embedded pages cannot get full access to your site by default.
Improving Documentation
pnpm lint:fixto fix formatting issues before opening the PR.Description
What?
Why?