docs
    site-kit: Redirects
    v7.2.0.md

    Redirects — @sonordev/site-kit/redirects

    Sonor-managed 301/302/307/308 redirect rules. Used by createProxy() or standalone.

    Usage

    Automatically handled when using createProxy():

    // proxy.ts
    import { createProxy } from '@sonordev/site-kit/proxy'
    
    export default createProxy()  // redirects: true by default
    
    // Inlined: an imported `config.matcher` is a build error. See the proxy README.
    export const config = {
      matcher: [
        '/((?!_next/static|_next/image|favicon\\.ico|.*\\.(?:ico|png|jpg|jpeg|gif|webp|svg|woff2?)$).*)',
      ],
    }

    For standalone use:

    import { handleManagedRedirects } from '@sonordev/site-kit/redirects'
    
    export async function middleware(request: NextRequest) {
      const redirect = await handleManagedRedirects(request, {})
      if (redirect) return redirect
      return NextResponse.next()
    }

    API

    handleManagedRedirects(request: NextRequest, config: RedirectConfig): Promise<NextResponse | undefined>
    fetchRedirectRules(config: RedirectConfig): Promise<RedirectRule[]>
    generateNextRedirects(config: RedirectConfig): Promise<Redirect[]>  // For next.config.js
    clearRedirectCache(): void  // Dev helper

    Config

    interface RedirectConfig {
      domain?: string              // Resolved from Sonor when using apiKey
      apiKey?: string              // Project API key
      site?: string                // Multi-site host, sent as ?site= and cached per host (default: NEXT_PUBLIC_SITE_URL host)
      portalApiUrl?: string        // Default: https://api.sonor.io
      cacheSeconds?: number        // Default: 300 (5 minutes)
    }

    Behavior

    1. Checks in-memory cache first
    2. Fetches rules from Sonor API if expired
    3. Matches pathname (exact or trailing-slash variant)
    4. Preserves query parameters on redirect
    5. Tracks redirect hit (fire-and-forget)
    6. Skips static assets and API routes

    Types

    interface RedirectRule {
      from_path: string
      to_path: string
      redirect_type: '301' | '302' | '307' | '308'
      is_enabled: boolean
    }