Skip to content

Add blog to website with an example post#73

Merged
fabian-hiller merged 2 commits intomainfrom
add-blog-for-formisch-website
Mar 16, 2026
Merged

Add blog to website with an example post#73
fabian-hiller merged 2 commits intomainfrom
add-blog-for-formisch-website

Conversation

@fabian-hiller
Copy link
Member

@fabian-hiller fabian-hiller commented Mar 16, 2026

Summary by CodeRabbit

  • New Features
    • Added a blog section with a listing page showing recent posts in reverse-chronological order.
    • Added individual blog post pages with cover images, titles, authors, publication dates, and post content.
    • Posts include per-post navigation links, responsive layouts, and an "Edit this page" link to view the source.

Copilot AI review requested due to automatic review settings March 16, 2026 18:19
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Mar 16, 2026
@vercel
Copy link

vercel bot commented Mar 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
formisch Ready Ready Preview, Comment Mar 16, 2026 7:11pm

Request Review

@fabian-hiller fabian-hiller self-assigned this Mar 16, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Adds a new MDX blog post, a layout component for rendering individual posts (including GitHub edit link), and a blog index route that loads MDX posts, extracts frontmatter, and renders a sorted list.

Changes

Cohort / File(s) Summary
Example Blog Post
website/src/routes/blog/(posts)/example-post/index.mdx
New MDX post with frontmatter (cover, title, description, published, authors). Imports a Link component and a TypeSafeIssues image component; renders text, a /api link, and the image.
Post Layout Component
website/src/routes/blog/(posts)/example-post/layout.tsx
New default-exported Qwik component that builds the article layout using document head and location: title, PostMeta (authors, published), PostCover, <Slot /> for content, and a computed GitHub "Edit" link. Defines local PostFrontmatter type.
Blog Index Route
website/src/routes/blog/index.tsx
New route exporting head, usePosts (routeLoader$) and default component. usePosts glob-imports all index.mdx posts, extracts frontmatter (cover, title, published, authors), derives per-post hrefs, sorts by published date (desc), and the page renders a responsive list with PostCover, titles, and PostMeta.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nibbled lines and stitched a post,

Frontmatter neat from coast to coast.
Covers bloom and links leap through,
Edit paths stitched fresh and new.
Hooray — a rabbit's blog debut!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add blog to website with an example post' accurately summarizes the main change: introducing a new blog feature with example content.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch add-blog-for-formisch-website
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can generate a title for your PR based on the changes with custom instructions.

Set the reviews.auto_title_instructions setting to generate a title for your PR based on the changes in the PR with custom instructions.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new Blog section to the Qwik website, including an example post with a dedicated post layout and media asset.

Changes:

  • Introduces /blog index route that discovers MDX posts via import.meta.glob and renders a “Latest posts” list.
  • Adds an example post route group with a post layout (cover/meta/content + “Edit page” link).
  • Adds an example MDX post and an accompanying image asset.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 8 comments.

File Description
website/src/routes/blog/index.tsx New blog index page + loader that enumerates MDX posts and renders cards.
website/src/routes/blog/(posts)/example-post/layout.tsx New post layout rendering title/meta/cover/content and an “Edit page” link.
website/src/routes/blog/(posts)/example-post/index.mdx Example blog post frontmatter/content, including image import.
website/src/routes/blog/(posts)/example-post/type-safe-issues.jpg Image asset used by the example post.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (2)
website/src/routes/blog/index.tsx (1)

20-25: Use interface for PostData.

PostData is an object shape and should be declared as an interface in this TS file.

Suggested change
-type PostData = {
+interface PostData {
   cover: string;
   title: string;
   published: string;
   authors: string[];
-};
+}

