---
Source: https://docs.microblink.com/platform/sdk/web/resources
Title: Hosting resources
Description: Guide to hosting WebAssembly resources for the Platform Web SDK in your application
---

# Hosting resources

The Platform Web SDK uses WebAssembly (WASM) to run document scanning and extraction when using capabilities such as [Scan ID](../../capabilities/scan-id.md) and [Scan & Verify ID](../../capabilities/scan-verify-id.md).
WASM resources are not automatically served—you must make them available at a publicly accessible URL before the SDK can load them.

There are two ways to handle WASM resource hosting: same-domain and cross-domain hosting.

## Same-domain hosting

If you can, host the WASM resources on the **same domain** as your web application.
This avoids all cross-origin [security complexities](https://w3c.github.io/webappsec-secure-contexts/).

To do that, copy the WASM assets from `node_modules/@microblink/platform-sdk/dist/resources` into a publicly accessible folder on your web server.
If you use Vite, you can automate this with a plugin in `vite.config.ts`:

```ts title="Example in Vite"




  plugins: [
    {
      name: "copy-resources",
      buildStart() {
        const packagePath = resolvePackagePath("@microblink/platform-sdk", ".")
          ?.replace("/package.json", "");
        const resourcesPath = `${packagePath}/dist/resources`;
        const destinationPath = "public/resources";

        if (fs.existsSync(destinationPath)) {
          fs.rmSync(destinationPath, { recursive: true, force: true });
        }

        fs.mkdirSync(destinationPath);
        fs.cpSync(resourcesPath, destinationPath, { recursive: true });
      },
    },
  ],
});
```

By default, the SDK looks for WASM resources at `/resources` on the same domain.

## Cross-domain hosting

If you must host resources on a different domain (for example if you use a CDN), you **should** configure the application server headers and you **must** configure the WASM resource server headers.

### Configure headers on your main application server

To use the multi-threaded (`SharedArrayBuffer`) version of the SDK, your primary web application should serve its HTML pages with the following two headers.

- `Cross-Origin-Opener-Policy: same-origin`: Isolates your page context from other top-level windows.
- `Cross-Origin-Embedder-Policy: require-corp`: Requires all embedded cross-origin resources to explicitly opt-in via CORS.

<Tabs queryString="server">
  <TabItem value="netlify" label="Netlify" default>

```toml
[[headers]]
  for = "/*"
  [headers.values]
    Cross-Origin-Opener-Policy = "same-origin"
    Cross-Origin-Embedder-Policy = "require-corp"
```

  </TabItem>
  <TabItem value="nginx" label="nginx">

```nginx
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
```

  </TabItem>
  <TabItem value="apache" label="Apache">

```apache
<IfModule mod_headers.c>
  Header set Cross-Origin-Opener-Policy "same-origin"
  Header set Cross-Origin-Embedder-Policy "require-corp"
</IfModule>
```

  </TabItem>
  <TabItem value="vercel" label="Vercel">

```json
{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "Cross-Origin-Opener-Policy", "value": "same-origin" },
        { "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" }
      ]
    }
  ]
}
```

  </TabItem>
</Tabs>

If you don't set these headers, the SDK will fall back to a non-threaded version.
Your scanning session will still work, but will be slower.

### Configure headers on your resource server (CDN)

The server hosting your WASM files **must** return the following headers.

- `Access-Control-Allow-Origin`: Explicitly permits your web application's domain to fetch the resources.
- `Cross-Origin-Resource-Policy: cross-origin`: Required when your main app uses `Cross-Origin-Embedder-Policy: require-corp`, so the browser allows the cross-origin resource to be loaded.

<Tabs queryString="server">
  <TabItem value="netlify" label="Netlify" default>

```toml
[[headers]]
  for = "/*"
  [headers.values]
    "Access-Control-Allow-Origin" = "https://my-app-url.com"
    "Cross-Origin-Resource-Policy" = "cross-origin"
```

  </TabItem>
  <TabItem value="nginx" label="nginx">

```nginx
add_header Access-Control-Allow-Origin "https://my-app-url.com" always;
add_header Cross-Origin-Resource-Policy "cross-origin" always;
```

  </TabItem>
  <TabItem value="apache" label="Apache">

```apache
<IfModule mod_headers.c>
  Header set Access-Control-Allow-Origin "https://my-app-url.com"
  Header set Cross-Origin-Resource-Policy "cross-origin"
</IfModule>
```

  </TabItem>
  <TabItem value="vercel" label="Vercel">

```json
{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        { "key": "Access-Control-Allow-Origin", "value": "https://my-app-url.com" },
        { "key": "Cross-Origin-Resource-Policy", "value": "cross-origin" }
      ]
    }
  ]
}
```

  </TabItem>
</Tabs>

### Use resourcesPath to specify the location of your WASM resources

To load resources from a CDN, pass the `resourcesPath` prop to the `IdvFlow` component.

```jsx

<IdvFlow
  apiConfig={{ url: "URL of your proxy service", workflowId: "your-workflow-id" }}
  consentData={consentData}
  //highlight-next-line
  resourcesPath="your CDN URL here"
/>
```

Pass the base URL of the directory containing the resources.
The SDK will locate the required files relative to that path.


Last updated on Jun 23, 2026
