⚡️ Changes
- Replace beaconscan slot/epoch links with beaconcha.in on history page (#17670) @Buttaa
- Tutorial: Providing your customers with a gasless experience (#17575) @qbzzt
- docs(get-eth): display correct content while hovering (#17636) @Uaitt
- Add VulSight - 10000 points (#17657) @0xMushow
- Update Elata project description in index.md (#17647) @AMelhede
- perf: convert footer to server component (#17650) @pettinarip
- SEO - Addressing remaining orphan pages (#17658) @mnelsonBT
- Adding sonny2k to consensus layer bug bounty hunters (#17656) @fredrik0x
- fix(ab-test): add custom dimension for segment queries (#17646) @pettinarip
- Add Codex to developer docs (#17638) @Nealo
- docs: add dia oracles (#17196) @khawlahssn
- fix(seo): remove duplicate @id in tutorials page JSON-LD (#17599) @wackerow
- fix(content): repair broken markdown table in restaking page (#17593) @wackerow
- feat(find-wallet): Add Infinex wallet #17586 (#17587) @riva-infinex
- docs: add Stork to oracles page (#17590) @galenmoore1
- fix: deduplicate block explorer lists (#17592) @wackerow
- hotfix kpi wrapping number (#17607) @pettinarip
- fix: update metamask open source status (#17273) @wackerow
- fix(analytics): ensure link click tracking works with ButtonLink (#17595) @pettinarip
- perf: limit RSS items to 3 per feed (#17580) @pettinarip
- Added Audittens and DongHan Kim to bug bounty leaderboard (#17588) @fredrik0x
- Update Nimbus URL on Bug Bounty Page (#17585) @fredrik0x
- fix: remove broken DeFi Pulse links (#17573) @konopkja
- fix: update outdated info on AI agents page (#17571) @konopkja
- fix(seo): add internal links to orphaned pages and homepage backlinks (#17578) @minimalsm
- fix(links): update stale internal links and add missing redirects (#17568) @minimalsm
- fix(breadcrumbs): update homepage text and add missing root breadcrumb (#17565) @minimalsm
- fix(i18n): disable automatic locale prefix redirect (#17561) @minimalsm
- content: add contextual internal links on key pages (#17570) @minimalsm
- feat(footer): add homepage link (#17566) @minimalsm
- Update execution-bounty-hunters.json (#17574) @fredrik0x
- Add slippage protection section to AI trading tutorial (#17266) @qbzzt
- Tutorial: Make your own AI trading agent (#17253) @qbzzt
- Re-enable Blobscan API fetch (#17262) @pettinarip
- fix(e2e): update whitepaper test to match new PDF link text (#17256) @pettinarip
- Handle invalid developer tools category slugs with 404 (#17254) @pettinarip
🌐 Translations
- i18n: automated Crowdin translation import (ru) (#17127) @wackerow
- i18n: automated Crowdin translation import (fr) (#17125) @wackerow
- SEO - fixing internal canonical links (#17673) @mnelsonBT
- SEO - updating broken external links (#17669) @mnelsonBT
- Fix broken consensus specs links (#17208) @someone19204
- SEO - internal redirecting links (#17666) @mnelsonBT
- i18n(cs): automated Crowdin translation import (part 10 of 13) (#17556) @minimalsm
- i18n(cs): automated Crowdin translation import (part 01 of 13) (#17547) @minimalsm
- SEO audit - best pages by link (#17652) @mnelsonBT
- SEO - Internal link errors (#17659) @mnelsonBT
- docs(stablecoins): correct typo (#17651) @Uaitt
- i18n: automated Crowdin translation import (ja) (#17132) @wackerow
- patch: tutorials list ui and header issues (#17635) @wackerow
- docs(revoke-access): correct wrong Blockscout URL (#17637) @Uaitt
- fix: escape apostrophes in French translations for strong tags [#17631] (#17632) @nicolasbalao
- i18n(cs): automated Crowdin translation import (part 07 of 13) (#17553) @minimalsm
- Redesign tutorials filter UI with skill tabs, search, and collapsible tags (#17579) @konopkja
- i18n: automated Crowdin translation import (tr) (#17182) @wackerow
- docs: correct weird sentence (#17591) @Uaitt
- feat: add ethskills.com link to developers page (#17572) @konopkja
- i18n(tr): automated Crowdin translation import (part 12 of 13) (#17428) @minimalsm
- i18n(tr): automated Crowdin translation import (part 13 of 13) (#17429) @minimalsm
- i18n(bn): automated Crowdin translation import (part 01 of 13) (#17430) @minimalsm
- i18n(bn): automated Crowdin translation import (part 02 of 13) (#17431) @minimalsm
- i18n(uk): automated Crowdin translation import (part 06 of 13) (#17474) @minimalsm
- i18n(uk): automated Crowdin translation import (part 08 of 13) (#17476) @minimalsm
- i18n(mr): automated Crowdin translation import (part 11 of 13) (#17518) @minimalsm
- i18n(de): automated Crowdin translation import (part 05 of 13) (#17382) @minimalsm
- i18n(de): automated Crowdin translation import (part 06 of 13) (#17383) @minimalsm
- i18n(de): automated Crowdin translation import (part 08 of 13) (#17385) @minimalsm
- i18n(de): automated Crowdin translation import (part 12 of 13) (#17389) @minimalsm
- i18n(de): automated Crowdin translation import (part 13 of 13) (#17390) @minimalsm
- i18n(bn): automated Crowdin translation import (part 04 of 13) (#17433) @minimalsm
- i18n(bn): automated Crowdin translation import (part 03 of 13) (#17432) @minimalsm
- i18n(bn): automated Crowdin translation import (part 05 of 13) (#17434) @minimalsm
- i18n(bn): automated Crowdin translation import (part 06 of 13) (#17435) @minimalsm
- i18n(bn): automated Crowdin translation import (part 12 of 13) (#17441) @minimalsm
- i18n(bn): automated Crowdin translation import (part 13 of 13) (#17442) @minimalsm
- i18n(pl): automated Crowdin translation import (part 01 of 13) (#17443) @minimalsm
- i18n(pl): automated Crowdin translation import (part 02 of 13) (#17444) @minimalsm
- i18n(pl): automated Crowdin translation import (part 04 of 13) (#17446) @minimalsm
- i18n(pl): automated Crowdin translation import (part 05 of 13) (#17447) @minimalsm
- i18n(pl): automated Crowdin translation import (part 06 of 13) (#17448) @minimalsm
- i18n(pl): automated Crowdin translation import (part 08 of 13) (#17450) @minimalsm
- i18n(pl): automated Crowdin translation import (part 11 of 13) (#17453) @minimalsm
- i18n(pl): automated Crowdin translation import (part 12 of 13) (#17454) @minimalsm
- i18n(pl): automated Crowdin translation import (part 13 of 13) (#17455) @minimalsm
- i18n(ur): automated Crowdin translation import (part 03 of 13) (#17458) @minimalsm
- i18n(ur): automated Crowdin translation import (part 05 of 13) (#17460) @minimalsm
- i18n(ur): automated Crowdin translation import (part 06 of 13) (#17461) @minimalsm
- i18n(ur): automated Crowdin translation import (part 08 of 13) (#17463) @minimalsm
- i18n(ur): automated Crowdin translation import (part 09 of 13) (#17464) @minimalsm
- i18n(ur): automated Crowdin translation import (part 12 of 13) (#17467) @minimalsm
- i18n(ur): automated Crowdin translation import (part 13 of 13) (#17468) @minimalsm
- i18n(uk): automated Crowdin translation import (part 01 of 13) (#17469) @minimalsm
- i18n(uk): automated Crowdin translation import (part 02 of 13) (#17470) @minimalsm
- i18n(uk): automated Crowdin translation import (part 03 of 13) (#17471) @minimalsm
- i18n(uk): automated Crowdin translation import (part 05 of 13) (#17473) @minimalsm
- i18n(uk): automated Crowdin translation import (part 09 of 13) (#17477) @minimalsm
- i18n(uk): automated Crowdin translation import (part 11 of 13) (#17479) @minimalsm
- i18n(uk): automated Crowdin translation import (part 12 of 13) (#17480) @minimalsm
- i18n(uk): automated Crowdin translation import (part 13 of 13) (#17481) @minimalsm
- i18n(ta): automated Crowdin translation import (part 01 of 13) (#17482) @minimalsm
- i18n(ta): automated Crowdin translation import (part 03 of 13) (#17484) @minimalsm
- i18n(ta): automated Crowdin translation import (part 05 of 13) (#17486) @minimalsm
- i18n(ta): automated Crowdin translation import (part 06 of 13) (#17487) @minimalsm
- i18n(ta): automated Crowdin translation import (part 08 of 13) (#17489) @minimalsm
- i18n(ta): automated Crowdin translation import (part 11 of 13) (#17492) @minimalsm
- i18n(ta): automated Crowdin translation import (part 12 of 13) (#17493) @minimalsm
- i18n(ta): automated Crowdin translation import (part 13 of 13) (#17494) @minimalsm
- i18n(te): automated Crowdin translation import (part 01 of 13) (#17495) @minimalsm
- i18n(te): automated Crowdin translation import (part 02 of 13) (#17496) @minimalsm
- i18n(te): automated Crowdin translation import (part 04 of 13) (#17498) @minimalsm
- i18n(te): automated Crowdin translation import (part 05 of 13) (#17499) @minimalsm
- i18n(te): automated Crowdin translation import (part 06 of 13) (#17500) @minimalsm
- i18n(te): automated Crowdin translation import (part 08 of 13) (#17502) @minimalsm
- i18n(te): automated Crowdin translation import (part 09 of 13) (#17503) @minimalsm
- i18n(te): automated Crowdin translation import (part 11 of 13) (#17505) @minimalsm
- i18n(te): automated Crowdin translation import (part 12 of 13) (#17506) @minimalsm
- i18n(te): automated Crowdin translation import (part 13 of 13) (#17507) @minimalsm
- i18n(mr): automated Crowdin translation import (part 01 of 13) (#17508) @minimalsm
- i18n(mr): automated Crowdin translation import (part 02 of 13) (#17509) @minimalsm
- i18n(mr): automated Crowdin translation import (part 03 of 13) (#17510) @minimalsm
- i18n(mr): automated Crowdin translation import (part 05 of 13) (#17512) @minimalsm
- i18n(mr): automated Crowdin translation import (part 06 of 13) (#17513) @minimalsm
- i18n(mr): automated Crowdin translation import (part 08 of 13) (#17515) @minimalsm
- i18n(mr): automated Crowdin translation import (part 12 of 13) (#17519) @minimalsm
- i18n(mr): automated Crowdin translation import (part 13 of 13) (#17520) @minimalsm
- i18n(zh-tw): automated Crowdin translation import (part 01 of 13) (#17534) @minimalsm
- i18n(sw): automated Crowdin translation import (part 02 of 13) (#17522) @minimalsm
- i18n(sw): automated Crowdin translation import (part 04 of 13) (#17524) @minimalsm
- i18n(sw): automated Crowdin translation import (part 03 of 13) (#17523) @minimalsm
- i18n(sw): automated Crowdin translation import (part 06 of 13) (#17526) @minimalsm
- i18n(sw): automated Crowdin translation import (part 08 of 13) (#17528) @minimalsm
- i18n(sw): automated Crowdin translation import (part 09 of 13) (#17529) @minimalsm
- i18n(sw): automated Crowdin translation import (part 13 of 13) (#17533) @minimalsm
- i18n(zh-tw): automated Crowdin translation import (part 12 of 13) (#17545) @minimalsm
- i18n(zh-tw): automated Crowdin translation import (part 11 of 13) (#17544) @minimalsm
- i18n(zh-tw): automated Crowdin translation import (part 13 of 13) (#17546) @minimalsm
- i18n(zh-tw): automated Crowdin translation import (part 09 of 13) (#17542) @minimalsm
- i18n(zh-tw): automated Crowdin translation import (part 08 of 13) (#17541) @minimalsm
- i18n(zh-tw): automated Crowdin translation import (part 06 of 13) (#17539) @minimalsm
- i18n(zh-tw): automated Crowdin translation import (part 05 of 13) (#17538) @minimalsm
- i18n(zh-tw): automated Crowdin translation import (part 04 of 13) (#17537) @minimalsm
- i18n(zh-tw): automated Crowdin translation import (part 03 of 13) (#17536) @minimalsm
- i18n(cs): automated Crowdin translation import (part 02 of 13) (#17548) @minimalsm
- i18n(cs): automated Crowdin translation import (part 03 of 13) (#17549) @minimalsm
- i18n(cs): automated Crowdin translation import (part 04 of 13) (#17550) @minimalsm
- i18n(cs): automated Crowdin translation import (part 05 of 13) (#17551) @minimalsm
- i18n(cs): automated Crowdin translation import (part 06 of 13) (#17552) @minimalsm
- i18n(cs): automated Crowdin translation import (part 08 of 13) (#17554) @minimalsm
- i18n(cs): automated Crowdin translation import (part 09 of 13) (#17555) @minimalsm
- i18n(cs): automated Crowdin translation import (part 11 of 13) (#17557) @minimalsm
- i18n(cs): automated Crowdin translation import (part 12 of 13) (#17558) @minimalsm
- i18n(cs): automated Crowdin translation import (part 13 of 13) (#17559) @minimalsm
📝 Documentation
- i18n: automated Crowdin translation import (ru) (#17127) @wackerow
- i18n: automated Crowdin translation import (fr) (#17125) @wackerow
- test(i18n): add unit tests for sanitizer (#17654) @myelinated-wackerow
- fix(i18n): sanitizer fixes and brand protection (#17653) @myelinated-wackerow
- i18n(cs): automated Crowdin translation import (part 10 of 13) (#17556) @minimalsm
- i18n(cs): automated Crowdin translation import (part 01 of 13) (#17547) @minimalsm
- i18n: automated Crowdin translation import (ja) (#17132) @wackerow
- fix(data-layer): add API key auth to beaconcha.in fetcher (#17630) @pettinarip
- i18n(cs): automated Crowdin translation import (part 07 of 13) (#17553) @minimalsm
- i18n: automated Crowdin translation import (tr) (#17182) @wackerow
🔧 Tooling
- i18n: automated Crowdin translation import (ru) (#17127) @wackerow
- i18n: automated Crowdin translation import (fr) (#17125) @wackerow
- test(i18n): add unit tests for sanitizer (#17654) @myelinated-wackerow
- fix(i18n): sanitizer fixes and brand protection (#17653) @myelinated-wackerow
- fix: use documented DefiLlama endpoint for DeFi TVL (#17648) @pettinarip
- feat: add translation glossary API endpoint (#17609) @wackerow
- i18n: automated Crowdin translation import (ja) (#17132) @wackerow
- deprecate(i18n): legacy crowdin infrastructure (#17165) @wackerow
- fix(ab-test): extract client IP from x-forwarded-for header (#17612) @pettinarip
- feat(data-layer): isolate env vars into dedicated .env file (#17270) @pettinarip
- Revert bot detection for A/B tests (#17605) @pettinarip
- i18n: automated Crowdin translation import (tr) (#17182) @wackerow
- feat: Homepage 2026 redesign (#17261) @pettinarip
- perf: replace dynamic imports with fs.readFile for i18n and md content (#17589) @pettinarip
- feat: A/B/C test for homepage 2026 redesign (#17294) @pettinarip
- fix(ci): complete injection prevention in translation review workflow (#17576) @pettinarip
- i18n(bn): automated Crowdin translation import (part 01 of 13) (#17430) @minimalsm
- i18n(pl): automated Crowdin translation import (part 01 of 13) (#17443) @minimalsm
- i18n(uk): automated Crowdin translation import (part 01 of 13) (#17469) @minimalsm
- i18n(ta): automated Crowdin translation import (part 01 of 13) (#17482) @minimalsm
- i18n(mr): automated Crowdin translation import (part 01 of 13) (#17508) @minimalsm
- fix(meta): add noindex for non-production environments (#17569) @minimalsm
- fix(ci): prevent auth bypass and command injection in Claude workflows (#17560) @wackerow
- fix(i18n): skip header ID sync when header counts mismatch (#17296) @minimalsm
- update: Review translations (#17279) @wackerow
- fix(ci): translation review posts to PR (#17259) @wackerow
📦 Dependencies
- build(deps): bump rollup from 4.46.2 to 4.59.0 (#17675) @dependabot
- build(deps): bump minimatch from 3.1.2 to 3.1.5 (#17677) @dependabot
- fix(i18n): sanitizer fixes and brand protection (#17653) @myelinated-wackerow
- build(deps-dev): bump storybook from 8.6.15 to 8.6.17 (#17674) @dependabot
- build(deps): bump bn.js from 4.12.2 to 4.12.3 (#17660) @dependabot
- build(deps): bump minimatch from 3.1.2 to 3.1.4 (#17655) @dependabot
- build(deps): bump ajv from 6.12.6 to 6.14.0 (#17613) @dependabot
- deprecate(i18n): legacy crowdin infrastructure (#17165) @wackerow
- fix(data-layer): add API key auth to beaconcha.in fetcher (#17630) @pettinarip
- feat(data-layer): isolate env vars into dedicated .env file (#17270) @pettinarip
- build(deps): bump swiper from 11.2.8 to 12.1.2 (#17601) @dependabot
- build(deps): bump axios from 1.9.0 to 1.13.5 (#17597) @dependabot
🦄 Contributors
Thank you @0xMushow, @AMelhede, @Buttaa, @Nealo, @Uaitt, @fredrik0x, @galenmoore1, @khawlahssn, @konopkja, @minimalsm, @mnelsonBT, @myelinated-wackerow, @nicolasbalao, @pettinarip, @qbzzt, @riva-infinex, @someone19204, @wackerow, Jakub Konopka and Ori Pomerantz for the contributions! 🏆