{"record":{"id":"94ce940277f664be","repo":"dotnet/runtime","slug":"this-browser-doesn-t-support-fetch-api-please-use","errorCode":null,"errorMessage":"This browser doesn't support fetch API. Please use a modern browser. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms","messagePattern":"This browser doesn't support fetch API\\. Please use a modern browser\\. See also https://learn\\.microsoft\\.com/aspnet/core/blazor/supported-platforms","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/http.ts","lineNumber":20,"sourceCode":"// The .NET Foundation licenses this file to you under the MIT license.\n\nimport BuildConfiguration from \"consts:configuration\";\n\nimport { wrap_as_cancelable_promise } from \"./cancelable-promise\";\nimport { ENVIRONMENT_IS_NODE, loaderHelpers, mono_assert } from \"./globals\";\nimport { assert_js_interop } from \"./invoke-js\";\nimport { MemoryViewType, Span } from \"./marshal\";\nimport type { VoidPtr } from \"./types/emscripten\";\nimport { ControllablePromise } from \"./types/internal\";\nimport { mono_log_debug } from \"./logging\";\n\n\nfunction verifyEnvironment () {\n    if (typeof globalThis.fetch !== \"function\" || typeof globalThis.AbortController !== \"function\") {\n        const message = ENVIRONMENT_IS_NODE\n            ? \"Please install `node-fetch` and `node-abort-controller` npm packages to enable HTTP client support.\"\n            : \"This browser doesn't support fetch API. Please use a modern browser. See also https://learn.microsoft.com/aspnet/core/blazor/supported-platforms\";\n        throw new Error(message);\n    }\n}\n\nfunction commonAsserts (controller: HttpController) {\n    assert_js_interop();\n    mono_assert(controller, \"expected controller\");\n}\n\nexport function http_wasm_supports_streaming_request (): boolean {\n    // Detecting streaming request support works like this:\n    // If the browser doesn't support a particular body type, it calls toString() on the object and uses the result as the body.\n    // So, if the browser doesn't support request streams, the request body becomes the string \"[object ReadableStream]\".\n    // When a string is used as a body, it conveniently sets the Content-Type header to text/plain;charset=UTF-8.\n    // So, if that header is set, then we know the browser doesn't support streams in request objects, and we can exit early.\n    // Safari does support streams in request objects, but doesn't allow them to be used with fetch, so the duplex option is tested, which Safari doesn't currently support.\n    // See https://developer.chrome.com/articles/fetch-streaming-requests/\n    if (typeof Request !== \"undefined\" && \"body\" in Request.prototype && typeof ReadableStream === \"function\" && typeof TransformStream === \"function\") {\n        let duplexAccessed = false;","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/browser/runtime/http.ts#L2-L38","documentation":"Thrown by verifyEnvironment in http.ts when not running on NodeJS (i.e. a browser) and either globalThis.fetch or globalThis.AbortController is missing. Modern browsers all provide both; this fires only on obsolete browsers (old WebView, legacy mobile WebViews, IE) or in unusual embedded web runtimes that lack the Fetch API.","triggerScenarios":"Loading the .NET wasm runtime in Internet Explorer or an old WebView that lacks fetch/AbortController; a custom embedded browser shell that did not expose Fetch API; HttpClient used in an environment that intentionally disabled fetch.","commonSituations":"Targeting legacy browsers; running inside an old Cordova/Capacitor WebView; corporate locked-down browsers.","solutions":["Use a supported modern browser (see the linked supported-platforms doc).","If you must support the old engine, polyfill fetch and AbortController with whatwg-fetch / abortcontroller-polyfill before the runtime starts.","Avoid HttpClient in code paths that run on unsupported browsers."],"exampleFix":"// before: no fetch in old WebView\n// after: load polyfills before dotnet runtime\nimport 'whatwg-fetch';\nimport 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';","handlingStrategy":"type-guard","validationCode":"// before using HttpClient from the wasm runtime in a browser\nif (typeof globalThis.fetch !== 'function' || typeof globalThis.AbortController !== 'function') {\n  // load whatwg-fetch and abortcontroller-polyfill, or show 'unsupported browser'\n}","typeGuard":"function browserSupportsFetch(): boolean {\n  return typeof globalThis.fetch === 'function' && typeof globalThis.AbortController === 'function';\n}","tryCatchPattern":null,"preventionTips":["Feature-detect fetch and AbortController before enabling HTTP scenarios.","Document minimum browser versions to users.","Provide a polyfill bundle for legacy WebView targets."],"tags":["browser","http","fetch","polyfill","compatibility"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}