Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intl.NumberFormat with style 'unit' doesn't work on Apple devices with pre-2021 OS #4630

Closed
jarek opened this issue Oct 1, 2022 · 8 comments · Fixed by #4660
Closed

Intl.NumberFormat with style 'unit' doesn't work on Apple devices with pre-2021 OS #4630

jarek opened this issue Oct 1, 2022 · 8 comments · Fixed by #4660

Comments

@jarek
Copy link
Collaborator

jarek commented Oct 1, 2022

We use Intl.NumberFormat(lang, { style: 'unit' }) to format hour, day, month, and year with localized names/numbers:

const getLocaleNumberFormat = (lang, { unit, unitDisplay, range }) =>
new Intl.NumberFormat(lang, {
style: 'unit',
unit,
unitDisplay: unitDisplay || 'long',
}).format(range);
This was introduced for the history view feature in #4220 four months ago.

Per https://caniuse.com/mdn-javascript_builtins_intl_numberformat_numberformat_options_unit_parameter , this is not supported by browsers used by about 7-8% of users.

In particular it is not supported by Safari on iOS before version 14.5 (making up about 1.5% of global users), nor on Safari on Mac OS before version 14.1. This seems to have been released in April 2021. Firefox gained support mid-2020, in version 78. Other major browsers supported this before 2020.

I would have hoped that the formatter would just leave anything it doesn't recognize unformatted, but it appears to throw errors instead. Here are a few reports:

Is it feasible to wrap the formatter in a try-catch and fallback to ISO format or other unlocalized format?

@jarek jarek changed the title Intl.NumberFormat with style 'unit' doesn't work on pre-2021 Apple devices Intl.NumberFormat with style 'unit' doesn't work on Apple devices with pre-2021 OS Oct 1, 2022
@VIKTORVAV99
Copy link
Member

Perhaps we need to look over the Babel config as it should have transpiled these (in theory at least).

@VIKTORVAV99
Copy link
Member

This explains it:

Missing polyfills
ES BigInt can't be polyfilled since it requires changes in the behavior of operators, you could find more info zloirock/core-js#381. You could try to use JSBI.
ES Proxy can't be polyfilled, you can try to use proxy-polyfill which provides a very little subset of features.
ES String#normalize is not a very useful feature, but this polyfill will be very large. If you need it, you can use unorm.
ECMA-402 Intl is missed because of the size. You can use those polyfills.
window.fetch is not a cross-platform feature, in some environments, it makes no sense. For this reason, I don't think it should be in core-js. Looking at a large number of requests it might be added in the future. Now you can use, for example, this polyfill.

Intl is missing from core-js and that is what Babel is using to pollyfill our code at the moment.
I'll look into how big of a size diff it would be adding the pollyfill suggested in the core-js readme or if it would be better to just fall back to ISO standard.

@jarek
Copy link
Collaborator Author

jarek commented Oct 2, 2022

I imagine the polyfill could be quite large if it contains names and short names and formats for all these units for our 27 languages? Worth checking though.

@VIKTORVAV99
Copy link
Member

I checked it out a little quick yesterday and if we only need Intl.NumberFormat it's about 15kb, not optimal but we can live with that. But if we need to add the other Intl polyfills as well we are talking hundreds of kb. But hopefully we just need Intl.NumberFormat as thats one of the newer functions to get added to the Intl object though.

@madsnedergaard
Copy link
Member

Thanks for gathering all the info here! 🙏
I just checked up on this and approximately 2% of our visits come from Safari <14.1, and I'd assume the majority of those users are still on English.
So I'd suggest we just fallback to a fixed, English-based format if support for Intl.NumberFormat is missing - not worth adding the polyfill :)

@VIKTORVAV99
Copy link
Member

VIKTORVAV99 commented Oct 6, 2022

Then I think the easiest way to implement this is simply using an if statment like this:

if (typeof Intl.NumberFormat != 'undefined'){
  // Intl Code
}
else {
  // Fallback code
}

@jarek
Copy link
Collaborator Author

jarek commented Oct 7, 2022

Going by the error message, it looks like Intl.NumberFormat is supported, but not the unit style in NumberFormat. So just checking if (typeof Intl.NumberFormat != 'undefined') might not resolve this particular problem.

@VIKTORVAV99
Copy link
Member

Going by the error message, it looks like Intl.NumberFormat is supported, but not the unit style in NumberFormat. So just checking if (typeof Intl.NumberFormat != 'undefined') might not resolve this particular problem.

True, perhaps a try catch would be more appropriate since it's a constructor option that's missing. Unless there is a specific way to check if a constructor option is supported?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants