feat(developer-hub): unified cross-product changelog at /changelog - #3910
feat(developer-hub): unified cross-product changelog at /changelog#3910aditya520 wants to merge 4 commits into
Conversation
Extend the market-data-only changelog into a cross-product hub covering Pyth Pro, Pyth Core, and Entropy. - Move the page from /price-feeds/changelog to top-level /changelog (308 redirect; nav, ChangelogBar, and BasePage repointed). - Product Updates tab: hand-authored MDX entries under content/changelog/, filterable by Product / Area / Type with live faceted counts, date-grouped cards with semantic type badges, and per-entry deep-link + copy. - Market Data tab: reuses the existing automated stream. - RSS: /changelog/feed.xml plus per-product feeds, a Subscribe menu, and <link rel="alternate"> auto-discovery on the page. - Full WAI-ARIA tabs (roving tabindex + arrow keys, tabpanel wiring), labelled filter groups, focus-visible rings, and a robust deep-link reveal that survives filter clearing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
5 Skipped Deployments
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bcb7a4116b
ℹ️ 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".
| - Provider-configurable fee schedules | ||
| - Batch reveal for high-volume apps | ||
|
|
||
| See [contract addresses](/entropy/contract-addresses) for the new deployments. |
There was a problem hiding this comment.
Point the Entropy entry to the existing chainlist page
This link leads to a 404 because there is no /entropy/contract-addresses page or redirect in the Developer Hub. The contract-address table is provided by content/docs/entropy/chainlist.mdx at /entropy/chainlist, so readers following this new changelog entry cannot reach the referenced deployment details.
Useful? React with 👍 / 👎.
| { | ||
| destination: "/changelog", | ||
| permanent: true, | ||
| source: "/price-feeds/changelog", | ||
| }, |
There was a problem hiding this comment.
Preserve the legacy raw-markdown changelog URLs
This redirect only matches the extensionless route. The documented raw-doc URLs /price-feeds/changelog.mdx and /price-feeds/changelog.md are explicitly excluded from the generic Price Feeds redirect below, so they instead rewrite through /mdx/price-feeds/changelog after the old document has been deleted and return 404. Add redirects for these variants to the corresponding /changelog.mdx or /changelog.md endpoints.
Useful? React with 👍 / 👎.
| "description": "Real-time financial market data", | ||
| "icon": "ChartLine", | ||
| "pages": ["core", "pro", "changelog"], | ||
| "pages": ["core", "pro"], |
There was a problem hiding this comment.
Add the unified changelog to the top-level page tree
Removing changelog here eliminates its only sidebar entry, but content/docs/meta.json still lists only price-feeds, express-relay, entropy, and api-reference. Because DocsLayout renders source.pageTree, the new cross-product page is absent from navigation even though it is now a top-level product-wide destination; add changelog to the root metadata when removing it from this section.
Useful? React with 👍 / 👎.
| const slugOf = (entry: CollectionEntry): string => | ||
| entry.info.path.replace(/\.mdx$/, ""); |
There was a problem hiding this comment.
🔍 slugOf relies on info.path being relative to the collection dir
slugOf in apps/developer-hub/src/lib/changelog-data.ts:16-17 derives the entry's stable anchor slug (used as id={entry.slug} on the card and in #slug deep links and RSS item links) from entry.info.path.replace(/\.mdx$/, ""). This is only correct if fumadocs-mdx's info.path is relative to the collection dir (content/changelog) rather than an absolute or project-root-relative path; otherwise slugs would contain slashes and break the anchor/deep-link behavior. Given the collection's flat content/changelog/ directory and that tsc is reported clean, this is consistent with fumadocs-mdx v14 behavior, but worth confirming against the generated .source output if deep links ever misbehave.
Was this helpful? React with 👍 or 👎 to provide feedback.
- Date groups now hang off a continuous vertical timeline rail with a node marker per date (Linear/Vercel-style changelog layout). - Each entry card carries a type-keyed left accent (feature/fix/breaking/ deprecation/docs) so the feed scans by change-type at a glance. - Slightly tightened the filter bar (chip padding + row gap). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rework the /changelog Product updates UI to match the Pyth Lazer (@pythnetwork/components) design language, built on the developer-hub component library and its design tokens: - Large editorial tabs plus a solid violet Subscribe (component-library Button + Popover), scoped to the Product updates tab. - Faceted checkbox filter (Product / Type / Area) with live counts, Clear all, and a mobile disclosure — modelled on ItemListFilter. - Tinted semantic type tags via states.* tokens; the entry date doubles as a permalink (useCopy); titles link to their anchor. - Relative-time labels computed at build time to avoid hydration drift. The docs shell already renders the page title and description, so the component renders no hero. The Market data tab is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…11y, tests Review-pass fixes for the cross-product changelog: - SSR: drop useSearchParams from HubTabs/ProductUpdates (it bailed the whole feed out of the static prerender). Default tab/filters and reconcile URL state after mount so the full feed renders into static HTML; remove the now-unnecessary Suspense boundary. - fix: relativeDate was off by one for any render at/after 12:00 UTC; diff whole UTC calendar days instead of folding in the current time-of-day. - fix: RSS route returned 400 for a bare `?product=`; treat empty as absent and serve the all-products feed. - fix: deep-link auto-scroll used a fixed 100ms timer that could fire before the target card mounts; gate the one-shot scroll on the card's presence. - DRY: import SITE from lib/changelog instead of redefining it in the RSS route. - a11y: announce "Link copied" via an sr-only role=status live region. - tests: add unit tests for the pure changelog helpers and parseListParam, and wire the missing test:unit script so jest runs in CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Turns the market-data-only changelog into a unified, cross-product Changelog at
/changelog, covering Pyth Pro, Pyth Core, and Entropy. Inspired by the Massive and Twilio changelogs.The page has two tabs:
content/changelog/), filterable and shareable.Features
#slugdeep link; opening one scrolls to, reveals (past pagination), and highlights the entry, dropping any filters that would hide it./changelog/feed.xmlplus per-product feeds (?product=…), surfaced via a Subscribe menu and advertised through<link rel="alternate">auto-discovery on the page.Authoring model
Entries are validated at build time by the
changelogcollection schema insource.config.ts:product(one ofpyth-pro/pyth-core/entropy),type(one offeature/fix/breaking-change/deprecation/docs), optionalarea, plustitleanddate. The filename (<YYYY-MM-DD>-<slug>.mdx) is the entry's stable share anchor.Wiring
/price-feeds/changelogto top-level/changelog(permanent redirect; removed from Price Feeds nav;ChangelogBarnow links to/changelog?tab=market-data;BasePagePageActions hidden for the new path).Design & accessibility
role="tabpanel"+aria-controls).role="group"Subscribe popover with focus restoration on Escape.Testing
tsc,biome, andstylelintclean; production build passes./changelog200,/price-feeds/changelog→ 308,feed.xml200 (well-formed XML; per-product item counts correct; unknown?product=→ 400).PAGE_SIZE=2).Review pass (follow-up — commit
162466037)A standards/correctness review of the branch produced these fixes:
useSearchParams()behind a fallback-less<Suspense>bailed the whole feed out of the static prerender. Removed the hook fromHubTabs/ProductUpdates; they now default to the updates tab with no filters (so the full feed renders into the static HTML) and reconcile URL state after mount. Dropped the now-unnecessary Suspense boundary. The no-JS HTML now contains every entry.relativeDatewas off by one for any render at/after 12:00 UTC (it folded the current time-of-day into aMath.round); it now diffs whole UTC calendar days.?product=returned 400 — it now serves the all-products feed (genuinely unknown non-empty values still 400). This refines the "unknown?product=→ 400" note above for the empty case.SITEfromlib/changeloginstead of redefining it.role="status"live region.matchesFilters,filterEntries,feedUrl,fmtEntryDate,relativeDateincl. the noon-UTC regression, andparseListParam) and wired the missingtest:unitscript so jest actually runs in CI.Re-verified:
tsc·biome·stylelint·jest(20/20) ·next buildall clean; light/dark/mobile plus filtering, deep-link reveal, and URL-state reconciliation exercised in-browser with no hydration errors.🤖 Generated with Claude Code