How to Add License Key Validation to Your Next.js Application
Next.js is the most popular React framework for building production applications. Whether you're building a SaaS dashboard, a premium content platform, or a white-label product, license key validation lets you control access and monetize your work. This guide covers both App Router and Pages Router patterns.
Why License Keys in Next.js?
Next.js applications often include premium features like:
- Advanced dashboards visible only to paying customers
- API endpoints that require valid subscriptions
- White-label deployments with per-customer licensing
- Premium components gated behind feature flags
Step 1: Install the SDK
npm install @traffic-orchestrator/client
Step 2: Create a Server-Side Validation Utility
License validation should always happen server-side to protect your API key:
// lib/license.ts
import { TrafficOrchestrator } from "@traffic-orchestrator/client"
const client = new TrafficOrchestrator({ baseUrl: "https://api.trafficorchestrator.com/api/v1", apiKey: process.env.TO_API_KEY, gracePeriod: true, gracePeriodTtl: 86400, })
export const validateLicense = async (key: string, domain: string) => { const result = await client.validate({ key, domain }) return result } ```
Step 3: API Route for License Validation (App Router)
Create an API route that your frontend can call:
// app/api/validate-license/route.ts
import { NextResponse } from "next/server"
import { validateLicense } from "@/lib/license"
export const POST = async (request: Request) => { const { key } = await request.json() const host = request.headers.get("host") || "localhost"
const result = await validateLicense(key, host) return NextResponse.json(result) } ```
Step 4: Middleware for Route Protection
Use Next.js middleware to protect entire route groups:
// middleware.ts
import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"
export const middleware = async (request: NextRequest) => { const licenseKey = request.cookies.get("license_key")?.value
if (!licenseKey) { return NextResponse.redirect(new URL("/activate", request.url)) }
// Validate server-side const res = await fetch(new URL("/api/validate-license", request.url), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ key: licenseKey }), })
const result = await res.json()
if (!result.valid) { return NextResponse.redirect(new URL("/activate?expired=true", request.url)) }
return NextResponse.next() }
export const config = { matcher: ["/dashboard/:path", "/settings/:path"], } ```
Step 5: React Hook for Client-Side Feature Gating
Create a hook to check license features in components:
// hooks/useLicense.ts
"use client"
import { useState, useEffect } from "react"
interface LicenseState { valid: boolean features: string[] loading: boolean }
export const useLicense = (licenseKey: string): LicenseState => { const [state, setState] = useState<LicenseState>({ valid: false, features: [], loading: true, })
useEffect(() => { fetch("/api/validate-license", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ key: licenseKey }), }) .then((r) => r.json()) .then((data) => setState({ valid: data.valid, features: data.features || [], loading: false })) .catch(() => setState({ valid: false, features: [], loading: false })) }, [licenseKey])
return state } ```
Use it in components:
// components/PremiumFeature.tsx
"use client"
import { useLicense } from "@/hooks/useLicense"
export const PremiumFeature = ({ licenseKey }: { licenseKey: string }) => { const { valid, features, loading } = useLicense(licenseKey)
if (loading) return <div>Checking license...</div> if (!valid) return <div>Please activate your license to access this feature.</div>
return ( <div> <h2>Pro Dashboard</h2> {features.includes("analytics") && <AnalyticsPanel />} {features.includes("export") && <ExportButton />} </div> ) } ```
Step 6: Server Component Pattern (App Router)
For server-rendered pages, validate directly in the component:
// app/dashboard/page.tsx
import { validateLicense } from "@/lib/license"
import { cookies } from "next/headers"
import { redirect } from "next/navigation"
export default async function DashboardPage() { const cookieStore = await cookies() const licenseKey = cookieStore.get("license_key")?.value
if (!licenseKey) redirect("/activate")
const license = await validateLicense(licenseKey, "yourdomain.com")
if (!license.valid) redirect("/activate?expired=true")
return ( <main> <h1>Dashboard</h1> <p>License: {license.key}</p> <p>Features: {license.features?.join(", ")}</p> </main> ) } ```
Next Steps
- Read the full Node.js SDK documentation
- Explore React license gating patterns
- Set up webhook integration for real-time events
- Learn about domain binding for SaaS protection
Traffic Orchestrator validates licenses at the edge in under 10ms, meaning your Next.js API routes and server components get instant license checks with zero cold starts.
Ship licensing in your next release
5 licenses, 500 validations/month, full API access. Set up in under 5 minutes — no credit card required.