feat: Add custom JSON-LD structured data support for blog posts - #338
Open
LindsayLiu777 wants to merge 1 commit into
Open
feat: Add custom JSON-LD structured data support for blog posts#338LindsayLiu777 wants to merge 1 commit into
LindsayLiu777 wants to merge 1 commit into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
gusye1234
reviewed
Jul 2, 2026
gusye1234
left a comment
Contributor
There was a problem hiding this comment.
Code Review — PR #338 (custom JSON-LD support)
Reviewed the diff. Clean, well-scoped change. CI green, tests pass, backward compatible.
Looks good:
- Optional
jsonLdexport is destructured off the dynamic MDX import — posts without it are unaffected. - Array-wrapping (
Array.isArray(jsonLd) ? jsonLd : [jsonLd]) is the right normalization — Google accepts a JSON-LD array in a single<script>tag. - Type declaration in
mdx.d.tsmatches the runtime shape. - Sits alongside the existing
blogPostingJsonLdscript without conflict.
Minor nits (non-blocking):
- Empty-array/object rendering.
{jsonLd && (...)}will still render a<script>tag if a post exportsjsonLd = []orjsonLd = {}. Consider{jsonLd && (Array.isArray(jsonLd) ? jsonLd.length > 0 : true) && (...)}if you want to guard against empty exports. Very minor — probably not worth the extra logic. - Type nit.
export const jsonLd: ... | undefined— since this is aconst, TS-wise it's always defined at value-time; theundefinedunion is more about "the module may not export this at all." Works fine as-is, just noting that?on a namespace/module member is a slightly more idiomatic way to express "optional export" (but TS doesn't support that on*.mdxmodule declarations, so this is fine). - Validation. No runtime validation that the exported object is well-formed JSON-LD. Since these are authored MDX files (not user input) and injected via
dangerouslySetInnerHTML, malformed JSON-LD is a authoring issue, not a security issue —JSON.stringifyhandles the escaping. Fine to leave as-is.
Assessment: Ready to merge from a code perspective. No blockers.
LindsayLiu777
pushed a commit
that referenced
this pull request
Jul 8, 2026
- Merge custom jsonLd export from PR #338 into blog page renderer - Add FAQPage schema to ai-agent-orchestration (3 FAQ items) - Include metadata.image in BlogPosting JSON-LD and OG/Twitter cards - Extend BlogPost type with optional image field Co-authored-by: Cursor <cursoragent@cursor.com>
gusye1234
added a commit
that referenced
this pull request
Aug 3, 2026
…(runtime-error auto-rewake followup) Tag a non-cleanly-ended turn so it's externally distinguishable from a clean nap/idle (the gap that let Blair's 2026-08-03 stall-kill masquerade as idle for 30min). Pure observability: records + traces the tag; the rewake policy that consumes it is B2. onTurnEnd behavior byte-for-byte unchanged. - turn_end event gains `endReason?: "errored"` (STRICT binary can-rewake judgement — single literal, not a union, so B2's `=== "errored"` gate can't be silently widened) + separate `terminationCause?: "runtime_error" | "killed_stalled"` (cause, for B2 branching) + `errorDetail?` free-text. - Two symmetric marker points keyed on CAUSE, never bare status (a voluntary idle-timeout stop also flips status→stopping): `terminate_stalled` effect → killed_stalled (Blair's actual case, independent of any death-rattle); 1556 non-superseded runtime error → runtime_error. Kill marker authoritative: a following rattle does not downgrade it. - Marker cleared at the trailing turn_end AND at the exit teardown (within the `=== state` guard) so a hard exit with no turn_end can't leak it onto the next turn. - endReason/terminationCause/errorDetail land in fsm-trace + onFsmTransition. Tests (810/810 green, typecheck 0): runtime-error tag; clean turn_end untagged (byte-identical); superseded reset/nap rattle no-tag; 3a marker-leak clear on hard exit; red-line-6 REAL induced stall (terminate_stalled, no injected error) → killed_stalled; voluntary idle-timeout stop flips stopping but stays untagged. Charter: plans/daemon-runtime-error-rewake.md (Cecilia arch #352 / Claudette gate #353). Root cause: /Gus/架构#338+#348.
GenerQAQ
pushed a commit
that referenced
this pull request
Aug 3, 2026
…(runtime-error auto-rewake followup) Tag a non-cleanly-ended turn so it's externally distinguishable from a clean nap/idle (the gap that let Blair's 2026-08-03 stall-kill masquerade as idle for 30min). Pure observability: records + traces the tag; the rewake policy that consumes it is B2. onTurnEnd behavior byte-for-byte unchanged. - turn_end event gains `endReason?: "errored"` (STRICT binary can-rewake judgement — single literal, not a union, so B2's `=== "errored"` gate can't be silently widened) + separate `terminationCause?: "runtime_error" | "killed_stalled"` (cause, for B2 branching) + `errorDetail?` free-text. - Two symmetric marker points keyed on CAUSE, never bare status (a voluntary idle-timeout stop also flips status→stopping): `terminate_stalled` effect → killed_stalled (Blair's actual case, independent of any death-rattle); 1556 non-superseded runtime error → runtime_error. Kill marker authoritative: a following rattle does not downgrade it. - Marker cleared at the trailing turn_end AND at the exit teardown (within the `=== state` guard) so a hard exit with no turn_end can't leak it onto the next turn. - endReason/terminationCause/errorDetail land in fsm-trace + onFsmTransition. Tests (810/810 green, typecheck 0): runtime-error tag; clean turn_end untagged (byte-identical); superseded reset/nap rattle no-tag; 3a marker-leak clear on hard exit; red-line-6 REAL induced stall (terminate_stalled, no injected error) → killed_stalled; voluntary idle-timeout stop flips stopping but stays untagged. Charter: plans/daemon-runtime-error-rewake.md (Cecilia arch #352 / Claudette gate #353). Root cause: /Gus/架构#338+#348.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Allow blog posts to export custom JSON-LD structured data (FAQ, HowTo, etc.) for Google rich snippet eligibility.
Changes
blog/[slug]/page.tsxto read optionaljsonLdexport from MDX filesmdx.d.tsUsage
In any MDX blog post:
Test plan