@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-kitWhat's new in 7.0
- Agents can use the site.
npx sonor-setup mcpserves 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_xxxxxCopy 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 checkModules
Every module has its own README in src/<module>/README.md with full API docs, types, and examples.
Core (every site)
| Module | Import | Purpose | Docs |
|---|---|---|---|
| Layout | @sonordev/site-kit/layout | RSC layout that composes all features | README |
| SEO | @sonordev/site-kit/seo | Managed metadata, schemas, FAQs, internal links | README |
| Analytics | @sonordev/site-kit/analytics | Page views, events, conversions, Web Vitals | README |
| Sitemap | @sonordev/site-kit/seo/sitemap | Auto-generated sitemap with Sonor sync. URLs follow next.config trailingSlash | README |
| Proxy | @sonordev/site-kit/proxy | Redirects, security headers, AI discovery (./middleware is its 7.x alias) | README |
| Redirects | @sonordev/site-kit/seo/redirects | Sonor-managed 301/302 redirect rules | README |
Content
| Module | Import | Purpose | Docs |
|---|---|---|---|
| Articles | @sonordev/site-kit/articles | Sonor-managed articles with SSG, topic clusters, E-E-A-T | README |
| Images | @sonordev/site-kit/website/images | Managed image slots with dev-mode editing | README |
| Reputation | @sonordev/site-kit/reputation | Reviews, testimonials, rating stats | README |
Engagement
| Module | Import | Purpose | Docs |
|---|---|---|---|
| Website chat | @sonordev/site-kit/chat | The chat launcher and Echo (Sonor → Messages) | README |
| Popups & Banners | @sonordev/site-kit/website/popups | Popups, banners and toasts from Sonor → Website, drawn in the site's own design | README |
| Forms | @sonordev/site-kit/forms | Managed forms with CRM routing, multi-step, validation | README |
| Signal | @sonordev/site-kit/signal | A/B experiments, behavior tracking, real-time config | README |
Commerce
| Module | Import | Purpose | Docs |
|---|---|---|---|
| Commerce | @sonordev/site-kit/commerce | Products, services, events, checkout | README |
| Sync | @sonordev/site-kit/sync | Booking/scheduling widget (Calendly-like) | README |
GEO / AEO (AI Visibility)
| Module | Import | Purpose | Docs |
|---|---|---|---|
| LLMs | @sonordev/site-kit/seo/llms | llms.txt, AEO components, Speakable schema | README |
| LLMs Contract | @sonordev/site-kit/seo/llms/contract | Shared types/sanitizers (the APIs use @sonordev/contracts/llms, the same code) | README |
| MCP | @sonordev/site-kit/mcp | MCP endpoint, server card, in-page WebMCP tools | README |
| Sonor MCP tools | @sonordev/site-kit/mcp/sonor | The built-in tools (sonorMcpServer) and tool-call reporting to Sonor | README |
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.
| Module | Import | Purpose | Docs |
|---|---|---|---|
| Motion | @sonordev/site-kit/motion | <Reveal>, <Parallax>, <ScrollScene> and the scroll engine — zero deps, ~2KB | README |
| Motion / GSAP | @sonordev/site-kit/motion/gsap | Lazy-loaded GSAP timelines (useGsap) — optional peer gsap | README |
| Motion / three | @sonordev/site-kit/motion/three | WebGL stages on the engine (useThreeStage) — optional peer three | README |
Liquid Glass chrome
| Module | Import | Purpose | Docs |
|---|---|---|---|
| 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 doneTypeScript
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.