Phase 1: blog migration to markdown + Astro#2143
Merged
Merged
Conversation
One-shot migration from the CFWheels wheels.dev blog_posts table. HTML content was converted to markdown via turndown + gfm plugin. Each post has frontmatter with title, slug, publishedAt, author, tags, categories, excerpt, coverImage, and legacyId. Images moved from wheels.dev/public/images to web/sites/blog/public/blog-images, with original cfwheels.org URLs preserved in post bodies. Migration script lives in wheels-dev/wheels.dev/migration/ — not checked in to this repo, since it's a one-shot and wheels.dev is being archived.
…overy Post-mortem on Task 6: the 75 images copied from wheels.dev/public/images/ are orphaned — zero blog posts reference them via body markdown or coverImage frontmatter. They were landing/admin UI assets, not blog content. Meanwhile, every post body references https://cfwheels.org/... image URLs that now 301 to wheels.dev/ — those are all currently broken. Wayback Machine recovery is a follow-up after Phase 1 ships. Leaves an empty blog-images/ directory (via .gitkeep) as the target for recovered images.
References the shared ../../content/blog/posts directory so content lives at the monorepo root rather than inside the blog site. Zod schema validates each post's frontmatter.
getAllPosts sorts by publishedAt desc; getAllTags returns a tag→count Map for the tags index; getPostsByTag filters; formatDate formats for display. All thin wrappers around Astro's getCollection.
PostLayout composes title/meta/tags/cover/body around a slot for rendered markdown. The [slug].astro dynamic route uses getStaticPaths to pre-render every entry in the posts collection.
Index shows the 10 newest posts; /page/2/ through /page/N/ cover older posts. PostCard component is reused here and on tag pages.
/tags/ lists every tag with post counts, sorted by popularity. /tags/[tag]/ lists posts filtered to that tag.
All posts in the collection, newest first, with tag categories and excerpt as description. @astrojs/rss handles feed validity.
Comments are backed by GitHub Discussions on wheels-dev/wheels in the 'Blog Comments' category. Mapping uses pathname so each post has its own thread. Users sign in with GitHub.
Embedded form posts to buttondown.com. Appears on every page above the site footer. Username 'wheelsdev' — update if the Buttondown handle changes.
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
web/content/blog/posts/wheelsdev)Migration approach
One-shot script at
wheels-dev/wheels.dev/migration/(not committed — wheels.dev is being archived in Phase 5). Script queried the DB, joined with users/tags/categories, converted HTML → markdown via turndown+gfm, emitted one .md per post with frontmatter.Known issue — broken legacy images
All blog post bodies reference
cfwheels.org/*image URLs that now 301-redirect towheels.dev/. Every post ships with broken inline images. Recovery is a follow-up (Wayback Machine scrape intoweb/sites/blog/public/blog-images/). This is accepted debt for Phase 1 launch.Test plan
/posts/[slug],/tags/[tag],/page/[page],/rss.xml,/sitemap-index.xmlall renderpnpm format:check+astro checkpassWhat's next
Phase 2 generates API reference from
docs/api/v*.jsoninto the api.wheels.dev Starlight site.