@sonordev/site-kit 2.8.2 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/blog/index.js +2 -1
  2. package/dist/blog/index.js.map +1 -1
  3. package/dist/blog/index.mjs +2 -1
  4. package/dist/blog/index.mjs.map +1 -1
  5. package/dist/{chunk-5SQ4NRPH.mjs → chunk-3AEOGV6V.mjs} +6 -4
  6. package/dist/chunk-3AEOGV6V.mjs.map +1 -0
  7. package/dist/chunk-662YHKWW.mjs +10 -0
  8. package/dist/chunk-662YHKWW.mjs.map +1 -0
  9. package/dist/{chunk-MNOVPHL6.mjs → chunk-72MRAYAS.mjs} +19 -14
  10. package/dist/chunk-72MRAYAS.mjs.map +1 -0
  11. package/dist/{chunk-MWE2HRPU.js → chunk-D5XTX5EB.js} +19 -14
  12. package/dist/chunk-D5XTX5EB.js.map +1 -0
  13. package/dist/{chunk-PKUTYMN7.js → chunk-J25JPU77.js} +2 -2
  14. package/dist/chunk-J25JPU77.js.map +1 -0
  15. package/dist/chunk-J7QI3GDX.js +12 -0
  16. package/dist/chunk-J7QI3GDX.js.map +1 -0
  17. package/dist/{chunk-L7XPPFSS.mjs → chunk-QDKQZ5XH.mjs} +2 -2
  18. package/dist/chunk-QDKQZ5XH.mjs.map +1 -0
  19. package/dist/{chunk-PAF5IGGF.js → chunk-XNUPJC6R.js} +6 -4
  20. package/dist/chunk-XNUPJC6R.js.map +1 -0
  21. package/dist/index.d.mts +1 -1
  22. package/dist/index.d.ts +1 -1
  23. package/dist/layout/index.js +3 -3
  24. package/dist/layout/index.mjs +1 -1
  25. package/dist/llms/index.d.mts +18 -4
  26. package/dist/llms/index.d.ts +18 -4
  27. package/dist/llms/index.js +26 -51
  28. package/dist/llms/index.js.map +1 -1
  29. package/dist/llms/index.mjs +16 -41
  30. package/dist/llms/index.mjs.map +1 -1
  31. package/dist/seo/index.d.mts +10 -205
  32. package/dist/seo/index.d.ts +10 -205
  33. package/dist/seo/index.js +16 -15
  34. package/dist/seo/index.js.map +1 -1
  35. package/dist/seo/index.mjs +7 -6
  36. package/dist/seo/index.mjs.map +1 -1
  37. package/dist/seo/server.d.mts +2 -106
  38. package/dist/seo/server.d.ts +2 -106
  39. package/dist/seo/server.js +56 -197
  40. package/dist/seo/server.js.map +1 -1
  41. package/dist/seo/server.mjs +2 -183
  42. package/dist/seo/server.mjs.map +1 -1
  43. package/dist/server-l6LMNvF1.d.ts +360 -0
  44. package/dist/server-mX5At_6x.d.mts +360 -0
  45. package/dist/sitemap/index.d.mts +1 -1
  46. package/dist/sitemap/index.d.ts +1 -1
  47. package/dist/sitemap/index.js +2 -2
  48. package/dist/sitemap/index.mjs +1 -1
  49. package/dist/{types-DYyIAgQg.d.mts → types-DPsbBKiu.d.mts} +1 -1
  50. package/dist/{types-DYyIAgQg.d.ts → types-DPsbBKiu.d.ts} +1 -1
  51. package/dist/{types-J7Z_FqmV.d.mts → types-DhCAWUmd.d.mts} +8 -0
  52. package/dist/{types-0NuBL1Gg.d.ts → types-xcP_owwn.d.ts} +8 -0
  53. package/package.json +1 -1
  54. package/dist/chunk-5SQ4NRPH.mjs.map +0 -1
  55. package/dist/chunk-L7XPPFSS.mjs.map +0 -1
  56. package/dist/chunk-MNOVPHL6.mjs.map +0 -1
  57. package/dist/chunk-MWE2HRPU.js.map +0 -1
  58. package/dist/chunk-PAF5IGGF.js.map +0 -1
  59. package/dist/chunk-PKUTYMN7.js.map +0 -1
  60. package/dist/routing-C7gmHWm9.d.ts +0 -163
  61. package/dist/routing-trNzR1Pz.d.mts +0 -163
@@ -1,7 +1,8 @@
1
1
  export { buildAiDiscoveryHeaders } from '../chunk-H4OBGC43.mjs';
2
- import { generateLLMsTxt, generateLLMsFullTxt } from '../chunk-MNOVPHL6.mjs';
3
- export { generateLLMsFullTxt, generateLLMsTxt, getBusinessInfo, getFAQItems, getLLMsData, getOptimizedLLMsTxt, getPageSummaries, getServices, writeLLMsTxtToPublic } from '../chunk-MNOVPHL6.mjs';
2
+ import { generateLLMsTxt, generateLLMsFullTxt } from '../chunk-72MRAYAS.mjs';
3
+ export { generateLLMsFullTxt, generateLLMsTxt, getBusinessInfo, getFAQItems, getLLMsData, getOptimizedLLMsTxt, getPageSummaries, getServices, writeLLMsTxtToPublic } from '../chunk-72MRAYAS.mjs';
4
4
  export { LLMS_DISCLAIMER_MAX_LENGTH, LLMS_PUBLIC_SUMMARY_MAX_LENGTH, LLM_GEO_CONTRACT_VERSION, MANAGED_LLM_SCHEMA_KNOWN_KEYS, pickManagedLlmSchemaForJsonLd, sanitizeLlmsDisclaimerLine, sanitizeLlmsPublicSummary, sanitizePrimaryLanguageTag } from '../chunk-H23ZT2I2.mjs';
5
+ import { safeJsonLd } from '../chunk-662YHKWW.mjs';
5
6
  import '../chunk-4XPGGLVP.mjs';
6
7
  import { createHash } from 'crypto';
7
8
  import { existsSync, readFileSync } from 'fs';
@@ -23,39 +24,25 @@ function llmsResponseHeaders(body, extra) {
23
24
  }
