Conversation
✅ Deploy Preview for ethereumorg ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
…s, config updates
… i18n routing for edge, htmr type workaround
…t to avoid rsc lazy element issue with radix slot
|
| Edge Case | Page | Result |
|---|---|---|
<a> links inside text |
/en/stablecoins/ (4 Translation components with glossary links) |
✅ Identical |
<strong> tags |
/en/run-a-node/ ("starts with you") |
✅ Identical |
Nested <a> with href |
/en/run-a-node/ ("downloads a copy of the Ethereum blockchain") |
✅ Identical |
HTML entities (', &) |
/en/run-a-node/ (apostrophes, ampersands throughout) |
✅ Identical |
| GlossaryTooltip transforms | /en/stablecoins/ (dapps, cryptography, Ethereum account tooltips) |
✅ Identical |
| Mixed text + HTML nodes | /en/run-a-node/ (entire page content) |
✅ Identical |
Only differences found
- Dynamic data — market cap numbers fetched at different build times (expected)
- JSON-LD metadata — preview URLs (
deploy-preview-17781.ethereum.itvsethereum.org) and empty contributor arrays (expected for preview builds) - One harmless
<!-- -->comment — React empty text node marker in one stablecoins sentence (no visual impact)
Methodology
Fetched raw SSR HTML from both sites via curl, stripped tags/scripts, extracted visible text around known <Translation> component output, and diffed. Focused on pages with the highest density of Translation usage: /en/stablecoins/ (links, glossary tooltips), /en/run-a-node/ (links, strong tags, entities), and /en/what-is-ethereum/ (custom transform tags).
Bundle Size Comparison (Next 14 vs Next 15)Compared gzipped transfer sizes between production (Next.js 14 + React 18) and preview deploy (Next.js 15 + React 19) by fetching all JS chunks via Per-Page Initial Load
Full Build Manifest (all shared chunks across the entire app)
Biggest Chunks Breakdown
Key Takeaways
MethodologyFetched homepage HTML from both sites, extracted all |
myelinated-wackerow
left a comment
There was a problem hiding this comment.
Review: Next.js 15 + React 19 Upgrade
Really clean upgrade, @pettinarip. The phased approach is solid and the patterns are consistent across all 143 files. Async params migration, "use client" on lazy imports, framer-motion -> motion, i18n routing split, LanguagePicker RSC fix, React 19 type fixes -- all look good.
Two things to address:
-
force-cacheon GasTable fetches needs revalidation --GasTable.tsxfetches gas prices and ETH price from Etherscan with{ cache: "force-cache" }, and the page has norevalidateexport. This means users see build-time prices until the next deploy. Sincewhat-is-etheris a static React page (nopublic/content/dependency), it's safe to use{ next: { revalidate: N } }here instead. The exact interval is flexible -- this isn't a live gas tracker, but we don't want it running too stale either. 300 (5 min), 1800 (30 min), or 3600 (1 hr) would all be reasonable -- your call. Same consideration applies to the collectibles page fetches for badges/stats. -
Document
staleTimesrationale -- ThestaleTimes: { dynamic: 30, static: 180 }restores Next 14 client Router Cache behavior, but the specific values (especially static at 180 vs Next 14's 300) would benefit from a brief comment explaining the intent for future maintainers. Something like:// Restore client-side Router Cache durations closer to Next 14 defaults // (Next 15 changed dynamic to 0s; static was 300s in Next 14) staleTimes: { dynamic: 30, static: 180 },
Reviewed by Claude Opus 4.6 (1M context)
|
@wackerow thanks. re: point 2, I thought that those numbers that I put were the v14 defaults. I'll update them again to match v14. |
… sentry compatibility
Addressed in #17781 (comment)

Summary
Upgrade from Next.js 14.2 + React 18 to Next.js 15 + React 19.
Phase 1 (prep, still on Next 14)
framer-motionwithmotion(27 files)pnpm.overridesfor React 19 peer depsPhase 2 (the upgrade)
next,react,react-dom,@types/react,eslint-config-next,@next/bundle-analyzerparams/searchParamsmigration across all pagesnext.config.jscleanup: removedefaultConfigspread, removeexperimental.instrumentationHook(stable in 15), moveoutputFileTracingExcludesto top-level, addstaleTimesfor client Router Cachei18n/routing.tsintorouting.ts+navigation.tsper next-intl official setup"use client"to allssr: falsedynamic imports (Next 15 requirement)useRefrequiring argument,ReactElement<unknown>propsPost-upgrade fixes
htmrwithhtml-react-parser— restores build-time type checking (removesignoreBuildErrorsworkaround)server.tsx→lazy.tsxfor client-side dynamic import wrappers (naming consistency)force-cacheto barefetch()calls (Next 15 defaults tono-store)@netlify/plugin-nextjsto latest for Next 15 supportDeferred to follow-up PRs
prism-react-rendererv1→v2 rewritereact-selectupgradereact-emoji-renderreplacementforwardRef(optional in React 19)unstable_cache→use cacheTest plan
npx tsc --noEmit— zero type errorspnpm lint— cleanpnpm build— successfulpnpm build-storybook— all stories render