# Vercel

Serve the ProductLense script from your Vercel domain with vercel.json, and forward events through a Vercel Function on the Scale plan.

On Vercel, a rewrite in `vercel.json` serves the script from your domain for any framework. For a Next.js app, the [Next.js guide](/docs/proxy/nextjs) keeps everything in `next.config.js` instead.

## Serve the script

```json title="vercel.json"
{
  "rewrites": [{ "source": "/js/a.js", "destination": "https://api.productlense.app/a.js" }]
}
```

```html
<script defer data-site="SITE_ID" data-api="https://api.productlense.app" src="/js/a.js"></script>
```

## Forward events (Scale plan)

Add a function and route `/m/api/e` to it. Store an API key with the `events` scope as the `PL_API_KEY` environment variable in the project settings.

```ts title="api/productlense-events.ts"
export const config = { runtime: 'edge' };

type Event = Record<string, unknown>;

export default async function handler(req: Request): Promise<Response> {
  if (req.method !== 'POST') return new Response(null, { status: 405 });
  const text = await req.text();
  if (text.length > 8192) return new Response(null, { status: 413 });
  let body: { b?: Event[] } & Event;
  try {
    body = JSON.parse(text);
  } catch {
    return new Response(null, { status: 400 });
  }
  // Vercel puts the visitor's address first in x-forwarded-for.
  const ip = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? '';
  const extra = { ip, ua: req.headers.get('user-agent') ?? '' };
  const out = body.b ? { ...body, b: body.b.map((e) => ({ ...e, ...extra })) } : { ...body, ...extra };
  const r = await fetch('https://api.productlense.app/api/v1/events', {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.PL_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify(out),
  });
  return new Response(null, { status: r.status });
}
```

```json title="vercel.json"
{
  "rewrites": [
    { "source": "/js/a.js", "destination": "https://api.productlense.app/a.js" },
    { "source": "/m/api/e", "destination": "/api/productlense-events" }
  ]
}
```

Then set `data-api="https://example.com/m"` on the tag.

## Check it works

1. Open `https://example.com/js/a.js`: it returns JavaScript.
2. Load a page with the developer tools open. The Network tab shows `a.js` from your domain and a `POST` to `api/e` with status `204`.
3. Open the Live page in the ProductLense dashboard. Your visit appears within a few seconds.
