Proper way to set polyfills?
Unanswered
Eric Burel posted this in #help-forum
Hi, I've noticed "replaceAll" operation on strings in not supported on older iOS: what is the best strategy to support such a feature?
I am currently adding a polyfill in a top-level script but it means it will apply to everybody
I would also tweak the tsconfig to have a better support (but I am not sure how)
Is there a way to load a script only on iOS? Perhaps adding it inline in a middleware depending on the user agent?
I am currently adding a polyfill in a top-level script but it means it will apply to everybody
I would also tweak the tsconfig to have a better support (but I am not sure how)
Is there a way to load a script only on iOS? Perhaps adding it inline in a middleware depending on the user agent?
29 Replies
Why not just check the user agent string?
where, when? I was thinking I could tweak the HTML content from the middleware but it only takes the request, we can't alter the response
given that the page is not dynamic, so I want to avoid using headers directly in the page
I suspect this is not really doable for a static page, unless I use some client-side logic but it seems faster to just load the polyfill rather than adding an additional "if" on navigator user agent
How many users are affected by this anyway?
And is your pollyfill doing a while loop checking for if the element exists
And/could you modify the string.prototype . replaceAll to you method if it doesn't exist?
From your first sentence I assume this is only for client side code.
Given this assumption is true, I'd consider having an effect in
Given there's no support, then lazy-load the script for the polyfill. Eventually there's a
I'm not sure if this would work 100%, but that would be an approach I would try
Given this assumption is true, I'd consider having an effect in
_app.tsx where you check the support for string.replaceAll. Given there's no support, then lazy-load the script for the polyfill. Eventually there's a
useScript effect to achieve that too.I'm not sure if this would work 100%, but that would be an approach I would try
@riský How many users are affected by this anyway?
the support is currently around 92%, I'd say above 95% I could drop the polyfill but here it affects older Apple devices (Safari is becoming the new IE...)
@Uri From your first sentence I assume this is only for client side code.
Given this assumption is true, I'd consider having an effect in `_app.tsx` where you check the support for `string.replaceAll`.
Given there's no support, then lazy-load the script for the polyfill. Eventually there's a `useScript` effect to achieve that too.
I'm not sure if this would work 100%, but that would be an approach I would try
yes in the node server "replaceAll" exists so only client are ever affecter by those kind of issues
doing that in an effect feels like it's much too late :/
doing that in an effect feels like it's much too late :/
the thing is that when doing that, you need to send almost as many info as the script
the code that loads the script is roughly as long as a replaceAll polyfill
so in the end I feel like only a server-side check could do that, but that means dynamic rendering
I feel like we lack an "endware" where we can alter the generated HTML but that could cause hydration issues anyway
I've been recommended this tool: https://github.com/JakeChampion/polyfill-service
@Eric Burel the code that loads the script is roughly as long as a replaceAll polyfill
I was surprised by this statement, so I checked the weight from possible solutions:
1. using
2. using
All in all, it seems to me legit to have the extra code from the
1. using
usehooks-ts would add 14Kb if you would add all hooks, so I assume that by using 1 only (which you could copy/paste too) would be way less: https://bundlephobia.com/package/usehooks-ts@2.9.12. using
string.prototype.replaceall would add 31Kb, and this you have to consume it all: https://bundlephobia.com/package/string.prototype.replaceall@1.0.8All in all, it seems to me legit to have the extra code from the
useScript hook https://usehooks-ts.com/react-hook/use-script#hook to then load dynamically the polyfill ponly if the feature is not available@Uri I was surprised by this statement, so I checked the weight from possible solutions:
1. using `usehooks-ts` would add 14Kb if you would add all hooks, so I assume that by using 1 only (which you could copy/paste too) would be way less: https://bundlephobia.com/package/usehooks-ts@2.9.1
2. using `string.prototype.replaceall` would add 31Kb, and this you have to consume it all: https://bundlephobia.com/package/string.prototype.replaceall@1.0.8
All in all, it seems to me legit to have the extra code from the `useScript` hook https://usehooks-ts.com/react-hook/use-script#hook to then load dynamically the polyfill ponly if the feature is not available
ha thanks for crunching actual numbers! but what I don't get is how you can guarantee that you load the scripts soon enough?
because using a hook means your app is hydrated
which might be too late, the "replaceAll" calls might have been already encountered
as they are part of the next application
That's a good question… 🤔
Would it be possible to defer the rendering from
Would it be possible to defer the rendering from
<Component {...pageProps} /> in _app.tsx based on the check and lead from the polyfill?@Uri That's a good question… 🤔
Would it be possible to defer the rendering from `<Component {...pageProps} />` in `_app.tsx` based on the check and lead from the polyfill?
it's difficult to tell when something as broad as "replaceAll" is used :/
I've opened a discussion ticket about "endwares" that would allow this for static pages.
Nice!
@Eric Burel i saw this part in the docs: https://nextjs.org/docs/architecture/supported-browsers#custom-polyfills and got exited, but then realised that it is pages dir 😦
@riský <@769111741098622976> i saw this part in the docs: <https://nextjs.org/docs/architecture/supported-browsers#custom-polyfills> and got exited, but then realised that it is pages dir 😦
yeah client-side it's not a really hard problem, to be fair I am really finnicky here because you can have a polyfill loader and it doesn't cost a lot
American
@Eric Burel hey, did you end up with a solution that you want to share? I'm looking to polyfill
Array.toReversedAmerican
I ended up doing this:
and importing that into my top-level layout
"use client";
import "core-js/features/array/to-reversed";
import "core-js/features/array/to-sorted";
import "core-js/features/array/to-spliced";
export function Polyfill() {
return null;
}and importing that into my top-level layout