@xcript-dev/next
v0.2.0
Published
Next.js integration for Xcript — middleware, hooks, server utilities, and pre-built components for license validation
Maintainers
Readme
@xcript-dev/next
Protect your Next.js app with license validation in 2 minutes.
Edge middleware · React hooks · Server utilities · Zero boilerplate.
Why This Instead of the Core SDK?
| | @xcript-dev/sdk | @xcript-dev/next |
|--|---|---|
| Validate a license | ✅ Manual call | ✅ Automatic at the edge |
| Cache results | ✅ Disk file | ✅ httpOnly cookie (no disk, no state) |
| Protect routes | ❌ Build it yourself | ✅ One line — protectedRoutes: ['/dashboard/*'] |
| React UI gating | ❌ Build it yourself | ✅ useLicense() hook |
| Server Actions | ❌ Build it yourself | ✅ requireLicense() |
| Works with App Router | — | ✅ Built for it |
If you use Next.js, use this package. It saves you hours of glue code.
Quick Start — 2 Minutes
1. Install
npm install @xcript-dev/next2. Add Middleware
// middleware.ts
import { withXcript } from '@xcript-dev/next'
export default withXcript({
apiKey: process.env.XCRIPT_API_KEY!,
licenseKey: process.env.XCRIPT_LICENSE_KEY!,
protectedRoutes: ['/dashboard/*', '/api/*'],
onInvalid: '/license-expired',
})
export const config = {
matcher: ['/dashboard/:path*', '/api/:path*'],
}3. Done.
Every request to /dashboard/* now validates the license automatically. Invalid? Redirected. Valid? Passes through. Cached for 5 minutes.
What You Get
- 🛡️ Edge validation — License checked before your page even renders
- 🍪 Automatic caching — Result stored in httpOnly cookie, re-validates every 5 min
- ⚛️ React hook —
useLicense()for conditional UI in client components - 🔒 Server utilities —
requireLicense()for protected Server Actions - 🎛️ Feature flags —
config['max_users']from your dashboard, no redeploy - 🚫 Kill switch — Revoke access instantly, middleware blocks on next request
- 📦 5 KB — Tiny. No bloat.
Full Example: Protected SaaS Dashboard
middleware.ts — Gate all dashboard routes
import { withXcript } from '@xcript-dev/next'
export default withXcript({
apiKey: process.env.XCRIPT_API_KEY!,
licenseKey: process.env.XCRIPT_LICENSE_KEY!,
protectedRoutes: ['/dashboard/*'],
onInvalid: '/license-expired',
revalidateInterval: 300, // Re-check every 5 min
})
export const config = { matcher: ['/dashboard/:path*'] }app/layout.tsx — Provide license context
import { XcriptProvider } from '@xcript-dev/next/client'
export default function DashboardLayout({ children }) {
return <XcriptProvider>{children}</XcriptProvider>
}app/dashboard/reports/page.tsx — Gate UI by features
'use client'
import { useLicense } from '@xcript-dev/next/client'
export default function ReportsPage() {
const { isValid, config, isLoading } = useLicense()
if (isLoading) return <p>Loading...</p>
if (!isValid) return <p>License required. <a href="/pricing">Upgrade</a></p>
const canExport = config['features']?.includes('export')
return (
<div>
<h1>Reports</h1>
<p>Max users: {config['max_users'] || '∞'}</p>
{canExport && <button>Export CSV</button>}
</div>
)
}app/actions/generate.ts — Protect server logic
'use server'
import { requireLicense } from '@xcript-dev/next/server'
export async function generateReport(data: FormData) {
const license = await requireLicense() // Throws 403 if invalid
const maxReports = parseInt(license.config['max_reports'] || '10')
// ... generate report
}How It Works
Request hits your app
│
▼
Middleware checks cookie (__xcript_status)
│
├── ✅ Cookie valid + fresh (<5 min) → Pass through
│
├── ⏰ Cookie expired → Re-validate against Xcript API
│ ├── ✅ Valid → Update cookie → Pass through
│ └── ❌ Invalid → Redirect to /license-expired
│
└── 🆕 No cookie → Validate against Xcript API
├── ✅ Valid → Set cookie → Pass through
└── ❌ Invalid → Redirect to /license-expiredConfiguration
Middleware Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| apiKey | string | Required | Your API key (xk_...) |
| licenseKey | string | Required | License key to validate |
| publicKey | string | — | Ed25519 public key for signature verification |
| protectedRoutes | string[] | All routes | Glob patterns to protect |
| onInvalid | string | Returns 403 | Redirect path on invalid license |
| revalidateInterval | number | 300 (5 min) | Seconds between re-validations |
| baseUrl | string | https://api.xcript.dev | API base URL |
Environment Variables
XCRIPT_API_KEY=xk_your_api_key
XCRIPT_LICENSE_KEY=XCR-XXXX-XXXX-XXXX
XCRIPT_PUBLIC_KEY=ed25519_hex_optionalRequirements
- Next.js ≥ 14 (App Router)
- React ≥ 18
Core SDK
For non-Next.js projects → @xcript-dev/sdk
Links
MIT © Xcript
