feat(blog): add MDX-powered post system with content collections#2
Open
edwintantawi wants to merge 22 commits into
Open
feat(blog): add MDX-powered post system with content collections#2edwintantawi wants to merge 22 commits into
edwintantawi wants to merge 22 commits into
Conversation
Split font imports out of app.css into their own stylesheet and preload them from the root route, avoiding render-blocking font loads.
Add createCsrfMiddleware to the start instance so server function requests are validated, independent of any specific route.
Introduce a content-collections pipeline that parses MDX posts under src/content/posts, compiles them via @mdx-js/rollup, and streams the rendered output through React Server Components so the compiled MDX never ships to the client bundle. - content-collections.ts defines the `posts` collection, validated against post.schema.ts and enriched with git-derived last-modified timestamps (modules/markdown/utils.ts). - modules/post exposes server functions to list and load posts, used by the new /posts and /posts/$slug routes. - vite.config.ts wires up the MDX plugin, content-collections vite plugin, and RSC support (needed to stream MDX without eval on Workers), and enables typography via @tailwindcss/typography. - Generalize the i18n pathname/prerender helpers (lib/i18n/utils.ts) to accept an arbitrary route list instead of a fixed config object, so the new /posts routes can be prerendered per locale alongside /.
🚀 Preview Deployment (2)Your changes have been deployed to a preview environment:
🏗️ This comment updates automatically with each push. |
…osts Introduce a series content type on top of the existing MDX pipeline: - Add `series` and `seriesPost` content collections with frontmatter validation, numeric order prefixes, and integrity checks that reject duplicate orders and posts orphaned by a missing `_index.mdx`. - Add the series module (server functions, schema, types) exposing list, detail, and post loaders backed by RSC-streamed MDX. - Add /series, /series/$slug, and /series/$slug/$postSlug routes plus a home-page nav link and the /series prerender path. - Move markdown-style-guide.mdx into a markdown series and add sample frontend-development series content.
Pulls in the packages behind the new MDX pipeline: shiki and rehype-pretty-code with @shikijs/transformers for compile-time syntax highlighting, remark-directive with mdast-util-directive/mdx-jsx for the :::tabs syntax, plus unist-util-visit, vfile and @types/mdast for the custom remark plugin.
Replaces the empty component map with app-aware overrides handed to the MDX runtime: Anchor routes internal links through TanStack Router and opens external ones in an isolated tab; CodeBlock wraps fenced code with a copy button that reads the block's rendered end state; and Tabs renders the group emitted by the :::tabs directive.
Extends the Vite MDX plugin with rehype-pretty-code (dual GitHub themes emitted as CSS variables, toggled by .dark) and the Shiki notation transformers for diff/focus/error/warning lines and indent guides. Adds a remark-tabs plugin that rewrites :::tabs / ::tab[Label] container directives into <Tabs> elements, and styles all of it in a new markdown.css imported from app.css. Renames plugin.ts to vite-plugin.ts to sit alongside the new plugins/ directory of remark transforms.
Grows the reference post into a full tour: paragraphs and line breaks, link variants, footnotes, and horizontal rules, plus a large code section covering language tags, titles, line/word highlights, line numbers, diffs, focus, errors/warnings, indent guides, and inline highlighting — alongside :::tabs and escape examples.
Support the build-time image pipeline and thumbnail captions: image-size for intrinsic dimensions, rehype-mdx-import-media to fingerprint local srcs, and hast/mdast utilities to parse inline-Markdown captions. Pin @types/hast to 3.0.5 in the workspace catalog to avoid a duplicate-copy type mismatch between mdast-util-to-hast and hast-util-raw.
Add a thumbnail module (schema, server-side caption parser, and figure component) and wire it into posts and series. Frontmatter gains an optional thumbnail whose document-relative src resolves to a fingerprinted asset at build time (resolveAsset) and whose inline-Markdown caption is rendered to HTML on the server, so no Markdown parser reaches the client. Series posts inherit the series thumbnail when they don't set their own, and detail pages render it above the header.
…tions Add a rehype-image build pass that stamps intrinsic width/height on colocated images to eliminate layout shift, and promotes a standalone titled image into a figure with a Markdown-rendered caption. Swap the MDX img tag for an app-aware Image component with lazy loading, run rehype-mdx-import-media (after rehype-image) to fingerprint local srcs, and add the matching prose image/figure styles. Also moves the font-ligature reset from code spans to the global root.
Rework the style guide into a complete reference covering frontmatter, GFM prose, code tooling, tabs, and the sharp edges around each, with example fences shown beside their rendered output. Add a series cover thumbnail with an image-credit caption and the supporting assets.
Drop the placeholder demo content now that the Markdown series is the canonical formatting reference for the site.
Rename utils.ts to markdown.utils.ts and vite-plugin.ts to markdown.vite.ts to match the module-prefixed filename convention, and update the imports in content-collections.ts and vite.config.ts.
Add a JSDoc block to MarkdownRender explaining that it renders compiled MDXContent with the app's mdxComponents overrides applied.
The title header was a flex container, where text-overflow has no effect. Switch it to a block box (line-height centers the single line) so a long filename ellipsis-truncates on narrow screens instead of overflowing.
Add the @shikijs/colorized-brackets transformer to the rehype-pretty-code pipeline so nested brackets render in level-cycling colors. Pinned to 4.3.1 to match the existing shiki/@shikijs/transformers version. Works with the dual-theme setup without CSS changes: under defaultColor: false the transformer overrides each bracket span's --shiki-light/ --shiki-dark vars, which markdown.css already reads.
Stamp a stable id on every heading (rehype-slug) and append a hover-revealed "#" permalink (rehype-autolink-headings) for deep linking, with scroll-margin-top so fragment jumps clear the top edge. Route hash links through a plain same-page anchor in the Anchor override so permalinks scroll in place instead of opening a new tab. Wrap GFM tables in a horizontal scroll container floored by a min-width, so wide tables scroll instead of crushing columns on narrow viewports, reusing the code block's thin-scrollbar styling.
Give footnote definitions and back-reference targets the same scroll-margin-top as headings, so following a footnote reference or its back-arrow lands with a gap above rather than flush against the top edge.
Rewrite `> [!NOTE]`-style blockquotes into styled Callout components via a new remarkAlert plugin. Supports the five GitHub alert types (NOTE, TIP, IMPORTANT, WARNING, CAUTION), each with an accent left border and icon, and documents them in the Markdown style guide.
Add extractTableOfContents, which reuses the render pipeline's rehype-slug
to build {depth, title, id} entries from a document's Markdown headings, so
#id links land on the same slugs the page renders. Wire the resulting toc
through the post, series, and series-post collections and expose it on their
document types and server functions.
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
/postsand/posts/$slugroutes backed by server functions inmodules/post/postsprerenders per locale alongside/Test plan
vp check(format, lint, type check)vp testvp dev— verify/,/posts, and/posts/markdown-style-guiderender correctly in both locales