Lumen
UI Components

Usage Badge

Lumen provides UI components so you can speed up your SaaS app development.

Installation

Required packages:

npm install @getlumen/react @getlumen/server

NextJS route

For NextJS and Supabase you should copy this code into api/lumen/[...all]/route.ts.

If you are using a different tech stack email us at founders@getlumen.dev and we will reply in less than 1h if we are awake.

// api/lumen/[...all]/route.ts
import { NextRequest, NextResponse } from "next/server";
import { lumenNextHandler } from "@getlumen/server";
import { auth } from "@clerk/nextjs/server";

const handler = async (request: NextRequest) => {
  const { userId } = await auth();

  if (!userId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  return NextResponse.json(
    await lumenNextHandler({
      request,
      userId,
    })
  );
};

export {
  handler as GET,
  handler as POST,
  handler as PUT,
  handler as DELETE,
  handler as PATCH,
  handler as OPTIONS,
  handler as HEAD,
};
// api/lumen/[...all]/route.ts
import { NextRequest, NextResponse } from "next/server";
import { createClient } from "@/lib/supabase/server";
import { lumenNextHandler } from "@getlumen/server";

const handler = async (request: NextRequest) => {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (!user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  return NextResponse.json(
    await lumenNextHandler({
      request,
      userId: user.id,
    })
  );
};

export {
  handler as GET,
  handler as POST,
  handler as PUT,
  handler as DELETE,
  handler as PATCH,
  handler as OPTIONS,
  handler as HEAD,
};
// api/lumen/[...all]/route.ts
import { auth } from "@/lib/auth";

export async function GET(request: Request) {
  const session = await auth.api.getSession({ headers: request.headers });
  if (!session?.user) {
    return Response.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { searchParams } = new URL(request.url);
  const externalCustomerId = searchParams.get("externalCustomerId");

  const response = await fetch(
    `https://api.getlumen.dev/v1/customers/subscription-status?externalCustomerId=${encodeURIComponent(
      externalCustomerId
    )}`,
    {
      headers: {
        Authorization: `Bearer ${process.env.LUMEN_SECRET_KEY}`,
      },
    }
  );

  return Response.json(await response.json());
}

import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth";
import { lumenNextHandler } from "@getlumen/server";

const handler = async (request: NextRequest) => {
  const session = await auth.api.getSession({ headers: request.headers });
  if (!session?.user) {
    return Response.json({ error: "Unauthorized" }, { status: 401 });
  }

  return NextResponse.json(
    await lumenNextHandler({
      request,
      userId: session.user.id,
    })
  );
};

export {
  handler as GET,
  handler as POST,
  handler as PUT,
  handler as DELETE,
  handler as PATCH,
  handler as OPTIONS,
  handler as HEAD,
};

Parameters

Required Parameters

  • featureSlug (string): The slug of the feature whose entitlement usage should be displayed.

Optional Parameters

  • label (string, optional):

    • Label to show before the usage stats
    • Default: Auto-generated from featureSlug by capitalizing and formatting it (e.g., "api-calls" becomes "API Calls:")
  • labelAfter (string, optional):

    • Label to show after the usage stats
    • Default: "credits"
  • creditCalculation ("used" | "available", optional):

    • Determines how credit usage is calculated and displayed
    • Default: "used"
    • When set to "used": shows credits used vs total
    • When set to "available": shows credits remaining vs total
  • apiUrl (string, optional):

    • API endpoint for fetching Lumen entitlements
    • Default: ${window.location.origin}/api/lumen
  • className (string, optional):

    • Additional CSS class names for the Badge component
    • Default: undefined (no additional classes)
  • theme ("green" | "yellow" | "blue", optional):

    • Color theme for the badge
    • Default: "blue"
    • Determines the background and text colors when usage is within limits
    • When over limit, all themes show red styling

Example with All Parameters

<UsageBadge
  featureSlug="ai-chat-requests"
  label="Custom Label:"
  labelAfter="remaining"
  creditCalculation="available"
  theme="green"
  className="my-custom-class"
  apiUrl="/custom/api/endpoint"
/>