import type { I18nConfig } from './types.js'; /** * Minimal request shape the middleware reads. Kept structural so the plugin * doesn't hard-depend on next/server types; a Next.js `NextRequest` satisfies it. */ type MiddlewareRequest = { cookies: { get: (name: string) => { value: string; } | undefined; }; headers: { get: (name: string) => null | string; }; nextUrl: { clone: () => URL; pathname: string; search: string; }; url: string; }; /** * What the factory returns — the caller (in Next middleware.ts) decides how to * act: `redirect` means send a 307 to `location` and set the locale cookie; * `next` means let the request pass through untouched. */ export type LocaleMiddlewareResult = { cookie?: { name: string; value: string; }; location: string; type: 'redirect'; } | { type: 'next'; }; type CreateLocaleMiddlewareArgs = { config: I18nConfig; /** * Consent category that gates *persisting* the locale cookie. The locale is * always detected (routing works regardless), but the choice is only written * to a cookie once the visitor has consented to this category. Defaults to * 'functional'. Pass 'necessary' to always persist (treat locale as strictly * necessary), which restores the pre-consent behaviour. */ consentCategory?: 'functional' | 'necessary'; /** Name of the consent cookie to read. Defaults to CONSENT_COOKIE. */ consentCookieName?: string; /** Cookie name for the locale choice. Defaults to LOCALE_COOKIE_NAME. */ cookieName?: string; }; /** * Builds locale-routing logic for Next.js middleware. * * Behavior: * - path already starts with a valid locale (/pl/...) → pass through * - any other path (/, /o-nas) → redirect to /{locale}{path}, where locale * comes from negotiateLocale (cookie → Accept-Language → default) * - the chosen locale is written to a cookie so the next visit is stable * * The plugin returns a decision; the thin middleware.ts in the client project * turns it into a NextResponse. This keeps all logic in the plugin while * respecting that middleware.ts must physically live in the client app. * * @example * // middleware.ts (client project) — one wiring file, no logic: * import { NextResponse } from 'next/server' * import { localeMiddleware } from './ipal.middleware' // created from this factory * export function proxy(req) { * const r = localeMiddleware(req) * if (r.type === 'next') return NextResponse.next() * const res = NextResponse.redirect(r.location) * // cookie is optional: only present when the visitor consented to the * // gating category (functional by default). Guard before setting. * if (r.cookie) res.cookies.set(r.cookie.name, r.cookie.value) * return res * } */ export declare function createLocaleMiddleware({ config, consentCategory, consentCookieName, cookieName, }: CreateLocaleMiddlewareArgs): (request: MiddlewareRequest) => LocaleMiddlewareResult; /** * Default Next.js middleware matcher: run on everything except API routes, the * admin panel, Next internals, and files with an extension (static assets). */ export declare const DEFAULT_MIDDLEWARE_MATCHER: string[]; export {};