@sonordev/site-kit 2.0.1 → 2.0.3

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 (55) hide show
  1. package/dist/SitemapSync-DXIV5TXI.mjs +4 -0
  2. package/dist/{SitemapSync-YK6IXOSY.mjs.map → SitemapSync-DXIV5TXI.mjs.map} +1 -1
  3. package/dist/SitemapSync-Z4NDW2S7.js +13 -0
  4. package/dist/{SitemapSync-FKYWGDAD.js.map → SitemapSync-Z4NDW2S7.js.map} +1 -1
  5. package/dist/blog/index.d.mts +6 -4
  6. package/dist/blog/index.d.ts +6 -4
  7. package/dist/blog/index.js +305 -20
  8. package/dist/blog/index.js.map +1 -1
  9. package/dist/blog/index.mjs +305 -21
  10. package/dist/blog/index.mjs.map +1 -1
  11. package/dist/blog/server.d.mts +41 -2
  12. package/dist/blog/server.d.ts +41 -2
  13. package/dist/blog/server.js +126 -685
  14. package/dist/blog/server.js.map +1 -1
  15. package/dist/blog/server.mjs +1 -663
  16. package/dist/blog/server.mjs.map +1 -1
  17. package/dist/{chunk-UD5447TC.js → chunk-6LZEGXDE.js} +3 -3
  18. package/dist/{chunk-UD5447TC.js.map → chunk-6LZEGXDE.js.map} +1 -1
  19. package/dist/{chunk-QW4RQHSK.js → chunk-ACBDH4RK.js} +15 -3
  20. package/dist/chunk-ACBDH4RK.js.map +1 -0
  21. package/dist/{chunk-TSK35UHV.mjs → chunk-HA5OXTXW.mjs} +15 -3
  22. package/dist/chunk-HA5OXTXW.mjs.map +1 -0
  23. package/dist/chunk-JUWYIDIA.js +823 -0
  24. package/dist/chunk-JUWYIDIA.js.map +1 -0
  25. package/dist/{chunk-WN2PUL6B.mjs → chunk-RVAFAOBA.mjs} +3 -3
  26. package/dist/{chunk-WN2PUL6B.mjs.map → chunk-RVAFAOBA.mjs.map} +1 -1
  27. package/dist/chunk-S2WK4LL7.mjs +791 -0
  28. package/dist/chunk-S2WK4LL7.mjs.map +1 -0
  29. package/dist/index.d.mts +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/layout/client.js +2 -2
  32. package/dist/layout/client.mjs +1 -1
  33. package/dist/layout/index.js +2 -2
  34. package/dist/layout/index.mjs +1 -1
  35. package/dist/seo/client.js +2 -2
  36. package/dist/seo/client.mjs +1 -1
  37. package/dist/seo/index.js +2 -2
  38. package/dist/seo/index.mjs +1 -1
  39. package/dist/seo/register-sitemap-cli.js +14 -1
  40. package/dist/seo/register-sitemap-cli.js.map +1 -1
  41. package/dist/seo/register-sitemap-cli.mjs +14 -1
  42. package/dist/seo/register-sitemap-cli.mjs.map +1 -1
  43. package/dist/sitemap/index.d.mts +7 -1
  44. package/dist/sitemap/index.d.ts +7 -1
  45. package/dist/sitemap/index.js +26 -7
  46. package/dist/sitemap/index.js.map +1 -1
  47. package/dist/sitemap/index.mjs +26 -7
  48. package/dist/sitemap/index.mjs.map +1 -1
  49. package/dist/{types-D08004rU.d.mts → types-DuvkNnu0.d.mts} +25 -1
  50. package/dist/{types-D08004rU.d.ts → types-DuvkNnu0.d.ts} +25 -1
  51. package/package.json +1 -1
  52. package/dist/SitemapSync-FKYWGDAD.js +0 -13
  53. package/dist/SitemapSync-YK6IXOSY.mjs +0 -4
  54. package/dist/chunk-QW4RQHSK.js.map +0 -1
  55. package/dist/chunk-TSK35UHV.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/blog/server.ts"],"names":["description"],"mappings":"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","file":"chunk-JUWYIDIA.js","sourcesContent":["/**\n * @sonordev/site-kit/blog/server\n * \n * Server-side functions for Next.js blog pages.\n * Includes metadata generation, sitemap, RSS feeds, and static params for SSG.\n */\n\nimport type { Metadata } from 'next'\nimport type { BlogPost, BlogAuthor, TocItem } from './types'\n\n// ============================================================================\n// CONFIGURATION\n// ============================================================================\n\ninterface BlogServerConfig {\n apiUrl: string\n apiKey: string\n}\n\nfunction getConfig(): BlogServerConfig {\n return {\n apiUrl: process.env.SONOR_API_URL || 'https://api.sonor.io',\n apiKey: process.env.SONOR_API_KEY || '',\n }\n}\n\n// ============================================================================\n// SEO VALIDATION UTILITIES\n// ============================================================================\n\nexport const SEO_LIMITS = {\n title: { min: 30, max: 60, recommended: 55 },\n metaDescription: { min: 120, max: 160, recommended: 155 },\n excerpt: { min: 100, max: 300, recommended: 200 },\n slug: { max: 75 },\n focusKeyphrase: { min: 2, max: 4, words: true }, // 2-4 words\n} as const\n\nexport interface SeoValidationResult {\n field: string\n value: string\n length: number\n limit: { min?: number; max: number; recommended?: number }\n status: 'good' | 'warning' | 'error'\n message: string\n}\n\n/**\n * Validate SEO title (60 chars max, keyword-first recommended)\n */\nexport function validateSeoTitle(title: string, focusKeyphrase?: string): SeoValidationResult {\n const length = title.length\n let status: SeoValidationResult['status'] = 'good'\n let message = 'Title length is optimal'\n\n if (length > SEO_LIMITS.title.max) {\n status = 'error'\n message = `Title is ${length - SEO_LIMITS.title.max} characters too long (max ${SEO_LIMITS.title.max})`\n } else if (length < SEO_LIMITS.title.min) {\n status = 'warning'\n message = `Title is short (${length}/${SEO_LIMITS.title.min} min)`\n } else if (focusKeyphrase && !title.toLowerCase().includes(focusKeyphrase.toLowerCase())) {\n status = 'warning'\n message = 'Focus keyphrase not found in title'\n } else if (focusKeyphrase && !title.toLowerCase().startsWith(focusKeyphrase.toLowerCase())) {\n status = 'warning'\n message = 'Title should start with focus keyphrase for best results'\n }\n\n return { field: 'title', value: title, length, limit: SEO_LIMITS.title, status, message }\n}\n\n/**\n * Validate meta description (150-160 chars, benefit-driven)\n */\nexport function validateMetaDescription(description: string, focusKeyphrase?: string): SeoValidationResult {\n const length = description.length\n let status: SeoValidationResult['status'] = 'good'\n let message = 'Meta description is optimal'\n\n if (length > SEO_LIMITS.metaDescription.max) {\n status = 'error'\n message = `Description will be truncated (${length}/${SEO_LIMITS.metaDescription.max})`\n } else if (length < SEO_LIMITS.metaDescription.min) {\n status = 'warning'\n message = `Description is short (${length}/${SEO_LIMITS.metaDescription.min} min)`\n } else if (focusKeyphrase && !description.toLowerCase().includes(focusKeyphrase.toLowerCase())) {\n status = 'warning'\n message = 'Focus keyphrase not found in description'\n }\n\n return { field: 'meta_description', value: description, length, limit: SEO_LIMITS.metaDescription, status, message }\n}\n\n/**\n * Full SEO validation for a blog post\n */\nexport function validateBlogPostSeo(post: Partial<BlogPost>): SeoValidationResult[] {\n const results: SeoValidationResult[] = []\n const focusKeyphrase = post.focus_keyphrase\n\n if (post.meta_title || post.title) {\n results.push(validateSeoTitle(post.meta_title || post.title || '', focusKeyphrase))\n }\n\n if (post.meta_description) {\n results.push(validateMetaDescription(post.meta_description, focusKeyphrase))\n }\n\n // Check H1 alignment (title should match keyword)\n if (post.title && focusKeyphrase) {\n const titleLower = post.title.toLowerCase()\n const keyLower = focusKeyphrase.toLowerCase()\n if (!titleLower.includes(keyLower)) {\n results.push({\n field: 'h1_alignment',\n value: post.title,\n length: post.title.length,\n limit: { max: 100 },\n status: 'warning',\n message: 'H1 (title) should include the focus keyphrase',\n })\n }\n }\n\n // Check word count (1200-2500 recommended for long-form)\n if (post.word_count !== undefined) {\n let wordStatus: SeoValidationResult['status'] = 'good'\n let wordMessage = 'Content length is optimal for SEO'\n \n if (post.word_count < 600) {\n wordStatus = 'error'\n wordMessage = `Content is thin (${post.word_count} words). Aim for 1200+ words.`\n } else if (post.word_count < 1200) {\n wordStatus = 'warning'\n wordMessage = `Content is short (${post.word_count} words). Long-form (1200-2500) ranks better.`\n } else if (post.word_count > 2500) {\n wordMessage = `Comprehensive content (${post.word_count} words). Consider splitting into a topic cluster.`\n }\n\n results.push({\n field: 'word_count',\n value: String(post.word_count),\n length: post.word_count,\n limit: { min: 1200, max: 2500, recommended: 1800 },\n status: wordStatus,\n message: wordMessage,\n })\n }\n\n return results\n}\n\n// ============================================================================\n// DATA FETCHING\n// ============================================================================\n\n/**\n * Fetch a blog post by slug (server-side)\n */\nexport async function getBlogPost(slug: string): Promise<BlogPost | null> {\n const { apiUrl, apiKey } = getConfig()\n\n if (!apiKey) {\n console.warn('[Blog] No API key configured')\n return null\n }\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/posts/${slug}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n })\n\n if (!response.ok) return null\n\n const data = await response.json()\n return data.post || null\n } catch (error) {\n console.error('[Blog] Error fetching post:', error)\n return null\n }\n}\n\n/**\n * Fetch all blog post slugs for static generation\n */\nexport async function getAllBlogSlugs(): Promise<{ slug: string; last_modified?: string }[]> {\n const { apiUrl, apiKey } = getConfig()\n\n if (!apiKey) {\n console.warn('[Blog] No API key configured')\n return []\n }\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/slugs`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.slugs || []\n } catch (error) {\n console.error('[Blog] Error fetching slugs:', error)\n return []\n }\n}\n\n/**\n * Fetch blog categories\n */\nexport async function getBlogCategories(): Promise<{ name: string; slug: string; post_count: number }[]> {\n const { apiUrl, apiKey } = getConfig()\n\n if (!apiKey) return []\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/categories`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.categories || []\n } catch (error) {\n console.error('[Blog] Error fetching categories:', error)\n return []\n }\n}\n\n// ============================================================================\n// METADATA GENERATION\n// ============================================================================\n\ninterface BlogMetadataOptions {\n /** Site name for og:site_name */\n siteName?: string\n /** Base URL of the site */\n siteUrl?: string\n /** Default OG image */\n defaultImage?: string\n /** Twitter handle */\n twitterHandle?: string\n}\n\n/**\n * Generate metadata for a blog post page\n */\nexport async function generateBlogPostMetadata(\n slug: string,\n options: BlogMetadataOptions = {}\n): Promise<Metadata> {\n const post = await getBlogPost(slug)\n const { siteName, siteUrl = '', defaultImage, twitterHandle } = options\n\n if (!post) {\n return {\n title: 'Post Not Found',\n description: 'The requested blog post could not be found.',\n }\n }\n\n const title = post.meta_title || post.title\n const description = post.meta_description || post.excerpt || ''\n const image = post.og_image || post.featured_image || defaultImage\n const url = `${siteUrl}/blog/${post.slug}`\n\n return {\n title,\n description,\n openGraph: {\n title: post.og_title || title,\n description: post.og_description || description,\n url,\n siteName,\n type: 'article',\n publishedTime: post.published_at,\n authors: post.author ? [typeof post.author === 'string' ? post.author : post.author.name] : undefined,\n images: image\n ? [\n {\n url: image,\n width: post.featured_image_width || 1200,\n height: post.featured_image_height || 630,\n alt: post.featured_image_alt || post.title,\n },\n ]\n : undefined,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: image ? [image] : undefined,\n creator: twitterHandle,\n },\n alternates: {\n canonical: post.canonical_url || url,\n },\n other: {\n 'article:published_time': post.published_at || '',\n 'article:section': typeof post.category === 'string' ? post.category : (post.category?.name || ''),\n },\n }\n}\n\n/**\n * Generate metadata for the blog index page\n */\nexport function generateBlogIndexMetadata(options: BlogMetadataOptions & {\n title?: string\n description?: string\n}): Metadata {\n const {\n title = 'Blog',\n description = 'Read our latest articles and insights.',\n siteName,\n siteUrl = '',\n defaultImage,\n twitterHandle,\n } = options\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n url: `${siteUrl}/blog`,\n siteName,\n type: 'website',\n images: defaultImage ? [{ url: defaultImage }] : undefined,\n },\n twitter: {\n card: 'summary_large_image',\n title,\n description,\n images: defaultImage ? [defaultImage] : undefined,\n creator: twitterHandle,\n },\n }\n}\n\n/**\n * Generate metadata for a category page\n */\nexport function generateBlogCategoryMetadata(\n categoryName: string,\n options: BlogMetadataOptions = {}\n): Metadata {\n const { siteName, siteUrl = '', defaultImage } = options\n const title = `${categoryName} - Blog`\n const description = `Browse all posts in ${categoryName}.`\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n url: `${siteUrl}/blog/category/${categoryName.toLowerCase()}`,\n siteName,\n type: 'website',\n images: defaultImage ? [{ url: defaultImage }] : undefined,\n },\n }\n}\n\n// ============================================================================\n// STATIC PARAMS GENERATION\n// ============================================================================\n\n/**\n * Generate static params for blog post pages\n * Usage: export const generateStaticParams = generateBlogStaticParams\n */\nexport async function generateBlogStaticParams(): Promise<{ slug: string }[]> {\n const slugs = await getAllBlogSlugs()\n return slugs.map((s) => ({ slug: s.slug }))\n}\n\n/**\n * Generate static params for category pages\n * Usage: export const generateStaticParams = generateCategoryStaticParams\n */\nexport async function generateCategoryStaticParams(): Promise<{ category: string }[]> {\n const categories = await getBlogCategories()\n return categories.map((c) => ({ category: c.slug }))\n}\n\n// ============================================================================\n// SITEMAP GENERATION\n// ============================================================================\n\ninterface SitemapEntry {\n url: string\n lastModified?: Date\n changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'\n priority?: number\n}\n\n/**\n * Generate sitemap entries for blog posts\n */\nexport async function generateBlogSitemap(\n siteUrl: string\n): Promise<SitemapEntry[]> {\n const slugs = await getAllBlogSlugs()\n const categories = await getBlogCategories()\n\n const entries: SitemapEntry[] = [\n // Blog index\n {\n url: `${siteUrl}/blog`,\n changeFrequency: 'daily',\n priority: 0.8,\n },\n ]\n\n // Category pages\n categories.forEach((cat) => {\n entries.push({\n url: `${siteUrl}/blog/category/${cat.slug}`,\n changeFrequency: 'weekly',\n priority: 0.6,\n })\n })\n\n // Individual posts\n slugs.forEach((post) => {\n entries.push({\n url: `${siteUrl}/blog/${post.slug}`,\n lastModified: post.last_modified ? new Date(post.last_modified) : undefined,\n changeFrequency: 'weekly',\n priority: 0.7,\n })\n })\n\n return entries\n}\n\n// ============================================================================\n// JSON-LD SCHEMA GENERATION\n// ============================================================================\n\n/**\n * Generate JSON-LD schema for a blog post\n */\nexport function generateBlogPostSchema(\n post: BlogPost,\n options: { siteUrl?: string; siteName?: string; logoUrl?: string } = {}\n): object {\n const { siteUrl = '', siteName, logoUrl } = options\n\n const schema: any = {\n '@context': 'https://schema.org',\n '@type': 'BlogPosting',\n headline: post.title,\n description: post.excerpt || post.meta_description,\n url: `${siteUrl}/blog/${post.slug}`,\n datePublished: post.published_at,\n dateModified: post.updated_at,\n author: {\n '@type': 'Person',\n name: typeof post.author === 'string' ? post.author : post.author?.name,\n },\n }\n\n if (post.featured_image) {\n schema.image = {\n '@type': 'ImageObject',\n url: post.featured_image,\n width: post.featured_image_width || 1200,\n height: post.featured_image_height || 630,\n }\n }\n\n if (siteName || logoUrl) {\n schema.publisher = {\n '@type': 'Organization',\n name: siteName,\n logo: logoUrl\n ? {\n '@type': 'ImageObject',\n url: logoUrl,\n }\n : undefined,\n }\n }\n\n // Add FAQ schema if present\n if (post.faq_items && Array.isArray(post.faq_items) && post.faq_items.length > 0) {\n schema.mainEntity = {\n '@type': 'FAQPage',\n mainEntity: post.faq_items.map((faq: { question: string; answer: string }) => ({\n '@type': 'Question',\n name: faq.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: faq.answer,\n },\n })),\n }\n }\n\n return schema\n}\n\n/**\n * Generate JSON-LD schema for blog index/listing page\n */\nexport function generateBlogListSchema(\n options: { siteUrl?: string; siteName?: string; description?: string } = {}\n): object {\n const { siteUrl = '', siteName, description } = options\n\n return {\n '@context': 'https://schema.org',\n '@type': 'Blog',\n name: siteName ? `${siteName} Blog` : 'Blog',\n description: description || 'Our latest articles and insights.',\n url: `${siteUrl}/blog`,\n }\n}\n\n// ============================================================================\n// FAQ SCHEMA (for PAA rankings)\n// ============================================================================\n\n/**\n * Generate standalone FAQ schema (great for PAA inclusion)\n */\nexport function generateFaqSchema(\n faqItems: { question: string; answer: string }[]\n): object | null {\n if (!faqItems || faqItems.length === 0) return null\n\n return {\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: faqItems.map((faq) => ({\n '@type': 'Question',\n name: faq.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: faq.answer,\n },\n })),\n }\n}\n\n// ============================================================================\n// HOWTO SCHEMA (for step-by-step posts)\n// ============================================================================\n\nexport interface HowToStep {\n name: string\n text: string\n image?: string\n url?: string\n}\n\n/**\n * Generate HowTo schema for step-by-step posts\n */\nexport function generateHowToSchema(\n post: BlogPost,\n steps: HowToStep[],\n options: { siteUrl?: string } = {}\n): object {\n const { siteUrl = '' } = options\n\n return {\n '@context': 'https://schema.org',\n '@type': 'HowTo',\n name: post.title,\n description: post.excerpt || post.meta_description,\n image: post.featured_image,\n totalTime: post.reading_time ? `PT${post.reading_time}M` : undefined,\n step: steps.map((step, index) => ({\n '@type': 'HowToStep',\n position: index + 1,\n name: step.name,\n text: step.text,\n image: step.image,\n url: step.url || `${siteUrl}/blog/${post.slug}#step-${index + 1}`,\n })),\n }\n}\n\n// ============================================================================\n// RSS FEED GENERATION\n// ============================================================================\n\ninterface RssFeedOptions {\n siteUrl: string\n siteName: string\n description?: string\n language?: string\n copyright?: string\n managingEditor?: string\n webMaster?: string\n ttl?: number // Time to live in minutes\n imageUrl?: string\n}\n\n/**\n * Fetch all published blog posts for RSS feed\n */\nexport async function getAllBlogPosts(): Promise<BlogPost[]> {\n const { apiUrl, apiKey } = getConfig()\n\n if (!apiKey) {\n console.warn('[Blog] No API key configured')\n return []\n }\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/posts?limit=100`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('[Blog] Error fetching posts for RSS:', error)\n return []\n }\n}\n\n/**\n * Escape XML special characters\n */\nfunction escapeXml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;')\n}\n\n/**\n * Strip HTML tags for RSS descriptions\n */\nfunction stripHtml(html: string): string {\n return html.replace(/<[^>]*>/g, '').trim()\n}\n\n/**\n * Generate RSS 2.0 feed XML\n */\nexport async function generateRssFeed(options: RssFeedOptions): Promise<string> {\n const {\n siteUrl,\n siteName,\n description = 'Latest blog posts and insights',\n language = 'en-us',\n copyright,\n managingEditor,\n webMaster,\n ttl = 60,\n imageUrl,\n } = options\n\n const posts = await getAllBlogPosts()\n const now = new Date().toUTCString()\n\n let rss = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<rss version=\"2.0\" xmlns:atom=\"http://www.w3.org/2005/Atom\" xmlns:content=\"http://purl.org/rss/1.0/modules/content/\">\n <channel>\n <title>${escapeXml(siteName)}</title>\n <link>${siteUrl}</link>\n <description>${escapeXml(description)}</description>\n <language>${language}</language>\n <lastBuildDate>${now}</lastBuildDate>\n <pubDate>${now}</pubDate>\n <ttl>${ttl}</ttl>\n <atom:link href=\"${siteUrl}/blog/rss.xml\" rel=\"self\" type=\"application/rss+xml\"/>\n`\n\n if (copyright) {\n rss += ` <copyright>${escapeXml(copyright)}</copyright>\\n`\n }\n\n if (managingEditor) {\n rss += ` <managingEditor>${escapeXml(managingEditor)}</managingEditor>\\n`\n }\n\n if (webMaster) {\n rss += ` <webMaster>${escapeXml(webMaster)}</webMaster>\\n`\n }\n\n if (imageUrl) {\n rss += ` <image>\n <url>${imageUrl}</url>\n <title>${escapeXml(siteName)}</title>\n <link>${siteUrl}</link>\n </image>\\n`\n }\n\n // Add each post as an item with FULL content (not excerpts)\n for (const post of posts) {\n const postUrl = `${siteUrl}/blog/${post.slug}`\n const pubDate = post.published_at ? new Date(post.published_at).toUTCString() : now\n const author = typeof post.author === 'string' ? post.author : post.author?.name || 'Unknown'\n \n // Use full content_html if available, otherwise content\n const fullContent = post.content_html || post.content || ''\n const description = post.excerpt || stripHtml(fullContent).substring(0, 300) + '...'\n\n rss += ` <item>\n <title>${escapeXml(post.title)}</title>\n <link>${postUrl}</link>\n <guid isPermaLink=\"true\">${postUrl}</guid>\n <description>${escapeXml(description)}</description>\n <content:encoded><![CDATA[${fullContent}]]></content:encoded>\n <pubDate>${pubDate}</pubDate>\n <author>${escapeXml(author)}</author>\n`\n\n if (post.category) {\n const categoryName = typeof post.category === 'string' ? post.category : post.category.name\n rss += ` <category>${escapeXml(categoryName)}</category>\\n`\n }\n\n if (post.tags && Array.isArray(post.tags)) {\n for (const tag of post.tags) {\n const tagName = typeof tag === 'string' ? tag : tag.name\n rss += ` <category>${escapeXml(tagName)}</category>\\n`\n }\n }\n\n if (post.featured_image) {\n rss += ` <enclosure url=\"${post.featured_image}\" type=\"image/jpeg\"/>\\n`\n }\n\n rss += ` </item>\\n`\n }\n\n rss += ` </channel>\n</rss>`\n\n return rss\n}\n\n/**\n * Generate Atom feed XML\n */\nexport async function generateAtomFeed(options: RssFeedOptions): Promise<string> {\n const {\n siteUrl,\n siteName,\n description = 'Latest blog posts and insights',\n managingEditor,\n } = options\n\n const posts = await getAllBlogPosts()\n const now = new Date().toISOString()\n\n let atom = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<feed xmlns=\"http://www.w3.org/2005/Atom\">\n <title>${escapeXml(siteName)}</title>\n <subtitle>${escapeXml(description)}</subtitle>\n <link href=\"${siteUrl}/blog/feed.xml\" rel=\"self\"/>\n <link href=\"${siteUrl}\"/>\n <id>${siteUrl}/blog</id>\n <updated>${now}</updated>\n`\n\n if (managingEditor) {\n atom += ` <author>\n <name>${escapeXml(managingEditor)}</name>\n </author>\\n`\n }\n\n for (const post of posts) {\n const postUrl = `${siteUrl}/blog/${post.slug}`\n const updated = post.updated_at || post.published_at || now\n const published = post.published_at || now\n const author = typeof post.author === 'string' ? post.author : post.author?.name || 'Unknown'\n const fullContent = post.content_html || post.content || ''\n\n atom += ` <entry>\n <title>${escapeXml(post.title)}</title>\n <link href=\"${postUrl}\"/>\n <id>${postUrl}</id>\n <updated>${new Date(updated).toISOString()}</updated>\n <published>${new Date(published).toISOString()}</published>\n <author>\n <name>${escapeXml(author)}</name>\n </author>\n <summary>${escapeXml(post.excerpt || stripHtml(fullContent).substring(0, 300))}</summary>\n <content type=\"html\"><![CDATA[${fullContent}]]></content>\n </entry>\\n`\n }\n\n atom += `</feed>`\n\n return atom\n}\n\n// ============================================================================\n// TOPIC CLUSTER SUPPORT\n// ============================================================================\n\nexport interface TopicCluster {\n pillar: BlogPost\n supportingPosts: BlogPost[]\n internalLinks: Array<{\n from: string // slug\n to: string // slug\n anchor: string\n }>\n}\n\n/**\n * Fetch posts by category for topic cluster organization\n */\nexport async function getPostsByCategory(categorySlug: string): Promise<BlogPost[]> {\n const { apiUrl, apiKey } = getConfig()\n\n if (!apiKey) return []\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/posts?category=${categorySlug}&limit=50`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('[Blog] Error fetching category posts:', error)\n return []\n }\n}\n\n/**\n * Identify topic clusters based on category grouping\n * Assumes the longest/most comprehensive post is the pillar\n */\nexport async function identifyTopicClusters(categorySlug: string): Promise<TopicCluster | null> {\n const posts = await getPostsByCategory(categorySlug)\n \n if (posts.length < 3) return null // Need at least a pillar + 2 supporting posts\n\n // Find pillar (longest post in category)\n const sortedByLength = [...posts].sort((a, b) => (b.word_count || 0) - (a.word_count || 0))\n const pillar = sortedByLength[0]\n const supportingPosts = sortedByLength.slice(1)\n\n // Generate suggested internal links\n const internalLinks: TopicCluster['internalLinks'] = []\n \n // Link from pillar to each supporting post\n for (const support of supportingPosts) {\n internalLinks.push({\n from: pillar.slug,\n to: support.slug,\n anchor: support.title,\n })\n }\n\n // Link from each supporting post back to pillar\n for (const support of supportingPosts) {\n internalLinks.push({\n from: support.slug,\n to: pillar.slug,\n anchor: pillar.title,\n })\n }\n\n return {\n pillar,\n supportingPosts,\n internalLinks,\n }\n}\n\n/**\n * Generate \"Related Insights\" section data\n */\nexport async function getRelatedInsights(\n currentSlug: string,\n options: { limit?: number; category?: string } = {}\n): Promise<BlogPost[]> {\n const { apiUrl, apiKey } = getConfig()\n const { limit = 3, category } = options\n\n if (!apiKey) return []\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/related`, {\n method: 'POST',\n headers: {\n 'x-api-key': apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n slug: currentSlug,\n limit,\n category,\n }),\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n return data.posts || []\n } catch (error) {\n console.error('[Blog] Error fetching related posts:', error)\n return []\n }\n}\n\n// ============================================================================\n// BREADCRUMB SCHEMA\n// ============================================================================\n\n/**\n * Generate BreadcrumbList schema for blog navigation\n */\nexport function generateBreadcrumbSchema(\n post: BlogPost,\n options: { siteUrl?: string; siteName?: string } = {}\n): object {\n const { siteUrl = '', siteName = 'Home' } = options\n\n const items = [\n {\n '@type': 'ListItem',\n position: 1,\n name: siteName,\n item: siteUrl,\n },\n {\n '@type': 'ListItem',\n position: 2,\n name: 'Blog',\n item: `${siteUrl}/blog`,\n },\n ]\n\n if (post.category) {\n const categoryName = typeof post.category === 'string' ? post.category : post.category.name\n const categorySlug = typeof post.category === 'string' \n ? post.category.toLowerCase().replace(/\\s+/g, '-')\n : post.category.slug\n\n items.push({\n '@type': 'ListItem',\n position: 3,\n name: categoryName,\n item: `${siteUrl}/blog/category/${categorySlug}`,\n })\n\n items.push({\n '@type': 'ListItem',\n position: 4,\n name: post.title,\n item: `${siteUrl}/blog/${post.slug}`,\n })\n } else {\n items.push({\n '@type': 'ListItem',\n position: 3,\n name: post.title,\n item: `${siteUrl}/blog/${post.slug}`,\n })\n }\n\n return {\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: items,\n }\n}\n\n// ============================================================================\n// COMBINED SCHEMA (Article + FAQ + Breadcrumb)\n// ============================================================================\n\n/**\n * Generate all relevant schemas for a blog post in a single array\n * This is the recommended way to include multiple schemas.\n * When post has E-E-A-T schema (post.schema), use it instead of generating Article/FAQ.\n */\nexport function generateAllBlogSchemas(\n post: BlogPost,\n options: { siteUrl?: string; siteName?: string; logoUrl?: string } = {}\n): object[] {\n const schemas: object[] = []\n\n // E-E-A-T: use pre-built schema from Signal when present\n const eeatSchema = post.schema\n if (eeatSchema) {\n const arr = Array.isArray(eeatSchema) ? eeatSchema : [eeatSchema]\n schemas.push(...arr)\n } else {\n // 1. Article/BlogPosting schema (always)\n schemas.push(generateBlogPostSchema(post, options))\n\n // 3. FAQ schema (if FAQs present)\n const faqItems = post.faq_items ?? (post as any).faqItems\n if (faqItems && faqItems.length > 0) {\n const faqSchema = generateFaqSchema(faqItems)\n if (faqSchema) schemas.push(faqSchema)\n }\n }\n\n // 2. Breadcrumb schema (always)\n schemas.push(generateBreadcrumbSchema(post, options))\n\n return schemas\n}\n\n// ============================================================================\n// AUTHOR PAGE DATA FETCHING\n// ============================================================================\n\n/**\n * Fetch a single author by slug\n */\nexport async function getAuthorBySlug(slug: string): Promise<BlogAuthor | null> {\n const { apiUrl, apiKey } = getConfig()\n\n if (!apiKey) {\n console.warn('[Blog] No API key configured')\n return null\n }\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/authors/${slug}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n })\n\n if (!response.ok) return null\n\n const data = await response.json()\n return data.author || null\n } catch (error) {\n console.error('[Blog] Error fetching author:', error)\n return null\n }\n}\n\n/**\n * Fetch an author's posts by slug\n */\nexport async function getAuthorPosts(\n slug: string,\n limit = 20\n): Promise<{ author: BlogAuthor | null; posts: BlogPost[]; total: number }> {\n const { apiUrl, apiKey } = getConfig()\n\n if (!apiKey) {\n console.warn('[Blog] No API key configured')\n return { author: null, posts: [], total: 0 }\n }\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/authors/${slug}/posts?limit=${limit}`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 60 },\n })\n\n if (!response.ok) return { author: null, posts: [], total: 0 }\n\n const data = await response.json()\n return {\n author: data.author || null,\n posts: data.posts || [],\n total: data.total || 0,\n }\n } catch (error) {\n console.error('[Blog] Error fetching author posts:', error)\n return { author: null, posts: [], total: 0 }\n }\n}\n\n/**\n * Fetch all author slugs for static generation\n */\nexport async function getAllAuthorSlugs(): Promise<{ slug: string }[]> {\n const { apiUrl, apiKey } = getConfig()\n\n if (!apiKey) {\n console.warn('[Blog] No API key configured')\n return []\n }\n\n try {\n const response = await fetch(`${apiUrl}/public/blog/authors`, {\n headers: { 'x-api-key': apiKey },\n next: { revalidate: 300 },\n })\n\n if (!response.ok) return []\n\n const data = await response.json()\n const authors: BlogAuthor[] = data.authors || []\n return authors.map((a) => ({ slug: a.slug }))\n } catch (error) {\n console.error('[Blog] Error fetching author slugs:', error)\n return []\n }\n}\n\n/**\n * Generate static params for author pages\n * Usage: export const generateStaticParams = generateAuthorStaticParams\n */\nexport async function generateAuthorStaticParams(): Promise<{ slug: string }[]> {\n return getAllAuthorSlugs()\n}\n\n// ============================================================================\n// AUTHOR METADATA & SCHEMA\n// ============================================================================\n\n/**\n * Generate Next.js Metadata for an author page\n */\nexport function generateAuthorPageMetadata(\n author: BlogAuthor,\n options: { siteUrl?: string; siteName?: string } = {}\n): Metadata {\n const { siteUrl = '', siteName } = options\n const title = `${author.name}${author.title ? ` - ${author.title}` : ''}`\n const description = author.short_bio || author.bio || `Articles by ${author.name}`\n const url = `${siteUrl}/blog/author/${author.slug}`\n\n return {\n title,\n description,\n openGraph: {\n title,\n description,\n url,\n siteName,\n type: 'profile',\n images: author.avatar_url ? [{ url: author.avatar_url }] : undefined,\n },\n twitter: {\n card: 'summary',\n title,\n description,\n images: author.avatar_url ? [author.avatar_url] : undefined,\n },\n alternates: {\n canonical: author.author_page_url || url,\n },\n }\n}\n\n/**\n * Generate Person JSON-LD schema for an author page\n */\nexport function generateAuthorSchema(\n author: BlogAuthor,\n options: { siteUrl?: string; siteName?: string } = {}\n): object {\n const { siteUrl = '', siteName } = options\n\n const sameAs: string[] = [...(author.same_as || [])]\n if (author.linkedin_url) sameAs.push(author.linkedin_url)\n if (author.twitter_url) sameAs.push(author.twitter_url)\n if (author.website_url) sameAs.push(author.website_url)\n if (author.social_links?.twitter) sameAs.push(`https://twitter.com/${author.social_links.twitter}`)\n if (author.social_links?.linkedin) sameAs.push(author.social_links.linkedin)\n if (author.social_links?.github) sameAs.push(`https://github.com/${author.social_links.github}`)\n\n // Deduplicate\n const uniqueSameAs = [...new Set(sameAs.filter(Boolean))]\n\n const schema: Record<string, any> = {\n '@context': 'https://schema.org',\n '@type': 'Person',\n name: author.name,\n url: author.author_page_url || `${siteUrl}/blog/author/${author.slug}`,\n }\n\n if (author.title) schema.jobTitle = author.title\n if (author.company) {\n schema.worksFor = {\n '@type': 'Organization',\n name: author.company,\n }\n }\n if (author.bio || author.short_bio) schema.description = author.short_bio || author.bio\n if (author.avatar_url) schema.image = author.avatar_url\n if (uniqueSameAs.length > 0) schema.sameAs = uniqueSameAs\n if (author.knows_about && author.knows_about.length > 0) schema.knowsAbout = author.knows_about\n if (author.credentials && author.credentials.length > 0) {\n schema.hasCredential = author.credentials.map((c) => ({\n '@type': 'EducationalOccupationalCredential',\n credentialCategory: c,\n }))\n }\n\n return schema\n}\n"]}
