Skip to main content
This feature is currently in alpha, and the design of it is rapidly evolving. Contact us at contact@humanlayer.dev to get early access.

Overview

The React embed channel allows you to embed HumanLayer approval flows directly in your React applications. This enables:
  • Custom approval UIs that match your application’s design
  • In-app approval workflows
  • Real-time updates using websockets
  • Integration with your existing authentication system

Installation

Backend Setup

In general you will need to implement two routes:
  1. Auth - Generate a JWT token containing user/tenant info, usually /api/humanlayer-auth
  2. Embed - Handle the embed requests, usually /api/humanlayer-embed
The specific location of your backend routes can be configured in the HumanLayerProvider component in Frontend Setup. For HumanLayer to verify the JWT token, you need to use the same signing key that you configured in the HumanLayer dashboard.
Create a FastAPI route to handle the embed requests and generate JWT tokens.You’ll also need to upload your public signing key to the HumanLayer dashboard.
from fastapi import FastAPI, Request
import jwt
import humanlayer_embed

app = FastAPI()

@app.post("/api/humanlayer-auth")
async def get_auth_token(
  user: Annotated[User, Depends(get_user)],
):
    # Generate a signed JWT containing user/tenant info
    token = jwt.encode(
        {
            "user_id": user.id,  # from your auth middleware
            "tenant_id": user.organization_id,  # from your auth middleware
            "exp": datetime.utcnow() + timedelta(minutes=15)  # token expires in 15 min
        },
        "your-signing-key",  # use your signing key
        algorithm="HS256"
    )

    return {"token": token}

@app.post("/api/humanlayer-embed")
async def handle_embed(request: Request):
    return await humanlayer_embed.handle_request_fastapi(request)
Create a Django view to handle the embed requests and generate JWT tokens.
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.utils.timezone import datetime, timedelta
import jwt
import humanlayer_embed
import json

@csrf_exempt
def get_auth_token(request):
    # Get user from your auth middleware
    user = request.user

    # Generate a signed JWT containing user/tenant info
    token = jwt.encode(
        {
            "user_id": user.id,
            "tenant_id": user.organization_id,
            "exp": datetime.utcnow() + timedelta(minutes=15)  # token expires in 15 min
        },
        "your-signing-key",  # use your signing key
        algorithm="HS256"
    )

    return JsonResponse({"token": token})

@csrf_exempt
async def handle_embed(request):
    return await humanlayer_embed.handle_request_django(request)

Create an Express route handler to handle the embed requests and generate JWT tokens.
import { handleRequest } from "@humanlayer/express";

function getAuthToken(req: Request, res: Response) {
  // Get user from your auth middleware
  const user = req.user;

  // Generate a signed JWT containing user/tenant info
  const token = jwt.sign(
    {
      user_id: user.id,
      tenant_id: user.organization_id,
    },
    "your-signing-key",
  );

  res.json({ token });
}

app.post("/api/humanlayer-auth", getAuthToken);
app.post("/api/humanlayer-embed", handleRequest);

Frontend Setup

npm install @humanlayer/react

Components

import { HumanLayerProvider, ApprovalQueue } from "@humanlayer/react";

function App() {
  const [token, setToken] = useState<string>();

  useEffect(() => {
    // Fetch auth token from your backend
    fetch("/api/humanlayer-auth")
      .then((r) => r.json())
      .then((data) => setToken(data.token));
  }, []);

  if (!token) return null;

  return (
    <HumanLayerProvider token={token}>
      <ApprovalQueue />
    </HumanLayerProvider>
  );
}

React Hooks

The React embed package also provides hooks for fetching data:
import { useApprovals } from "@humanlayer/react";

function ApprovalList() {
  const { approvals, loading } = useApprovals();

  if (loading) return <div>Loading...</div>;

  return (
    <div>
      {approvals.map((approval) => (
        <div key={approval.id}>{approval.message}</div>
      ))}
    </div>
  );
}

Next Steps

I