Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Jan 27, 2026

Related GitHub Issue

Linear issue: MKT-69

Roo Code Task Context (Optional)

View task on Roo Code Cloud

Description

Adds the /blog/[slug] page that renders individual blog posts with request-time publish gating.

Key implementation details:

  1. Dynamic rendering: export const dynamic = "force-dynamic" ensures publish gating at request time
  2. Node.js runtime: export const runtime = "nodejs" for filesystem reads
  3. Security: Returns 404 for drafts, future-scheduled posts, or invalid slugs (no leakage)
  4. Markdown rendering: Uses react-markdown + remark-gfm (no raw HTML)
  5. Typography: Consistent styling with custom component overrides
  6. Metadata: Dynamic OG tags with title, description, and publish date

Build output shows dynamic rendering:

ƒ /blog/[slug]                           176 B         104 kB

Test Procedure

  1. Build passes: pnpm -C apps/web-roo-code build
  2. Visit /blog/prds-are-becoming-artifacts-of-the-past in dev
  3. Verify markdown renders with proper formatting
  4. Verify 404 returned for non-existent slugs
  5. Verify 404 returned for draft/future posts (change post status to test)

Pre-Submission Checklist

  • Issue Linked: This PR is linked to Linear issue MKT-69
  • Scope: Blog post page only
  • Self-Review: Verified 404 logic and markdown rendering
  • Testing: Build and lint pass
  • Documentation Impact: N/A
  • Contribution Guidelines: Reviewed

Screenshots / Videos

N/A - requires full stack for visual testing

Documentation Updates

  • No documentation updates required

Additional Notes

Dependencies (included via merge):

  • MKT-67: Content pipeline
  • MKT-73: First post
  • MKT-68: Blog index

Security:

  • No raw HTML rendering (safe by default)
  • Drafts and future posts return 404
  • No generateStaticParams (preserves request-time gating)

Get in Touch

Via Roo Code Cloud task link above


Important

Adds a dynamic /blog/[slug] page with publish gating, markdown rendering, and metadata handling, including content management and validation in content.ts.

  • Behavior:
    • Adds /blog/[slug] page with dynamic rendering and publish gating using dynamic = "force-dynamic" and runtime = "nodejs" in page.tsx.
    • Returns 404 for drafts, future-scheduled posts, or invalid slugs in page.tsx.
    • Renders markdown using react-markdown and remark-gfm without raw HTML in page.tsx.
  • Content Management:
    • Implements getAllBlogPosts() and getBlogPostBySlug() in content.ts for loading and filtering posts.
    • Validates frontmatter using zod in content.ts.
    • Adds BlogContentError for handling content validation errors in content.ts.
  • Metadata and SEO:
    • Generates dynamic metadata including OG tags in page.tsx.
    • Uses ogImageUrl for generating image URLs for metadata in page.tsx.
  • Dependencies:
    • Adds gray-matter for frontmatter parsing in package.json.

This description was created by Ellipsis for aa4c2d9. You can customize this summary. It will automatically update as commits are pushed.

- Add gray-matter for frontmatter parsing
- Create BlogPost type and zod schema for validation
- Implement PT timezone helpers (getNowPt, parsePublishTimePt)
- Implement content loading (getAllBlogPosts, getBlogPostBySlug)
- Implement isPublished for request-time publish gating
- Add validation for frontmatter and duplicate slugs
- Create content/blog directory for markdown files

Closes: MKT-67
…he Past

Adds the first canonical blog post to validate the content pipeline:
- Title: PRDs Are Becoming Artifacts of the Past
- Slug: prds-are-becoming-artifacts-of-the-past
- Status: published
- Publish date: 2026-01-12 at 9:00am PT

Content sourced from Office Hours S01E15 with Paige Bailey.

Closes: MKT-73
- Create blog index page at /blog
- Use force-dynamic for request-time publish gating
- Require Node.js runtime for filesystem reads
- Display posts with title, description, and date
- Add empty state when no posts are published
- Include tags display (up to 3)

Closes: MKT-68
- Create dynamic route for individual blog posts
- Use force-dynamic for request-time publish gating
- Require Node.js runtime for filesystem reads
- Return 404 for drafts, future posts, or invalid slugs
- Render Markdown with react-markdown + remark-gfm
- No raw HTML rendering (safe by default)
- Include consistent typography and styling

Closes: MKT-69
@roomote
Copy link
Contributor Author

roomote bot commented Jan 27, 2026

Rooviewer Clock   See task on Roo Cloud

Review complete. Previous issue fixed, but 1 new issue introduced.

  • Fix lexicographic time comparison in content.ts - posts on the same date are sorted incorrectly because publish_time_pt strings are compared alphabetically instead of numerically
  • Add missing import for parsePublishTimePt in content.ts - the function is used on line 160 but not imported, causing a runtime error
Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

@github-actions
Copy link
Contributor

🚀 Preview deployed!

Your changes have been deployed to Vercel:

Preview URL: https://roo-code-website-fyxsdiwuc-roo-code.vercel.app

This preview will be updated automatically when you push new commits to this PR.

@mp-roocode mp-roocode self-assigned this Jan 27, 2026
Co-authored-by: roomote[bot] <219738659+roomote[bot]@users.noreply.github.com>
if (dateCompare !== 0) {
return dateCompare
}
return parsePublishTimePt(b.publish_time_pt) - parsePublishTimePt(a.publish_time_pt)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

parsePublishTimePt is used here but not imported. The import statement on line 7 only includes getNowPt from "./pt-time". This will cause a runtime error when getAllBlogPosts is called. Update line 7 to: import { getNowPt, parsePublishTimePt } from "./pt-time"

Fix it with Roo Code or mention @roomote and request a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

2 participants