24
25
  function createLLMsTxtHandler(options = {}) {
25
26
  const { preferStatic = true, ...generateOptions } = options;
26
- return async function GET(request) {
27
+ return async function GET(_request) {
27
28
  try {
28
29
  if (preferStatic) {
29
30
  const staticPath = join(process.cwd(), "public", "llms.txt");
30
31
  if (existsSync(staticPath)) {
31
32
  const markdown2 = readFileSync(staticPath, "utf-8");
32
- const inm2 = request.headers.get("if-none-match");
33
- const headers2 = llmsResponseHeaders(markdown2, {
34
- "X-Sections": "static"
35
- });
36
- const etag2 = headers2.ETag;
37
- if (inm2 && etag2 && inm2 === etag2) {
38
- return new Response(null, { status: 304, headers: headers2 });
39
- }
40
33
  return new Response(markdown2, {
41
34
  status: 200,
42
- headers: headers2
35
+ headers: llmsResponseHeaders(markdown2, { "X-Sections": "static" })
43
36
  });
44
37
  }
45
38
  }
46
39
  const { markdown, metadata } = await generateLLMsTxt(generateOptions);
47
- const inm = request.headers.get("if-none-match");
48
- const headers = llmsResponseHeaders(markdown, {
49
- "X-Generated-At": metadata.generated_at,
50
- "X-Sections": metadata.sections.join(",")
51
- });
52
- const etag = headers.ETag;
53
- if (inm && etag && inm === etag) {
54
- return new Response(null, { status: 304, headers });
55
- }
56
40
  return new Response(markdown, {
57
41
  status: 200,
58
- headers
42
+ headers: llmsResponseHeaders(markdown, {
43
+ "X-Generated-At": metadata.generated_at,
44
+ "X-Sections": metadata.sections.join(",")
45
+ })
59
46
  });
60
47
  } catch (error) {
61
48
  console.error("@sonordev/llms: Error generating llms.txt:", error);
@@ -71,37 +58,25 @@ function createLLMsTxtHandler(options = {}) {
71
58
  }
72
59
  function createLLMsFullTxtHandler(options = {}) {
73
60
  const { preferStatic = true, ...generateOptions } = options;
74
- return async function GET(request) {
61
+ return async function GET(_request) {
75
62
  try {
76
63
  if (preferStatic) {
77
64
  const staticPath = join(process.cwd(), "public", "llms-full.txt");
78
65
  if (existsSync(staticPath)) {
79
66
  const markdown2 = readFileSync(staticPath, "utf-8");
80
- const inm2 = request.headers.get("if-none-match");
81
- const headers2 = llmsResponseHeaders(markdown2, { "X-Sections": "static" });
82
- const etag2 = headers2.ETag;
83
- if (inm2 && etag2 && inm2 === etag2) {
84
- return new Response(null, { status: 304, headers: headers2 });
85
- }
86
67
  return new Response(markdown2, {
87
68
  status: 200,
88
- headers: headers2
69
+ headers: llmsResponseHeaders(markdown2, { "X-Sections": "static" })
89
70
  });
90
71
  }
91
72
  }
92
73
  const { markdown, metadata } = await generateLLMsFullTxt(generateOptions);
93
- const inm = request.headers.get("if-none-match");
94
- const headers = llmsResponseHeaders(markdown, {
95
- "X-Generated-At": metadata.generated_at,
96
- "X-Sections": metadata.sections.join(",")
97
- });
98
- const etag = headers.ETag;
99
- if (inm && etag && inm === etag) {
100
- return new Response(null, { status: 304, headers });
101
- }
102
74
  return new Response(markdown, {
103
75
  status: 200,
104
- headers
76
+ headers: llmsResponseHeaders(markdown, {
77
+ "X-Generated-At": metadata.generated_at,
78
+ "X-Sections": metadata.sections.join(",")
79
+ })
105
80
  });
106
81
  } catch (error) {
107
82
  console.error("@sonordev/llms: Error generating llms-full.txt:", error);
@@ -128,7 +103,7 @@ function SpeakableSchema({
128
103
  {
129
104
  type: "application/ld+json",
130
105
  dangerouslySetInnerHTML: {
131
- __html: JSON.stringify(schema, null, 0)
106
+ __html: safeJsonLd(schema)
132
107
  }
133
108
  }
134
109
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/llms/handlers.ts","../../src/llms/SpeakableSchema.tsx","../../src/llms/AEOComponents.tsx","../../src/llms/revalidate.ts"],"names":["markdown","inm","headers","etag","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @sonordev/site-kit/llms - Next.js Route Handlers\n * \n * Ready-to-use route handlers for /llms.txt and /llms-full.txt\n */\n\nimport { createHash } from 'crypto'\nimport { existsSync, readFileSync } from 'fs'\nimport { join } from 'path'\nimport { generateLLMsTxt, generateLLMsFullTxt } from './generateLLMsTxt'\nimport type { GenerateLLMSTxtOptions } from './types'\n\nfunction weakEtag(body: string): string {\n const h = createHash('sha1').update(body, 'utf8').digest('base64url')\n return `W/\"${h}\"`\n}\n\n/** Cache + validation headers for plain-text llms responses (dynamic or static). */\nexport function llmsResponseHeaders(body: string, extra?: Record<string, string>): HeadersInit {\n return {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Cache-Control':\n 'public, max-age=300, s-maxage=3600, stale-while-revalidate=86400, stale-if-error=86400',\n ETag: weakEtag(body),\n Vary: 'Accept-Encoding',\n ...extra,\n }\n}\n\nexport interface LLMsTxtHandlerOptions extends GenerateLLMSTxtOptions {\n /** When true, serve static public/llms.txt if it exists (default: true for build-time flow) */\n preferStatic?: boolean\n}\n\n/**\n * Create a route handler for /llms.txt\n * \n * Zero-config by default - uses SONOR_API_KEY from environment.\n *\n * @example\n * ```ts\n * // app/llms.txt/route.ts (zero-config)\n * import { createLLMsTxtHandler } from '@sonordev/site-kit/llms'\n *\n * export const GET = createLLMsTxtHandler()\n * ```\n *\n * @example\n * ```ts\n * // With preferStatic: serve build-time file if exists\n * export const GET = createLLMsTxtHandler({\n * preferStatic: true,\n * includeServices: false\n * })\n * ```\n */\nexport function createLLMsTxtHandler(\n options: LLMsTxtHandlerOptions = {}\n): (request: Request) => Promise<Response> {\n const { preferStatic = true, ...generateOptions } = options\n\n return async function GET(request: Request): Promise<Response> {\n try {\n // Serve static file if available (build-time optimized)\n if (preferStatic) {\n const staticPath = join(process.cwd(), 'public', 'llms.txt')\n if (existsSync(staticPath)) {\n const markdown = readFileSync(staticPath, 'utf-8')\n const inm = request.headers.get('if-none-match')\n const headers = llmsResponseHeaders(markdown, {\n 'X-Sections': 'static',\n })\n const etag = (headers as Record<string, string>).ETag\n if (inm && etag && inm === etag) {\n return new Response(null, { status: 304, headers })\n }\n return new Response(markdown, {\n status: 200,\n headers,\n })\n }\n }\n\n const { markdown, metadata } = await generateLLMsTxt(generateOptions)\n const inm = request.headers.get('if-none-match')\n const headers = llmsResponseHeaders(markdown, {\n 'X-Generated-At': metadata.generated_at,\n 'X-Sections': metadata.sections.join(','),\n })\n const etag = (headers as Record<string, string>).ETag\n if (inm && etag && inm === etag) {\n return new Response(null, { status: 304, headers })\n }\n\n return new Response(markdown, {\n status: 200,\n headers,\n })\n } catch (error) {\n console.error('@sonordev/llms: Error generating llms.txt:', error)\n return new Response('# Error\\n\\nUnable to generate llms.txt content.', {\n status: 500,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Cache-Control': 'no-store',\n },\n })\n }\n }\n}\n\n/**\n * Create a route handler for /llms-full.txt\n * \n * Zero-config by default - uses SONOR_API_KEY from environment.\n *\n * @example\n * ```ts\n * // app/llms-full.txt/route.ts (zero-config)\n * import { createLLMsFullTxtHandler } from '@sonordev/site-kit/llms'\n * \n * export const GET = createLLMsFullTxtHandler()\n * ```\n */\nexport function createLLMsFullTxtHandler(\n options: LLMsTxtHandlerOptions = {}\n): (request: Request) => Promise<Response> {\n const { preferStatic = true, ...generateOptions } = options\n\n return async function GET(request: Request): Promise<Response> {\n try {\n // Serve static file if available (build-time optimized)\n if (preferStatic) {\n const staticPath = join(process.cwd(), 'public', 'llms-full.txt')\n if (existsSync(staticPath)) {\n const markdown = readFileSync(staticPath, 'utf-8')\n const inm = request.headers.get('if-none-match')\n const headers = llmsResponseHeaders(markdown, { 'X-Sections': 'static' })\n const etag = (headers as Record<string, string>).ETag\n if (inm && etag && inm === etag) {\n return new Response(null, { status: 304, headers })\n }\n return new Response(markdown, {\n status: 200,\n headers,\n })\n }\n }\n\n const { markdown, metadata } = await generateLLMsFullTxt(generateOptions)\n const inm = request.headers.get('if-none-match')\n const headers = llmsResponseHeaders(markdown, {\n 'X-Generated-At': metadata.generated_at,\n 'X-Sections': metadata.sections.join(','),\n })\n const etag = (headers as Record<string, string>).ETag\n if (inm && etag && inm === etag) {\n return new Response(null, { status: 304, headers })\n }\n\n return new Response(markdown, {\n status: 200,\n headers,\n })\n } catch (error) {\n console.error('@sonordev/llms: Error generating llms-full.txt:', error)\n return new Response('# Error\\n\\nUnable to generate llms-full.txt content.', {\n status: 500,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Cache-Control': 'no-store',\n },\n })\n }\n }\n}\n","/**\n * @sonordev/site-kit/llms - Speakable Schema Generator\n * \n * Generates JSON-LD with SpeakableSpecification for voice assistant\n * and AI system content extraction.\n * \n * @see https://schema.org/speakable\n * @see https://developers.google.com/search/docs/appearance/structured-data/speakable\n */\n\nimport * as React from 'react'\nimport type { SpeakableSchemaProps, SpeakableConfig } from './types'\n\n/**\n * Generate a WebPage or Article schema with speakable specification\n * \n * @example\n * ```tsx\n * // In a page component\n * <SpeakableSchema\n * type=\"Article\"\n * name=\"Family Law Services in Cincinnati\"\n * url=\"https://heinrichlaw.com/family-law\"\n * speakable={{\n * cssSelectors: ['.page-summary', '.key-points', 'h1']\n * }}\n * />\n * ```\n */\nexport function SpeakableSchema({\n type,\n name,\n url,\n speakable,\n additionalProperties = {},\n}: SpeakableSchemaProps): React.ReactElement {\n const schema = createSpeakableSchema(type, name, url, speakable, additionalProperties)\n \n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{\n __html: JSON.stringify(schema, null, 0),\n }}\n />\n )\n}\n\n/**\n * Create speakable schema object (for manual use or testing)\n */\nexport function createSpeakableSchema(\n type: 'Article' | 'WebPage',\n name: string,\n url: string,\n speakable: SpeakableConfig,\n additionalProperties: Record<string, unknown> = {}\n): Record<string, unknown> {\n const speakableSpec: Record<string, unknown> = {\n '@type': 'SpeakableSpecification',\n }\n\n // Prefer CSS selectors, fall back to XPath\n if (speakable.cssSelectors?.length) {\n speakableSpec.cssSelector = speakable.cssSelectors\n } else if (speakable.xPaths?.length) {\n speakableSpec.xpath = speakable.xPaths\n } else {\n // Default speakable selectors for common patterns\n speakableSpec.cssSelector = [\n 'h1',\n '[data-speakable]',\n '.page-summary',\n '.key-points',\n 'meta[name=\"description\"]'\n ]\n }\n\n return {\n '@context': 'https://schema.org',\n '@type': type,\n name,\n url,\n speakable: speakableSpec,\n ...additionalProperties,\n }\n}\n\n/**\n * Default speakable CSS selectors for common page elements\n */\nexport const DEFAULT_SPEAKABLE_SELECTORS = {\n /** Standard page elements */\n page: ['h1', 'meta[name=\"description\"]', '.page-summary'],\n /** Article/blog post elements */\n article: ['h1', '.article-summary', '.article-intro', 'meta[name=\"description\"]'],\n /** Service page elements */\n service: ['h1', '.service-overview', '.key-benefits', 'meta[name=\"description\"]'],\n /** FAQ page elements */\n faq: ['h1', '.faq-intro', '.faq-item'],\n /** Contact page elements */\n contact: ['h1', '.contact-intro', '.business-hours', '.contact-info'],\n}\n\n/**\n * Get recommended speakable selectors for a page type\n */\nexport function getSpeakableSelectorsForPage(\n pageType: 'page' | 'article' | 'service' | 'faq' | 'contact'\n): string[] {\n return DEFAULT_SPEAKABLE_SELECTORS[pageType] || DEFAULT_SPEAKABLE_SELECTORS.page\n}\n\nexport default SpeakableSchema\n","/**\n * @sonordev/site-kit/llms - AEO Components\n * \n * Answer Engine Optimization (AEO) components for structuring content\n * in a way that AI systems can easily extract and cite.\n * \n * These components create semantic HTML with proper structure for:\n * - Featured snippets\n * - AI-generated answers\n * - Voice assistant responses\n * - AI retrieval and citation (Sonor AI Visibility)\n */\n\nimport * as React from 'react'\nimport type { AEOBlockProps, AEOSummaryProps, AEODefinitionProps, AEOClaimProps } from './types'\n\n/**\n * AEOBlock - Generic content block optimized for AI extraction\n * \n * Wraps content with semantic HTML and Sonor data attributes.\n * Use for any content you want AI systems to prioritize.\n * \n * @example\n * ```tsx\n * <AEOBlock type=\"answer\" question=\"What is family law?\" speakable>\n * Family law is the area of legal practice that deals with family-related \n * matters such as divorce, child custody, adoption, and domestic relations.\n * </AEOBlock>\n * ```\n */\nexport function AEOBlock({\n id,\n type,\n question,\n speakable = true,\n entityId,\n children,\n className = '',\n}: AEOBlockProps): React.ReactElement {\n const blockId = id || `aeo-${type}-${Math.random().toString(36).slice(2, 8)}`\n \n const baseClasses = `aeo-block aeo-${type}`\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n // Common data attributes for Sonor AI\n const sonorAttrs = {\n 'data-sonor-ai': type,\n 'data-sonor-block': 'true',\n ...(entityId && { 'data-sonor-entity': entityId }),\n }\n\n // Q&A format for answer type\n if (type === 'answer' && question) {\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n itemScope\n itemType=\"https://schema.org/Question\"\n >\n <h3 itemProp=\"name\" className=\"aeo-question\">\n {question}\n </h3>\n <div \n itemScope \n itemType=\"https://schema.org/Answer\" \n itemProp=\"acceptedAnswer\"\n className=\"aeo-answer\"\n >\n <div itemProp=\"text\">\n {children}\n </div>\n </div>\n </section>\n )\n }\n\n // Definition format\n if (type === 'definition') {\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n >\n {children}\n </section>\n )\n }\n\n // Steps format (numbered list)\n if (type === 'steps') {\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n itemScope\n itemType=\"https://schema.org/HowTo\"\n >\n {children}\n </section>\n )\n }\n\n // Default wrapper\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n >\n {children}\n </section>\n )\n}\n\n/**\n * AEOSummary - Key points summary for AI extraction\n * \n * Creates a scannable list of key points that AI can easily cite.\n * Perfect for \"at a glance\" or \"key takeaways\" sections.\n * \n * @example\n * ```tsx\n * <AEOSummary \n * title=\"Key Points\" \n * points={[\n * \"Family law covers divorce, custody, and adoption\",\n * \"Ohio is an equitable distribution state\",\n * \"Child custody decisions prioritize the child's best interests\"\n * ]} \n * />\n * ```\n */\nexport function AEOSummary({\n title = 'Key Points',\n points,\n speakable = true,\n entityId,\n className = '',\n}: AEOSummaryProps): React.ReactElement {\n const baseClasses = 'aeo-summary'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <div \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"summary\"\n data-sonor-ai=\"summary\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n >\n {title && <h3 className=\"aeo-summary-title\">{title}</h3>}\n <ul className=\"aeo-summary-points\">\n {points.map((point, index) => (\n <li key={index} className=\"aeo-summary-point\">\n {point}\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\n/**\n * AEODefinition - Term definition optimized for featured snippets\n * \n * Creates a clear definition format that works well for\n * \"What is X?\" queries in AI search results.\n * \n * @example\n * ```tsx\n * <AEODefinition \n * term=\"Equitable Distribution\" \n * definition=\"A legal principle used in Ohio divorce cases where marital \n * property is divided fairly, though not necessarily equally, between spouses.\"\n * />\n * ```\n */\nexport function AEODefinition({\n term,\n definition,\n speakable = true,\n entityId,\n source,\n className = '',\n}: AEODefinitionProps): React.ReactElement {\n const baseClasses = 'aeo-definition'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <dl \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"definition\"\n data-sonor-ai=\"definition\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n {...(source && { 'data-sonor-source': source })}\n itemScope\n itemType=\"https://schema.org/DefinedTerm\"\n >\n <dt className=\"aeo-term\" itemProp=\"name\">\n <strong>{term}</strong>\n </dt>\n <dd className=\"aeo-definition-text\" itemProp=\"description\">\n {definition}\n </dd>\n </dl>\n )\n}\n\n/**\n * AEOSteps - How-to steps for featured snippets\n * \n * Creates numbered steps with HowTo schema markup.\n * \n * @example\n * ```tsx\n * <AEOSteps title=\"How to File for Divorce in Ohio\">\n * <AEOStep number={1} name=\"Gather Documents\">\n * Collect financial records, property deeds, and marriage certificate.\n * </AEOStep>\n * <AEOStep number={2} name=\"File Petition\">\n * Submit divorce petition to the county court.\n * </AEOStep>\n * </AEOSteps>\n * ```\n */\nexport function AEOSteps({\n title,\n children,\n speakable = true,\n entityId,\n className = '',\n}: {\n title: string\n children: React.ReactNode\n speakable?: boolean\n entityId?: string\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-steps'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <section \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"steps\"\n data-sonor-ai=\"steps\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n itemScope\n itemType=\"https://schema.org/HowTo\"\n >\n <h3 className=\"aeo-steps-title\" itemProp=\"name\">{title}</h3>\n <ol className=\"aeo-steps-list\">\n {children}\n </ol>\n </section>\n )\n}\n\n/**\n * AEOStep - Individual step within AEOSteps\n */\nexport function AEOStep({\n number,\n name,\n children,\n}: {\n number: number\n name: string\n children: React.ReactNode\n}): React.ReactElement {\n return (\n <li \n className=\"aeo-step\"\n itemScope\n itemType=\"https://schema.org/HowToStep\"\n itemProp=\"step\"\n >\n <span className=\"aeo-step-number\" itemProp=\"position\">{number}</span>\n <strong className=\"aeo-step-name\" itemProp=\"name\">{name}</strong>\n <div className=\"aeo-step-content\" itemProp=\"text\">\n {children}\n </div>\n </li>\n )\n}\n\n/**\n * AEOComparison - Comparison table for AI extraction\n * \n * Creates a structured comparison that AI can understand and cite.\n * \n * @example\n * ```tsx\n * <AEOComparison \n * title=\"Divorce vs. Dissolution in Ohio\"\n * items={[\n * { aspect: 'Agreement', optionA: 'May be contested', optionB: 'Must be agreed upon' },\n * { aspect: 'Timeline', optionA: '6-12 months', optionB: '30-90 days' },\n * ]}\n * labelA=\"Divorce\"\n * labelB=\"Dissolution\"\n * />\n * ```\n */\nexport function AEOComparison({\n title,\n items,\n labelA,\n labelB,\n speakable = true,\n entityId,\n className = '',\n}: {\n title: string\n items: Array<{ aspect: string; optionA: string; optionB: string }>\n labelA: string\n labelB: string\n speakable?: boolean\n entityId?: string\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-comparison'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <section \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"comparison\"\n data-sonor-ai=\"comparison\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n >\n <h3 className=\"aeo-comparison-title\">{title}</h3>\n <table className=\"aeo-comparison-table\">\n <thead>\n <tr>\n <th>Aspect</th>\n <th>{labelA}</th>\n <th>{labelB}</th>\n </tr>\n </thead>\n <tbody>\n {items.map((item, index) => (\n <tr key={index}>\n <td className=\"aeo-comparison-aspect\">{item.aspect}</td>\n <td className=\"aeo-comparison-a\">{item.optionA}</td>\n <td className=\"aeo-comparison-b\">{item.optionB}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </section>\n )\n}\n\n/**\n * AEOClaim - AI-Verifiable Claim with Provenance\n * \n * Wraps factual claims with machine-readable source and confidence data.\n * LLMs prioritize verifiable facts with clear provenance.\n * \n * @example\n * ```tsx\n * <AEOClaim \n * source=\"KRS 281A.170\" \n * sourceUrl=\"https://apps.legislature.ky.gov/law/statutes/statute.aspx?id=6398\"\n * confidence={0.95}\n * claimType=\"statute\"\n * >\n * A CDL suspension is triggered at 26 MPH over the limit.\n * </AEOClaim>\n * ```\n */\nexport function AEOClaim({\n source,\n sourceUrl,\n confidence = 1.0,\n claimType = 'fact',\n retrievedAt,\n children,\n className = '',\n}: AEOClaimProps): React.ReactElement {\n const baseClasses = 'aeo-claim'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <span \n className={combinedClasses}\n data-sonor-claim=\"true\"\n data-sonor-source={source}\n {...(sourceUrl && { 'data-sonor-source-url': sourceUrl })}\n data-sonor-confidence={confidence.toString()}\n data-sonor-claim-type={claimType}\n {...(retrievedAt && { 'data-sonor-retrieved': retrievedAt })}\n itemScope\n itemType=\"https://schema.org/Claim\"\n >\n <span itemProp=\"text\">{children}</span>\n {sourceUrl ? (\n <meta itemProp=\"citation\" content={sourceUrl} />\n ) : (\n <meta itemProp=\"citation\" content={source} />\n )}\n </span>\n )\n}\n\n/**\n * AEOEntity - Inline entity annotation\n * \n * Wraps entity mentions with machine-readable entity IDs for knowledge graph linking.\n * \n * @example\n * ```tsx\n * <AEOEntity entityId=\"person-123\" entityType=\"person\" name=\"Shannon Sexton\">\n * Attorney Shannon Sexton\n * </AEOEntity> handles CDL defense cases.\n * ```\n */\nexport function AEOEntity({\n entityId,\n entityType,\n name,\n url,\n children,\n className = '',\n}: {\n entityId: string\n entityType: 'organization' | 'person' | 'service' | 'product' | 'location' | 'concept' | 'credential'\n name: string\n url?: string\n children: React.ReactNode\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-entity'\n const combinedClasses = className ? `${baseClasses} aeo-entity-${entityType} ${className}` : `${baseClasses} aeo-entity-${entityType}`\n\n return (\n <span \n className={combinedClasses}\n data-sonor-entity={entityId}\n data-sonor-entity-type={entityType}\n data-sonor-entity-name={name}\n {...(url && { 'data-sonor-entity-url': url })}\n itemScope\n itemType={`https://schema.org/${entityType === 'organization' ? 'Organization' : entityType === 'person' ? 'Person' : entityType === 'location' ? 'Place' : 'Thing'}`}\n >\n <span itemProp=\"name\">{children}</span>\n {url && <link itemProp=\"url\" href={url} />}\n </span>\n )\n}\n\n// ============================================\n// Content Provenance Components\n// ============================================\n\n/**\n * AEOProvenanceList - Display sources/citations for content\n * \n * Shows a list of provenance sources with machine-readable attributes.\n * LLMs use this to verify claims and assess source quality.\n * \n * @example\n * ```tsx\n * <AEOProvenanceList \n * title=\"Sources\"\n * sources={[\n * { id: '1', source_type: 'legal_statute', title: 'KRS 281A.170', url: '...' },\n * { id: '2', source_type: 'news_article', title: 'CDL News', publisher: 'Transport Weekly' }\n * ]}\n * />\n * ```\n */\nexport function AEOProvenanceList({\n sources,\n title = 'Sources & References',\n className = '',\n}: {\n sources: Array<{\n id: string\n source_type: 'press_release' | 'news_article' | 'legal_statute' | 'research_paper' | 'official_document' | 'internal' | 'citation'\n title: string\n url?: string\n publisher?: string\n published_at?: string\n accessed_at?: string\n excerpt?: string\n confidence?: number\n identifier?: string\n }>\n title?: string\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-provenance-list'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n const getSchemaType = (sourceType: string): string => {\n switch (sourceType) {\n case 'legal_statute':\n return 'https://schema.org/Legislation'\n case 'research_paper':\n return 'https://schema.org/ScholarlyArticle'\n case 'news_article':\n return 'https://schema.org/NewsArticle'\n case 'press_release':\n return 'https://schema.org/NewsArticle'\n default:\n return 'https://schema.org/CreativeWork'\n }\n }\n\n return (\n <aside \n className={combinedClasses}\n data-sonor-provenance=\"list\"\n data-sonor-source-count={sources.length.toString()}\n itemScope\n itemType=\"https://schema.org/ItemList\"\n >\n <h4 className=\"aeo-provenance-title\" itemProp=\"name\">{title}</h4>\n <ol className=\"aeo-provenance-sources\">\n {sources.map((source, index) => (\n <li \n key={source.id}\n className=\"aeo-provenance-item\"\n data-sonor-source-id={source.id}\n data-sonor-source-type={source.source_type}\n {...(source.confidence && { 'data-sonor-confidence': source.confidence.toString() })}\n itemScope\n itemType={getSchemaType(source.source_type)}\n itemProp=\"itemListElement\"\n >\n <span className=\"aeo-provenance-number\">[{index + 1}]</span>\n {source.url ? (\n <a \n href={source.url} \n className=\"aeo-provenance-link\"\n itemProp=\"url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <span itemProp=\"name\">{source.title}</span>\n </a>\n ) : (\n <span itemProp=\"name\">{source.title}</span>\n )}\n {source.publisher && (\n <span className=\"aeo-provenance-publisher\" itemProp=\"publisher\">\n — {source.publisher}\n </span>\n )}\n {source.published_at && (\n <time \n className=\"aeo-provenance-date\" \n itemProp=\"datePublished\"\n dateTime={source.published_at}\n >\n ({new Date(source.published_at).toLocaleDateString()})\n </time>\n )}\n {source.identifier && (\n <span className=\"aeo-provenance-identifier\" data-sonor-identifier={source.identifier}>\n {source.identifier}\n </span>\n )}\n {source.excerpt && (\n <blockquote className=\"aeo-provenance-excerpt\" itemProp=\"description\">\n {source.excerpt}\n </blockquote>\n )}\n </li>\n ))}\n </ol>\n </aside>\n )\n}\n\n/**\n * AEOCitedContent - Content with inline citations linked to sources\n * \n * Wraps content that contains numbered citations [1], [2] etc., and links them\n * to a list of provenance sources for AI verification.\n * \n * @example\n * ```tsx\n * <AEOCitedContent \n * sources={[\n * { id: '1', source_type: 'legal_statute', title: 'KRS 281A.170' },\n * { id: '2', source_type: 'news_article', title: 'FMCSA Guidelines 2024' }\n * ]}\n * showSourcesList={true}\n * >\n * <p>Kentucky law requires CDL holders to report violations within 30 days [1]. \n * Federal guidelines add additional requirements [2].</p>\n * </AEOCitedContent>\n * ```\n */\nexport function AEOCitedContent({\n children,\n sources,\n showSourcesList = true,\n className = '',\n}: {\n children: React.ReactNode\n sources: Array<{\n id: string\n source_type: 'press_release' | 'news_article' | 'legal_statute' | 'research_paper' | 'official_document' | 'internal' | 'citation'\n title: string\n url?: string\n publisher?: string\n published_at?: string\n accessed_at?: string\n excerpt?: string\n confidence?: number\n identifier?: string\n }>\n showSourcesList?: boolean\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-cited-content'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <section \n className={combinedClasses}\n data-sonor-ai=\"cited-content\"\n data-sonor-provenance=\"inline\"\n data-sonor-source-count={sources.length.toString()}\n >\n <div className=\"aeo-cited-body\">\n {children}\n </div>\n {showSourcesList && sources.length > 0 && (\n <AEOProvenanceList sources={sources} title=\"References\" />\n )}\n </section>\n )\n}\n\nexport default AEOBlock\n","/**\n * @sonordev/site-kit/llms - On-demand Revalidation\n *\n * Provides a route handler that Portal can call when llms-relevant data changes\n * (page summaries, FAQs, services, etc.) to bust the Next.js ISR cache.\n *\n * @example\n * ```ts\n * // app/api/revalidate-llms/route.ts\n * import { createLlmsRevalidateHandler } from '@sonordev/site-kit/llms'\n *\n * export const POST = createLlmsRevalidateHandler(process.env.REVALIDATION_SECRET!)\n * ```\n */\n\ntype RevalidatePathFn = (path: string, type?: 'page' | 'layout') => void\n\n/**\n * Create a POST handler that revalidates /llms.txt and /llms-full.txt caches.\n * Protected by a shared secret.\n */\nexport function createLlmsRevalidateHandler(\n secret: string,\n options?: {\n /** Additional paths to revalidate alongside llms files */\n extraPaths?: string[]\n /** Custom revalidatePath (for testing or frameworks other than Next.js) */\n revalidatePath?: RevalidatePathFn\n },\n): (request: Request) => Promise<Response> {\n return async function POST(request: Request): Promise<Response> {\n try {\n // Validate secret from Authorization header or query param\n const authHeader = request.headers.get('authorization')\n const url = new URL(request.url)\n const tokenFromQuery = url.searchParams.get('secret')\n const token = authHeader?.replace(/^Bearer\\s+/i, '') || tokenFromQuery\n\n if (!secret || token !== secret) {\n return new Response(JSON.stringify({ error: 'Invalid secret' }), {\n status: 401,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n\n // Import Next.js revalidatePath (dynamic to avoid hard dep for non-Next consumers)\n let revalidatePath: RevalidatePathFn\n if (options?.revalidatePath) {\n revalidatePath = options.revalidatePath\n } else {\n const nextCache = await import('next/cache')\n revalidatePath = nextCache.revalidatePath\n }\n\n const paths = ['/llms.txt', '/llms-full.txt', ...(options?.extraPaths || [])]\n for (const p of paths) {\n revalidatePath(p)\n }\n\n return new Response(\n JSON.stringify({ revalidated: true, paths }),\n {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n },\n )\n } catch (err) {\n console.error('[site-kit/llms] Revalidation failed:', err)\n return new Response(\n JSON.stringify({ error: 'Revalidation failed' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } },\n )\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/llms/handlers.ts","../../src/llms/SpeakableSchema.tsx","../../src/llms/AEOComponents.tsx","../../src/llms/revalidate.ts"],"names":["markdown","jsx"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @sonordev/site-kit/llms - Next.js Route Handlers\n * \n * Ready-to-use route handlers for /llms.txt and /llms-full.txt\n */\n\nimport { createHash } from 'crypto'\nimport { existsSync, readFileSync } from 'fs'\nimport { join } from 'path'\nimport { generateLLMsTxt, generateLLMsFullTxt } from './generateLLMsTxt'\nimport type { GenerateLLMSTxtOptions } from './types'\n\nfunction weakEtag(body: string): string {\n const h = createHash('sha1').update(body, 'utf8').digest('base64url')\n return `W/\"${h}\"`\n}\n\n/** Cache + validation headers for plain-text llms responses (dynamic or static). */\nexport function llmsResponseHeaders(body: string, extra?: Record<string, string>): HeadersInit {\n return {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Cache-Control':\n 'public, max-age=300, s-maxage=3600, stale-while-revalidate=86400, stale-if-error=86400',\n ETag: weakEtag(body),\n Vary: 'Accept-Encoding',\n ...extra,\n }\n}\n\nexport interface LLMsTxtHandlerOptions extends GenerateLLMSTxtOptions {\n /** When true, serve static public/llms.txt if it exists (default: true for build-time flow) */\n preferStatic?: boolean\n}\n\n/**\n * Create a route handler for /llms.txt\n *\n * Zero-config by default - uses SONOR_API_KEY from environment.\n *\n * The returned handler never reads the incoming Request: any access to\n * `request.headers` (etc.) opts the whole route into dynamic rendering, which\n * breaks static prerendering of /llms.txt during `next build` and logs\n * \"Dynamic server usage\" errors on every consumer site. Conditional-request\n * (ETag/304) handling is left to the Next static layer / CDN, which already\n * does it for prerendered responses.\n *\n * @example\n * ```ts\n * // app/llms.txt/route.ts (zero-config)\n * import { createLLMsTxtHandler } from '@sonordev/site-kit/llms'\n *\n * export const GET = createLLMsTxtHandler()\n * // Next 15+: GET route handlers are dynamic by default; opt into\n * // prerendering so the file is served statically from the CDN:\n * export const revalidate = 3600\n * ```\n *\n * @example\n * ```ts\n * // With preferStatic: serve build-time file if exists\n * export const GET = createLLMsTxtHandler({\n * preferStatic: true,\n * includeServices: false\n * })\n * ```\n */\nexport function createLLMsTxtHandler(\n options: LLMsTxtHandlerOptions = {}\n): (request?: Request) => Promise<Response> {\n const { preferStatic = true, ...generateOptions } = options\n\n return async function GET(_request?: Request): Promise<Response> {\n try {\n // Serve static file if available (build-time optimized)\n if (preferStatic) {\n const staticPath = join(process.cwd(), 'public', 'llms.txt')\n if (existsSync(staticPath)) {\n const markdown = readFileSync(staticPath, 'utf-8')\n return new Response(markdown, {\n status: 200,\n headers: llmsResponseHeaders(markdown, { 'X-Sections': 'static' }),\n })\n }\n }\n\n const { markdown, metadata } = await generateLLMsTxt(generateOptions)\n return new Response(markdown, {\n status: 200,\n headers: llmsResponseHeaders(markdown, {\n 'X-Generated-At': metadata.generated_at,\n 'X-Sections': metadata.sections.join(','),\n }),\n })\n } catch (error) {\n console.error('@sonordev/llms: Error generating llms.txt:', error)\n return new Response('# Error\\n\\nUnable to generate llms.txt content.', {\n status: 500,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Cache-Control': 'no-store',\n },\n })\n }\n }\n}\n\n/**\n * Create a route handler for /llms-full.txt\n *\n * Zero-config by default - uses SONOR_API_KEY from environment.\n *\n * Like createLLMsTxtHandler, the returned handler never reads the incoming\n * Request so the route stays statically prerenderable.\n *\n * @example\n * ```ts\n * // app/llms-full.txt/route.ts (zero-config)\n * import { createLLMsFullTxtHandler } from '@sonordev/site-kit/llms'\n *\n * export const GET = createLLMsFullTxtHandler()\n * export const revalidate = 3600\n * ```\n */\nexport function createLLMsFullTxtHandler(\n options: LLMsTxtHandlerOptions = {}\n): (request?: Request) => Promise<Response> {\n const { preferStatic = true, ...generateOptions } = options\n\n return async function GET(_request?: Request): Promise<Response> {\n try {\n // Serve static file if available (build-time optimized)\n if (preferStatic) {\n const staticPath = join(process.cwd(), 'public', 'llms-full.txt')\n if (existsSync(staticPath)) {\n const markdown = readFileSync(staticPath, 'utf-8')\n return new Response(markdown, {\n status: 200,\n headers: llmsResponseHeaders(markdown, { 'X-Sections': 'static' }),\n })\n }\n }\n\n const { markdown, metadata } = await generateLLMsFullTxt(generateOptions)\n return new Response(markdown, {\n status: 200,\n headers: llmsResponseHeaders(markdown, {\n 'X-Generated-At': metadata.generated_at,\n 'X-Sections': metadata.sections.join(','),\n }),\n })\n } catch (error) {\n console.error('@sonordev/llms: Error generating llms-full.txt:', error)\n return new Response('# Error\\n\\nUnable to generate llms-full.txt content.', {\n status: 500,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Cache-Control': 'no-store',\n },\n })\n }\n }\n}\n","/**\n * @sonordev/site-kit/llms - Speakable Schema Generator\n * \n * Generates JSON-LD with SpeakableSpecification for voice assistant\n * and AI system content extraction.\n * \n * @see https://schema.org/speakable\n * @see https://developers.google.com/search/docs/appearance/structured-data/speakable\n */\n\nimport * as React from 'react'\nimport type { SpeakableSchemaProps, SpeakableConfig } from './types'\nimport { safeJsonLd } from '../seo/safeJsonLd'\n\n/**\n * Generate a WebPage or Article schema with speakable specification\n * \n * @example\n * ```tsx\n * // In a page component\n * <SpeakableSchema\n * type=\"Article\"\n * name=\"Family Law Services in Cincinnati\"\n * url=\"https://heinrichlaw.com/family-law\"\n * speakable={{\n * cssSelectors: ['.page-summary', '.key-points', 'h1']\n * }}\n * />\n * ```\n */\nexport function SpeakableSchema({\n type,\n name,\n url,\n speakable,\n additionalProperties = {},\n}: SpeakableSchemaProps): React.ReactElement {\n const schema = createSpeakableSchema(type, name, url, speakable, additionalProperties)\n \n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{\n __html: safeJsonLd(schema),\n }}\n />\n )\n}\n\n/**\n * Create speakable schema object (for manual use or testing)\n */\nexport function createSpeakableSchema(\n type: 'Article' | 'WebPage',\n name: string,\n url: string,\n speakable: SpeakableConfig,\n additionalProperties: Record<string, unknown> = {}\n): Record<string, unknown> {\n const speakableSpec: Record<string, unknown> = {\n '@type': 'SpeakableSpecification',\n }\n\n // Prefer CSS selectors, fall back to XPath\n if (speakable.cssSelectors?.length) {\n speakableSpec.cssSelector = speakable.cssSelectors\n } else if (speakable.xPaths?.length) {\n speakableSpec.xpath = speakable.xPaths\n } else {\n // Default speakable selectors for common patterns\n speakableSpec.cssSelector = [\n 'h1',\n '[data-speakable]',\n '.page-summary',\n '.key-points',\n 'meta[name=\"description\"]'\n ]\n }\n\n return {\n '@context': 'https://schema.org',\n '@type': type,\n name,\n url,\n speakable: speakableSpec,\n ...additionalProperties,\n }\n}\n\n/**\n * Default speakable CSS selectors for common page elements\n */\nexport const DEFAULT_SPEAKABLE_SELECTORS = {\n /** Standard page elements */\n page: ['h1', 'meta[name=\"description\"]', '.page-summary'],\n /** Article/blog post elements */\n article: ['h1', '.article-summary', '.article-intro', 'meta[name=\"description\"]'],\n /** Service page elements */\n service: ['h1', '.service-overview', '.key-benefits', 'meta[name=\"description\"]'],\n /** FAQ page elements */\n faq: ['h1', '.faq-intro', '.faq-item'],\n /** Contact page elements */\n contact: ['h1', '.contact-intro', '.business-hours', '.contact-info'],\n}\n\n/**\n * Get recommended speakable selectors for a page type\n */\nexport function getSpeakableSelectorsForPage(\n pageType: 'page' | 'article' | 'service' | 'faq' | 'contact'\n): string[] {\n return DEFAULT_SPEAKABLE_SELECTORS[pageType] || DEFAULT_SPEAKABLE_SELECTORS.page\n}\n\nexport default SpeakableSchema\n","/**\n * @sonordev/site-kit/llms - AEO Components\n * \n * Answer Engine Optimization (AEO) components for structuring content\n * in a way that AI systems can easily extract and cite.\n * \n * These components create semantic HTML with proper structure for:\n * - Featured snippets\n * - AI-generated answers\n * - Voice assistant responses\n * - AI retrieval and citation (Sonor AI Visibility)\n */\n\nimport * as React from 'react'\nimport type { AEOBlockProps, AEOSummaryProps, AEODefinitionProps, AEOClaimProps } from './types'\n\n/**\n * AEOBlock - Generic content block optimized for AI extraction\n * \n * Wraps content with semantic HTML and Sonor data attributes.\n * Use for any content you want AI systems to prioritize.\n * \n * @example\n * ```tsx\n * <AEOBlock type=\"answer\" question=\"What is family law?\" speakable>\n * Family law is the area of legal practice that deals with family-related \n * matters such as divorce, child custody, adoption, and domestic relations.\n * </AEOBlock>\n * ```\n */\nexport function AEOBlock({\n id,\n type,\n question,\n speakable = true,\n entityId,\n children,\n className = '',\n}: AEOBlockProps): React.ReactElement {\n const blockId = id || `aeo-${type}-${Math.random().toString(36).slice(2, 8)}`\n \n const baseClasses = `aeo-block aeo-${type}`\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n // Common data attributes for Sonor AI\n const sonorAttrs = {\n 'data-sonor-ai': type,\n 'data-sonor-block': 'true',\n ...(entityId && { 'data-sonor-entity': entityId }),\n }\n\n // Q&A format for answer type\n if (type === 'answer' && question) {\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n itemScope\n itemType=\"https://schema.org/Question\"\n >\n <h3 itemProp=\"name\" className=\"aeo-question\">\n {question}\n </h3>\n <div \n itemScope \n itemType=\"https://schema.org/Answer\" \n itemProp=\"acceptedAnswer\"\n className=\"aeo-answer\"\n >\n <div itemProp=\"text\">\n {children}\n </div>\n </div>\n </section>\n )\n }\n\n // Definition format\n if (type === 'definition') {\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n >\n {children}\n </section>\n )\n }\n\n // Steps format (numbered list)\n if (type === 'steps') {\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n itemScope\n itemType=\"https://schema.org/HowTo\"\n >\n {children}\n </section>\n )\n }\n\n // Default wrapper\n return (\n <section \n id={blockId}\n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type={type}\n {...sonorAttrs}\n >\n {children}\n </section>\n )\n}\n\n/**\n * AEOSummary - Key points summary for AI extraction\n * \n * Creates a scannable list of key points that AI can easily cite.\n * Perfect for \"at a glance\" or \"key takeaways\" sections.\n * \n * @example\n * ```tsx\n * <AEOSummary \n * title=\"Key Points\" \n * points={[\n * \"Family law covers divorce, custody, and adoption\",\n * \"Ohio is an equitable distribution state\",\n * \"Child custody decisions prioritize the child's best interests\"\n * ]} \n * />\n * ```\n */\nexport function AEOSummary({\n title = 'Key Points',\n points,\n speakable = true,\n entityId,\n className = '',\n}: AEOSummaryProps): React.ReactElement {\n const baseClasses = 'aeo-summary'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <div \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"summary\"\n data-sonor-ai=\"summary\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n >\n {title && <h3 className=\"aeo-summary-title\">{title}</h3>}\n <ul className=\"aeo-summary-points\">\n {points.map((point, index) => (\n <li key={index} className=\"aeo-summary-point\">\n {point}\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\n/**\n * AEODefinition - Term definition optimized for featured snippets\n * \n * Creates a clear definition format that works well for\n * \"What is X?\" queries in AI search results.\n * \n * @example\n * ```tsx\n * <AEODefinition \n * term=\"Equitable Distribution\" \n * definition=\"A legal principle used in Ohio divorce cases where marital \n * property is divided fairly, though not necessarily equally, between spouses.\"\n * />\n * ```\n */\nexport function AEODefinition({\n term,\n definition,\n speakable = true,\n entityId,\n source,\n className = '',\n}: AEODefinitionProps): React.ReactElement {\n const baseClasses = 'aeo-definition'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <dl \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"definition\"\n data-sonor-ai=\"definition\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n {...(source && { 'data-sonor-source': source })}\n itemScope\n itemType=\"https://schema.org/DefinedTerm\"\n >\n <dt className=\"aeo-term\" itemProp=\"name\">\n <strong>{term}</strong>\n </dt>\n <dd className=\"aeo-definition-text\" itemProp=\"description\">\n {definition}\n </dd>\n </dl>\n )\n}\n\n/**\n * AEOSteps - How-to steps for featured snippets\n * \n * Creates numbered steps with HowTo schema markup.\n * \n * @example\n * ```tsx\n * <AEOSteps title=\"How to File for Divorce in Ohio\">\n * <AEOStep number={1} name=\"Gather Documents\">\n * Collect financial records, property deeds, and marriage certificate.\n * </AEOStep>\n * <AEOStep number={2} name=\"File Petition\">\n * Submit divorce petition to the county court.\n * </AEOStep>\n * </AEOSteps>\n * ```\n */\nexport function AEOSteps({\n title,\n children,\n speakable = true,\n entityId,\n className = '',\n}: {\n title: string\n children: React.ReactNode\n speakable?: boolean\n entityId?: string\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-steps'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <section \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"steps\"\n data-sonor-ai=\"steps\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n itemScope\n itemType=\"https://schema.org/HowTo\"\n >\n <h3 className=\"aeo-steps-title\" itemProp=\"name\">{title}</h3>\n <ol className=\"aeo-steps-list\">\n {children}\n </ol>\n </section>\n )\n}\n\n/**\n * AEOStep - Individual step within AEOSteps\n */\nexport function AEOStep({\n number,\n name,\n children,\n}: {\n number: number\n name: string\n children: React.ReactNode\n}): React.ReactElement {\n return (\n <li \n className=\"aeo-step\"\n itemScope\n itemType=\"https://schema.org/HowToStep\"\n itemProp=\"step\"\n >\n <span className=\"aeo-step-number\" itemProp=\"position\">{number}</span>\n <strong className=\"aeo-step-name\" itemProp=\"name\">{name}</strong>\n <div className=\"aeo-step-content\" itemProp=\"text\">\n {children}\n </div>\n </li>\n )\n}\n\n/**\n * AEOComparison - Comparison table for AI extraction\n * \n * Creates a structured comparison that AI can understand and cite.\n * \n * @example\n * ```tsx\n * <AEOComparison \n * title=\"Divorce vs. Dissolution in Ohio\"\n * items={[\n * { aspect: 'Agreement', optionA: 'May be contested', optionB: 'Must be agreed upon' },\n * { aspect: 'Timeline', optionA: '6-12 months', optionB: '30-90 days' },\n * ]}\n * labelA=\"Divorce\"\n * labelB=\"Dissolution\"\n * />\n * ```\n */\nexport function AEOComparison({\n title,\n items,\n labelA,\n labelB,\n speakable = true,\n entityId,\n className = '',\n}: {\n title: string\n items: Array<{ aspect: string; optionA: string; optionB: string }>\n labelA: string\n labelB: string\n speakable?: boolean\n entityId?: string\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-comparison'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <section \n className={combinedClasses}\n data-speakable={speakable ? 'true' : undefined}\n data-aeo-type=\"comparison\"\n data-sonor-ai=\"comparison\"\n data-sonor-block=\"true\"\n {...(entityId && { 'data-sonor-entity': entityId })}\n >\n <h3 className=\"aeo-comparison-title\">{title}</h3>\n <table className=\"aeo-comparison-table\">\n <thead>\n <tr>\n <th>Aspect</th>\n <th>{labelA}</th>\n <th>{labelB}</th>\n </tr>\n </thead>\n <tbody>\n {items.map((item, index) => (\n <tr key={index}>\n <td className=\"aeo-comparison-aspect\">{item.aspect}</td>\n <td className=\"aeo-comparison-a\">{item.optionA}</td>\n <td className=\"aeo-comparison-b\">{item.optionB}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </section>\n )\n}\n\n/**\n * AEOClaim - AI-Verifiable Claim with Provenance\n * \n * Wraps factual claims with machine-readable source and confidence data.\n * LLMs prioritize verifiable facts with clear provenance.\n * \n * @example\n * ```tsx\n * <AEOClaim \n * source=\"KRS 281A.170\" \n * sourceUrl=\"https://apps.legislature.ky.gov/law/statutes/statute.aspx?id=6398\"\n * confidence={0.95}\n * claimType=\"statute\"\n * >\n * A CDL suspension is triggered at 26 MPH over the limit.\n * </AEOClaim>\n * ```\n */\nexport function AEOClaim({\n source,\n sourceUrl,\n confidence = 1.0,\n claimType = 'fact',\n retrievedAt,\n children,\n className = '',\n}: AEOClaimProps): React.ReactElement {\n const baseClasses = 'aeo-claim'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <span \n className={combinedClasses}\n data-sonor-claim=\"true\"\n data-sonor-source={source}\n {...(sourceUrl && { 'data-sonor-source-url': sourceUrl })}\n data-sonor-confidence={confidence.toString()}\n data-sonor-claim-type={claimType}\n {...(retrievedAt && { 'data-sonor-retrieved': retrievedAt })}\n itemScope\n itemType=\"https://schema.org/Claim\"\n >\n <span itemProp=\"text\">{children}</span>\n {sourceUrl ? (\n <meta itemProp=\"citation\" content={sourceUrl} />\n ) : (\n <meta itemProp=\"citation\" content={source} />\n )}\n </span>\n )\n}\n\n/**\n * AEOEntity - Inline entity annotation\n * \n * Wraps entity mentions with machine-readable entity IDs for knowledge graph linking.\n * \n * @example\n * ```tsx\n * <AEOEntity entityId=\"person-123\" entityType=\"person\" name=\"Shannon Sexton\">\n * Attorney Shannon Sexton\n * </AEOEntity> handles CDL defense cases.\n * ```\n */\nexport function AEOEntity({\n entityId,\n entityType,\n name,\n url,\n children,\n className = '',\n}: {\n entityId: string\n entityType: 'organization' | 'person' | 'service' | 'product' | 'location' | 'concept' | 'credential'\n name: string\n url?: string\n children: React.ReactNode\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-entity'\n const combinedClasses = className ? `${baseClasses} aeo-entity-${entityType} ${className}` : `${baseClasses} aeo-entity-${entityType}`\n\n return (\n <span \n className={combinedClasses}\n data-sonor-entity={entityId}\n data-sonor-entity-type={entityType}\n data-sonor-entity-name={name}\n {...(url && { 'data-sonor-entity-url': url })}\n itemScope\n itemType={`https://schema.org/${entityType === 'organization' ? 'Organization' : entityType === 'person' ? 'Person' : entityType === 'location' ? 'Place' : 'Thing'}`}\n >\n <span itemProp=\"name\">{children}</span>\n {url && <link itemProp=\"url\" href={url} />}\n </span>\n )\n}\n\n// ============================================\n// Content Provenance Components\n// ============================================\n\n/**\n * AEOProvenanceList - Display sources/citations for content\n * \n * Shows a list of provenance sources with machine-readable attributes.\n * LLMs use this to verify claims and assess source quality.\n * \n * @example\n * ```tsx\n * <AEOProvenanceList \n * title=\"Sources\"\n * sources={[\n * { id: '1', source_type: 'legal_statute', title: 'KRS 281A.170', url: '...' },\n * { id: '2', source_type: 'news_article', title: 'CDL News', publisher: 'Transport Weekly' }\n * ]}\n * />\n * ```\n */\nexport function AEOProvenanceList({\n sources,\n title = 'Sources & References',\n className = '',\n}: {\n sources: Array<{\n id: string\n source_type: 'press_release' | 'news_article' | 'legal_statute' | 'research_paper' | 'official_document' | 'internal' | 'citation'\n title: string\n url?: string\n publisher?: string\n published_at?: string\n accessed_at?: string\n excerpt?: string\n confidence?: number\n identifier?: string\n }>\n title?: string\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-provenance-list'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n const getSchemaType = (sourceType: string): string => {\n switch (sourceType) {\n case 'legal_statute':\n return 'https://schema.org/Legislation'\n case 'research_paper':\n return 'https://schema.org/ScholarlyArticle'\n case 'news_article':\n return 'https://schema.org/NewsArticle'\n case 'press_release':\n return 'https://schema.org/NewsArticle'\n default:\n return 'https://schema.org/CreativeWork'\n }\n }\n\n return (\n <aside \n className={combinedClasses}\n data-sonor-provenance=\"list\"\n data-sonor-source-count={sources.length.toString()}\n itemScope\n itemType=\"https://schema.org/ItemList\"\n >\n <h4 className=\"aeo-provenance-title\" itemProp=\"name\">{title}</h4>\n <ol className=\"aeo-provenance-sources\">\n {sources.map((source, index) => (\n <li \n key={source.id}\n className=\"aeo-provenance-item\"\n data-sonor-source-id={source.id}\n data-sonor-source-type={source.source_type}\n {...(source.confidence && { 'data-sonor-confidence': source.confidence.toString() })}\n itemScope\n itemType={getSchemaType(source.source_type)}\n itemProp=\"itemListElement\"\n >\n <span className=\"aeo-provenance-number\">[{index + 1}]</span>\n {source.url ? (\n <a \n href={source.url} \n className=\"aeo-provenance-link\"\n itemProp=\"url\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <span itemProp=\"name\">{source.title}</span>\n </a>\n ) : (\n <span itemProp=\"name\">{source.title}</span>\n )}\n {source.publisher && (\n <span className=\"aeo-provenance-publisher\" itemProp=\"publisher\">\n — {source.publisher}\n </span>\n )}\n {source.published_at && (\n <time \n className=\"aeo-provenance-date\" \n itemProp=\"datePublished\"\n dateTime={source.published_at}\n >\n ({new Date(source.published_at).toLocaleDateString()})\n </time>\n )}\n {source.identifier && (\n <span className=\"aeo-provenance-identifier\" data-sonor-identifier={source.identifier}>\n {source.identifier}\n </span>\n )}\n {source.excerpt && (\n <blockquote className=\"aeo-provenance-excerpt\" itemProp=\"description\">\n {source.excerpt}\n </blockquote>\n )}\n </li>\n ))}\n </ol>\n </aside>\n )\n}\n\n/**\n * AEOCitedContent - Content with inline citations linked to sources\n * \n * Wraps content that contains numbered citations [1], [2] etc., and links them\n * to a list of provenance sources for AI verification.\n * \n * @example\n * ```tsx\n * <AEOCitedContent \n * sources={[\n * { id: '1', source_type: 'legal_statute', title: 'KRS 281A.170' },\n * { id: '2', source_type: 'news_article', title: 'FMCSA Guidelines 2024' }\n * ]}\n * showSourcesList={true}\n * >\n * <p>Kentucky law requires CDL holders to report violations within 30 days [1]. \n * Federal guidelines add additional requirements [2].</p>\n * </AEOCitedContent>\n * ```\n */\nexport function AEOCitedContent({\n children,\n sources,\n showSourcesList = true,\n className = '',\n}: {\n children: React.ReactNode\n sources: Array<{\n id: string\n source_type: 'press_release' | 'news_article' | 'legal_statute' | 'research_paper' | 'official_document' | 'internal' | 'citation'\n title: string\n url?: string\n publisher?: string\n published_at?: string\n accessed_at?: string\n excerpt?: string\n confidence?: number\n identifier?: string\n }>\n showSourcesList?: boolean\n className?: string\n}): React.ReactElement {\n const baseClasses = 'aeo-cited-content'\n const combinedClasses = className ? `${baseClasses} ${className}` : baseClasses\n\n return (\n <section \n className={combinedClasses}\n data-sonor-ai=\"cited-content\"\n data-sonor-provenance=\"inline\"\n data-sonor-source-count={sources.length.toString()}\n >\n <div className=\"aeo-cited-body\">\n {children}\n </div>\n {showSourcesList && sources.length > 0 && (\n <AEOProvenanceList sources={sources} title=\"References\" />\n )}\n </section>\n )\n}\n\nexport default AEOBlock\n","/**\n * @sonordev/site-kit/llms - On-demand Revalidation\n *\n * Provides a route handler that Portal can call when llms-relevant data changes\n * (page summaries, FAQs, services, etc.) to bust the Next.js ISR cache.\n *\n * @example\n * ```ts\n * // app/api/revalidate-llms/route.ts\n * import { createLlmsRevalidateHandler } from '@sonordev/site-kit/llms'\n *\n * export const POST = createLlmsRevalidateHandler(process.env.REVALIDATION_SECRET!)\n * ```\n */\n\ntype RevalidatePathFn = (path: string, type?: 'page' | 'layout') => void\n\n/**\n * Create a POST handler that revalidates /llms.txt and /llms-full.txt caches.\n * Protected by a shared secret.\n */\nexport function createLlmsRevalidateHandler(\n secret: string,\n options?: {\n /** Additional paths to revalidate alongside llms files */\n extraPaths?: string[]\n /** Custom revalidatePath (for testing or frameworks other than Next.js) */\n revalidatePath?: RevalidatePathFn\n },\n): (request: Request) => Promise<Response> {\n return async function POST(request: Request): Promise<Response> {\n try {\n // Validate secret from Authorization header or query param\n const authHeader = request.headers.get('authorization')\n const url = new URL(request.url)\n const tokenFromQuery = url.searchParams.get('secret')\n const token = authHeader?.replace(/^Bearer\\s+/i, '') || tokenFromQuery\n\n if (!secret || token !== secret) {\n return new Response(JSON.stringify({ error: 'Invalid secret' }), {\n status: 401,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n\n // Import Next.js revalidatePath (dynamic to avoid hard dep for non-Next consumers)\n let revalidatePath: RevalidatePathFn\n if (options?.revalidatePath) {\n revalidatePath = options.revalidatePath\n } else {\n const nextCache = await import('next/cache')\n revalidatePath = nextCache.revalidatePath\n }\n\n const paths = ['/llms.txt', '/llms-full.txt', ...(options?.extraPaths || [])]\n for (const p of paths) {\n revalidatePath(p)\n }\n\n return new Response(\n JSON.stringify({ revalidated: true, paths }),\n {\n status: 200,\n headers: { 'Content-Type': 'application/json' },\n },\n )\n } catch (err) {\n console.error('[site-kit/llms] Revalidation failed:', err)\n return new Response(\n JSON.stringify({ error: 'Revalidation failed' }),\n { status: 500, headers: { 'Content-Type': 'application/json' } },\n )\n }\n }\n}\n"]}
@@ -1,201 +1,10 @@
1
- import { c as ManagedSchemaProps, e as ManagedFAQProps, g as ManagedInternalLinksProps, i as ManagedContentProps, h as ManagedContentBlock, p as ManagedScriptsProps } from '../types-DYyIAgQg.mjs';
2
- export { A as ABTest, k as ABTestResult, F as FAQItem, l as GetABVariantOptions, G as GetManagedMetadataOptions, n as GetRedirectOptions, r as GetRobotsOptions, t as GetSitemapEntriesOptions, d as ManagedFAQData, f as ManagedLink, M as ManagedMetadataResult, m as ManagedRedirect, o as ManagedScript, R as RedirectResult, q as RobotsDirective, a as SEOPageData, b as SchemaMarkup, s as SitemapEntry, S as SonorSEOConfig } from '../types-DYyIAgQg.mjs';
3
- export { b as generateSitemap, c as getABVariant, g as getManagedMetadata, a as getManagedMetadataWithAB, d as getRedirect, e as getRobotsDirective, i as isIndexable } from '../routing-trNzR1Pz.mjs';
1
+ import { a as ManagedSchemaProps, c as ManagedFAQProps, d as ManagedInternalLinksProps, e as ManagedContentProps, f as ManagedContentBlock, g as ManagedScriptsProps } from '../types-DPsbBKiu.mjs';
2
+ export { A as ABTest, k as ABTestResult, F as FAQItem, l as GetABVariantOptions, G as GetManagedMetadataOptions, n as GetRedirectOptions, q as GetRobotsOptions, s as GetSitemapEntriesOptions, b as ManagedFAQData, j as ManagedLink, M as ManagedMetadataResult, m as ManagedRedirect, o as ManagedScript, R as RedirectResult, p as RobotsDirective, h as SEOPageData, i as SchemaMarkup, r as SitemapEntry, S as SonorSEOConfig } from '../types-DPsbBKiu.mjs';
3
+ export { E as EntityType, P as PageSeoContext, S as SEOEntity, e as generateSitemap, m as getABTest, b as getABVariant, l as getContentBlock, t as getEntities, v as getEntityEnhancedSchema, j as getFAQData, k as getInternalLinks, g as getManagedMetadata, a as getManagedMetadataWithAB, o as getManagedScripts, u as getPrimaryEntity, c as getRedirect, n as getRedirectData, p as getRobotsData, d as getRobotsDirective, f as getSEOPageData, h as getSchemaMarkups, q as getSitemapEntries, w as getVisibilityScore, x as getVisibilitySummary, i as isIndexable, r as recordABImpression, s as registerSitemap } from '../server-mX5At_6x.mjs';
4
4
  import { ResolvingMetadata, Metadata } from 'next';
5
5
  import * as React from 'react';
6
6
  export { SitemapSync } from './client.mjs';
7
7
 
8
- /**
9
- * @sonordev/site-kit/seo - Server-Only API Functions
10
- *
11
- * SECURITY: These functions use private environment variables
12
- * and should ONLY be imported in server-side code (RSC, API routes, server actions).
13
- *
14
- * DO NOT import this file in client components or it will expose API keys.
15
- */
16
-
17
- /** Response shape for POST /api/public/seo/page-context */
18
- type PageSeoContext = {
19
- page: any | null;
20
- schemas: any[];
21
- project: {
22
- id: string;
23
- title?: string | null;
24
- domain?: string | null;
25
- logo_url?: string | null;
26
- site_url?: string | null;
27
- } | null;
28
- };
29
- /**
30
- * Fetch SEO page data - cached per request
31
- * @server-only
32
- */
33
- declare const getSEOPageData: (path: string) => Promise<{
34
- page: any;
35
- project: {
36
- id: string;
37
- title?: string | null;
38
- domain?: string | null;
39
- logo_url?: string | null;
40
- site_url?: string | null;
41
- } | null;
42
- }>;
43
- /**
44
- * Fetch schema markups for a page - cached per request (shares loadPageSeoContext with getSEOPageData)
45
- * @server-only
46
- */
47
- declare const getSchemaMarkups: (path: string, options?: {
48
- includeTypes?: string[];
49
- excludeTypes?: string[];
50
- }) => Promise<any[]>;
51
- /**
52
- * Fetch FAQ data for a page - cached per request
53
- * @server-only
54
- */
55
- declare const getFAQData: (path: string) => Promise<any>;
56
- /**
57
- * Fetch internal links for a page - cached per request
58
- * @server-only
59
- */
60
- declare const getInternalLinks: (sourcePath: string, options?: {
61
- position?: string;
62
- limit?: number;
63
- }) => Promise<any[]>;
64
- /**
65
- * Fetch content block - cached per request
66
- * @server-only
67
- */
68
- declare const getContentBlock: (path: string, section: string) => Promise<any>;
69
- /**
70
- * Fetch A/B test and determine variant - cached per request
71
- * @server-only
72
- */
73
- declare const getABTest: (path: string, field: string) => Promise<any>;
74
- /**
75
- * Record A/B test impression
76
- * @server-only
77
- */
78
- declare function recordABImpression(testId: string, variant: 'a' | 'b', sessionId?: string): Promise<void>;
79
- /**
80
- * Fetch redirect for a path - cached per request
81
- * @server-only
82
- */
83
- declare const getRedirectData: (path: string) => Promise<any>;
84
- /**
85
- * Fetch managed scripts - cached per request
86
- * @server-only
87
- */
88
- declare const getManagedScripts: (position: string, currentPath?: string) => Promise<any[]>;
89
- /**
90
- * Fetch robots directive for a page - cached per request
91
- * @server-only
92
- */
93
- declare const getRobotsData: (path: string) => Promise<any>;
94
- /**
95
- * Fetch sitemap entries - cached per request
96
- * @server-only
97
- */
98
- declare const getSitemapEntries: (options?: {
99
- publishedOnly?: boolean;
100
- }) => Promise<any[]>;
101
- /**
102
- * Register/sync sitemap entries from the client site
103
- * Call this at build time to populate seo_pages from your sitemap.xml
104
- * @server-only
105
- *
106
- * @example
107
- * ```ts
108
- * // scripts/register-sitemap.ts (run at build time)
109
- * import { registerSitemap } from '@sonordev/seo/server'
110
- *
111
- * await registerSitemap([
112
- * { path: '/', priority: 1.0, changefreq: 'daily' },
113
- * { path: '/about', priority: 0.8, changefreq: 'weekly' },
114
- * ])
115
- * ```
116
- */
117
- declare function registerSitemap(entries: Array<{
118
- path: string;
119
- title?: string;
120
- priority?: number;
121
- changefreq?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
122
- }>, options?: {
123
- /**
124
- * Sync mode:
125
- * - 'full-replace': replaces the entire page set (default for build-time sync)
126
- * - 'additive': adds/updates pages but never deletes existing ones
127
- */
128
- mode?: 'additive' | 'full-replace';
129
- }): Promise<{
130
- success: boolean;
131
- created: number;
132
- updated: number;
133
- }>;
134
- /**
135
- * Entity types for the knowledge graph
136
- */
137
- type EntityType = 'organization' | 'person' | 'service' | 'product' | 'location' | 'concept' | 'credential';
138
- /**
139
- * Entity from the knowledge graph
140
- */
141
- interface SEOEntity {
142
- id: string;
143
- project_id: string;
144
- entity_type: EntityType;
145
- name: string;
146
- slug: string;
147
- properties: Record<string, unknown>;
148
- knows_about: string[];
149
- same_as: string[];
150
- schema_type?: string;
151
- is_primary: boolean;
152
- }
153
- /**
154
- * Fetch entities for a project - cached per request
155
- * Returns the entity graph for enhanced schema markup
156
- * @server-only
157
- */
158
- declare const getEntities: (options?: {
159
- type?: EntityType;
160
- }) => Promise<SEOEntity[]>;
161
- /**
162
- * Fetch primary entity (the business) - cached per request
163
- * @server-only
164
- */
165
- declare const getPrimaryEntity: () => Promise<SEOEntity | null>;
166
- /**
167
- * Fetch entity-enhanced schema for a page
168
- * Returns Organization schema with knowsAbout, areaServed, employee, etc.
169
- * @server-only
170
- */
171
- declare const getEntityEnhancedSchema: (pagePath: string) => Promise<object[]>;
172
- /**
173
- * Get AI visibility score for a page
174
- * @server-only
175
- */
176
- declare const getVisibilityScore: (pagePath: string) => Promise<{
177
- overall_score: number;
178
- entity_coverage: number;
179
- answer_density: number;
180
- chunk_readability: number;
181
- authority_signals: number;
182
- schema_completeness: number;
183
- } | null>;
184
- /**
185
- * Get AI visibility summary for project
186
- * @server-only
187
- */
188
- declare const getVisibilitySummary: () => Promise<{
189
- overall_score: number;
190
- total_entities: number;
191
- pages_analyzed: number;
192
- top_recommendations: Array<{
193
- priority: string;
194
- type: string;
195
- message: string;
196
- }>;
197
- } | null>;
198
-
199
8
  /**
200
9
  * @sonordev/site-kit/seo - withManagedMetadata
201
10
  *
@@ -323,17 +132,13 @@ declare function ManagedNoScripts(props: {
323
132
  }): React.ReactElement;
324
133
 
325
134
  /**
326
- * LocationPageContent - Server Component for fetching location page sections
327
- *
328
- * Usage:
329
- * <LocationPageContent
330
- * projectId="uuid"
331
- * path="/areas/seattle-wa/plumbing"
332
- * section="hero"
333
- * />
135
+ * @deprecated DO NOT USE. This component calls an endpoint that does not exist
136
+ * (and sends project_id from the client, violating the x-api-key-only auth
137
+ * contract) — it has only ever rendered its fallback. Location page content is
138
+ * served through the standard managed-content path instead. Kept exported so
139
+ * existing imports keep compiling; it renders the fallback and warns.
334
140
  *
335
- * This component fetches content from seo_location_pages.sections for a given
336
- * path and section, making it editable in Portal without code deploys.
141
+ * LocationPageContent - Server Component for fetching location page sections
337
142
  */
338
143
 
339
144
  interface LocationPageContentProps {
@@ -388,4 +193,4 @@ declare const getLocationSection: (projectId: string, path: string, section: str
388
193
  */
389
194
  declare function LocationPageContent(props: LocationPageContentProps): React.ReactElement;
390
195
 
391
- export { type EntityType, LLMSchema, type HeroSectionContent as LocationHeroContent, LocationPageContent, type LocationPageContentProps, type LocationSectionData, type ServiceGridContent as LocationServicesContent, type TextSectionContent as LocationTextContent, ManagedContent, ManagedContentBlock, ManagedContentProps, ManagedFAQ, ManagedFAQProps, ManagedInternalLinks, ManagedInternalLinksProps, ManagedNoScripts, ManagedSchema, ManagedSchemaProps, ManagedScripts, ManagedScriptsProps, type PageSeoContext, type SEOEntity, createBreadcrumbSchema, createSchema, createWebSiteOrganizationStub, getABTest, getContentBlock, getEntities, getEntityEnhancedSchema, getFAQData, getInternalLinks, getLocationSection, getManagedContentData, getManagedScripts, getPrimaryEntity, getRedirectData, getRobotsData, getSEOPageData, getSchemaMarkups, getSitemapEntries, getVisibilityScore, getVisibilitySummary, recordABImpression, registerSitemap, withManagedMetadata };
196
+ export { LLMSchema, type HeroSectionContent as LocationHeroContent, LocationPageContent, type LocationPageContentProps, type LocationSectionData, type ServiceGridContent as LocationServicesContent, type TextSectionContent as LocationTextContent, ManagedContent, ManagedContentBlock, ManagedContentProps, ManagedFAQ, ManagedFAQProps, ManagedInternalLinks, ManagedInternalLinksProps, ManagedNoScripts, ManagedSchema, ManagedSchemaProps, ManagedScripts, ManagedScriptsProps, createBreadcrumbSchema, createSchema, createWebSiteOrganizationStub, getLocationSection, getManagedContentData, withManagedMetadata };