Set environment variables
Copy
NEXT_PUBLIC_WACHT_PUBLISHABLE_KEY=pk_test_xxx
WACHT_API_KEY=wk_live_xxx
Wrap your app with DeploymentProvider
Copy
// app/layout.tsx
import { DeploymentProvider } from '@wacht/nextjs'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<DeploymentProvider publicKey={process.env.NEXT_PUBLIC_WACHT_PUBLISHABLE_KEY!}>
{children}
</DeploymentProvider>
</body>
</html>
)
}
Protect routes with proxy/middleware
Copy
// proxy.ts (Next.js 16+)
import { NextResponse } from 'next/server'
import { createRouteMatcher, wachtMiddleware } from '@wacht/nextjs/server'
const isProtected = createRouteMatcher(['/dashboard(.*)', '/api/private(.*)'])
export default wachtMiddleware(async (auth, req) => {
if (!isProtected(req)) return NextResponse.next()
await auth.protect()
return NextResponse.next()
}, {
apiRoutePrefixes: ['/api', '/trpc'],
})
export const config = {
matcher: [
'/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)',
'/(api|trpc)(.*)',
],
}
Use the backend client in server code (optional)
Copy
// app/api/webhooks/route.ts
import { NextResponse } from 'next/server'
import { wachtClient } from '@wacht/nextjs/server'
export async function GET() {
const client = await wachtClient()
const apps = await client.webhooks.listWebhookApps()
return NextResponse.json({ apps })
}
Sign-in UI example
Copy
// app/sign-in/page.tsx
import { SignInForm } from '@wacht/nextjs'
export default function Page() {
return <SignInForm />
}
Middleware options
Copy
type WachtMiddlewareOptions = {
publishableKey?: string
signInUrl?: string
authCookieName?: string
sessionCookieName?: string
devSessionCookieName?: string
clockSkewInMs?: number
requiredIssuer?: string
apiRoutePrefixes?: string[]
isApiRoute?: (request: NextRequest) => boolean
gatewayUrl?: string
}
API route classification
Copy
{ apiRoutePrefixes: ['/api', '/trpc'] }
Copy
{ isApiRoute: (req) => req.nextUrl.pathname.startsWith('/internal') }
