New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@opendatalabs/connect-js

Package Overview
Dependencies
Maintainers
4
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@opendatalabs/connect-js

JavaScript SDK for embedding Open Data Labs Connect flows

latest
npmnpm
Version
1.19.0
Version published
Weekly downloads
0
Maintainers
4
Weekly downloads
 
Created
Source

@opendatalabs/connect-js

JavaScript SDK for launching Open Data Labs Connect and reading the selected data from the user's Personal Server.

The v2 flow uses the same trust split as Plaid Link or Stripe Connect:

  • your backend holds the Open Data Labs API key
  • your backend chooses the source and scopes
  • your frontend opens Vana in a second tab and keeps your app tab alive
  • after the user approves, your backend reads the approved scopes from the user's Personal Server

Installation

npm install @opendatalabs/connect-js

Backend

// lib/odl.ts
import { createConnectController } from "@opendatalabs/connect-js/server";

export const odl = createConnectController({
  apiBaseUrl: process.env.ODL_API_BASE_URL!,
  apiKey: process.env.ODL_API_KEY!,
  appId: process.env.ODL_APP_ID!,
  defaultOrigin: process.env.APP_URL ?? "https://your-app.com",
  source: "instagram",
  scopes: ["read:profile", "read:posts"],
});
// app/api/connect/session/route.ts
import { odl } from "@/lib/odl";

export async function POST() {
  return Response.json(
    await odl.createConnectSession({
      redirectUrl: `${process.env.APP_URL ?? "https://your-app.com"}/connect/return`,
    })
  );
}
// app/api/connect/status/route.ts
import { odl } from "@/lib/odl";

export async function GET(request: Request) {
  const connectionId = new URL(request.url).searchParams.get("connectionId");
  if (!connectionId) {
    return Response.json({ error: "Missing connectionId" }, { status: 400 });
  }
  return Response.json(await odl.getStatus(connectionId));
}
// app/api/connect/data/route.ts
import { odl } from "@/lib/odl";

export async function GET(request: Request) {
  const connectionId = new URL(request.url).searchParams.get("connectionId");
  if (!connectionId) {
    return Response.json({ error: "Missing connectionId" }, { status: 400 });
  }
  return Response.json(await odl.readAllWhenReady(connectionId));
}

React

import { useTwoTabConnect } from "@opendatalabs/connect-js/react";

export function ConnectButton() {
  const connect = useTwoTabConnect({
    openingUrl: process.env.NEXT_PUBLIC_VANA_CONNECT_OPENING_URL,
    createSession: async () => {
      const res = await fetch("/api/connect/session", { method: "POST" });
      if (!res.ok) throw new Error("Failed to create Connect session");
      return res.json();
    },
    getStatus: async (connectionId) => {
      const res = await fetch(
        `/api/connect/status?connectionId=${encodeURIComponent(connectionId)}`
      );
      if (!res.ok) throw new Error("Failed to fetch Connect status");
      return res.json();
    },
    readResult: async (connectionId) => {
      const res = await fetch(
        `/api/connect/data?connectionId=${encodeURIComponent(connectionId)}`
      );
      if (!res.ok) throw new Error("Failed to read Connect data");
      return res.json();
    },
  });

  return (
    <button disabled={connect.state.type !== "idle"} onClick={() => connect.start()} type="button">
      {connect.state.type === "idle" ? "Connect data" : "Connecting..."}
    </button>
  );
}

useTwoTabConnect opens a Vana-hosted holding page synchronously inside the click event, then redirects that tab to the Connect approval page after your backend creates the session. This avoids popup blockers without showing users a blank about:blank tab.

The default holding page is https://app.vana.org/connect/opening. For dev or staging, set NEXT_PUBLIC_VANA_CONNECT_OPENING_URL to the matching Vana app, for example https://app-dev.vana.org/connect/opening.

Source IDs

Use stable source IDs such as instagram or icloud_notes, not display names such as "Instagram" or "iCloud Notes".

Requirements

  • Keep your API key on the server.
  • Choose source and scopes on the server.
  • Add each app domain in the dashboard before creating sessions for it.
  • Keep the Vana tab open while your app reads from the user's Personal Server.

FAQs

Package last updated on 31 Jul 2026

Related posts