blog: support multiple authors for blog articles#3965
blog: support multiple authors for blog articles#3965devin-ai-integration[bot] wants to merge 2 commits intomainfrom
Conversation
Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
✅ Deploy Preview for hyprnote-storybook canceled.
|
✅ Deploy Preview for hyprnote ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
🟡 Array rendered directly as text in mobile view of ArticleListItem
In the mobile view (sm:hidden) of ArticleListItem, article.author (now a string[]) is rendered directly inside a <span> without .join(). React renders arrays by concatenating elements without separators, so ["John Jeong", "Yujong Lee"] would display as John JeongYujong Lee instead of John Jeong, Yujong Lee.
Root Cause
At apps/web/src/routes/_view/blog/index.tsx:577, the code reads:
<span className="text-sm text-neutral-500">{article.author}</span>This was not updated to use .join(", ") like the other occurrences in the same file (e.g., line 559 and line 417). The desktop view at line 559 correctly uses Array.isArray(article.author) ? article.author.join(", ") : article.author, but this mobile counterpart was missed.
Impact: Multi-author articles display author names concatenated without any separator in the mobile view of the blog listing page.
(Refers to line 577)
Was this helpful? React with 👍 or 👎 to provide feedback.
| if (data.frontmatter.meta_description) | ||
| setMetaDescription(data.frontmatter.meta_description); | ||
| if (data.frontmatter.author) setAuthor(data.frontmatter.author); | ||
| if (data.frontmatter.author) setAuthor([data.frontmatter.author]); |
There was a problem hiding this comment.
🟡 Google Docs import always wraps author in array, risking double-wrapping
When importing from Google Docs in the FileEditor, setAuthor([data.frontmatter.author]) always wraps the returned author value in an array. If the import API ever returns an array-typed author (e.g., from YAML that already has a list), this would produce a nested array like [["name"]].
Root Cause
At apps/web/src/routes/admin/collections/index.tsx:2723:
if (data.frontmatter.author) setAuthor([data.frontmatter.author]);The ImportResult interface at line 3262 types author as string, so currently this is safe at the TypeScript level. However, the actual API response could contain an array if the source document's YAML frontmatter has a list-format author. The code should normalize defensively, similar to how branchFileData.frontmatter.author is handled at line 2616:
author: Array.isArray(branchFileData.frontmatter.author) ? branchFileData.frontmatter.author : branchFileData.frontmatter.author ? [branchFileData.frontmatter.author] : undefinedImpact: If the Google Docs import returns an array author, the editor state would contain [["name"]] instead of ["name"], causing display and save issues.
| if (data.frontmatter.author) setAuthor([data.frontmatter.author]); | |
| if (data.frontmatter.author) setAuthor(Array.isArray(data.frontmatter.author) ? data.frontmatter.author : [data.frontmatter.author]); |
Was this helpful? React with 👍 or 👎 to provide feedback.
Co-Authored-By: john@hyprnote.com <john@hyprnote.com>
blog: support multiple authors for blog articles
Summary
Changes the blog
authorfield from a single string to an array of strings throughout the stack:content-collections.ts): Accepts bothstringandstring[]viaz.union, normalizes tostring[]in the transform for backward compatibility with existing articlesAuthorSelectfrom a single-select dropdown to a multi-select with toggle behavior, checkmarks, and×remove buttons$slug.tsx): Renders multiple author avatars + names in the hero section; related article sorting usessome/includesoverlap instead of strict equalityindex.tsx,_view/index.tsx): Shows first author's avatar in card views, joins all names with commas for display textsave.ts): Outputs author as a YAML list inbuildFrontmattergithub-content.ts): Updates default frontmatter template, function signatures, and PR body generationog.tsx): Splits comma-joined author param to resolve first author's avatarReview & Testing Checklist for Human
×remove buttons work, and the dropdown closes on outside click. This was not visually tested.FileEditor(line ~2720),setAuthor([data.frontmatter.author])always wraps in an array — if the imported YAML already has an array-format author, this could produce[["name"]]. Test importing a doc.z.union+Array.isArraynormalization handles backward compat, but verify a few existing articles load without errors on both the blog listing and individual article pages.blogSchemainog.tsxstill expectsauthor: z.string()(unchanged), and the caller now passesarticle.author.join(", "). Confirm OG images render correctly for articles.Notes
Requested by: @ComputelessComputer
Link to Devin run