docs
    site-kit: Layout
    v7.2.0.md

    Layout — @sonordev/site-kit/layout

    RSC-compatible master layout that auto-composes all site-kit features.

    Usage

    // app/layout.tsx
    import { SiteKitLayout } from '@sonordev/site-kit/layout'
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en">
          <body>
            <SiteKitLayout>{children}</SiteKitLayout>
          </body>
        </html>
      )
    }

    Zero-config: reads SONOR_API_KEY from env, injects it into client modules automatically.

    Props

    interface SiteKitLayoutProps {
      children: React.ReactNode
      apiKey?: string                         // Defaults to SONOR_API_KEY env var
      apiUrl?: string                         // Defaults to SONOR_API_URL, then https://api.sonor.io
      projectId?: string                      // For chat routing (auto-resolved if omitted)
      analytics?: boolean | AnalyticsConfig   // Default: true
      chat?: boolean | ChatLayoutConfig       // Default: true (website chat; config = launcher placement)
      popups?: boolean                        // Default: true (Website → Popups & Banners)
      engage?: boolean | EngageConfig         // Deprecated: false turns chat and popups off; an object configures the launcher
      signal?: boolean | SignalConfig         // Default: false
      sitemapSync?: boolean                   // Default: false (build-time + server reconciler own this)
      fleet?: boolean                         // Default: true (once-per-session kit version heartbeat)
      defer?: boolean                         // Default: true (client modules wait for load + idle)
      favicon?: boolean                       // Default: true
      managedScripts?: boolean                // Default: true
      debug?: boolean                         // Default: false
      showLlmsTxtFooterLink?: boolean         // Default: false (prefer middleware discovery headers)
      speculation?: boolean | { mode?: 'prerender' | 'prefetch'; exclude?: string[] } // Default: false
    }

    Module options live with each module: Analytics (trackPageViews, excludePaths, site, allowInFrame, allowLocalhost) Website chat (position, offsetBottom, zIndex, allowInFrame) and Popups and banners.

    What It Composes

    Server-side (RSC):

    • ManagedFavicon — Sonor logo as <link> tags
    • ManagedScripts — tracking pixels/analytics tags in <head> and body-end positions
    • API preconnect/dns-prefetch hints

    Client-side (lazy-loaded island):

    • AnalyticsProvider — page views, scroll depth, heatmap clicks, Web Vitals
    • SitePopups — popups, banners and toasts
    • SiteChat — website chat (Echo)
    • SignalBridge — A/B experiments, behavior tracking (opt-in)
    • SitemapSync — parses /sitemap.xml and syncs to Sonor (opt-in)
    • FleetHeartbeat — reports the kit version and enabled modules once per session

    Since 4.0.0 none of these wrap your page. {children} renders first and every module mounts after it as a childless sibling, so SiteKitLayout never pushes a route to client rendering. Analytics, chat, popups, SitemapSync and the heartbeat also wait for window load + idle (or the first interaction) unless you pass defer={false}. SignalBridge isn't deferred, so experiment variants apply early. Visitor and session IDs come from a shared storage singleton rather than a provider.

    Note

    SiteKitProvider was removed in 4.0.0. It wrapped the whole tree client-side, which broke RSC. Migrate an older layout with npx sonor-setup codemod --only provider-to-layout --write.