@bydefault/vercel
v0.1.7
Published
Bydefault request capture SDK for Vercel and Next.js middleware/proxy.
Maintainers
Readme
@bydefault/vercel
Request capture for Vercel and Next.js proxy.ts / middleware.ts.
The SDK only tracks GET requests for page-like routes. Preflight-style
requests such as HEAD, POST, and other methods are ignored.
By default, /api and /api/* routes are excluded so citation counts reflect
content reads without capturing API endpoints. You can customize this with
exclude.
Install
npm install @bydefault/vercelVercel middleware (any framework)
On Vercel, track resolves the deployment's own waitUntil from the
request context (Node.js and Edge runtimes alike), so the report rides
after the response with no context parameter to accept:
import { Tracker } from '@bydefault/vercel'
const tracker = new Tracker({
token: process.env.BYDEFAULT_INGEST_TOKEN,
})
export default function middleware(request: Request) {
tracker.track(request)
}Works as middleware.ts at the project root of any framework deployed to
Vercel, and as Next.js middleware.ts / proxy.ts (name the export proxy
on Next.js 16+).
Next.js proxy.ts (self-hosted)
Off Vercel there is no request context, so hand track the framework's
event to keep the report off the response path:
import { Tracker } from '@bydefault/vercel'
import { NextResponse, type NextFetchEvent, type NextRequest } from 'next/server'
const tracker = new Tracker({
token: process.env.BYDEFAULT_INGEST_TOKEN,
})
export function proxy(request: NextRequest, event: NextFetchEvent) {
tracker.track(request, event)
return NextResponse.next()
}Excluding routes
const tracker = new Tracker({
token: process.env.BYDEFAULT_INGEST_TOKEN,
exclude: ['/api', '/admin', /^\/internal\//],
})String excludes match the exact pathname and descendants, so '/api' excludes
both /api and /api/ping. Pass exclude: [] to disable the default /api
exclusion.
Timeout
Each report is bounded to 5 seconds by default. The report runs after the
response through waitUntil (or Next's after()), which keeps the invocation
alive until it settles, so a bound is what keeps a stalled connection from
holding a function open until the platform kills it. A report that misses the
bound is dropped and surfaces through onError; the site is never affected.
const tracker = new Tracker({
token: process.env.BYDEFAULT_INGEST_TOKEN,
timeoutMs: 2_000, // 0 disables the bound
})Local development
Point endpoint at the Bydefault app:
const tracker = new Tracker({
token: process.env.BYDEFAULT_INGEST_TOKEN,
endpoint: 'http://localhost:3000',
})Payload
The SDK sends a simple request envelope:
type RequestPayload = {
timestamp?: string
method: string
url: string
ip?: string
geo?: {
country?: string
}
referer?: string
userAgent?: string
accept?: string
acceptLanguage?: string
requestId?: string
}It does not read the request body and does not send the full request header set. The SDK only sends the fields Bydefault needs for request attribution, country display, and AI-provider detection. No precise location (region, city, coordinates) is transmitted; the visitor IP is used server-side to verify claimed crawler identities against the operator's published IP ranges and is never stored.
If no token is configured, tracking is disabled with a single console warning. The SDK never throws from the middleware path, so a missing or misconfigured token can never affect your site.
