A bare `toLocaleString()` is not a formatting choice, it is the absence of one. With no locale argument the result comes from the runtime's default — the server's ICU default in Node, the user's browser setting in the client — so the same value renders `8,420` in one place and `8.420` in another with nothing in the code to explain the difference.
In a prerendered app that is a hydration bug, not a cosmetic one. This site sets `ssr: false` with a `prerender()` list, so every page is HTML generated in Node and then hydrated in the browser: the two runs format the same number against two different default locales, React finds text it did not expect, and what it does about it is not something to reason about per-component. The fix is the same in either direction — say which locale you mean.
The library's formatters are where that decision is written down once. `FormattedNumber`, `FormattedCurrency` and `FormattedPercentage` render the value through `Intl.NumberFormat` with a locale from the nearest `I18nProvider` (mount one, or pass `locale`); `FormattedDate` pins both a locale and an IANA time zone, so a date is not silently reinterpreted in the reader's zone. For string contexts where a component cannot go — a chart tick callback, a `valueFormatter`, an aria-label — `formatNumber(value, locale)` and `formatCurrency(value, locale)` take the locale as an argument, which is the point: it cannot be forgotten.
`CalendarDate#toString()` and `Time#toString()` from `@internationalized/date` fail the same way from the other end, and worse. They are not locale-dependent at all — they return ISO 8601, the wire format — so instead of a different spelling in each runtime you get the serialization in every runtime: `2026-06-30` in a Description sitting a few pixels under a trigger whose segments spell the same day `30.6.2026`. GritQL cannot see types, so "a value whose type comes from @internationalized/date" is not a pattern that can be written. The position is. A `.toString()` rendered as JSX *text* is either redundant — React stringifies whatever you hand it — or a serialization leak, and neither is something anyone writes on purpose, so that position, and only that position, is what the check matches.
Two honest limits. `FormattedStorage` is not a byte formatter — it takes gigabytes and rolls up to TB, with no KB, MB or PB and no binary-vs-decimal choice — so hand-rolled byte arithmetic is outside what this rule can redirect you to. And `new Intl.DateTimeFormat().resolvedOptions().timeZone`, the standard way to ask what zone you are in, is a construction like any other and is reported; that one is a suppression with a reason, not a rewrite.