🚀 DAY 5 OF LAUNCH WEEK:Introducing Webhook Events for Alert Changes.Learn more →
Socket
Book a DemoInstallSign in
Socket

@gadgetinc/react-chatgpt-apps

Package Overview
Dependencies
Maintainers
6
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@gadgetinc/react-chatgpt-apps

<img alt="GitHub CI status" src="https://badgen.net/github/checks/ga

latest
Source
npmnpm
Version
0.2.3
Version published
Maintainers
6
Created
Source

Gadget logo

GitHub CI status npm version

React components for building ChatGPT Apps powered by Gadget backends.

@gadgetinc/react-chatgpt-apps is a React library for connecting ChatGPT Apps to Gadget backend applications. It provides:

  • A <Provider> component that automatically authenticates your ChatGPT App with your Gadget backend
  • Easy integration with @gadgetinc/react hooks for reading and writing data
  • Automatic token management using OpenAI's and Gadget's authentication system

When building a ChatGPT App that needs to interact with a Gadget backend, this library handles all the authentication complexity for you, allowing your React components to focus on building great user experiences.

Installation

@gadgetinc/react-chatgpt-apps is a companion package to your Gadget app's JavaScript client and @gadgetinc/react, so you need to install all three packages.

First, set up the Gadget NPM registry and install your app's client:

npm config set @gadget-client:registry https://registry.gadget.dev/npm

# then install your app's client
npm install @gadget-client/your-chatgpt-app-slug

Full installation instructions for your app's client can be found in the Gadget docs at https://docs.gadget.dev/api/<your-app-slug>/external-api-calls/installing.

Then, install the React libraries:

npm install @gadgetinc/react @gadgetinc/react-chatgpt-apps react
# or
yarn add @gadgetinc/react @gadgetinc/react-chatgpt-apps react

Setup

To use this library, wrap your ChatGPT App's React components in the Provider component from this package. The Provider automatically handles authentication with your Gadget backend using OpenAI's authentication system.

// in web/chatgpt-widgets/root.tsx
import { Provider } from "@gadgetinc/react-chatgpt-apps";
import { api } from "../api";

function App() {
  return (
    <Provider api={api}>
      <YourChatGPTAppComponents />
    </Provider>
  );
}

export default App;

That's it! The Provider component will:

  • Automatically fetch an authentication token from OpenAI when your app loads
  • Configure your Gadget API client to use this token for all requests
  • Ensure all API calls wait for authentication to be ready before proceeding

Example usage

Once you've wrapped your app in the Provider, you can use all the hooks from @gadgetinc/react to interact with your Gadget backend:

import { useAction, useFindMany } from "@gadgetinc/react";
import { api } from "../../api";

function TaskList() {
  // Fetch tasks from your Gadget backend - authentication is handled automatically
  const [{ data: tasks, fetching, error }] = useFindMany(api.task, {
    select: {
      id: true,
      title: true,
      completed: true,
    },
  });

  // Set up an action to mark tasks as complete
  const [_, completeTask] = useAction(api.task.complete);

  if (fetching) return <div>Loading tasks...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <ul>
      {tasks.map((task) => (
        <li key={task.id}>
          <input type="checkbox" checked={task.completed} onChange={() => completeTask({ id: task.id })} />
          {task.title}
        </li>
      ))}
    </ul>
  );
}

Authentication

When a user installs your ChatGPT App, they will authenticate themselves with your Gadget backend, and establish some kind of user identity in your session model, user model, or similar. When you use this provider, API calls made from your Widgets will act with that same identity by re-using the same JWT token that your Gadget backend provisioned at install time.

Using without authentication

If you don't need authentication for your ChatGPT widgets such that they are safe to be world readable, you can disable authentication in the provider by setting the authenticate prop to false:

// in web/chatgpt-widgets/root.tsx
import { Provider } from "@gadgetinc/react-chatgpt-apps";
import { api } from "../api";

function App() {
  return (
    <Provider api={api} authenticate={false}>
      <YourChatGPTAppComponents />
    </Provider>
  );
}

export default App;

How it works

ChatGPT Apps use a special authentication mechanism provided by OpenAI. When your app loads in ChatGPT, it can request an authentication token from OpenAI that identifies the current user and conversation. This library:

  • Calls OpenAI's callTool function with the special __getGadgetAuthTokenV1 tool to retrieve an authentication token
  • Configures your Gadget API client to include this token in all HTTP requests as a Bearer token
  • Ensures that any API calls made before the token is fetched will wait for authentication to be ready

This all happens automatically when you wrap your app in the Provider component. Your Gadget backend will receive the authenticated requests and can use the token to identify the user and enforce permissions.

API Documentation

<Provider api={api}>

The Provider component must wrap your ChatGPT App to enable authenticated communication with your Gadget backend.

Props:

  • api (required): An instance of your Gadget application's API client. Example: new Client() where Client is imported from @gadget-client/your-app-slug.
  • children (required): Your React components that will use the Gadget API.

Example:

import { Client } from "@gadget-client/my-chatgpt-app";
import { Provider } from "@gadgetinc/react-chatgpt-apps";

const api = new Client();

export function App() {
  return (
    <Provider api={api}>
      <YourComponents />
    </Provider>
  );
}

The Provider component:

  • Automatically fetches an authentication token from OpenAI when mounted
  • Configures your API client to use this token for all requests
  • Handles token management transparently - you don't need to manually pass tokens around
  • Ensures all API calls wait for authentication to be ready

