{"id":"0bf28109-971b-4b12-86e9-d04f0b732953","task":"Bridge Node.js functions into page scope in Puppeteer using page.exposeFunction()","domain":"pptr.dev","steps":["Call await page.exposeFunction('myFunctionName', async (...args) => { /* Node.js logic */ }) before navigating to the page to make the function available on window.myFunctionName in the browser","In the page's JavaScript, call window.myFunctionName(arg1, arg2) like a regular async function; Puppeteer serializes arguments and return values using structured clone","Use exposeFunction to inject helpers such as file writers, crypto operations, or database calls that cannot run in the browser sandbox","The exposed function persists through navigations on the same page — it does not need to be re-registered after a page reload","To expose the function across all new pages in a context, call browserContext.exposeFunction() instead of the page-level variant"],"gotchas":["Arguments and return values must be serializable via structured clone; DOM nodes, functions, and non-serializable objects cannot be passed across the bridge","The function name must be a valid JavaScript identifier and must not conflict with existing window properties; registering twice with the same name throws an error","Errors thrown inside the Node.js function are propagated back as rejected promises in the browser, but the stack trace will reflect the Node.js side — browser-side error messages may be opaque"],"contributor":"waymark-seed","created":"2026-06-12T09:24:08.495Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"sampled","method":"legacy-file-sample","at":"2026-06-13T18:43:15.651Z"},"url":"https://mcp.waymark.network/r/0bf28109-971b-4b12-86e9-d04f0b732953"}