INTEGRATIONS / BROWSER + SERVER RECIPE

pageflock, meet HTML + your backend.

A complete local example pairs a plain HTML button with a small Node.js server. The browser never receives your pageflock key.

← All integrations

Your first connection.

  1. 01

    Save both files below in one folder: index.html and server.mjs. Use Node.js 22 or newer and set WAGGLE_API_KEY in your terminal.

  2. 02

    Run node server.mjs, then open http://127.0.0.1:3001. Click Extract example.com to send one real request; successful extraction uses one credit.

  3. 03

    This sample listens only on your computer and accepts only example.com. For a hosted application, add your own sign-in, CSRF protection and user quotas before exposing an endpoint.

Tool reference: HTML + your backend documentation ↗

Build the request.

Set the environment variables in your terminal for these code examples. In automation tools, enter the URL and credentials in the tool’s own fields.

index.htmlHTML · browser
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>pageflock extraction demo</title>
</head>
<body>
  <h1>Your first pageflock result</h1>
  <p>Each successful request uses one credit.</p>
  <button id="run">Extract example.com</button>
  <pre id="result" aria-live="polite"></pre>
  <script type="module">
    const button = document.querySelector("#run");
    const output = document.querySelector("#result");
    button.addEventListener("click", async () => {
      button.disabled = true;
      output.textContent = "Extracting…";
      try {
        const response = await fetch("/api/pageflock-request", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: "{}",
          signal: AbortSignal.timeout(50000),
        });
        const result = await response.json();
        if (!response.ok) throw new Error(JSON.stringify(result));
        output.textContent = JSON.stringify(result, null, 2);
      } catch (error) {
        output.textContent = String(error);
      } finally {
        button.disabled = false;
      }
    });
  </script>
</body>
</html>
server.mjsJavaScript · local Node.js server
import { createServer } from "node:http";
import { readFile } from "node:fs/promises";

const apiKey = process.env.WAGGLE_API_KEY;
if (!apiKey) throw new Error("Set WAGGLE_API_KEY");
const origin = "http://127.0.0.1:3001";
const html = await readFile(new URL("./index.html", import.meta.url));
let busy = false;

const server = createServer(async (request, response) => {
  const json = (status, data) => {
    response.writeHead(status, {
      "Content-Type": "application/json",
      "Cache-Control": "no-store",
      "X-Content-Type-Options": "nosniff",
    });
    response.end(JSON.stringify(data));
  };
  if (request.headers.host !== "127.0.0.1:3001") {
    return json(403, { error: "Open the local demo URL" });
  }
  if (request.method === "GET" && request.url === "/") {
    response.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
    return response.end(html);
  }
  if (request.method !== "POST" || request.url !== "/api/pageflock-request") {
    return json(404, { error: "Not found" });
  }
  if (request.headers.origin !== origin) {
    return json(403, { error: "This demo accepts same-origin requests only" });
  }
  if (busy) return json(429, { error: "Wait for the current request" });
  busy = true;
  request.resume(); // The demo ignores input and uses a fixed public URL.
  try {
    const upstream = await fetch("https://pageflock.hyvelabs.tech/api/pageflock/v1/scrape", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${apiKey}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ url: "https://example.com" }),
      signal: AbortSignal.timeout(45000),
    });
    json(upstream.status, await upstream.json());
  } catch {
    json(502, { error: "pageflock request failed. Check Activity before retrying." });
  } finally {
    busy = false;
  }
});
server.listen(3001, "127.0.0.1", () => console.log(origin));

Reading or copying this example does not send a request or use credits.

YOUR PRIVACY

Choose what works for you. You can reopen these settings from the footer at any time.