As per coding guidelines, "**/*.{ts,tsx}: Prefer interface over type for defining object shapes in TypeScript".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/src/routes/blog/index.tsx` around lines 20 - 25, Replace the
object-shaped type alias PostData with an equivalent interface declaration:
change "type PostData = { cover: string; title: string; published: string;
authors: string[] }" to "interface PostData { cover: string; title: string;
published: string; authors: string[] }", preserving the exact property names and
types (and export if required), so the symbol PostData becomes an interface
rather than a type alias.
website/src/routes/blog/(posts)/example-post/layout.tsx (1)

6-10: Switch PostFrontmatter from type to interface.

For object-shape declarations in TS files, prefer interface here.

Suggested change
-type PostFrontmatter = {
+interface PostFrontmatter {
   cover: string;
   authors: string[];
   published: string;
-};
+}

As per coding guidelines, "**/*.{ts,tsx}: Prefer interface over type for defining object shapes in TypeScript".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@website/src/routes/blog/`(posts)/example-post/layout.tsx around lines 6 - 10,
Replace the object-shaped TypeScript alias with an interface by changing the
declaration "type PostFrontmatter = { cover: string; authors: string[];
published: string; }" to an equivalent "interface PostFrontmatter { cover:
string; authors: string[]; published: string; }" so the symbol PostFrontmatter
is an interface rather than a type alias; ensure any usages/imports remain
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@website/src/routes/blog/`(posts)/example-post/layout.tsx:
- Line 47: The edit-link assembly assumes location.url.pathname ends with a
slash, causing broken URLs like "...example-postindex.mdx"; update the
construction to ensure a slash before "index.mdx" by normalizing
location.url.pathname (e.g., append '/' if it doesn't already end with one) or
by inserting a '/' between the sliced pathname and "index.mdx"; locate the href
usage where location.url.pathname is sliced in the component and change the
string concatenation to use the normalized pathname so the final URL always
contains the separating slash.
- Line 12: Add the required JSDoc block and the tree-shaking annotation above
the exported component factory: place a /** ... */ JSDoc describing the
component immediately above the export and add the single-line comment //
`@__NO_SIDE_EFFECTS__` directly above the export default component$(() => { ... })
declaration so the exported component factory has both the documentation and the
no-side-effects annotation.

In `@website/src/routes/blog/index.tsx`:
- Line 30: The export of the pure loader factory export const usePosts =
routeLoader$(...) is missing the tree-shaking annotation; add the single-line
comment // `@__NO_SIDE_EFFECTS__` immediately above the export (between any JSDoc
and the export statement) so the usePosts route loader is annotated for no side
effects and can be tree-shaken by the bundler.
- Line 46: The comparator passed to .sort in website/src/routes/blog/index.tsx
currently returns only 1 or -1; update the comparator (the inline function in
.sort((a, b) => ...)) to explicitly return 0 when a.published === b.published.
For example, implement a three-way comparison of a.published and b.published (or
their Date values) and return -1, 0, or 1 accordingly so equal publish dates
produce 0.
- Line 49: Add a JSDoc block immediately above the default export of the
component (the export default component$() factory) describing the component and
include a no-side-effects marker for tree-shaking; specifically, add a /** ...
*/ JSDoc with a short description and a `@noSideEffects` (or equivalent
project-standard tag) and prepend the component$() call with the
pure/no-side-effects annotation used by the codebase (e.g., /* `@__PURE__` */ or
the repo's preferred marker) so the default exported component is documented and
marked for tree-shaking.

---

Nitpick comments:
In `@website/src/routes/blog/`(posts)/example-post/layout.tsx:
- Around line 6-10: Replace the object-shaped TypeScript alias with an interface
by changing the declaration "type PostFrontmatter = { cover: string; authors:
string[]; published: string; }" to an equivalent "interface PostFrontmatter {
cover: string; authors: string[]; published: string; }" so the symbol
PostFrontmatter is an interface rather than a type alias; ensure any
usages/imports remain unchanged.

In `@website/src/routes/blog/index.tsx`:
- Around line 20-25: Replace the object-shaped type alias PostData with an
equivalent interface declaration: change "type PostData = { cover: string;
title: string; published: string; authors: string[] }" to "interface PostData {
cover: string; title: string; published: string; authors: string[] }",
preserving the exact property names and types (and export if required), so the
symbol PostData becomes an interface rather than a type alias.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74c68c0a-bc85-45f5-9f64-86f58cc53398

📥 Commits

Reviewing files that changed from the base of the PR and between d591cf7 and af7822b.

⛔ Files ignored due to path filters (1)
  • website/src/routes/blog/(posts)/example-post/type-safe-issues.jpg is excluded by !**/*.jpg
📒 Files selected for processing (3)
  • website/src/routes/blog/(posts)/example-post/index.mdx
  • website/src/routes/blog/(posts)/example-post/layout.tsx
  • website/src/routes/blog/index.tsx

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: af7822b393

ℹ️ 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".

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@fabian-hiller fabian-hiller merged commit 89961a0 into main Mar 16, 2026
23 of 24 checks passed
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 60b9b1a1fc

ℹ️ 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".

};
})
)
).sort((a, b) => (a.published < b.published ? 1 : -1))

Choose a reason for hiding this comment

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

P2 Badge Handle equal publish dates in sort comparator

The usePosts comparator returns -1 for every non-< case, so it also returns -1 when a.published === b.published. That violates Array.prototype.sort expectations and can produce unstable ordering for posts published on the same day, which makes the “Latest posts” list nondeterministic across runs/environments instead of preserving a consistent order for ties.

Useful? React with 👍 / 👎.

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

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants