# Manual Injection [Overview](../README.md) . [Inspect](inspect.md) . [Capture](capture.md) . [Record](record.md) * [Adding the Script](#adding-the-script) * [Viewing What It Records](#viewing-what-it-records) * [Local Capture API](#local-capture-api) * [Loading the Script from JavaScript / TypeScript](#loading-the-script-from-javascript--typescript) * [Inside a Web Worker](#inside-a-web-worker) * [TypeScript Types](#typescript-types) If the WebGPU Inspector's automatic injection isn't working to inspect the page (workers inside of iframes can cause trouble), you can include `webgpu_inspector.js` directly in a page. This also lets you drive capture from the page itself, with no DevTools panel and no browser extension. ## Adding the Script Add the script tag to your page **before** any code that uses WebGPU, so the inspector can patch the WebGPU API before it's used: ```html ``` To pin to a specific release instead of tracking `main`, replace `@main` with a version tag, for example: ```html ``` When loaded this way, the script wraps the page's WebGPU API and exposes the inspector instance as `webgpuInspector` on the global (i.e. `window.webgpuInspector` in a page context, `self.webgpuInspector` in a worker context). ## Viewing What It Records Once the inspector is loaded, you have two ways to view what it records: 1. Open the WebGPU Inspector DevTools panel from the browser extension. The DevTools panel must be open when the page is loaded (refreshing the page may be necessary) in order to receive all of the WebGPU data from the beginning of the page's execution. 2. Drive capture from the page itself with the [Local Capture API](#local-capture-api) — no DevTools panel required. ## Local Capture API The manually-injected script exposes a small JavaScript API that lets the page record one or more frames of WebGPU activity entirely on the page side and save the result as a capture file. The file is in the same format as **Save Capture** in the DevTools Capture panel produces, so it can be opened with **Load Capture** in the [Capture panel](capture.md) for inspection. ```js // 1. Turn on the local capture store. Must be called BEFORE any WebGPU object // is created — the inspector does not retroactively replay // descriptors for objects that existed before this call. webgpuInspector.initialize(); // 2. Wrap one frame's worth of WebGPU work between // begin/end. Repeat the pair as many times as you want; // each pair appends another frame's commands (and the // textures/buffers they reference) to the export. webgpuInspector.beginFrameCapture(); renderOneFrame(); // your normal WebGPU rendering code webgpuInspector.endFrameCapture(); // (optional) capture more frames webgpuInspector.beginFrameCapture(); renderOneFrame(); webgpuInspector.endFrameCapture(); // 3. Wait for any in-flight texture/buffer readbacks, // build the capture, and trigger a browser download. // The filename argument is optional. await webgpuInspector.saveCaptureData("my_capture.wgpuc"); ``` `saveCaptureData()` returns a `Promise` that resolves once the download is initiated. The capture is split into small metadata plus out-of-band payload byte blobs, and the resolved value is `{ metadata, payloads }`: - `metadata` — the capture object (objects, command list, validation errors). Buffer/texture bytes appear as lightweight `{ __payloadId, __typedArray, __length, __byteLength }` references instead of inline data. - `payloads` — an array of `{ id, typedArray, bytes }` (the actual `Uint8Array` byte blobs). The downloaded file is the **WGPUCAP binary container**: an ASCII header line and the metadata JSON (readable in a text editor), followed by the raw payload bytes, so nothing is base64-inflated. It is loadable via DevTools "Load Capture" and the plugin's `load_capture_file` tool, which also still accept the older NDJSON and single-object `.json` captures. To serialize it yourself, use `encodeCaptureBinaryParts({ metadata, payloads })` from `src/utils/capture_binary.js`. After `saveCaptureData()` resolves, captured commands are cleared. You can call `beginFrameCapture()` / `endFrameCapture()` again to record more frames and `saveCaptureData()` again to produce another file. Object descriptors that were created earlier remain in the store so they continue to be available in subsequent captures. ## Loading the Script from JavaScript / TypeScript The snippets above assume `webgpu_inspector.js` was added with a `