← gitpulse
New Feature·Pushed May 1, 2026·M

Stories feed and detail pages now render from JSON

Gitpulse stories now surface in a chronological feed with individual detail pages. The site reads from JSON files, with stub fixtures included for design verification.

The gitpulse site can now display merged pull requests and direct pushes as short editorial stories. A content collection system reads from JSON files in the stories directory, rendering them as a feed on the homepage and as individual detail pages at build time. When no stories exist, the site shows an empty state explaining that content will appear once the analyzer runs. Each story displays a kind label ("merged" or "direct push"), headline, standfirst, author, and date. Individual story pages include the full body text, formatted date, and a link back to the original PR or commit on GitHub. Two stub fixtures are included so the visual identity can be verified before real analyzer output exists. These placeholders—one merged PR and one direct push—will be replaced when the analyzer starts producing actual content. This lays the foundation for the analyzer-to-site pipeline, establishing the JSON format and rendering infrastructure that will populate the development log going forward.
Technical description
The site gains a content collection system that reads story data from JSON and renders it across two pages. A discriminated union type [[code ref=4]]Story[[/code]] models two story kinds: pull request merges and direct pushes to the default branch. The union shares a common [[code ref=4]]StoryBase[[/code]] shape (id, headline, standfirst, author, date) while each branch adds its specific fields ([[code]]prNumber[[/code]] for PRs, [[code]]commitUrl[[/code]] for direct pushes). The [[code ref=1]]loadStories[[/code]] function reads all [[code]].json[[/code]] files from the content directory at build time, parses them, and sorts by [[code]]committedAt[[/code]] descending. The [[code]]loadStory[[/code]] function looks up a single story by ID. The homepage now calls [[code ref=1]]loadStories[[/code]] and maps over the result with the [[code ref=2]]StoryCard[[/code]] component, which renders each story's kind label, formatted date, headline as a link, standfirst, and author. When the array is empty, an empty state message appears. Individual story pages live at [[code]]/stories/[id]/[[/code]] and use [[code ref=3]]generateStaticParams[[/code]] to enumerate all story IDs at build time, producing static HTML for each. The [[code ref=6]]StoryPage[[/code]] component handles rendering—extracting the kind-specific source URL, formatting dates with [[code]]Intl.DateTimeFormat[[/code]], and linking back to GitHub. ````mermaid graph LR A["src/content/stories/*.json"] --> B["loadStories()"] B --> C["HomePage"] B --> D["generateStaticParams()"] D --> E["stories/[id]/page.tsx"] C --> F["StoryCard"] E --> G["Story detail"] F --> H["Feed cards"] ```` Two fixture files verify the visual design: [[code]]example-merged-pr.json[[/code]] and [[code]]example-direct-push.json[[/code]]. Both use the octocat/GitHub fictional author and will be overwritten when the analyzer produces real output. **Files at a Glance** - [[code]]src/lib/stories.ts[[/code]] — Story types and load functions - [[code]]src/components/StoryCard.tsx[[/code]] — Feed card component - [[code]]src/app/page.tsx[[/code]] — Homepage feed renderer - [[code]]src/app/stories/[id]/page.tsx[[/code]] — Individual story page - [[code]]src/content/stories/example-merged-pr.json[[/code]] — PR fixture - [[code]]src/content/stories/example-direct-push.json[[/code]] — Direct push fixture

Categories

  • New Feature (85%)Core addition: reading JSON stories from a content directory and rendering them as a feed with individual detail pages. This is the primary deliverable.
  • Maintenance (10%)Includes two stub fixture files for design verification before real analyzer output exists. These are temporary placeholders.
  • Configuration (5%)Sets up the content collection infrastructure and file format contracts that future analyzer output will conform to.