Next.js Discord

Discord Forum

Proper way to set polyfills?

Unanswered
Eric Burel posted this in #help-forum
Open in Discord
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?

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 _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...)
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 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
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?
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.toReversed
American
I ended up doing this:

"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