/** * Server-side tracking proxy for Matomo. * * Proxies tracking requests through your own domain using a randomly * generated endpoint path that changes on every build — effectively * bypassing ad-blockers that block known analytics domains or patterns. * * How it works: * 1. `withMatomoProxy()` generates a random path at build time (e.g. `/api/a3f7b2c1e9`) * 2. It adds a Next.js rewrite: `/api/{random}/:path*` → `/api/mp/:path*` * 3. You create a catch-all API route at `app/api/mp/[...path]/route.ts` * that uses `createMatomoProxyHandler()` to forward requests to Matomo * 4. The browser only ever talks to YOUR domain — ad-blockers see nothing suspicious * 5. Each build produces a different path, so blockers can't hardcode it * * @module server-proxy */ /** Options for the Matomo server-side proxy */ export interface MatomoProxyOptions { /** Full URL of your Matomo instance (e.g. "https://analytics.example.com") */ matomoUrl: string; /** * Custom proxy path prefix. If not provided, a random path is generated * at build time to avoid detection by ad-blockers. * * ⚠️ Using a fixed path reduces ad-block resistance since the path * won't change between builds. * * @default auto-generated random path per build */ proxyPath?: string; /** * Internal path of the API route that hosts `createMatomoProxyHandler()`. * This is the rewrite *destination* — the browser never sees it. * * ⚠️ Avoid path segments starting with `_`: the App Router treats * `_`-prefixed folders as private folders and excludes them from routing, * so the internal route would 404. * * Set it to `/api/__mp` only if you have an existing Pages Router setup * at `pages/api/__mp/[...path].ts` that you don't want to rename. * * @default "/api/mp" */ handlerPath?: string; /** * Matomo Site ID – exposed as a build-time env var * `NEXT_PUBLIC_MATOMO_PROXY_SITE_ID` for the client to consume. */ siteId?: string; } /** Shape of the rewrite rules we inject into the Next.js config */ interface NextRewrite { source: string; destination: string; } type NextRewritesObject = { beforeFiles?: NextRewrite[]; afterFiles?: NextRewrite[]; fallback?: NextRewrite[]; }; type NextRewritesResult = NextRewrite[] | NextRewritesObject; /** Minimal Next.js config shape we care about */ interface NextConfig { rewrites?: () => Promise | NextRewritesResult; env?: Record; [key: string]: unknown; } /** * Generates a random, opaque path segment for the proxy endpoint. * * A new path is generated on every call, ensuring each build gets * a unique endpoint that ad-blockers cannot predict or hardcode. * * @returns A path like `/a3f7b2c1e9` * * @internal */ export declare function generateProxyPath(): string; /** * Wraps your Next.js config to add a server-side proxy for Matomo. * * This: * 1. Generates a **random** endpoint path that changes on every build * 2. Adds a Next.js rewrite from the random path to an internal API route * 3. Exposes `NEXT_PUBLIC_MATOMO_PROXY_PATH` for the client * 4. Exposes `MATOMO_PROXY_TARGET` (server-only) for the API route handler * * The browser sends tracking requests to `yoursite.com/api/{random}/{opaque}`. * Next.js rewrites them to `/api/mp/{opaque}`, where the handler * forwards them to your Matomo instance. * * @example * ```js * // next.config.mjs * import { withMatomoProxy } from "@socialgouv/matomo-next"; * * const nextConfig = { /* ... *\/ }; * * export default withMatomoProxy({ * matomoUrl: "https://analytics.example.com", * })(nextConfig); * ``` */ export declare function withMatomoProxy(options: MatomoProxyOptions): (nextConfig: T) => T; /** * Creates Next.js App Router route handlers (GET & POST) that proxy * requests to your Matomo instance. * * The handler reads `MATOMO_PROXY_TARGET` (set by `withMatomoProxy`) * to know where to forward requests. It forwards relevant headers * (User-Agent, Accept-Language, client IP) so Matomo can accurately * track visitors. * * @example * ```ts * // app/api/mp/[...path]/route.ts * import { createMatomoProxyHandler } from "@socialgouv/matomo-next/lib/server-proxy"; * export const { GET, POST } = createMatomoProxyHandler(); * ``` */ export declare function createMatomoProxyHandler(): { GET: (request: Request, context: { params: Promise<{ path?: string[]; }> | { path?: string[]; }; }) => Promise; POST: (request: Request, context: { params: Promise<{ path?: string[]; }> | { path?: string[]; }; }) => Promise; }; /** * Returns the proxy URL to use instead of the direct Matomo URL. * * If a proxy path was configured via `withMatomoProxy`, this function * returns the origin + proxy path. Otherwise it returns `null` and you * should fall back to the direct Matomo URL. * * @example * ```ts * import { getProxyUrl } from "@socialgouv/matomo-next"; * * const url = getProxyUrl() ?? "https://analytics.example.com"; * trackAppRouter({ url, siteId: "1", pathname, searchParams }); * ``` */ export declare function getProxyUrl(): string | null; /** * Returns just the proxy path (without origin), or null. * * Useful when you need to pass the path as the `url` parameter to * `trackAppRouter` / `trackPagesRouter` – in Next.js, relative URLs * work since the browser will resolve them against the current origin. */ export declare function getProxyPath(): string | null; export {}; //# sourceMappingURL=server-proxy.d.ts.map