Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expo React Native Can't find variable: TextDecoder

So for some reason i'm having this bug when i try to run the app on the Expo Go app in my phone. Apparently is ok if i run on the web browser.

This is the error log

ReferenceError: Can't find variable: TextDecoder

Stack trace:
node_modules\expo\build\environment\react-native-logs.fx.js:27:4 in error
node_modules\react-native\Libraries\Core\ExceptionsManager.js:95:4 in reportException
node_modules\react-native\Libraries\Core\ExceptionsManager.js:141:19 in handleException
node_modules\react-native\Libraries\Core\setUpErrorHandling.js:24:6 in handleError
node_modules@react-native\polyfills\error-guard.js:49:36 in ErrorUtils.reportFatalError
node_modules\metro-runtime\src\polyfills\require.js:203:6 in guardedLoadModule
http://192.168.0.29:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false&strict=false&minify=false:190345:3 in global code ...

like image 774
José Carlos Avatar asked Sep 11 '25 06:09

José Carlos


1 Answers

The reason it's working for you on the web but not on the phone is because TextDecoder is a web API that's generally available in all modern browsers JS engines but it is not supported on Hermes (React Native's JS engine). The way to fix the issue is to use a polyfill for the API and expose it globally.

One simple way to achieve this is to use this polyfill library. Another way is to mimic what that library does which gives you more flexibility to choose what polyfill to use as there are many options to choose from (see the competitors list here for example). To do this you'll need to install the polyfill of your choice (e.g. npx expo install text-encoding) and then create a file with the following content:

import { polyfillGlobal } from "react-native/Libraries/Utilities/PolyfillFunctions"

const applyGlobalPolyfills = () => {
  const { TextEncoder, TextDecoder } = require("text-encoding")

  polyfillGlobal("TextEncoder", () => TextEncoder)
  polyfillGlobal("TextDecoder", () => TextDecoder)
}

export default applyGlobalPolyfills

then import this file in your App.js file (or your root _layout.js if using Expo's Router v2) and call the exported function like so:

import applyGlobalPolyfills from "path/to/applyGlobalPolyfills" // <-- Change the path
applyGlobalPolyfills()

// ...rest of App.js file

Probably worth noting that you can add any other global API you need support for this way. You can either add it to the same file or split it up to different util functions per global API for tree shaking, etc.

like image 84
ybentz Avatar answered Sep 14 '25 18:09

ybentz