{"record":{"id":"abeaa716e747fe43","repo":"dotnet/runtime","slug":"this-browser-doesn-t-support-fetch-api-please-use-abeaa7","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/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/http.ts","lineNumber":19,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nimport BuildConfiguration from \"consts:configuration\";\n\nimport type { VoidPtr, ControllablePromise } from \"./types\";\n\nimport { wrapAsCancelablePromise } from \"./cancelable-promise\";\nimport { ENVIRONMENT_IS_NODE } from \"./per-module\";\nimport { assertJsInterop } from \"./utils\";\nimport { MemoryViewType, Span } from \"./marshaled-types\";\nimport { dotnetLogger, dotnetAssert } from \"./cross-module\";\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    if (BuildConfiguration !== \"Debug\") {\n        return;\n    }\n    assertJsInterop();\n    dotnetAssert.check(controller, \"expected controller\");\n}\n\nexport function httpSupportsStreamingRequest(): 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.","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/http.ts#L1-L37","documentation":"verifyEnvironment detects a non-Node (browser) host where global fetch is missing, meaning the browser/engine is too old to support the Fetch API that the .NET WASM HttpClient depends on. The message directs users to the Blazor supported-platforms doc.","triggerScenarios":"Loading the .NET WASM app in a browser or WebView that lacks a global fetch function — old Safari, a legacy embedded WebView, or a stripped-down automation engine.","commonSituations":"Legacy enterprise browsers; old mobile WebViews; embedded devices with outdated browser engines; browser automation against a minimal engine.","solutions":["Run the app in a supported modern browser (see the Blazor supported-platforms doc).","If you must support an old engine, polyfill fetch and AbortController globally before runtime init.","Detect missing fetch on load and show end users a clear upgrade message."],"exampleFix":"// before: app loads in an old WebView -> throws on first HTTP call\n\n// after: feature-detect and block/polyfill\nif (typeof window.fetch !== \"function\") {\n  showUpgradeNotice(); // or load a fetch polyfill\n}","handlingStrategy":"validation","validationCode":"if (typeof globalThis.fetch !== \"function\") {\n  showUpgradeNotice(\"This app needs a browser with Fetch support.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Declare minimum browser support and feature-detect fetch on load.","Use a supported Chromium-based WebView for embedded scenarios.","If supporting legacy engines is unavoidable, load a fetch/AbortController polyfill before runtime init."],"tags":["http","browser-support","fetch","compatibility"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}