@@ -63,7 +63,7 @@ var LazySignalBridge = dynamic(
63
63
  { ssr: false }
64
64
  );
65
65
  var LazySitemapSync = dynamic(
66
- () => import('./SitemapSync-YK6IXOSY.mjs').then((m) => ({ default: m.SitemapSync })),
66
+ () => import('./SitemapSync-DXIV5TXI.mjs').then((m) => ({ default: m.SitemapSync })),
67
67
  { ssr: false }
68
68
  );
69
69
  function SiteKitClientProviders({
@@ -150,5 +150,5 @@ function SiteKitClientProviders({
150
150
  }
151
151
 
152
152
  export { SiteKitClientProviders };
153
- //# sourceMappingURL=chunk-WN2PUL6B.mjs.map
154
- //# sourceMappingURL=chunk-WN2PUL6B.mjs.map
153
+ //# sourceMappingURL=chunk-RVAFAOBA.mjs.map
154
+ //# sourceMappingURL=chunk-RVAFAOBA.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/identity.tsx","../src/layout/SiteKitClientProviders.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-WN2PUL6B.mjs","sourcesContent":["/**\n * @sonordev/site-kit/shared — Unified Identity Management\n *\n * Single source of truth for visitor and session IDs across\n * Analytics, Signal, and Engage modules.\n *\n * Storage keys:\n * localStorage: _sk_vid (visitor ID, persists ~forever)\n * sessionStorage: _sk_sid (session ID, per-tab)\n * sessionStorage: _sk_stime (last activity timestamp for timeout)\n *\n * Storage keys are prefixed with `_sk_*`.\n */\n\n'use client'\n\nimport React, { createContext, useContext, useMemo } from 'react'\n\n// ============================================\n// ID Generation\n// ============================================\n\nfunction generateId(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID()\n }\n // Fallback for older environments\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16)\n })\n}\n\n/**\n * Get or create a persistent visitor ID.\n * Stored in localStorage under `_sk_vid`.\n */\nexport function getOrCreateVisitorId(): string {\n if (typeof window === 'undefined') return ''\n\n let visitorId = localStorage.getItem('_sk_vid')\n\n if (!visitorId) {\n visitorId = generateId()\n }\n\n localStorage.setItem('_sk_vid', visitorId)\n return visitorId\n}\n\n/**\n * Get or create a session ID with inactivity timeout.\n * Stored in sessionStorage under `_sk_sid`.\n * Session expires after `timeoutMinutes` of inactivity (default 30).\n */\nexport function getOrCreateSessionId(timeoutMinutes = 30): string {\n if (typeof window === 'undefined') return ''\n\n const now = Date.now()\n const timeoutMs = timeoutMinutes * 60 * 1000\n\n const existingSession = sessionStorage.getItem('_sk_sid')\n const lastActivity = sessionStorage.getItem('_sk_stime')\n\n if (existingSession && lastActivity) {\n const elapsed = now - parseInt(lastActivity, 10)\n if (elapsed < timeoutMs) {\n // Session still active — refresh timestamp\n sessionStorage.setItem('_sk_stime', now.toString())\n sessionStorage.setItem('_sk_sid', existingSession)\n return existingSession\n }\n }\n\n // New session (first visit or timeout expired)\n const newSession = generateId()\n sessionStorage.setItem('_sk_sid', newSession)\n sessionStorage.setItem('_sk_stime', now.toString())\n return newSession\n}\n\n// ============================================\n// React Context\n// ============================================\n\nexport interface SiteKitIdentity {\n visitorId: string\n sessionId: string\n}\n\nconst SiteKitIdentityContext = createContext<SiteKitIdentity | null>(null)\n\nexport interface SiteKitIdentityProviderProps {\n visitorId: string\n sessionId: string\n children: React.ReactNode\n}\n\nexport function SiteKitIdentityProvider({\n visitorId,\n sessionId,\n children,\n}: SiteKitIdentityProviderProps) {\n const value = useMemo(() => ({ visitorId, sessionId }), [visitorId, sessionId])\n\n return (\n <SiteKitIdentityContext.Provider value={value}>\n {children}\n </SiteKitIdentityContext.Provider>\n )\n}\n\n/**\n * Access the shared visitor/session identity.\n * Falls back to generating IDs directly if used outside of SiteKitIdentityProvider.\n */\nexport function useSiteKitIdentity(): SiteKitIdentity {\n const context = useContext(SiteKitIdentityContext)\n if (context) return context\n\n // Fallback for standalone usage outside SiteKitLayout\n return {\n visitorId: getOrCreateVisitorId(),\n sessionId: getOrCreateSessionId(),\n }\n}\n","'use client'\n\n/**\n * SiteKitClientProviders — Client Island\n *\n * This is the 'use client' boundary for SiteKitLayout.\n * It composes the client-only providers (Analytics, Engage, Signal, SitemapSync)\n * that require React context or browser APIs.\n *\n * All modules are lazy-loaded via next/dynamic so their JS is only downloaded\n * when the feature is enabled — keeping the initial bundle lightweight.\n *\n * All modules share a unified identity (visitor ID + session ID) via\n * SiteKitIdentityProvider, ensuring consistent tracking across Analytics,\n * Signal, and Engage.\n *\n * Props are passed down from the server-side SiteKitLayout component,\n * which reads env vars at render time.\n */\n\nimport React, { Suspense, useCallback, useRef, useState, type ReactNode } from 'react'\nimport dynamic from 'next/dynamic'\nimport {\n SiteKitIdentityProvider,\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\n// Lazy-load feature modules — JS only downloaded when feature is enabled\nconst LazyAnalyticsProvider = dynamic(\n () => import('../analytics/AnalyticsProvider').then(m => ({ default: m.AnalyticsProvider })),\n { ssr: false },\n)\nconst LazyEngageWidget = dynamic(\n () => import('../engage/EngageWidget').then(m => ({ default: m.EngageWidget })),\n { ssr: false },\n)\nconst LazySignalBridge = dynamic(\n () => import('../signal/SignalBridge').then(m => ({ default: m.SignalBridge })),\n { ssr: false },\n)\nconst LazySitemapSync = dynamic(\n () => import('../SitemapSync').then(m => ({ default: m.SitemapSync })),\n { ssr: false },\n)\n\nexport interface SiteKitClientProvidersProps {\n children: ReactNode\n apiKey: string\n apiUrl: string\n projectId?: string\n analytics?: boolean | AnalyticsConfig\n engage?: boolean | EngageConfig\n signal?: boolean | SignalConfig\n sitemapSync?: boolean\n debug?: boolean\n}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = true,\n debug = false,\n}: SiteKitClientProvidersProps) {\n // Set window globals for modules that still read from them\n if (typeof window !== 'undefined') {\n ;(window as any).__SITE_KIT_API_URL__ = apiUrl\n ;(window as any).__SITE_KIT_API_KEY__ = apiKey\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n }\n\n // Unified identity — single source of truth for all modules\n const [visitorId] = useState(() => getOrCreateVisitorId())\n const [sessionId] = useState(() => getOrCreateSessionId())\n\n // Page metadata bridge: Analytics writes, Signal reads\n const pageMetadataRef = useRef<Record<string, unknown> | null>(null)\n const onPageMetadata = useCallback((metadata: Record<string, unknown>) => {\n pageMetadataRef.current = metadata\n }, [])\n\n let content = <>{children}</>\n\n // Wrap with SignalBridge if enabled\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n content = (\n <LazySignalBridge\n enabled\n realtime={signalConfig.realtime !== false}\n experiments={signalConfig.experiments !== false}\n behaviorTracking={signalConfig.behaviorTracking !== false}\n visitorId={visitorId}\n sessionId={sessionId}\n pageMetadataRef={pageMetadataRef}\n >\n {content}\n </LazySignalBridge>\n )\n }\n\n // Wrap with Analytics if enabled\n if (analytics) {\n const analyticsConfig: AnalyticsConfig =\n typeof analytics === 'object' ? analytics : {}\n content = (\n <Suspense fallback={null}>\n <LazyAnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n trackPageViews={analyticsConfig.trackPageViews !== false}\n trackWebVitals={analyticsConfig.trackWebVitals !== false}\n trackScrollDepth={analyticsConfig.trackScrollDepth !== false}\n trackClicks={analyticsConfig.trackClicks !== false}\n debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n >\n {content}\n </LazyAnalyticsProvider>\n </Suspense>\n )\n }\n\n // Add Engage widget if enabled (renders alongside, doesn't wrap)\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n content = (\n <>\n {content}\n <LazyEngageWidget\n apiUrl={apiUrl}\n apiKey={apiKey}\n projectId={projectId}\n position={engageConfig.position || 'bottom-right'}\n chatEnabled={engageConfig.chatEnabled !== false}\n />\n </>\n )\n }\n\n // Add SitemapSync if enabled\n if (sitemapSync) {\n content = (\n <>\n {content}\n <LazySitemapSync debug={debug} />\n </>\n )\n }\n\n return (\n <SiteKitIdentityProvider visitorId={visitorId} sessionId={sessionId}>\n {content}\n </SiteKitIdentityProvider>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/shared/identity.tsx","../src/layout/SiteKitClientProviders.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-RVAFAOBA.mjs","sourcesContent":["/**\n * @sonordev/site-kit/shared — Unified Identity Management\n *\n * Single source of truth for visitor and session IDs across\n * Analytics, Signal, and Engage modules.\n *\n * Storage keys:\n * localStorage: _sk_vid (visitor ID, persists ~forever)\n * sessionStorage: _sk_sid (session ID, per-tab)\n * sessionStorage: _sk_stime (last activity timestamp for timeout)\n *\n * Storage keys are prefixed with `_sk_*`.\n */\n\n'use client'\n\nimport React, { createContext, useContext, useMemo } from 'react'\n\n// ============================================\n// ID Generation\n// ============================================\n\nfunction generateId(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID()\n }\n // Fallback for older environments\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16)\n })\n}\n\n/**\n * Get or create a persistent visitor ID.\n * Stored in localStorage under `_sk_vid`.\n */\nexport function getOrCreateVisitorId(): string {\n if (typeof window === 'undefined') return ''\n\n let visitorId = localStorage.getItem('_sk_vid')\n\n if (!visitorId) {\n visitorId = generateId()\n }\n\n localStorage.setItem('_sk_vid', visitorId)\n return visitorId\n}\n\n/**\n * Get or create a session ID with inactivity timeout.\n * Stored in sessionStorage under `_sk_sid`.\n * Session expires after `timeoutMinutes` of inactivity (default 30).\n */\nexport function getOrCreateSessionId(timeoutMinutes = 30): string {\n if (typeof window === 'undefined') return ''\n\n const now = Date.now()\n const timeoutMs = timeoutMinutes * 60 * 1000\n\n const existingSession = sessionStorage.getItem('_sk_sid')\n const lastActivity = sessionStorage.getItem('_sk_stime')\n\n if (existingSession && lastActivity) {\n const elapsed = now - parseInt(lastActivity, 10)\n if (elapsed < timeoutMs) {\n // Session still active — refresh timestamp\n sessionStorage.setItem('_sk_stime', now.toString())\n sessionStorage.setItem('_sk_sid', existingSession)\n return existingSession\n }\n }\n\n // New session (first visit or timeout expired)\n const newSession = generateId()\n sessionStorage.setItem('_sk_sid', newSession)\n sessionStorage.setItem('_sk_stime', now.toString())\n return newSession\n}\n\n// ============================================\n// React Context\n// ============================================\n\nexport interface SiteKitIdentity {\n visitorId: string\n sessionId: string\n}\n\nconst SiteKitIdentityContext = createContext<SiteKitIdentity | null>(null)\n\nexport interface SiteKitIdentityProviderProps {\n visitorId: string\n sessionId: string\n children: React.ReactNode\n}\n\nexport function SiteKitIdentityProvider({\n visitorId,\n sessionId,\n children,\n}: SiteKitIdentityProviderProps) {\n const value = useMemo(() => ({ visitorId, sessionId }), [visitorId, sessionId])\n\n return (\n <SiteKitIdentityContext.Provider value={value}>\n {children}\n </SiteKitIdentityContext.Provider>\n )\n}\n\n/**\n * Access the shared visitor/session identity.\n * Falls back to generating IDs directly if used outside of SiteKitIdentityProvider.\n */\nexport function useSiteKitIdentity(): SiteKitIdentity {\n const context = useContext(SiteKitIdentityContext)\n if (context) return context\n\n // Fallback for standalone usage outside SiteKitLayout\n return {\n visitorId: getOrCreateVisitorId(),\n sessionId: getOrCreateSessionId(),\n }\n}\n","'use client'\n\n/**\n * SiteKitClientProviders — Client Island\n *\n * This is the 'use client' boundary for SiteKitLayout.\n * It composes the client-only providers (Analytics, Engage, Signal, SitemapSync)\n * that require React context or browser APIs.\n *\n * All modules are lazy-loaded via next/dynamic so their JS is only downloaded\n * when the feature is enabled — keeping the initial bundle lightweight.\n *\n * All modules share a unified identity (visitor ID + session ID) via\n * SiteKitIdentityProvider, ensuring consistent tracking across Analytics,\n * Signal, and Engage.\n *\n * Props are passed down from the server-side SiteKitLayout component,\n * which reads env vars at render time.\n */\n\nimport React, { Suspense, useCallback, useRef, useState, type ReactNode } from 'react'\nimport dynamic from 'next/dynamic'\nimport {\n SiteKitIdentityProvider,\n getOrCreateVisitorId,\n getOrCreateSessionId,\n} from '../shared/identity'\nimport type { AnalyticsConfig, EngageConfig, SignalConfig } from './types'\n\n// Lazy-load feature modules — JS only downloaded when feature is enabled\nconst LazyAnalyticsProvider = dynamic(\n () => import('../analytics/AnalyticsProvider').then(m => ({ default: m.AnalyticsProvider })),\n { ssr: false },\n)\nconst LazyEngageWidget = dynamic(\n () => import('../engage/EngageWidget').then(m => ({ default: m.EngageWidget })),\n { ssr: false },\n)\nconst LazySignalBridge = dynamic(\n () => import('../signal/SignalBridge').then(m => ({ default: m.SignalBridge })),\n { ssr: false },\n)\nconst LazySitemapSync = dynamic(\n () => import('../SitemapSync').then(m => ({ default: m.SitemapSync })),\n { ssr: false },\n)\n\nexport interface SiteKitClientProvidersProps {\n children: ReactNode\n apiKey: string\n apiUrl: string\n projectId?: string\n analytics?: boolean | AnalyticsConfig\n engage?: boolean | EngageConfig\n signal?: boolean | SignalConfig\n sitemapSync?: boolean\n debug?: boolean\n}\n\nexport function SiteKitClientProviders({\n children,\n apiKey,\n apiUrl,\n projectId,\n analytics = true,\n engage = true,\n signal = false,\n sitemapSync = true,\n debug = false,\n}: SiteKitClientProvidersProps) {\n // Set window globals for modules that still read from them\n if (typeof window !== 'undefined') {\n ;(window as any).__SITE_KIT_API_URL__ = apiUrl\n ;(window as any).__SITE_KIT_API_KEY__ = apiKey\n ;(window as any).__SITE_KIT_DEBUG__ = debug\n }\n\n // Unified identity — single source of truth for all modules\n const [visitorId] = useState(() => getOrCreateVisitorId())\n const [sessionId] = useState(() => getOrCreateSessionId())\n\n // Page metadata bridge: Analytics writes, Signal reads\n const pageMetadataRef = useRef<Record<string, unknown> | null>(null)\n const onPageMetadata = useCallback((metadata: Record<string, unknown>) => {\n pageMetadataRef.current = metadata\n }, [])\n\n let content = <>{children}</>\n\n // Wrap with SignalBridge if enabled\n if (signal) {\n const signalConfig: SignalConfig =\n typeof signal === 'object' ? signal : {}\n content = (\n <LazySignalBridge\n enabled\n realtime={signalConfig.realtime !== false}\n experiments={signalConfig.experiments !== false}\n behaviorTracking={signalConfig.behaviorTracking !== false}\n visitorId={visitorId}\n sessionId={sessionId}\n pageMetadataRef={pageMetadataRef}\n >\n {content}\n </LazySignalBridge>\n )\n }\n\n // Wrap with Analytics if enabled\n if (analytics) {\n const analyticsConfig: AnalyticsConfig =\n typeof analytics === 'object' ? analytics : {}\n content = (\n <Suspense fallback={null}>\n <LazyAnalyticsProvider\n apiUrl={apiUrl}\n apiKey={apiKey}\n trackPageViews={analyticsConfig.trackPageViews !== false}\n trackWebVitals={analyticsConfig.trackWebVitals !== false}\n trackScrollDepth={analyticsConfig.trackScrollDepth !== false}\n trackClicks={analyticsConfig.trackClicks !== false}\n debug={debug}\n externalVisitorId={visitorId}\n externalSessionId={sessionId}\n onPageMetadata={onPageMetadata}\n >\n {content}\n </LazyAnalyticsProvider>\n </Suspense>\n )\n }\n\n // Add Engage widget if enabled (renders alongside, doesn't wrap)\n if (engage) {\n const engageConfig: EngageConfig =\n typeof engage === 'object' ? engage : {}\n content = (\n <>\n {content}\n <LazyEngageWidget\n apiUrl={apiUrl}\n apiKey={apiKey}\n projectId={projectId}\n position={engageConfig.position || 'bottom-right'}\n chatEnabled={engageConfig.chatEnabled !== false}\n />\n </>\n )\n }\n\n // Add SitemapSync if enabled\n if (sitemapSync) {\n content = (\n <>\n {content}\n <LazySitemapSync debug={debug} />\n </>\n )\n }\n\n return (\n <SiteKitIdentityProvider visitorId={visitorId} sessionId={sessionId}>\n {content}\n </SiteKitIdentityProvider>\n )\n}\n"]}