Engineering

How to Add License Key Validation to Your Next.js Application

TOT
Traffic Orchestrator Team
Engineering
April 10, 2026 5 min read 633 words
Share

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

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.

TOT
Traffic Orchestrator Team
Engineering

The engineering team behind Traffic Orchestrator, building enterprise-grade software licensing infrastructure used by developers worldwide.

Was this article helpful?
Get licensing insights delivered

Engineering deep-dives, security advisories, and product updates. Unsubscribe anytime.

Share this article
Free Plan Available

Ship licensing in your next release

5 licenses, 500 validations/month, full API access. Set up in under 5 minutes — no credit card required.

2-minute setup No credit card Cancel anytime