docs
    site-kit: Overview
    v7.2.0.md

    @sonordev/site-kit

    All-in-one integration kit for Sonor-powered Next.js sites. One package, one env var, every module: SEO, Analytics, Forms, Articles, Commerce, Website chat, Popups, GEO/AEO, Booking, Reputation, A/B Testing, and more — all managed from the Sonor dashboard at app.sonor.io.

    Install

    npm install @sonordev/site-kit

    What's new in 7.0

    • Agents can use the site. npx sonor-setup mcp serves the built-in Sonor tools over MCP (business profile, services, FAQ, pages, articles, reviews, and inquiries when you turn them on), and Sonor's AI Visibility tab shows which agents called them. See src/mcp/README.md.
    • Organised the way Sonor's dashboard is: one entry per module (./website/*, ./seo/*, ./chat), a types-only root entry, and the setup CLI in its own package, sonor-setup.
    • ESM only, Next 16 only, 0.6 MB (from 4 MB), with no react-markdown in your install and support for Cache Components.

    Move a site when you next touch it: npx sonor-setup codemod --write, then build. See docs/MIGRATING-TO-7.md.

    Setup

    One environment variable:

    # .env.local
    SONOR_API_KEY=sonor_xxxxxxxx_xxxxx

    Copy the key from app.sonor.io: Projects → your project → Settings → API Keys. Keys start with sonor_. Keep it server-side, with no NEXT_PUBLIC_ prefix.

    One layout component:

    // 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>
      )
    }

    SiteKitLayout is an RSC-compatible async Server Component that auto-composes: analytics tracking, website chat, popups, favicons, and managed scripts. No client-side provider wrapping needed: client modules mount as deferred siblings after {children}, so the page stays server-rendered. Props and module options: src/layout/README.md.

    Proxy (optional but recommended):

    // proxy.ts
    import { createProxy } from '@sonordev/site-kit/proxy'
    
    export default createProxy()
    
    // Inlined on purpose: Next statically parses `config.matcher` at build time
    // and rejects an imported value. `siteKitMatcher` is a reference value to
    // copy from, never a binding to export.
    export const config = {
      matcher: [
        '/((?!_next/static|_next/image|favicon\\.ico|.*\\.(?:ico|png|jpg|jpeg|gif|webp|svg|woff2?)$).*)',
      ],
    }

    Handles Sonor-managed redirects, security headers, and AI discovery headers.

    CLI (optional — scaffolds everything):

    npx sonor-setup init
    npx sonor-setup scaffold   # sitemap, robots, llms.txt, middleware, manifest
    npx sonor-setup status     # health check

    Modules

    Every module has its own README in src/<module>/README.md with full API docs, types, and examples.

    Core (every site)

    ModuleImportPurposeDocs
    Layout@sonordev/site-kit/layoutRSC layout that composes all featuresREADME
    SEO@sonordev/site-kit/seoManaged metadata, schemas, FAQs, internal linksREADME
    Analytics@sonordev/site-kit/analyticsPage views, events, conversions, Web VitalsREADME
    Sitemap@sonordev/site-kit/seo/sitemapAuto-generated sitemap with Sonor sync. URLs follow next.config trailingSlashREADME
    Proxy@sonordev/site-kit/proxyRedirects, security headers, AI discovery (./middleware is its 7.x alias)README
    Redirects@sonordev/site-kit/seo/redirectsSonor-managed 301/302 redirect rulesREADME

    Content

    ModuleImportPurposeDocs
    Articles@sonordev/site-kit/articlesSonor-managed articles with SSG, topic clusters, E-E-A-TREADME
    Images@sonordev/site-kit/website/imagesManaged image slots with dev-mode editingREADME
    Reputation@sonordev/site-kit/reputationReviews, testimonials, rating statsREADME

    Engagement

    ModuleImportPurposeDocs
    Website chat@sonordev/site-kit/chatThe chat launcher and Echo (Sonor → Messages)README
    Popups & Banners@sonordev/site-kit/website/popupsPopups, banners and toasts from Sonor → Website, drawn in the site's own designREADME
    Forms@sonordev/site-kit/formsManaged forms with CRM routing, multi-step, validationREADME
    Signal@sonordev/site-kit/signalA/B experiments, behavior tracking, real-time configREADME

    Commerce

    ModuleImportPurposeDocs
    Commerce@sonordev/site-kit/commerceProducts, services, events, checkoutREADME
    Sync@sonordev/site-kit/syncBooking/scheduling widget (Calendly-like)README

    GEO / AEO (AI Visibility)

    ModuleImportPurposeDocs
    LLMs@sonordev/site-kit/seo/llmsllms.txt, AEO components, Speakable schemaREADME
    LLMs Contract@sonordev/site-kit/seo/llms/contractShared types/sanitizers (the APIs use @sonordev/contracts/llms, the same code)README
    MCP@sonordev/site-kit/mcpMCP endpoint, server card, in-page WebMCP toolsREADME
    Sonor MCP tools@sonordev/site-kit/mcp/sonorThe built-in tools (sonorMcpServer) and tool-call reporting to SonorREADME

    Motion

    Three tiers as three subpaths — a site only installs and ships what it imports. Server HTML always stays visible; above-the-fold content is never animated in.

    ModuleImportPurposeDocs
    Motion@sonordev/site-kit/motion<Reveal>, <Parallax>, <ScrollScene> and the scroll engine — zero deps, ~2KBREADME
    Motion / GSAP@sonordev/site-kit/motion/gsapLazy-loaded GSAP timelines (useGsap) — optional peer gsapREADME
    Motion / three@sonordev/site-kit/motion/threeWebGL stages on the engine (useThreeStage) — optional peer threeREADME

    Liquid Glass chrome

    ModuleImportPurposeDocs
    CTA bar@sonordev/site-kit/website/cta-bar<CtaBar> + <CtaBarAction>: the floating glass mobile CTA bar. Hides over its form and while typing, compacts on scroll, lifts the Echo launcher, emits cta_click. Server component.README

    Echo's launcher and chat window use the same glass recipe; see Website chat.


    How It Works

    SONOR_API_KEY in .env.local
           │
           ▼
    SiteKitLayout (RSC server component)
    ├── Server-side:
    │   ├── ManagedFavicon         (Sonor logo → <link> tags)
    │   ├── ManagedScripts         (tracking pixels, analytics tags)
    │   └── API preconnect hints
    │
    ├── Client-side (childless siblings after {children}, deferred to idle):
    │   ├── AnalyticsProvider      (page views, scroll depth, Web Vitals)
    │   ├── SitePopups             (popups, banners, toasts)
    │   ├── SiteChat               (website chat: Echo)
    │   ├── SignalBridge           (A/B experiments, opt-in, not deferred)
    │   ├── SitemapSync            (browser sitemap fallback, opt-in)
    │   └── FleetHeartbeat         (kit version + modules, once per session)
    │
    └── Middleware (separate):
        ├── Redirects              (Sonor-managed 301/302)
        ├── Security headers       (CSP frame-ancestors, nosniff, etc.)
        └── AI discovery           (Link: rel="describedby" → /llms.txt)
    

    All data flows through the Sonor API (api.sonor.io) authenticated by your API key. No direct database access, no Supabase keys exposed to the client.


    Import Paths

    // Core
    import { SiteKitLayout } from '@sonordev/site-kit/layout'
    import { createProxy, siteKitMatcher } from '@sonordev/site-kit/proxy'   // in proxy.ts
    
    // SEO
    import { getManagedMetadata, ManagedSchema, ManagedFAQ } from '@sonordev/site-kit/seo'
    
    // Analytics
    import { AnalyticsProvider, useAnalytics, WebVitals } from '@sonordev/site-kit/analytics'
    
    // Forms
    import { ManagedForm, useForm, formsApi, field } from '@sonordev/site-kit/forms'
    
    // Articles (server components — keeps server-only data helpers out of client bundles)
    import { Article, ArticleList, ClusterLandingPage } from '@sonordev/site-kit/articles/server-ui'
    import { getArticle, generateArticleStaticParams } from '@sonordev/site-kit/articles/server'
    
    // Commerce
    import { OfferingCard, ProductPage, EventCalendar } from '@sonordev/site-kit/commerce'
    
    // Booking
    import { BookingWidget } from '@sonordev/site-kit/sync'
    
    // Website chat, and popups (SiteKitLayout mounts both; its `chat` and `popups` props turn them off)
    import { SiteChat, ChatWidget } from '@sonordev/site-kit/chat'
    import { SitePopups, PopupBlocks } from '@sonordev/site-kit/website/popups'
    
    // Signal (A/B)
    import { SignalBridge, SignalExperiment, useSignal } from '@sonordev/site-kit/signal'
    
    // GEO / AEO
    import { createLLMsTxtHandler, buildAiDiscoveryHeaders } from '@sonordev/site-kit/seo/llms'
    import { AEOBlock, AEOSummary, AEOSteps, SpeakableSchema } from '@sonordev/site-kit/seo/llms'
    
    // Agent tools (MCP): see src/mcp/README.md, or run `npx sonor-setup mcp`
    import { createMcpHandler, createMcpServerCardHandler } from '@sonordev/site-kit/mcp'
    import { sonorMcpServer, reportToolCallsToSonor } from '@sonordev/site-kit/mcp/sonor'
    import { WebMcpTools } from '@sonordev/site-kit/mcp/client'
    
    // Sitemap
    import { createSitemap } from '@sonordev/site-kit/seo/sitemap'
    
    // Images
    import { ManagedImage } from '@sonordev/site-kit/website/images'
    
    // Reputation
    import { TestimonialSection, fetchReviews } from '@sonordev/site-kit/reputation'
    
    // Redirects
    import { handleManagedRedirects } from '@sonordev/site-kit/seo/redirects'
    
    // Robots (the AI crawler helpers live in /llms; /robots re-exports them)
    import { createRobots, buildAiCrawlerRules, createRobotsTxtHandler } from '@sonordev/site-kit/seo/robots'
    
    // Motion (tier 0, zero deps) — tiers 1/2 need `npm i gsap` / `npm i three`
    import { Reveal, Parallax, ScrollScene, registerScene } from '@sonordev/site-kit/motion'
    import { useGsap } from '@sonordev/site-kit/motion/gsap'
    import { useThreeStage, canRunWebGL } from '@sonordev/site-kit/motion/three'
    
    // Liquid Glass mobile CTA bar (server component; pass Next Link via `as`)
    import { CtaBar, CtaBarAction } from '@sonordev/site-kit/website/cta-bar'
    
    // Styles (optional)
    import '@sonordev/site-kit/brand.css'
    import '@sonordev/site-kit/forms/styles.css'

    Environment Variables

    # Required (server-only — SiteKitLayout injects into client automatically):
    SONOR_API_KEY=sonor_xxxxxxxx_xxxxx
    
    # Optional:
    SONOR_API_URL=https://api.sonor.io              # Sonor API (default)
    NEXT_PUBLIC_SITE_URL=https://example.com         # For CLI status checks + sitemap
    REVALIDATION_SECRET=your_secret                  # On-demand ISR for llms.txt
    MCP_TRANSPORT_SECRET=...                         # Netlify MCP relay (npx sonor-setup mcp writes it)

    Uptrade-era variables (UPTRADE_API_KEY, NEXT_PUBLIC_UPTRADE_API_KEY) aren't read, and uptrade_ keys aren't accepted. A site that only sets those runs with no key. Move it to SONOR_API_KEY with npx sonor-setup codemod --only uptrade-to-sonor --write.


    CLI

    The setup CLI is its own package since 7.0, sonor-setup. npx fetches it; a site that runs it from package.json scripts adds it as a dev dependency. (sonor-register-sitemap, the postbuild step, stays here.)

    npx sonor-setup <command>
    
    Commands:
      init           Initialize site-kit in a Next.js project
      scaffold       Scaffold sitemap, robots, llms.txt, proxy, manifest
      mcp            Give agents the site's tools (MCP endpoint, server card, relay)
      setup          AI-powered SEO setup (metadata, schemas, FAQs)
      scan           Scan codebase for integration opportunities
      migrate        Migrate detected components to site-kit
      sync           Sync local content to Sonor
      status         Health check (API, llms.txt, sitemap, layout)
      geo            Check GEO/llms.txt wiring
      images         Scan, upload, and manage images
      locations      Generate location pages
      faqs           Sync ManagedFAQ paths
      api-routes     Generate API proxy routes
      install        Install @sonordev/site-kit
      upgrade        Upgrade to latest version
      codemod        Move an older site to the current site-kit (--check, --write)
      next16         Move middleware.ts to proxy.ts
      verify         Exit 0 when the integration is done

    TypeScript

    Fully typed. All types are exported from their respective module paths:

    import type { LLMsDataResponse, GenerateLLMSTxtOptions } from '@sonordev/site-kit/seo/llms'
    import type { ManagedFormConfig, UseFormReturn } from '@sonordev/site-kit/forms'
    import type { Article, TopicCluster } from '@sonordev/site-kit/articles'
    import type { CommerceOffering, SizeChart } from '@sonordev/site-kit/commerce'
    import type { SiteKitLayoutProps } from '@sonordev/site-kit/layout'

    Architecture Note

    @sonordev/site-kit is the client bridge between Next.js marketing sites and the Sonor platform. All persistent data (forms, articles, SEO config, analytics) lives in Sonor — site-kit fetches, renders, and tracks.

    • Server components (SEO, Articles, Images): Import directly, RSC-compatible, no provider needed
    • Client modules (Analytics, chat, popups, Signal): Lazy-loaded via SiteKitLayout, tree-shaken
    • Build-time (Sitemap, llms.txt): Run during next build, sync to Sonor
    • Middleware (Redirects, Security, AI Discovery): Runs on every request edge

    Full docs for every module: sonor.dev.