Using with @gadgetinc/react hooks

Once your app is wrapped in the Provider, you can use all the hooks from @gadgetinc/react to interact with your Gadget backend. All requests will automatically include the authentication token.

See the @gadgetinc/react documentation for the full list of available hooks including:

  • useFindOne - Fetch a single record by ID
  • useFindMany - Fetch a list of records with filtering, sorting, and pagination
  • useAction - Run actions on your Gadget models
  • useGlobalAction - Run global actions
  • useFetch - Make custom HTTP requests to your Gadget backend

All of these hooks will work seamlessly with the ChatGPT Apps authentication provided by this package.

ChatGPT-Specific Hooks

This package also provides hooks for interacting with the ChatGPT environment and OpenAI APIs. These hooks enable your app to respond to the ChatGPT context and provide a native experience.

useDisplayMode()

Access the current display mode of your ChatGPT app.

import { useDisplayMode } from "@gadgetinc/react-chatgpt-apps";

function MyWidget() {
  const displayMode = useDisplayMode();

  return <div>{displayMode === "fullscreen" ? <FullScreenView /> : <CompactView />}</div>;
}

Returns one of:

  • "pip" - Picture-in-picture mode (small floating window)
  • "inline" - Inline mode (embedded in the chat)
  • "fullscreen" - Fullscreen mode (takes up the entire screen)
  • null - If not available

useMaxHeight()

Get the maximum height available for your app in pixels.

import { useMaxHeight } from "@gadgetinc/react-chatgpt-apps";

function MyWidget() {
  const maxHeight = useMaxHeight();

  return <div style={{ maxHeight }}>Content that respects viewport limits</div>;
}

This value updates dynamically as the display mode or window size changes.

useRequestDisplayMode()

Request a change to the app's display mode.

import { useRequestDisplayMode } from "@gadgetinc/react-chatgpt-apps";

function MyWidget() {
  const requestDisplayMode = useRequestDisplayMode();

  const goFullscreen = async () => {
    const result = await requestDisplayMode("fullscreen");
    console.log("Granted mode:", result.mode);
  };

  return <button onClick={goFullscreen}>Go Fullscreen</button>;
}

Note: The host may reject or modify the request (e.g., on mobile, PiP is always coerced to fullscreen).

useWidgetState(defaultState)

Manage persistent widget state that syncs with ChatGPT's storage system.

import { useWidgetState } from "@gadgetinc/react-chatgpt-apps";

function Counter() {
  const [state, setState] = useWidgetState({ count: 0 });

  return <button onClick={() => setState({ count: (state?.count ?? 0) + 1 })}>Count: {state?.count ?? 0}</button>;
}

Similar to React's useState, but state persists across re-renders and display mode changes.

useWidgetProps(defaultProps)

Access the tool output props passed to your ChatGPT app.

import { useWidgetProps } from "@gadgetinc/react-chatgpt-apps";

function MyWidget() {
  const props = useWidgetProps({ userId: "unknown", theme: "light" });

  return <div>User ID: {props.userId}</div>;
}

When ChatGPT invokes your app, it may provide initial data through the toolOutput property. This hook retrieves that data with optional defaults.

useSendMessage()

Send follow-up messages to the ChatGPT conversation programmatically.

import { useSendMessage } from "@gadgetinc/react-chatgpt-apps";

function QuickActions() {
  const sendMessage = useSendMessage();

  return <button onClick={() => sendMessage("Tell me more about this")}>Ask for more details</button>;
}

Useful for creating interactive experiences that guide the conversation.

useOpenExternal()

Open external URLs in a way that respects the ChatGPT environment.

import { useOpenExternal } from "@gadgetinc/react-chatgpt-apps";

function LinkButton() {
  const openExternal = useOpenExternal();

  return <button onClick={() => openExternal("https://example.com")}>Visit Example</button>;
}

Attempts to use ChatGPT's native link handler, falling back to window.open if unavailable.

useCallTool()

Call external tools/APIs that have been configured in your ChatGPT app.

import { useCallTool } from "@gadgetinc/react-chatgpt-apps";

function WeatherWidget() {
  const callTool = useCallTool();

  const fetchWeather = async () => {
    const response = await callTool("weatherApi", { city: "San Francisco" });
    console.log(response?.result);
  };

  return <button onClick={fetchWeather}>Get Weather</button>;
}

useOpenAiGlobal(key)

Low-level hook for accessing OpenAI global values by key.

import { useOpenAiGlobal } from "@gadgetinc/react-chatgpt-apps";

function ThemeAwareComponent() {
  const theme = useOpenAiGlobal("theme");
  const locale = useOpenAiGlobal("locale");

  return <div className={theme}>Content in {locale}</div>;
}

Most apps should use the more specific hooks like useDisplayMode, useMaxHeight, etc. instead of using this hook directly.

Authentication Flow

When your ChatGPT App loads, the following happens automatically:

  • The Provider component calls OpenAI's callTool function with the __getGadgetAuthTokenV1 tool name
  • OpenAI returns an authentication token specific to the current user and conversation
  • The Provider configures your Gadget API client to include this token as a Bearer token in the Authorization header of all HTTP requests
  • Your Gadget backend receives the token and can use it to identify the user and enforce permissions

If the token fetch fails (for example, if the app is not running in a ChatGPT environment), an error will be thrown. This ensures your app doesn't make unauthenticated requests by mistake.

FAQs

Package last updated on 12 Nov 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts