@dsaplatform/content-sdk 1.4.0 → 1.5.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.
- package/dist/headless.d.mts +0 -23
- package/dist/headless.d.ts +0 -23
- package/dist/index.d.mts +123 -27
- package/dist/index.d.ts +123 -27
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +0 -23
- package/dist/server.d.ts +0 -23
- package/package.json +6 -3
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/provider.tsx","../src/hooks.ts","../src/components/ArticleFeed.tsx","../src/components/ArticlePage.tsx","../src/components/FaqBlock.tsx","../src/components/RelatedArticles.tsx","../src/components/SeoMetaBridge.tsx"],"sourcesContent":["import type {\n DsaContentConfig,\n Article,\n ArticleListItem,\n ArticleFilters,\n PaginatedResponse,\n Category,\n SitemapEntry,\n} from './types';\n\n/**\n * ContentClient — HTTP client for DSA Content Engine Public API.\n * Works in both Node.js (SSR) and browser environments.\n */\nexport class ContentClient {\n private apiUrl: string;\n private apiKey: string;\n private cacheStrategy: RequestCache;\n private revalidateSeconds?: number;\n\n constructor(config: DsaContentConfig) {\n this.apiUrl = config.apiUrl.replace(/\\/+$/, '');\n this.apiKey = config.apiKey;\n this.cacheStrategy =\n config.cacheStrategy === 'revalidate'\n ? 'default'\n : config.cacheStrategy === 'force-cache'\n ? 'force-cache'\n : 'no-cache';\n this.revalidateSeconds = config.revalidateSeconds;\n }\n\n private async request<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T> {\n const url = new URL(`${this.apiUrl}${path}`);\n if (params) {\n Object.entries(params).forEach(([k, v]) => {\n if (v !== undefined && v !== null && v !== '') {\n url.searchParams.set(k, String(v));\n }\n });\n }\n url.searchParams.set('site_key', this.apiKey);\n\n const fetchOptions: RequestInit & { next?: { revalidate?: number } } = {\n method: 'GET',\n headers: { 'X-API-Key': this.apiKey },\n cache: this.cacheStrategy,\n };\n\n // Next.js ISR revalidation\n if (this.revalidateSeconds && this.cacheStrategy !== 'no-cache') {\n fetchOptions.next = { revalidate: this.revalidateSeconds };\n }\n\n const res = await fetch(url.toString(), fetchOptions);\n\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`DSA Content API error ${res.status}: ${text || res.statusText}`);\n }\n\n return res.json() as Promise<T>;\n }\n\n /** Normalize article array fields to guarantee they're never null/undefined */\n private normalizeArticle(article: Article): Article {\n return {\n ...article,\n headings: article.headings ?? [],\n faq: article.faq ?? [],\n internal_links: article.internal_links ?? [],\n secondary_keywords: article.secondary_keywords ?? [],\n schema_json: article.schema_json ?? null,\n content_json: article.content_json ?? null,\n };\n }\n\n /** Get paginated list of published articles */\n async getArticles(filters?: ArticleFilters): Promise<PaginatedResponse<ArticleListItem>> {\n const raw = await this.request<Record<string, any>>('/api/public/articles', {\n page: filters?.page,\n per_page: filters?.per_page,\n pillar: filters?.pillar,\n cluster: filters?.cluster,\n content_type: filters?.content_type,\n search: filters?.search,\n });\n return {\n items: raw.items ?? raw.data ?? [],\n total: raw.total ?? 0,\n page: raw.page ?? 1,\n per_page: raw.per_page ?? 20,\n total_pages: raw.total_pages ?? raw.pages ?? 1,\n };\n }\n\n /** Get a single article by slug */\n async getArticleBySlug(slug: string): Promise<Article> {\n const article = await this.request<Article>(`/api/public/articles/${encodeURIComponent(slug)}`);\n return this.normalizeArticle(article);\n }\n\n /** Get related articles for a given slug */\n async getRelatedArticles(slug: string, limit = 3): Promise<ArticleListItem[]> {\n const raw = await this.request<Record<string, any>>(\n `/api/public/articles/${encodeURIComponent(slug)}/related`,\n { limit },\n );\n return raw.items ?? (Array.isArray(raw) ? raw : []);\n }\n\n /** Get all categories (pillars + clusters) with article counts */\n async getCategories(): Promise<Category[]> {\n const raw = await this.request<Record<string, any>>('/api/public/categories');\n return raw.items ?? (Array.isArray(raw) ? raw : []);\n }\n\n /** Get sitemap data for all published articles */\n async getSitemap(): Promise<SitemapEntry[]> {\n const raw = await this.request<Record<string, any>>('/api/public/sitemap');\n return raw.items ?? (Array.isArray(raw) ? raw : []);\n }\n}\n","'use client';\n\nimport React, { createContext, useContext, useMemo } from 'react';\nimport { ContentClient } from './client';\nimport type { DsaContentConfig } from './types';\n\nconst ContentContext = createContext<ContentClient | null>(null);\n\nexport interface DsaContentProviderProps {\n config: DsaContentConfig;\n children: React.ReactNode;\n}\n\n/**\n * Wrap your app (or a subtree) with DsaContentProvider to enable\n * the useDsaContent() hook and all data-fetching hooks.\n *\n * ```tsx\n * <DsaContentProvider config={{ apiUrl: \"...\", apiKey: \"...\" }}>\n * <App />\n * </DsaContentProvider>\n * ```\n */\nexport function DsaContentProvider({ config, children }: DsaContentProviderProps) {\n const client = useMemo(() => new ContentClient(config), [config.apiUrl, config.apiKey]);\n return <ContentContext.Provider value={client}>{children}</ContentContext.Provider>;\n}\n\n/**\n * Access the ContentClient instance from context.\n * Must be called inside a DsaContentProvider.\n */\nexport function useDsaContent(): ContentClient {\n const client = useContext(ContentContext);\n if (!client) {\n throw new Error('useDsaContent() must be used inside <DsaContentProvider>');\n }\n return client;\n}\n","'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { useDsaContent } from './provider';\nimport type {\n ArticleFilters,\n UseArticlesState,\n UseArticleState,\n UseArticleListState,\n UseCategoriesState,\n} from './types';\n\n/**\n * Fetch a paginated list of published articles.\n *\n * ```tsx\n * const { articles, loading, error, pagination } = useArticles({ page: 1, per_page: 10 });\n * ```\n */\nexport function useArticles(filters?: ArticleFilters): UseArticlesState & { refetch: () => void } {\n const client = useDsaContent();\n const [state, setState] = useState<UseArticlesState>({\n articles: [],\n loading: true,\n error: null,\n pagination: { page: 1, per_page: 10, total: 0, total_pages: 0 },\n });\n\n const fetch = useCallback(() => {\n setState((s) => ({ ...s, loading: true, error: null }));\n client\n .getArticles(filters)\n .then((res) =>\n setState({\n articles: res.items,\n loading: false,\n error: null,\n pagination: {\n page: res.page,\n per_page: res.per_page,\n total: res.total,\n total_pages: res.total_pages,\n },\n }),\n )\n .catch((err) =>\n setState((s) => ({ ...s, loading: false, error: err instanceof Error ? err : new Error(String(err)) })),\n );\n }, [client, filters?.page, filters?.per_page, filters?.pillar, filters?.cluster, filters?.content_type, filters?.search]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n return { ...state, refetch: fetch };\n}\n\n/**\n * Fetch a single article by slug.\n *\n * ```tsx\n * const { article, loading, error } = useArticle(\"my-article-slug\");\n * ```\n */\nexport function useArticle(slug: string | undefined): UseArticleState & { refetch: () => void } {\n const client = useDsaContent();\n const [state, setState] = useState<UseArticleState>({ article: null, loading: true, error: null });\n\n const fetch = useCallback(() => {\n if (!slug) {\n setState({ article: null, loading: false, error: null });\n return;\n }\n setState((s) => ({ ...s, loading: true, error: null }));\n client\n .getArticleBySlug(slug)\n .then((article) => setState({ article, loading: false, error: null }))\n .catch((err) =>\n setState({ article: null, loading: false, error: err instanceof Error ? err : new Error(String(err)) }),\n );\n }, [client, slug]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n return { ...state, refetch: fetch };\n}\n\n/**\n * Fetch related articles for a given slug.\n *\n * ```tsx\n * const { articles, loading } = useRelatedArticles(\"my-article-slug\", 4);\n * ```\n */\nexport function useRelatedArticles(slug: string | undefined, limit = 3): UseArticleListState & { refetch: () => void } {\n const client = useDsaContent();\n const [state, setState] = useState<UseArticleListState>({ articles: [], loading: true, error: null });\n\n const fetch = useCallback(() => {\n if (!slug) {\n setState({ articles: [], loading: false, error: null });\n return;\n }\n setState((s) => ({ ...s, loading: true, error: null }));\n client\n .getRelatedArticles(slug, limit)\n .then((articles) => setState({ articles, loading: false, error: null }))\n .catch((err) =>\n setState({ articles: [], loading: false, error: err instanceof Error ? err : new Error(String(err)) }),\n );\n }, [client, slug, limit]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n return { ...state, refetch: fetch };\n}\n\n/**\n * Fetch all categories (pillars + clusters).\n *\n * ```tsx\n * const { categories, loading } = useCategories();\n * ```\n */\nexport function useCategories(): UseCategoriesState & { refetch: () => void } {\n const client = useDsaContent();\n const [state, setState] = useState<UseCategoriesState>({ categories: [], loading: true, error: null });\n\n const fetch = useCallback(() => {\n setState((s) => ({ ...s, loading: true, error: null }));\n client\n .getCategories()\n .then((categories) => setState({ categories, loading: false, error: null }))\n .catch((err) =>\n setState({ categories: [], loading: false, error: err instanceof Error ? err : new Error(String(err)) }),\n );\n }, [client]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n return { ...state, refetch: fetch };\n}\n","'use client';\n\nimport React from 'react';\nimport type { ArticleListItem } from '../types';\n\nexport interface ArticleFeedProps {\n articles: ArticleListItem[];\n layout?: 'grid' | 'list';\n columns?: 1 | 2 | 3;\n showExcerpt?: boolean;\n showImage?: boolean;\n showMeta?: boolean;\n onArticleClick?: (slug: string) => void;\n className?: string;\n /** \"light\" | \"dark\" | \"inherit\" — sets CSS variable defaults. Use \"inherit\" to control via your own CSS vars. */\n theme?: 'light' | 'dark' | 'inherit';\n renderArticle?: (article: ArticleListItem) => React.ReactNode;\n}\n\nconst themeVars = {\n light: {\n '--dsa-text': '#111827',\n '--dsa-text-muted': '#6b7280',\n '--dsa-text-faint': '#9ca3af',\n '--dsa-card-bg': '#fff',\n '--dsa-card-border': '#e5e7eb',\n '--dsa-badge-bg': '#f3f4f6',\n '--dsa-badge-text': '#4b5563',\n '--dsa-hover-shadow': '0 4px 12px rgba(0,0,0,0.08)',\n },\n dark: {\n '--dsa-text': '#f3f4f6',\n '--dsa-text-muted': '#9ca3af',\n '--dsa-text-faint': '#6b7280',\n '--dsa-card-bg': '#1f2937',\n '--dsa-card-border': '#374151',\n '--dsa-badge-bg': '#374151',\n '--dsa-badge-text': '#d1d5db',\n '--dsa-hover-shadow': '0 4px 12px rgba(0,0,0,0.3)',\n },\n} as const;\n\nfunction DefaultCard({\n article,\n layout,\n showExcerpt,\n showImage,\n showMeta,\n onClick,\n}: {\n article: ArticleListItem;\n layout: 'grid' | 'list';\n showExcerpt: boolean;\n showImage: boolean;\n showMeta: boolean;\n onClick?: () => void;\n}) {\n const isGrid = layout === 'grid';\n const [hovered, setHovered] = React.useState(false);\n\n const cardStyle: React.CSSProperties = {\n ...(isGrid\n ? { border: '1px solid var(--dsa-card-border)', borderRadius: '0.75rem', overflow: 'hidden', background: 'var(--dsa-card-bg)', cursor: 'pointer', transition: 'box-shadow 0.2s' }\n : { display: 'flex', border: '1px solid var(--dsa-card-border)', borderRadius: '0.75rem', overflow: 'hidden', background: 'var(--dsa-card-bg)', cursor: 'pointer', transition: 'box-shadow 0.2s' }),\n ...(hovered ? { boxShadow: 'var(--dsa-hover-shadow)' } : {}),\n };\n\n return (\n <article\n style={cardStyle}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n onClick={onClick}\n role=\"link\"\n tabIndex={0}\n onKeyDown={(e) => e.key === 'Enter' && onClick?.()}\n >\n {showImage && article.featured_image_url && (\n <img\n src={article.featured_image_url}\n alt={article.featured_image_alt || article.title}\n style={isGrid\n ? { width: '100%', height: '200px', objectFit: 'cover' as const, display: 'block' }\n : { width: '240px', minHeight: '160px', objectFit: 'cover' as const, flexShrink: 0 }}\n loading=\"lazy\"\n />\n )}\n <div style={isGrid ? { padding: '1.25rem' } : { padding: '1.25rem', flex: 1 }}>\n <h3 style={{ margin: '0 0 0.5rem', fontSize: '1.125rem', fontWeight: 600, lineHeight: 1.3, color: 'var(--dsa-text)' }}>\n {article.title}\n </h3>\n {showExcerpt && article.excerpt && (\n <p style={{ margin: '0 0 0.75rem', fontSize: '0.875rem', color: 'var(--dsa-text-muted)', lineHeight: 1.5 }}>\n {article.excerpt}\n </p>\n )}\n {showMeta && (\n <div style={{ display: 'flex', gap: '0.75rem', fontSize: '0.75rem', color: 'var(--dsa-text-faint)', flexWrap: 'wrap' as const }}>\n {article.pillar_name && (\n <span style={{ display: 'inline-block', padding: '0.125rem 0.5rem', borderRadius: '9999px', background: 'var(--dsa-badge-bg)', fontSize: '0.75rem', color: 'var(--dsa-badge-text)' }}>\n {article.pillar_name}\n </span>\n )}\n {article.content_type && (\n <span style={{ display: 'inline-block', padding: '0.125rem 0.5rem', borderRadius: '9999px', background: 'var(--dsa-badge-bg)', fontSize: '0.75rem', color: 'var(--dsa-badge-text)' }}>\n {article.content_type.replace(/_/g, ' ')}\n </span>\n )}\n {article.reading_time_minutes && <span>{article.reading_time_minutes} min read</span>}\n {article.published_at && <span>{new Date(article.published_at).toLocaleDateString()}</span>}\n </div>\n )}\n </div>\n </article>\n );\n}\n\n/**\n * Renders a grid or list of article cards.\n * Supports theme=\"light\" | \"dark\" | \"inherit\" via CSS variables.\n *\n * CSS variables (override in your own CSS for full control):\n * --dsa-text, --dsa-text-muted, --dsa-text-faint,\n * --dsa-card-bg, --dsa-card-border,\n * --dsa-badge-bg, --dsa-badge-text, --dsa-hover-shadow\n */\nexport function ArticleFeed({\n articles,\n layout = 'grid',\n columns = 3,\n showExcerpt = true,\n showImage = true,\n showMeta = true,\n onArticleClick,\n className,\n theme = 'light',\n renderArticle,\n}: ArticleFeedProps) {\n const gridTemplateColumns = layout === 'grid' ? `repeat(${columns}, 1fr)` : '1fr';\n const vars = theme !== 'inherit' ? themeVars[theme] : {};\n\n return (\n <div\n className={className}\n style={{ display: 'grid', gap: '1.5rem', gridTemplateColumns, ...vars } as React.CSSProperties}\n >\n {(articles ?? []).map((article) =>\n renderArticle ? (\n <React.Fragment key={article.id}>{renderArticle(article)}</React.Fragment>\n ) : (\n <DefaultCard\n key={article.id}\n article={article}\n layout={layout}\n showExcerpt={showExcerpt}\n showImage={showImage}\n showMeta={showMeta}\n onClick={() => onArticleClick?.(article.slug)}\n />\n ),\n )}\n </div>\n );\n}\n","'use client';\n\nimport React from 'react';\nimport type { Article, ArticleListItem, FaqItem } from '../types';\nimport { FaqBlock } from './FaqBlock';\nimport { RelatedArticles } from './RelatedArticles';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ArticleTheme = 'light' | 'dark' | 'inherit';\n\nexport interface ArticlePageProps {\n article: Article;\n showFaq?: boolean;\n showTableOfContents?: boolean;\n showMeta?: boolean;\n showRelated?: boolean;\n relatedArticles?: ArticleListItem[];\n onRelatedClick?: (slug: string) => void;\n className?: string;\n /** Extra class(es) on the `<div>` that wraps `content_html`. */\n contentClassName?: string;\n /**\n * `\"light\"` / `\"dark\"` — SDK applies inline styles + CSS vars + built-in prose rules.\n * `\"inherit\"` — SDK applies NO inline styles; only CSS classes and\n * `data-*` attributes are rendered so the host site has full control.\n *\n * In all modes the content body div has:\n * - `className=\"dsa-article-body\"`\n * - `data-dsa-article-body`\n *\n * @default \"light\"\n */\n theme?: ArticleTheme;\n /** Disable built-in prose styles injected via `<style>`. Works only in light/dark themes. */\n disableProseStyles?: boolean;\n components?: {\n H1?: React.ComponentType<{ children: React.ReactNode }>;\n Toc?: React.ComponentType<{ headings: Article['headings'] }>;\n Faq?: React.ComponentType<{ items: FaqItem[] }>;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Theme CSS variable presets\n// ---------------------------------------------------------------------------\n\nconst themeVars = {\n light: {\n '--dsa-text': '#111827',\n '--dsa-text-muted': '#6b7280',\n '--dsa-text-faint': '#9ca3af',\n '--dsa-card-bg': '#fff',\n '--dsa-card-border': '#e5e7eb',\n '--dsa-toc-bg': '#f9fafb',\n '--dsa-badge-bg': '#eff6ff',\n '--dsa-badge-text': '#2563eb',\n '--dsa-badge-alt-bg': '#f0fdf4',\n '--dsa-badge-alt-text': '#16a34a',\n '--dsa-content-text': '#374151',\n '--dsa-h2-text': '#111827',\n '--dsa-h3-text': '#1f2937',\n '--dsa-h4-text': '#1f2937',\n '--dsa-link': '#2563eb',\n '--dsa-link-hover': '#1d4ed8',\n '--dsa-blockquote-border': '#d1d5db',\n '--dsa-blockquote-text': '#4b5563',\n '--dsa-pre-bg': '#f3f4f6',\n '--dsa-table-border': '#e5e7eb',\n '--dsa-table-header-bg': '#f9fafb',\n '--dsa-divider': '#e5e7eb',\n },\n dark: {\n '--dsa-text': '#f3f4f6',\n '--dsa-text-muted': '#9ca3af',\n '--dsa-text-faint': '#6b7280',\n '--dsa-card-bg': '#1f2937',\n '--dsa-card-border': '#374151',\n '--dsa-toc-bg': '#111827',\n '--dsa-badge-bg': '#1e3a5f',\n '--dsa-badge-text': '#93c5fd',\n '--dsa-badge-alt-bg': '#14532d',\n '--dsa-badge-alt-text': '#86efac',\n '--dsa-content-text': '#d1d5db',\n '--dsa-h2-text': '#f3f4f6',\n '--dsa-h3-text': '#e5e7eb',\n '--dsa-h4-text': '#e5e7eb',\n '--dsa-link': '#60a5fa',\n '--dsa-link-hover': '#93c5fd',\n '--dsa-blockquote-border': '#4b5563',\n '--dsa-blockquote-text': '#9ca3af',\n '--dsa-pre-bg': '#111827',\n '--dsa-table-border': '#374151',\n '--dsa-table-header-bg': '#111827',\n '--dsa-divider': '#374151',\n },\n} as const;\n\n// ---------------------------------------------------------------------------\n// Built-in prose stylesheet (injected once via <style>)\n// ---------------------------------------------------------------------------\n\nconst PROSE_STYLE_ID = 'dsa-article-prose';\n\nconst proseCSS = /* css */ `\n[data-dsa-article-body] h2 { font-size: 1.5rem; font-weight: 700; line-height: 1.3; color: var(--dsa-h2-text, #111827); margin: 2rem 0 0.75rem; }\n[data-dsa-article-body] h3 { font-size: 1.25rem; font-weight: 600; line-height: 1.4; color: var(--dsa-h3-text, #1f2937); margin: 1.75rem 0 0.5rem; }\n[data-dsa-article-body] h4 { font-size: 1.125rem; font-weight: 600; line-height: 1.4; color: var(--dsa-h4-text, #1f2937); margin: 1.5rem 0 0.5rem; }\n[data-dsa-article-body] p { margin: 0 0 1.25rem; }\n[data-dsa-article-body] ul,\n[data-dsa-article-body] ol { margin: 0 0 1.25rem; padding-left: 1.5rem; }\n[data-dsa-article-body] li { margin: 0 0 0.375rem; }\n[data-dsa-article-body] li > ul,\n[data-dsa-article-body] li > ol { margin: 0.375rem 0 0; }\n[data-dsa-article-body] blockquote { margin: 1.5rem 0; padding: 0.75rem 1.25rem; border-left: 4px solid var(--dsa-blockquote-border, #d1d5db); color: var(--dsa-blockquote-text, #4b5563); font-style: italic; }\n[data-dsa-article-body] pre { margin: 1.5rem 0; padding: 1rem; background: var(--dsa-pre-bg, #f3f4f6); border-radius: 0.5rem; overflow-x: auto; font-size: 0.875rem; }\n[data-dsa-article-body] code { font-size: 0.875em; }\n[data-dsa-article-body] table { width: 100%; margin: 1.5rem 0; border-collapse: collapse; font-size: 0.9375rem; }\n[data-dsa-article-body] th,\n[data-dsa-article-body] td { padding: 0.5rem 0.75rem; border: 1px solid var(--dsa-table-border, #e5e7eb); text-align: left; }\n[data-dsa-article-body] th { background: var(--dsa-table-header-bg, #f9fafb); font-weight: 600; }\n[data-dsa-article-body] img { max-width: 100%; height: auto; border-radius: 0.5rem; margin: 1.5rem 0; }\n[data-dsa-article-body] a { color: var(--dsa-link, #2563eb); text-decoration: underline; text-underline-offset: 2px; }\n[data-dsa-article-body] a:hover { color: var(--dsa-link-hover, #1d4ed8); }\n[data-dsa-article-body] hr { border: none; border-top: 1px solid var(--dsa-divider, #e5e7eb); margin: 2rem 0; }\n[data-dsa-article-body] > *:first-child { margin-top: 0; }\n[data-dsa-article-body] > *:last-child { margin-bottom: 0; }\n`.trim();\n\nfunction useProseStyles(enabled: boolean) {\n React.useEffect(() => {\n if (!enabled) return;\n if (typeof document === 'undefined') return;\n if (document.getElementById(PROSE_STYLE_ID)) return;\n const el = document.createElement('style');\n el.id = PROSE_STYLE_ID;\n el.textContent = proseCSS;\n document.head.appendChild(el);\n }, [enabled]);\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction DefaultToc({ headings }: { headings: Article['headings'] }) {\n if (!headings || headings.length === 0) return null;\n return (\n <nav className=\"dsa-toc\" data-dsa-toc=\"\" style={{ background: 'var(--dsa-toc-bg, #f9fafb)', border: '1px solid var(--dsa-card-border, #e5e7eb)', borderRadius: '0.75rem', padding: '1.25rem', marginBottom: '2rem' }}>\n <p style={{ fontSize: '0.875rem', fontWeight: 600, color: 'var(--dsa-text-muted, #374151)', margin: '0 0 0.75rem', textTransform: 'uppercase' as const, letterSpacing: '0.05em' }}>\n Table of Contents\n </p>\n <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>\n {headings.map((h, i) => (\n <li key={i} style={{ padding: '0.25rem 0', paddingLeft: `${(h.level - 2) * 1}rem` }}>\n <a href={`#${h.id}`} style={{ color: 'var(--dsa-text-muted, #4b5563)', textDecoration: 'none', fontSize: '0.875rem' }}>\n {h.text}\n </a>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n\nfunction InheritToc({ headings }: { headings: Article['headings'] }) {\n if (!headings || headings.length === 0) return null;\n return (\n <nav className=\"dsa-toc\" data-dsa-toc=\"\">\n <p className=\"dsa-toc-title\">Table of Contents</p>\n <ul className=\"dsa-toc-list\">\n {headings.map((h, i) => (\n <li key={i} className=\"dsa-toc-item\" style={{ paddingLeft: `${(h.level - 2) * 1}rem` }}>\n <a href={`#${h.id}`} className=\"dsa-toc-link\">\n {h.text}\n </a>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\n/**\n * Full article page with optional TOC, FAQ, related articles, and JSON-LD.\n *\n * **light / dark** — SDK applies inline styles with `--dsa-*` CSS variable\n * overrides, plus built-in prose rules for the article body.\n *\n * **inherit** — SDK renders only semantic HTML with stable CSS classes\n * and `data-*` attributes. No inline styles, no injected `<style>`.\n *\n * ### Stable CSS selectors (always present)\n *\n * | Element | Class | Data attribute |\n * |---------|-------|----------------|\n * | Root | `className` prop | `data-dsa-theme` |\n * | Body | `dsa-article-body` + `contentClassName` | `data-dsa-article-body` |\n * | TOC | `dsa-toc` | `data-dsa-toc` |\n * | Meta | `dsa-meta` | `data-dsa-meta` |\n *\n * ```tsx\n * // Works out of the box\n * <ArticlePage article={article} />\n *\n * // Inherit — host site provides all styles\n * <ArticlePage article={article} theme=\"inherit\" contentClassName=\"prose dark:prose-invert\" />\n * ```\n */\nexport function ArticlePage({\n article,\n showFaq = true,\n showTableOfContents = true,\n showMeta = true,\n showRelated = false,\n relatedArticles,\n onRelatedClick,\n className,\n contentClassName,\n theme = 'light',\n disableProseStyles = false,\n components,\n}: ArticlePageProps) {\n const inherit = theme === 'inherit';\n useProseStyles(!inherit && !disableProseStyles);\n\n const H1 = components?.H1 || (inherit\n ? ({ children }: { children: React.ReactNode }) => <h1 className=\"dsa-h1\">{children}</h1>\n : ({ children }: { children: React.ReactNode }) => (\n <h1 className=\"dsa-h1\" style={{ fontSize: '2.25rem', fontWeight: 700, lineHeight: 1.2, color: 'var(--dsa-text)', margin: '0 0 1rem' }}>{children}</h1>\n ));\n const Toc = components?.Toc || (inherit ? InheritToc : DefaultToc);\n const FaqComponent = components?.Faq || FaqBlock;\n const vars = !inherit ? themeVars[theme] : {};\n const bodyClasses = ['dsa-article-body', contentClassName].filter(Boolean).join(' ');\n\n return (\n <article\n className={className}\n data-dsa-theme={theme}\n style={inherit ? undefined : { maxWidth: '48rem', margin: '0 auto', fontFamily: 'system-ui, -apple-system, sans-serif', ...vars } as React.CSSProperties}\n >\n {showMeta && (\n <div className=\"dsa-meta\" data-dsa-meta=\"\" style={inherit ? undefined : { display: 'flex', gap: '1rem', flexWrap: 'wrap' as const, fontSize: '0.875rem', color: 'var(--dsa-text-muted)', marginBottom: '1.5rem' }}>\n {article.pillar_name && (\n <span className=\"dsa-badge\" style={inherit ? undefined : { display: 'inline-block', padding: '0.125rem 0.5rem', borderRadius: '9999px', background: 'var(--dsa-badge-bg)', color: 'var(--dsa-badge-text)', fontSize: '0.75rem' }}>\n {article.pillar_name}\n </span>\n )}\n {article.content_type && (\n <span className=\"dsa-badge dsa-badge--alt\" style={inherit ? undefined : { display: 'inline-block', padding: '0.125rem 0.5rem', borderRadius: '9999px', background: 'var(--dsa-badge-alt-bg, var(--dsa-badge-bg))', color: 'var(--dsa-badge-alt-text, var(--dsa-badge-text))', fontSize: '0.75rem' }}>\n {article.content_type.replace(/_/g, ' ')}\n </span>\n )}\n {article.reading_time_minutes && <span className=\"dsa-reading-time\">{article.reading_time_minutes} min read</span>}\n {article.published_at && <span className=\"dsa-published-at\">{new Date(article.published_at).toLocaleDateString()}</span>}\n </div>\n )}\n\n <H1>{article.h1 || article.title}</H1>\n\n {/* Author byline (E-E-A-T) */}\n {article.author?.name && (\n <div className=\"dsa-author\" data-dsa-author=\"\" style={inherit ? undefined : { display: 'flex', alignItems: 'center', gap: '0.75rem', marginBottom: '1.5rem' }}>\n {article.author.image_url && (\n <img\n className=\"dsa-author-avatar\"\n src={article.author.image_url}\n alt={article.author.name}\n style={inherit ? undefined : { width: '2.5rem', height: '2.5rem', borderRadius: '9999px', objectFit: 'cover' as const }}\n />\n )}\n <div>\n <div style={inherit ? undefined : { fontSize: '0.875rem', fontWeight: 600, color: 'var(--dsa-text)' }}>\n {article.author.url ? (\n <a href={article.author.url} className=\"dsa-author-link\" rel=\"author\" style={inherit ? undefined : { color: 'inherit', textDecoration: 'none' }}>\n {article.author.name}\n </a>\n ) : article.author.name}\n {article.author.job_title && (\n <span className=\"dsa-author-title\" style={inherit ? undefined : { fontWeight: 400, color: 'var(--dsa-text-muted)', marginLeft: '0.25rem' }}>\n {' '}· {article.author.job_title}\n </span>\n )}\n </div>\n {article.author.bio && (\n <p className=\"dsa-author-bio\" style={inherit ? undefined : { fontSize: '0.75rem', color: 'var(--dsa-text-muted)', margin: '0.125rem 0 0' }}>\n {article.author.bio}\n </p>\n )}\n </div>\n </div>\n )}\n\n {article.featured_image_url && (\n <img\n className=\"dsa-featured-image\"\n src={article.featured_image_url}\n alt={article.featured_image_alt || article.title}\n style={inherit ? undefined : { width: '100%', borderRadius: '0.75rem', marginBottom: '2rem' }}\n />\n )}\n\n {showTableOfContents && (article.headings ?? []).length > 0 && (\n <Toc headings={article.headings} />\n )}\n\n {/* Article body */}\n <div\n className={bodyClasses}\n data-dsa-article-body=\"\"\n style={inherit ? undefined : { lineHeight: 1.75, color: 'var(--dsa-content-text)', fontSize: '1.0625rem' }}\n dangerouslySetInnerHTML={{ __html: article.content_html }}\n />\n\n {showFaq && (article.faq ?? []).length > 0 && (\n <>\n <hr className=\"dsa-divider\" style={inherit ? undefined : { border: 'none', borderTop: '1px solid var(--dsa-divider)', margin: '2.5rem 0' }} />\n <FaqComponent items={article.faq} />\n </>\n )}\n\n {article.schema_json && (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(article.schema_json) }}\n />\n )}\n\n {showRelated && relatedArticles && relatedArticles.length > 0 && (\n <>\n <hr className=\"dsa-divider\" style={inherit ? undefined : { border: 'none', borderTop: '1px solid var(--dsa-divider)', margin: '2.5rem 0' }} />\n <RelatedArticles articles={relatedArticles} onArticleClick={onRelatedClick} theme={theme} />\n </>\n )}\n </article>\n );\n}\n","'use client';\n\nimport React, { useState } from 'react';\nimport type { FaqItem } from '../types';\n\nexport interface FaqBlockProps {\n items: FaqItem[];\n collapsible?: boolean;\n defaultOpen?: boolean;\n className?: string;\n title?: string;\n /** \"light\" | \"dark\" | \"inherit\" */\n theme?: 'light' | 'dark' | 'inherit';\n}\n\nconst themeVars = {\n light: {\n '--dsa-text': '#111827',\n '--dsa-text-muted': '#4b5563',\n '--dsa-text-faint': '#9ca3af',\n '--dsa-divider': '#e5e7eb',\n },\n dark: {\n '--dsa-text': '#f3f4f6',\n '--dsa-text-muted': '#d1d5db',\n '--dsa-text-faint': '#6b7280',\n '--dsa-divider': '#374151',\n },\n} as const;\n\nfunction FaqItemComponent({\n item,\n collapsible,\n defaultOpen,\n}: {\n item: FaqItem;\n collapsible: boolean;\n defaultOpen: boolean;\n}) {\n const [open, setOpen] = useState(defaultOpen);\n\n if (!collapsible) {\n return (\n <div style={{ borderBottom: '1px solid var(--dsa-divider)', padding: '0.75rem 0' }}>\n <p style={{ fontSize: '1rem', fontWeight: 600, color: 'var(--dsa-text)', margin: '0 0 0.5rem' }}>{item.question}</p>\n <div style={{ fontSize: '0.9375rem', color: 'var(--dsa-text-muted)', lineHeight: 1.6 }}>{item.answer}</div>\n </div>\n );\n }\n\n return (\n <div style={{ borderBottom: '1px solid var(--dsa-divider)', padding: '0.75rem 0' }}>\n <button\n style={{\n display: 'flex', justifyContent: 'space-between', alignItems: 'center',\n cursor: 'pointer', background: 'none', border: 'none', width: '100%',\n textAlign: 'left' as const, padding: '0.5rem 0', fontSize: '1rem',\n fontWeight: 600, color: 'var(--dsa-text)', fontFamily: 'inherit',\n }}\n onClick={() => setOpen(!open)}\n aria-expanded={open}\n >\n <span>{item.question}</span>\n <span style={{ flexShrink: 0, marginLeft: '1rem', transition: 'transform 0.2s', fontSize: '1.25rem', color: 'var(--dsa-text-faint)', transform: open ? 'rotate(180deg)' : 'rotate(0deg)' }}>\n ▼\n </span>\n </button>\n {open && <div style={{ fontSize: '0.9375rem', color: 'var(--dsa-text-muted)', lineHeight: 1.6, paddingTop: '0.5rem' }}>{item.answer}</div>}\n </div>\n );\n}\n\n/**\n * FAQ block with Schema.org FAQPage markup.\n * Supports theme=\"light\" | \"dark\" | \"inherit\" via CSS variables.\n */\nexport function FaqBlock({\n items,\n collapsible = true,\n defaultOpen = false,\n className,\n title = 'Frequently Asked Questions',\n theme = 'light',\n}: FaqBlockProps) {\n if (!items || items.length === 0) return null;\n const vars = theme !== 'inherit' ? themeVars[theme] : {};\n\n const schemaData = {\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: items.map((item) => ({\n '@type': 'Question',\n name: item.question,\n acceptedAnswer: { '@type': 'Answer', text: item.answer },\n })),\n };\n\n return (\n <section className={className} style={{ marginTop: '1rem', ...vars } as React.CSSProperties}>\n <h2 style={{ fontSize: '1.5rem', fontWeight: 700, color: 'var(--dsa-text)', margin: '0 0 1rem' }}>{title}</h2>\n {items.map((item, i) => (\n <FaqItemComponent key={i} item={item} collapsible={collapsible} defaultOpen={defaultOpen} />\n ))}\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaData) }}\n />\n </section>\n );\n}\n","'use client';\n\nimport React from 'react';\nimport type { ArticleListItem } from '../types';\n\nexport interface RelatedArticlesProps {\n articles: ArticleListItem[];\n title?: string;\n limit?: number;\n onArticleClick?: (slug: string) => void;\n className?: string;\n /** \"light\" | \"dark\" | \"inherit\" */\n theme?: 'light' | 'dark' | 'inherit';\n}\n\nconst themeVars = {\n light: {\n '--dsa-text': '#111827',\n '--dsa-text-muted': '#6b7280',\n '--dsa-card-bg': '#fff',\n '--dsa-card-border': '#e5e7eb',\n },\n dark: {\n '--dsa-text': '#f3f4f6',\n '--dsa-text-muted': '#9ca3af',\n '--dsa-card-bg': '#1f2937',\n '--dsa-card-border': '#374151',\n },\n} as const;\n\n/**\n * Related articles widget.\n * Supports theme=\"light\" | \"dark\" | \"inherit\" via CSS variables.\n */\nexport function RelatedArticles({\n articles,\n title = 'Related Articles',\n limit = 3,\n onArticleClick,\n className,\n theme = 'light',\n}: RelatedArticlesProps) {\n const displayed = (articles ?? []).slice(0, limit);\n if (displayed.length === 0) return null;\n const vars = theme !== 'inherit' ? themeVars[theme] : {};\n\n return (\n <section className={className} style={{ marginTop: '1rem', ...vars } as React.CSSProperties}>\n <h3 style={{ fontSize: '1.25rem', fontWeight: 700, color: 'var(--dsa-text)', margin: '0 0 1rem' }}>{title}</h3>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))', gap: '1rem' }}>\n {displayed.map((a) => (\n <div\n key={a.id}\n style={{ border: '1px solid var(--dsa-card-border)', borderRadius: '0.5rem', overflow: 'hidden', cursor: 'pointer', transition: 'box-shadow 0.2s', background: 'var(--dsa-card-bg)' }}\n onClick={() => onArticleClick?.(a.slug)}\n role=\"link\"\n tabIndex={0}\n onKeyDown={(e) => e.key === 'Enter' && onArticleClick?.(a.slug)}\n >\n {a.featured_image_url && (\n <img\n src={a.featured_image_url}\n alt={a.featured_image_alt || a.title}\n style={{ width: '100%', height: '140px', objectFit: 'cover' as const, display: 'block' }}\n loading=\"lazy\"\n />\n )}\n <div style={{ padding: '1rem' }}>\n <h4 style={{ fontSize: '0.9375rem', fontWeight: 600, color: 'var(--dsa-text)', margin: 0, lineHeight: 1.3 }}>{a.title}</h4>\n {a.excerpt && <p style={{ fontSize: '0.8125rem', color: 'var(--dsa-text-muted)', marginTop: '0.5rem', lineHeight: 1.4 }}>{a.excerpt}</p>}\n </div>\n </div>\n ))}\n </div>\n </section>\n );\n}\n","import type { Article } from '../types';\n\n/**\n * Generate Next.js App Router Metadata object from an Article.\n * Use in page.tsx generateMetadata():\n *\n * ```ts\n * import { generateArticleMetadata } from \"@dsaplatform/content-sdk/server\";\n *\n * export async function generateMetadata({ params }) {\n * const article = await fetchArticleBySlug(config, params.slug);\n * return generateArticleMetadata(article, \"https://example.com\");\n * }\n * ```\n */\nexport function generateArticleMetadata(\n article: Article,\n siteUrl?: string,\n): Record<string, any> {\n const url = siteUrl\n ? `${siteUrl.replace(/\\/+$/, '')}/blog/${article.slug}`\n : undefined;\n\n const meta: Record<string, any> = {\n title: article.meta_title || article.title,\n description: article.meta_description || article.excerpt || '',\n openGraph: {\n title: article.meta_title || article.title,\n description: article.meta_description || article.excerpt || '',\n type: 'article',\n publishedTime: article.published_at || undefined,\n modifiedTime: article.updated_at || undefined,\n ...(url ? { url } : {}),\n ...(article.featured_image_url\n ? {\n images: [\n {\n url: article.featured_image_url,\n alt: article.featured_image_alt || article.title,\n },\n ],\n }\n : {}),\n },\n twitter: {\n card: 'summary_large_image',\n title: article.meta_title || article.title,\n description: article.meta_description || article.excerpt || '',\n ...(article.featured_image_url ? { images: [article.featured_image_url] } : {}),\n },\n ...(article.canonical_url\n ? { alternates: { canonical: article.canonical_url } }\n : url\n ? { alternates: { canonical: url } }\n : {}),\n };\n\n // Author metadata\n if (article.author?.name) {\n meta.authors = [{ name: article.author.name, url: article.author.url || undefined }];\n }\n\n return meta;\n}\n\n// ---------------------------------------------------------------------------\n// Schema.org builders\n// ---------------------------------------------------------------------------\n\nfunction buildArticleSchema(article: Article, siteUrl?: string): Record<string, any> {\n // If the Content Engine already generated schema_json with author/publisher/speakable,\n // use it directly — it's the most complete version.\n if (article.schema_json && article.schema_json['@context']) {\n return article.schema_json;\n }\n\n const url = siteUrl\n ? `${siteUrl.replace(/\\/+$/, '')}/blog/${article.slug}`\n : undefined;\n\n const schema: Record<string, any> = {\n '@context': 'https://schema.org',\n '@type': 'Article',\n headline: article.meta_title || article.title,\n description: article.meta_description || article.excerpt || '',\n datePublished: article.published_at || undefined,\n dateModified: article.updated_at || article.published_at || undefined,\n ...(article.featured_image_url ? { image: article.featured_image_url } : {}),\n ...(url ? { url } : {}),\n ...(article.target_keyword\n ? { keywords: [article.target_keyword, ...(article.secondary_keywords || [])].join(', ') }\n : {}),\n };\n\n // Author (Person) — E-E-A-T\n if (article.author?.name) {\n const author: Record<string, any> = {\n '@type': 'Person',\n name: article.author.name,\n };\n if (article.author.url) author.url = article.author.url;\n if (article.author.image_url) author.image = article.author.image_url;\n if (article.author.job_title) author.jobTitle = article.author.job_title;\n const sameAs: string[] = [];\n if (article.author.url) sameAs.push(article.author.url);\n if (article.author.socials) {\n for (const v of Object.values(article.author.socials)) {\n if (v && v.startsWith('http')) sameAs.push(v);\n }\n }\n if (sameAs.length) author.sameAs = sameAs;\n schema.author = author;\n }\n\n // Publisher (Organization) — E-E-A-T\n if (article.publisher?.name) {\n const pub: Record<string, any> = {\n '@type': 'Organization',\n name: article.publisher.name,\n };\n if (article.publisher.url) pub.url = article.publisher.url;\n if (article.publisher.logo_url) {\n pub.logo = { '@type': 'ImageObject', url: article.publisher.logo_url };\n }\n schema.publisher = pub;\n }\n\n // Speakable\n schema.speakable = {\n '@type': 'SpeakableSpecification',\n cssSelector: ['[data-speakable]', '.dsa-article-body > p:first-of-type'],\n };\n\n // FAQ\n if (article.faq?.length) {\n schema.mainEntity = article.faq.map((item) => ({\n '@type': 'Question',\n name: item.question,\n acceptedAnswer: {\n '@type': 'Answer',\n text: item.answer,\n },\n }));\n }\n\n return schema;\n}\n\nfunction buildBreadcrumbSchema(article: Article, siteUrl?: string): Record<string, any> | null {\n if (!siteUrl) return null;\n const base = siteUrl.replace(/\\/+$/, '');\n\n const items: { name: string; url: string }[] = [\n { name: 'Home', url: base },\n { name: 'Blog', url: `${base}/blog` },\n ];\n\n if (article.pillar_name) {\n items.push({ name: article.pillar_name, url: `${base}/blog?pillar=${encodeURIComponent(article.pillar_name)}` });\n }\n\n items.push({\n name: article.h1 || article.title,\n url: `${base}/blog/${article.slug}`,\n });\n\n return {\n '@context': 'https://schema.org',\n '@type': 'BreadcrumbList',\n itemListElement: items.map((item, i) => ({\n '@type': 'ListItem',\n position: i + 1,\n name: item.name,\n item: item.url,\n })),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Renders JSON-LD structured data for an article.\n * Outputs Article schema (with Author, Publisher, Speakable, FAQ)\n * and BreadcrumbList schema when siteUrl is provided.\n *\n * ```tsx\n * <SeoMetaBridge article={article} siteUrl=\"https://example.com\" />\n * ```\n */\nexport function SeoMetaBridge({\n article,\n siteUrl,\n}: {\n article: Article;\n siteUrl?: string;\n}) {\n const articleSchema = buildArticleSchema(article, siteUrl);\n const breadcrumbSchema = buildBreadcrumbSchema(article, siteUrl);\n\n return (\n <>\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(articleSchema) }}\n />\n {breadcrumbSchema && (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema) }}\n />\n )}\n </>\n );\n}\n"],"mappings":"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","names":["ContentClient","config","path","params","url","k","v","fetchOptions","res","text","article","filters","raw","slug","limit","createContext","useContext","useMemo","jsx","ContentContext","createContext","DsaContentProvider","config","children","client","useMemo","ContentClient","useDsaContent","useContext","useState","useEffect","useCallback","useArticles","filters","client","useDsaContent","state","setState","useState","fetch","useCallback","res","err","s","useEffect","useArticle","slug","article","useRelatedArticles","limit","articles","useCategories","categories","React","jsx","jsxs","themeVars","DefaultCard","article","layout","showExcerpt","showImage","showMeta","onClick","isGrid","hovered","setHovered","cardStyle","e","ArticleFeed","articles","columns","onArticleClick","className","theme","renderArticle","gridTemplateColumns","vars","React","useState","jsx","jsxs","themeVars","FaqItemComponent","item","collapsible","defaultOpen","open","setOpen","FaqBlock","items","className","title","theme","vars","schemaData","i","jsx","jsxs","themeVars","RelatedArticles","articles","title","limit","onArticleClick","className","theme","displayed","vars","a","e","Fragment","jsx","jsxs","themeVars","PROSE_STYLE_ID","proseCSS","useProseStyles","enabled","React","el","DefaultToc","headings","h","i","InheritToc","ArticlePage","article","showFaq","showTableOfContents","showMeta","showRelated","relatedArticles","onRelatedClick","className","contentClassName","theme","disableProseStyles","components","inherit","H1","children","Toc","FaqComponent","FaqBlock","vars","bodyClasses","RelatedArticles","Fragment","jsx","jsxs","generateArticleMetadata","article","siteUrl","url","meta","buildArticleSchema","schema","author","sameAs","v","pub","item","buildBreadcrumbSchema","base","items","i","SeoMetaBridge","articleSchema","breadcrumbSchema"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/provider.tsx","../src/hooks.ts","../src/lead-form-hook.ts","../src/components/ArticleFeed.tsx","../src/components/ArticlePage.tsx","../src/components/FaqBlock.tsx","../src/components/RelatedArticles.tsx","../src/components/SeoMetaBridge.tsx","../src/components/DsaLeadForm.tsx"],"sourcesContent":["import type {\n DsaContentConfig,\n Article,\n ArticleListItem,\n ArticleFilters,\n PaginatedResponse,\n Category,\n SitemapEntry,\n} from './types';\n\n/**\n * ContentClient — HTTP client for DSA Content Engine Public API.\n * Works in both Node.js (SSR) and browser environments.\n */\nexport class ContentClient {\n private apiUrl: string;\n private apiKey: string;\n private cacheStrategy: RequestCache;\n private revalidateSeconds?: number;\n\n constructor(config: DsaContentConfig) {\n this.apiUrl = config.apiUrl.replace(/\\/+$/, '');\n this.apiKey = config.apiKey;\n this.cacheStrategy =\n config.cacheStrategy === 'revalidate'\n ? 'default'\n : config.cacheStrategy === 'force-cache'\n ? 'force-cache'\n : 'no-cache';\n this.revalidateSeconds = config.revalidateSeconds;\n }\n\n private async request<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T> {\n const url = new URL(`${this.apiUrl}${path}`);\n if (params) {\n Object.entries(params).forEach(([k, v]) => {\n if (v !== undefined && v !== null && v !== '') {\n url.searchParams.set(k, String(v));\n }\n });\n }\n url.searchParams.set('site_key', this.apiKey);\n\n const fetchOptions: RequestInit & { next?: { revalidate?: number } } = {\n method: 'GET',\n headers: { 'X-API-Key': this.apiKey },\n cache: this.cacheStrategy,\n };\n\n // Next.js ISR revalidation\n if (this.revalidateSeconds && this.cacheStrategy !== 'no-cache') {\n fetchOptions.next = { revalidate: this.revalidateSeconds };\n }\n\n const res = await fetch(url.toString(), fetchOptions);\n\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw new Error(`DSA Content API error ${res.status}: ${text || res.statusText}`);\n }\n\n return res.json() as Promise<T>;\n }\n\n /** Normalize article array fields to guarantee they're never null/undefined */\n private normalizeArticle(article: Article): Article {\n return {\n ...article,\n headings: article.headings ?? [],\n faq: article.faq ?? [],\n internal_links: article.internal_links ?? [],\n secondary_keywords: article.secondary_keywords ?? [],\n schema_json: article.schema_json ?? null,\n content_json: article.content_json ?? null,\n };\n }\n\n /** Get paginated list of published articles */\n async getArticles(filters?: ArticleFilters): Promise<PaginatedResponse<ArticleListItem>> {\n const raw = await this.request<Record<string, any>>('/api/public/articles', {\n page: filters?.page,\n per_page: filters?.per_page,\n pillar: filters?.pillar,\n cluster: filters?.cluster,\n content_type: filters?.content_type,\n search: filters?.search,\n });\n return {\n items: raw.items ?? raw.data ?? [],\n total: raw.total ?? 0,\n page: raw.page ?? 1,\n per_page: raw.per_page ?? 20,\n total_pages: raw.total_pages ?? raw.pages ?? 1,\n };\n }\n\n /** Get a single article by slug */\n async getArticleBySlug(slug: string): Promise<Article> {\n const article = await this.request<Article>(`/api/public/articles/${encodeURIComponent(slug)}`);\n return this.normalizeArticle(article);\n }\n\n /** Get related articles for a given slug */\n async getRelatedArticles(slug: string, limit = 3): Promise<ArticleListItem[]> {\n const raw = await this.request<Record<string, any>>(\n `/api/public/articles/${encodeURIComponent(slug)}/related`,\n { limit },\n );\n return raw.items ?? (Array.isArray(raw) ? raw : []);\n }\n\n /** Get all categories (pillars + clusters) with article counts */\n async getCategories(): Promise<Category[]> {\n const raw = await this.request<Record<string, any>>('/api/public/categories');\n return raw.items ?? (Array.isArray(raw) ? raw : []);\n }\n\n /** Get sitemap data for all published articles */\n async getSitemap(): Promise<SitemapEntry[]> {\n const raw = await this.request<Record<string, any>>('/api/public/sitemap');\n return raw.items ?? (Array.isArray(raw) ? raw : []);\n }\n}\n","'use client';\n\nimport React, { createContext, useContext, useMemo } from 'react';\nimport { ContentClient } from './client';\nimport type { DsaContentConfig } from './types';\n\nconst ContentContext = createContext<ContentClient | null>(null);\n\nexport interface DsaContentProviderProps {\n config: DsaContentConfig;\n children: React.ReactNode;\n}\n\n/**\n * Wrap your app (or a subtree) with DsaContentProvider to enable\n * the useDsaContent() hook and all data-fetching hooks.\n *\n * ```tsx\n * <DsaContentProvider config={{ apiUrl: \"...\", apiKey: \"...\" }}>\n * <App />\n * </DsaContentProvider>\n * ```\n */\nexport function DsaContentProvider({ config, children }: DsaContentProviderProps) {\n const client = useMemo(() => new ContentClient(config), [config.apiUrl, config.apiKey]);\n return <ContentContext.Provider value={client}>{children}</ContentContext.Provider>;\n}\n\n/**\n * Access the ContentClient instance from context.\n * Must be called inside a DsaContentProvider.\n */\nexport function useDsaContent(): ContentClient {\n const client = useContext(ContentContext);\n if (!client) {\n throw new Error('useDsaContent() must be used inside <DsaContentProvider>');\n }\n return client;\n}\n","'use client';\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { useDsaContent } from './provider';\nimport type {\n ArticleFilters,\n UseArticlesState,\n UseArticleState,\n UseArticleListState,\n UseCategoriesState,\n} from './types';\n\n/**\n * Fetch a paginated list of published articles.\n *\n * ```tsx\n * const { articles, loading, error, pagination } = useArticles({ page: 1, per_page: 10 });\n * ```\n */\nexport function useArticles(filters?: ArticleFilters): UseArticlesState & { refetch: () => void } {\n const client = useDsaContent();\n const [state, setState] = useState<UseArticlesState>({\n articles: [],\n loading: true,\n error: null,\n pagination: { page: 1, per_page: 10, total: 0, total_pages: 0 },\n });\n\n const fetch = useCallback(() => {\n setState((s) => ({ ...s, loading: true, error: null }));\n client\n .getArticles(filters)\n .then((res) =>\n setState({\n articles: res.items,\n loading: false,\n error: null,\n pagination: {\n page: res.page,\n per_page: res.per_page,\n total: res.total,\n total_pages: res.total_pages,\n },\n }),\n )\n .catch((err) =>\n setState((s) => ({ ...s, loading: false, error: err instanceof Error ? err : new Error(String(err)) })),\n );\n }, [client, filters?.page, filters?.per_page, filters?.pillar, filters?.cluster, filters?.content_type, filters?.search]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n return { ...state, refetch: fetch };\n}\n\n/**\n * Fetch a single article by slug.\n *\n * ```tsx\n * const { article, loading, error } = useArticle(\"my-article-slug\");\n * ```\n */\nexport function useArticle(slug: string | undefined): UseArticleState & { refetch: () => void } {\n const client = useDsaContent();\n const [state, setState] = useState<UseArticleState>({ article: null, loading: true, error: null });\n\n const fetch = useCallback(() => {\n if (!slug) {\n setState({ article: null, loading: false, error: null });\n return;\n }\n setState((s) => ({ ...s, loading: true, error: null }));\n client\n .getArticleBySlug(slug)\n .then((article) => setState({ article, loading: false, error: null }))\n .catch((err) =>\n setState({ article: null, loading: false, error: err instanceof Error ? err : new Error(String(err)) }),\n );\n }, [client, slug]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n return { ...state, refetch: fetch };\n}\n\n/**\n * Fetch related articles for a given slug.\n *\n * ```tsx\n * const { articles, loading } = useRelatedArticles(\"my-article-slug\", 4);\n * ```\n */\nexport function useRelatedArticles(slug: string | undefined, limit = 3): UseArticleListState & { refetch: () => void } {\n const client = useDsaContent();\n const [state, setState] = useState<UseArticleListState>({ articles: [], loading: true, error: null });\n\n const fetch = useCallback(() => {\n if (!slug) {\n setState({ articles: [], loading: false, error: null });\n return;\n }\n setState((s) => ({ ...s, loading: true, error: null }));\n client\n .getRelatedArticles(slug, limit)\n .then((articles) => setState({ articles, loading: false, error: null }))\n .catch((err) =>\n setState({ articles: [], loading: false, error: err instanceof Error ? err : new Error(String(err)) }),\n );\n }, [client, slug, limit]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n return { ...state, refetch: fetch };\n}\n\n/**\n * Fetch all categories (pillars + clusters).\n *\n * ```tsx\n * const { categories, loading } = useCategories();\n * ```\n */\nexport function useCategories(): UseCategoriesState & { refetch: () => void } {\n const client = useDsaContent();\n const [state, setState] = useState<UseCategoriesState>({ categories: [], loading: true, error: null });\n\n const fetch = useCallback(() => {\n setState((s) => ({ ...s, loading: true, error: null }));\n client\n .getCategories()\n .then((categories) => setState({ categories, loading: false, error: null }))\n .catch((err) =>\n setState({ categories: [], loading: false, error: err instanceof Error ? err : new Error(String(err)) }),\n );\n }, [client]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n return { ...state, refetch: fetch };\n}\n","'use client';\n\nimport { useState, useCallback } from 'react';\nimport type {\n DsaLeadFormConfig,\n LeadFormPayload,\n LeadFormSubmitResult,\n UseLeadFormState,\n} from './types';\n\n/**\n * Headless hook for lead capture — handles submission to DSA webhook.\n * Use this when you want full control over form UI.\n *\n * ```tsx\n * const { submitting, submitted, error, submit, reset } = useDsaLeadForm({\n * webhookUrl: \"https://api.example.com\",\n * projectSlug: \"my-project\",\n * webhookToken: \"abc123\",\n * });\n *\n * const handleSubmit = (e) => {\n * e.preventDefault();\n * submit({ email: \"user@example.com\", name: \"John\" });\n * };\n * ```\n */\nexport function useDsaLeadForm(config: DsaLeadFormConfig): UseLeadFormState {\n const [submitting, setSubmitting] = useState(false);\n const [submitted, setSubmitted] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const submit = useCallback(\n async (data: LeadFormPayload): Promise<LeadFormSubmitResult> => {\n setSubmitting(true);\n setError(null);\n try {\n const baseUrl = config.webhookUrl.replace(/\\/+$/, '');\n const url = `${baseUrl}/api/webhook/form/${encodeURIComponent(config.projectSlug)}?token=${encodeURIComponent(config.webhookToken)}`;\n\n const body: Record<string, string> = { ...data } as any;\n if (!body.source_url && typeof window !== 'undefined') {\n body.source_url = window.location.href;\n }\n\n const res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n const json = await res.json().catch(() => ({}));\n\n if (!res.ok) {\n const msg = json.error || `Submission failed (${res.status})`;\n throw new Error(msg);\n }\n\n setSubmitted(true);\n return { ok: true, message: json.message };\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n return { ok: false, error: e.message };\n } finally {\n setSubmitting(false);\n }\n },\n [config.webhookUrl, config.projectSlug, config.webhookToken],\n );\n\n const reset = useCallback(() => {\n setSubmitting(false);\n setSubmitted(false);\n setError(null);\n }, []);\n\n return { submitting, submitted, error, submit, reset };\n}\n","'use client';\n\nimport React from 'react';\nimport type { ArticleListItem } from '../types';\n\nexport interface ArticleFeedProps {\n articles: ArticleListItem[];\n layout?: 'grid' | 'list';\n columns?: 1 | 2 | 3;\n showExcerpt?: boolean;\n showImage?: boolean;\n showMeta?: boolean;\n onArticleClick?: (slug: string) => void;\n className?: string;\n /** \"light\" | \"dark\" | \"inherit\" — sets CSS variable defaults. Use \"inherit\" to control via your own CSS vars. */\n theme?: 'light' | 'dark' | 'inherit';\n renderArticle?: (article: ArticleListItem) => React.ReactNode;\n}\n\nconst themeVars = {\n light: {\n '--dsa-text': '#111827',\n '--dsa-text-muted': '#6b7280',\n '--dsa-text-faint': '#9ca3af',\n '--dsa-card-bg': '#fff',\n '--dsa-card-border': '#e5e7eb',\n '--dsa-badge-bg': '#f3f4f6',\n '--dsa-badge-text': '#4b5563',\n '--dsa-hover-shadow': '0 4px 12px rgba(0,0,0,0.08)',\n },\n dark: {\n '--dsa-text': '#f3f4f6',\n '--dsa-text-muted': '#9ca3af',\n '--dsa-text-faint': '#6b7280',\n '--dsa-card-bg': '#1f2937',\n '--dsa-card-border': '#374151',\n '--dsa-badge-bg': '#374151',\n '--dsa-badge-text': '#d1d5db',\n '--dsa-hover-shadow': '0 4px 12px rgba(0,0,0,0.3)',\n },\n} as const;\n\nfunction DefaultCard({\n article,\n layout,\n showExcerpt,\n showImage,\n showMeta,\n onClick,\n}: {\n article: ArticleListItem;\n layout: 'grid' | 'list';\n showExcerpt: boolean;\n showImage: boolean;\n showMeta: boolean;\n onClick?: () => void;\n}) {\n const isGrid = layout === 'grid';\n const [hovered, setHovered] = React.useState(false);\n\n const cardStyle: React.CSSProperties = {\n ...(isGrid\n ? { border: '1px solid var(--dsa-card-border)', borderRadius: '0.75rem', overflow: 'hidden', background: 'var(--dsa-card-bg)', cursor: 'pointer', transition: 'box-shadow 0.2s' }\n : { display: 'flex', border: '1px solid var(--dsa-card-border)', borderRadius: '0.75rem', overflow: 'hidden', background: 'var(--dsa-card-bg)', cursor: 'pointer', transition: 'box-shadow 0.2s' }),\n ...(hovered ? { boxShadow: 'var(--dsa-hover-shadow)' } : {}),\n };\n\n return (\n <article\n style={cardStyle}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n onClick={onClick}\n role=\"link\"\n tabIndex={0}\n onKeyDown={(e) => e.key === 'Enter' && onClick?.()}\n >\n {showImage && article.featured_image_url && (\n <img\n src={article.featured_image_url}\n alt={article.featured_image_alt || article.title}\n style={isGrid\n ? { width: '100%', height: '200px', objectFit: 'cover' as const, display: 'block' }\n : { width: '240px', minHeight: '160px', objectFit: 'cover' as const, flexShrink: 0 }}\n loading=\"lazy\"\n />\n )}\n <div style={isGrid ? { padding: '1.25rem' } : { padding: '1.25rem', flex: 1 }}>\n <h3 style={{ margin: '0 0 0.5rem', fontSize: '1.125rem', fontWeight: 600, lineHeight: 1.3, color: 'var(--dsa-text)' }}>\n {article.title}\n </h3>\n {showExcerpt && article.excerpt && (\n <p style={{ margin: '0 0 0.75rem', fontSize: '0.875rem', color: 'var(--dsa-text-muted)', lineHeight: 1.5 }}>\n {article.excerpt}\n </p>\n )}\n {showMeta && (\n <div style={{ display: 'flex', gap: '0.75rem', fontSize: '0.75rem', color: 'var(--dsa-text-faint)', flexWrap: 'wrap' as const }}>\n {article.pillar_name && (\n <span style={{ display: 'inline-block', padding: '0.125rem 0.5rem', borderRadius: '9999px', background: 'var(--dsa-badge-bg)', fontSize: '0.75rem', color: 'var(--dsa-badge-text)' }}>\n {article.pillar_name}\n </span>\n )}\n {article.content_type && (\n <span style={{ display: 'inline-block', padding: '0.125rem 0.5rem', borderRadius: '9999px', background: 'var(--dsa-badge-bg)', fontSize: '0.75rem', color: 'var(--dsa-badge-text)' }}>\n {article.content_type.replace(/_/g, ' ')}\n </span>\n )}\n {article.reading_time_minutes && <span>{article.reading_time_minutes} min read</span>}\n {article.published_at && <span>{new Date(article.published_at).toLocaleDateString()}</span>}\n </div>\n )}\n </div>\n </article>\n );\n}\n\n/**\n * Renders a grid or list of article cards.\n * Supports theme=\"light\" | \"dark\" | \"inherit\" via CSS variables.\n *\n * CSS variables (override in your own CSS for full control):\n * --dsa-text, --dsa-text-muted, --dsa-text-faint,\n * --dsa-card-bg, --dsa-card-border,\n * --dsa-badge-bg, --dsa-badge-text, --dsa-hover-shadow\n */\nexport function ArticleFeed({\n articles,\n layout = 'grid',\n columns = 3,\n showExcerpt = true,\n showImage = true,\n showMeta = true,\n onArticleClick,\n className,\n theme = 'light',\n renderArticle,\n}: ArticleFeedProps) {\n const gridTemplateColumns = layout === 'grid' ? `repeat(${columns}, 1fr)` : '1fr';\n const vars = theme !== 'inherit' ? themeVars[theme] : {};\n\n return (\n <div\n className={className}\n style={{ display: 'grid', gap: '1.5rem', gridTemplateColumns, ...vars } as React.CSSProperties}\n >\n {(articles ?? []).map((article) =>\n renderArticle ? (\n <React.Fragment key={article.id}>{renderArticle(article)}</React.Fragment>\n ) : (\n <DefaultCard\n key={article.id}\n article={article}\n layout={layout}\n showExcerpt={showExcerpt}\n showImage={showImage}\n showMeta={showMeta}\n onClick={() => onArticleClick?.(article.slug)}\n />\n ),\n )}\n </div>\n );\n}\n","'use client';\n\nimport React from 'react';\nimport type { Article, ArticleListItem, FaqItem } from '../types';\nimport { FaqBlock } from './FaqBlock';\nimport { RelatedArticles } from './RelatedArticles';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ArticleTheme = 'light' | 'dark' | 'inherit';\n\nexport interface ArticlePageProps {\n article: Article;\n showFaq?: boolean;\n showTableOfContents?: boolean;\n showMeta?: boolean;\n showRelated?: boolean;\n relatedArticles?: ArticleListItem[];\n onRelatedClick?: (slug: string) => void;\n className?: string;\n /** Extra class(es) on the `<div>` that wraps `content_html`. */\n contentClassName?: string;\n /**\n * `\"light\"` / `\"dark\"` — SDK applies inline styles + CSS vars + built-in prose rules.\n * `\"inherit\"` — SDK applies NO inline styles; only CSS classes and\n * `data-*` attributes are rendered so the host site has full control.\n *\n * In all modes the content body div has:\n * - `className=\"dsa-article-body\"`\n * - `data-dsa-article-body`\n *\n * @default \"light\"\n */\n theme?: ArticleTheme;\n /** Disable built-in prose styles injected via `<style>`. Works only in light/dark themes. */\n disableProseStyles?: boolean;\n components?: {\n H1?: React.ComponentType<{ children: React.ReactNode }>;\n Toc?: React.ComponentType<{ headings: Article['headings'] }>;\n Faq?: React.ComponentType<{ items: FaqItem[] }>;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Theme CSS variable presets\n// ---------------------------------------------------------------------------\n\nconst themeVars = {\n light: {\n '--dsa-text': '#111827',\n '--dsa-text-muted': '#6b7280',\n '--dsa-text-faint': '#9ca3af',\n '--dsa-card-bg': '#fff',\n '--dsa-card-border': '#e5e7eb',\n '--dsa-toc-bg': '#f9fafb',\n '--dsa-badge-bg': '#eff6ff',\n '--dsa-badge-text': '#2563eb',\n '--dsa-badge-alt-bg': '#f0fdf4',\n '--dsa-badge-alt-text': '#16a34a',\n '--dsa-content-text': '#374151',\n '--dsa-h2-text': '#111827',\n '--dsa-h3-text': '#1f2937',\n '--dsa-h4-text': '#1f2937',\n '--dsa-link': '#2563eb',\n '--dsa-link-hover': '#1d4ed8',\n '--dsa-blockquote-border': '#d1d5db',\n '--dsa-blockquote-text': '#4b5563',\n '--dsa-pre-bg': '#f3f4f6',\n '--dsa-table-border': '#e5e7eb',\n '--dsa-table-header-bg': '#f9fafb',\n '--dsa-divider': '#e5e7eb',\n },\n dark: {\n '--dsa-text': '#f3f4f6',\n '--dsa-text-muted': '#9ca3af',\n '--dsa-text-faint': '#6b7280',\n '--dsa-card-bg': '#1f2937',\n '--dsa-card-border': '#374151',\n '--dsa-toc-bg': '#111827',\n '--dsa-badge-bg': '#1e3a5f',\n '--dsa-badge-text': '#93c5fd',\n '--dsa-badge-alt-bg': '#14532d',\n '--dsa-badge-alt-text': '#86efac',\n '--dsa-content-text': '#d1d5db',\n '--dsa-h2-text': '#f3f4f6',\n '--dsa-h3-text': '#e5e7eb',\n '--dsa-h4-text': '#e5e7eb',\n '--dsa-link': '#60a5fa',\n '--dsa-link-hover': '#93c5fd',\n '--dsa-blockquote-border': '#4b5563',\n '--dsa-blockquote-text': '#9ca3af',\n '--dsa-pre-bg': '#111827',\n '--dsa-table-border': '#374151',\n '--dsa-table-header-bg': '#111827',\n '--dsa-divider': '#374151',\n },\n} as const;\n\n// ---------------------------------------------------------------------------\n// Built-in prose stylesheet (injected once via <style>)\n// ---------------------------------------------------------------------------\n\nconst PROSE_STYLE_ID = 'dsa-article-prose';\n\nconst proseCSS = /* css */ `\n[data-dsa-article-body] h2 { font-size: 1.5rem; font-weight: 700; line-height: 1.3; color: var(--dsa-h2-text, #111827); margin: 2rem 0 0.75rem; }\n[data-dsa-article-body] h3 { font-size: 1.25rem; font-weight: 600; line-height: 1.4; color: var(--dsa-h3-text, #1f2937); margin: 1.75rem 0 0.5rem; }\n[data-dsa-article-body] h4 { font-size: 1.125rem; font-weight: 600; line-height: 1.4; color: var(--dsa-h4-text, #1f2937); margin: 1.5rem 0 0.5rem; }\n[data-dsa-article-body] p { margin: 0 0 1.25rem; }\n[data-dsa-article-body] ul,\n[data-dsa-article-body] ol { margin: 0 0 1.25rem; padding-left: 1.5rem; }\n[data-dsa-article-body] li { margin: 0 0 0.375rem; }\n[data-dsa-article-body] li > ul,\n[data-dsa-article-body] li > ol { margin: 0.375rem 0 0; }\n[data-dsa-article-body] blockquote { margin: 1.5rem 0; padding: 0.75rem 1.25rem; border-left: 4px solid var(--dsa-blockquote-border, #d1d5db); color: var(--dsa-blockquote-text, #4b5563); font-style: italic; }\n[data-dsa-article-body] pre { margin: 1.5rem 0; padding: 1rem; background: var(--dsa-pre-bg, #f3f4f6); border-radius: 0.5rem; overflow-x: auto; font-size: 0.875rem; }\n[data-dsa-article-body] code { font-size: 0.875em; }\n[data-dsa-article-body] table { width: 100%; margin: 1.5rem 0; border-collapse: collapse; font-size: 0.9375rem; }\n[data-dsa-article-body] th,\n[data-dsa-article-body] td { padding: 0.5rem 0.75rem; border: 1px solid var(--dsa-table-border, #e5e7eb); text-align: left; }\n[data-dsa-article-body] th { background: var(--dsa-table-header-bg, #f9fafb); font-weight: 600; }\n[data-dsa-article-body] img { max-width: 100%; height: auto; border-radius: 0.5rem; margin: 1.5rem 0; }\n[data-dsa-article-body] a { color: var(--dsa-link, #2563eb); text-decoration: underline; text-underline-offset: 2px; }\n[data-dsa-article-body] a:hover { color: var(--dsa-link-hover, #1d4ed8); }\n[data-dsa-article-body] hr { border: none; border-top: 1px solid var(--dsa-divider, #e5e7eb); margin: 2rem 0; }\n[data-dsa-article-body] > *:first-child { margin-top: 0; }\n[data-dsa-article-body] > *:last-child { margin-bottom: 0; }\n`.trim();\n\nfunction useProseStyles(enabled: boolean) {\n React.useEffect(() => {\n if (!enabled) return;\n if (typeof document === 'undefined') return;\n if (document.getElementById(PROSE_STYLE_ID)) return;\n const el = document.createElement('style');\n el.id = PROSE_STYLE_ID;\n el.textContent = proseCSS;\n document.head.appendChild(el);\n }, [enabled]);\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction DefaultToc({ headings }: { headings: Article['headings'] }) {\n if (!headings || headings.length === 0) return null;\n return (\n <nav className=\"dsa-toc\" data-dsa-toc=\"\" style={{ background: 'var(--dsa-toc-bg, #f9fafb)', border: '1px solid var(--dsa-card-border, #e5e7eb)', borderRadius: '0.75rem', padding: '1.25rem', marginBottom: '2rem' }}>\n <p style={{ fontSize: '0.875rem', fontWeight: 600, color: 'var(--dsa-text-muted, #374151)', margin: '0 0 0.75rem', textTransform: 'uppercase' as const, letterSpacing: '0.05em' }}>\n Table of Contents\n </p>\n <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>\n {headings.map((h, i) => (\n <li key={i} style={{ padding: '0.25rem 0', paddingLeft: `${(h.level - 2) * 1}rem` }}>\n <a href={`#${h.id}`} style={{ color: 'var(--dsa-text-muted, #4b5563)', textDecoration: 'none', fontSize: '0.875rem' }}>\n {h.text}\n </a>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n\nfunction InheritToc({ headings }: { headings: Article['headings'] }) {\n if (!headings || headings.length === 0) return null;\n return (\n <nav className=\"dsa-toc\" data-dsa-toc=\"\">\n <p className=\"dsa-toc-title\">Table of Contents</p>\n <ul className=\"dsa-toc-list\">\n {headings.map((h, i) => (\n <li key={i} className=\"dsa-toc-item\" style={{ paddingLeft: `${(h.level - 2) * 1}rem` }}>\n <a href={`#${h.id}`} className=\"dsa-toc-link\">\n {h.text}\n </a>\n </li>\n ))}\n </ul>\n </nav>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\n/**\n * Full article page with optional TOC, FAQ, related articles, and JSON-LD.\n *\n * **light / dark** — SDK applies inline styles with `--dsa-*` CSS variable\n * overrides, plus built-in prose rules for the article body.\n *\n * **inherit** — SDK renders only semantic HTML with stable CSS classes\n * and `data-*` attributes. No inline styles, no injected `<style>`.\n *\n * ### Stable CSS selectors (always present)\n *\n * | Element | Class | Data attribute |\n * |---------|-------|----------------|\n * | Root | `className` prop | `data-dsa-theme` |\n * | Body | `dsa-article-body` + `contentClassName` | `data-dsa-article-body` |\n * | TOC | `dsa-toc` | `data-dsa-toc` |\n * | Meta | `dsa-meta` | `data-dsa-meta` |\n *\n * ```tsx\n * // Works out of the box\n * <ArticlePage article={article} />\n *\n * // Inherit — host site provides all styles\n * <ArticlePage article={article} theme=\"inherit\" contentClassName=\"prose dark:prose-invert\" />\n * ```\n */\nexport function ArticlePage({\n article,\n showFaq = true,\n showTableOfContents = true,\n showMeta = true,\n showRelated = false,\n relatedArticles,\n onRelatedClick,\n className,\n contentClassName,\n theme = 'light',\n disableProseStyles = false,\n components,\n}: ArticlePageProps) {\n const inherit = theme === 'inherit';\n useProseStyles(!inherit && !disableProseStyles);\n\n const H1 = components?.H1 || (inherit\n ? ({ children }: { children: React.ReactNode }) => <h1 className=\"dsa-h1\">{children}</h1>\n : ({ children }: { children: React.ReactNode }) => (\n <h1 className=\"dsa-h1\" style={{ fontSize: '2.25rem', fontWeight: 700, lineHeight: 1.2, color: 'var(--dsa-text)', margin: '0 0 1rem' }}>{children}</h1>\n ));\n const Toc = components?.Toc || (inherit ? InheritToc : DefaultToc);\n const FaqComponent = components?.Faq || FaqBlock;\n const vars = !inherit ? themeVars[theme] : {};\n const bodyClasses = ['dsa-article-body', contentClassName].filter(Boolean).join(' ');\n\n return (\n <article\n className={className}\n data-dsa-theme={theme}\n style={inherit ? undefined : { maxWidth: '48rem', margin: '0 auto', fontFamily: 'system-ui, -apple-system, sans-serif', ...vars } as React.CSSProperties}\n >\n {showMeta && (\n <div className=\"dsa-meta\" data-dsa-meta=\"\" style={inherit ? undefined : { display: 'flex', gap: '1rem', flexWrap: 'wrap' as const, fontSize: '0.875rem', color: 'var(--dsa-text-muted)', marginBottom: '1.5rem' }}>\n {article.pillar_name && (\n <span className=\"dsa-badge\" style={inherit ? undefined : { display: 'inline-block', padding: '0.125rem 0.5rem', borderRadius: '9999px', background: 'var(--dsa-badge-bg)', color: 'var(--dsa-badge-text)', fontSize: '0.75rem' }}>\n {article.pillar_name}\n </span>\n )}\n {article.content_type && (\n <span className=\"dsa-badge dsa-badge--alt\" style={inherit ? undefined : { display: 'inline-block', padding: '0.125rem 0.5rem', borderRadius: '9999px', background: 'var(--dsa-badge-alt-bg, var(--dsa-badge-bg))', color: 'var(--dsa-badge-alt-text, var(--dsa-badge-text))', fontSize: '0.75rem' }}>\n {article.content_type.replace(/_/g, ' ')}\n </span>\n )}\n {article.reading_time_minutes && <span className=\"dsa-reading-time\">{article.reading_time_minutes} min read</span>}\n {article.published_at && <span className=\"dsa-published-at\">{new Date(article.published_at).toLocaleDateString()}</span>}\n </div>\n )}\n\n <H1>{article.h1 || article.title}</H1>\n\n {article.featured_image_url && (\n <img\n className=\"dsa-featured-image\"\n src={article.featured_image_url}\n alt={article.featured_image_alt || article.title}\n style={inherit ? undefined : { width: '100%', borderRadius: '0.75rem', marginBottom: '2rem' }}\n />\n )}\n\n {showTableOfContents && (article.headings ?? []).length > 0 && (\n <Toc headings={article.headings} />\n )}\n\n {/* Article body */}\n <div\n className={bodyClasses}\n data-dsa-article-body=\"\"\n style={inherit ? undefined : { lineHeight: 1.75, color: 'var(--dsa-content-text)', fontSize: '1.0625rem' }}\n dangerouslySetInnerHTML={{ __html: article.content_html }}\n />\n\n {showFaq && (article.faq ?? []).length > 0 && (\n <>\n <hr className=\"dsa-divider\" style={inherit ? undefined : { border: 'none', borderTop: '1px solid var(--dsa-divider)', margin: '2.5rem 0' }} />\n <FaqComponent items={article.faq} />\n </>\n )}\n\n {article.schema_json && (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(article.schema_json) }}\n />\n )}\n\n {showRelated && relatedArticles && relatedArticles.length > 0 && (\n <>\n <hr className=\"dsa-divider\" style={inherit ? undefined : { border: 'none', borderTop: '1px solid var(--dsa-divider)', margin: '2.5rem 0' }} />\n <RelatedArticles articles={relatedArticles} onArticleClick={onRelatedClick} theme={theme} />\n </>\n )}\n </article>\n );\n}\n","'use client';\n\nimport React, { useState } from 'react';\nimport type { FaqItem } from '../types';\n\nexport interface FaqBlockProps {\n items: FaqItem[];\n collapsible?: boolean;\n defaultOpen?: boolean;\n className?: string;\n title?: string;\n /** \"light\" | \"dark\" | \"inherit\" */\n theme?: 'light' | 'dark' | 'inherit';\n}\n\nconst themeVars = {\n light: {\n '--dsa-text': '#111827',\n '--dsa-text-muted': '#4b5563',\n '--dsa-text-faint': '#9ca3af',\n '--dsa-divider': '#e5e7eb',\n },\n dark: {\n '--dsa-text': '#f3f4f6',\n '--dsa-text-muted': '#d1d5db',\n '--dsa-text-faint': '#6b7280',\n '--dsa-divider': '#374151',\n },\n} as const;\n\nfunction FaqItemComponent({\n item,\n collapsible,\n defaultOpen,\n}: {\n item: FaqItem;\n collapsible: boolean;\n defaultOpen: boolean;\n}) {\n const [open, setOpen] = useState(defaultOpen);\n\n if (!collapsible) {\n return (\n <div style={{ borderBottom: '1px solid var(--dsa-divider)', padding: '0.75rem 0' }}>\n <p style={{ fontSize: '1rem', fontWeight: 600, color: 'var(--dsa-text)', margin: '0 0 0.5rem' }}>{item.question}</p>\n <div style={{ fontSize: '0.9375rem', color: 'var(--dsa-text-muted)', lineHeight: 1.6 }}>{item.answer}</div>\n </div>\n );\n }\n\n return (\n <div style={{ borderBottom: '1px solid var(--dsa-divider)', padding: '0.75rem 0' }}>\n <button\n style={{\n display: 'flex', justifyContent: 'space-between', alignItems: 'center',\n cursor: 'pointer', background: 'none', border: 'none', width: '100%',\n textAlign: 'left' as const, padding: '0.5rem 0', fontSize: '1rem',\n fontWeight: 600, color: 'var(--dsa-text)', fontFamily: 'inherit',\n }}\n onClick={() => setOpen(!open)}\n aria-expanded={open}\n >\n <span>{item.question}</span>\n <span style={{ flexShrink: 0, marginLeft: '1rem', transition: 'transform 0.2s', fontSize: '1.25rem', color: 'var(--dsa-text-faint)', transform: open ? 'rotate(180deg)' : 'rotate(0deg)' }}>\n ▼\n </span>\n </button>\n {open && <div style={{ fontSize: '0.9375rem', color: 'var(--dsa-text-muted)', lineHeight: 1.6, paddingTop: '0.5rem' }}>{item.answer}</div>}\n </div>\n );\n}\n\n/**\n * FAQ block with Schema.org FAQPage markup.\n * Supports theme=\"light\" | \"dark\" | \"inherit\" via CSS variables.\n */\nexport function FaqBlock({\n items,\n collapsible = true,\n defaultOpen = false,\n className,\n title = 'Frequently Asked Questions',\n theme = 'light',\n}: FaqBlockProps) {\n if (!items || items.length === 0) return null;\n const vars = theme !== 'inherit' ? themeVars[theme] : {};\n\n const schemaData = {\n '@context': 'https://schema.org',\n '@type': 'FAQPage',\n mainEntity: items.map((item) => ({\n '@type': 'Question',\n name: item.question,\n acceptedAnswer: { '@type': 'Answer', text: item.answer },\n })),\n };\n\n return (\n <section className={className} style={{ marginTop: '1rem', ...vars } as React.CSSProperties}>\n <h2 style={{ fontSize: '1.5rem', fontWeight: 700, color: 'var(--dsa-text)', margin: '0 0 1rem' }}>{title}</h2>\n {items.map((item, i) => (\n <FaqItemComponent key={i} item={item} collapsible={collapsible} defaultOpen={defaultOpen} />\n ))}\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaData) }}\n />\n </section>\n );\n}\n","'use client';\n\nimport React from 'react';\nimport type { ArticleListItem } from '../types';\n\nexport interface RelatedArticlesProps {\n articles: ArticleListItem[];\n title?: string;\n limit?: number;\n onArticleClick?: (slug: string) => void;\n className?: string;\n /** \"light\" | \"dark\" | \"inherit\" */\n theme?: 'light' | 'dark' | 'inherit';\n}\n\nconst themeVars = {\n light: {\n '--dsa-text': '#111827',\n '--dsa-text-muted': '#6b7280',\n '--dsa-card-bg': '#fff',\n '--dsa-card-border': '#e5e7eb',\n },\n dark: {\n '--dsa-text': '#f3f4f6',\n '--dsa-text-muted': '#9ca3af',\n '--dsa-card-bg': '#1f2937',\n '--dsa-card-border': '#374151',\n },\n} as const;\n\n/**\n * Related articles widget.\n * Supports theme=\"light\" | \"dark\" | \"inherit\" via CSS variables.\n */\nexport function RelatedArticles({\n articles,\n title = 'Related Articles',\n limit = 3,\n onArticleClick,\n className,\n theme = 'light',\n}: RelatedArticlesProps) {\n const displayed = (articles ?? []).slice(0, limit);\n if (displayed.length === 0) return null;\n const vars = theme !== 'inherit' ? themeVars[theme] : {};\n\n return (\n <section className={className} style={{ marginTop: '1rem', ...vars } as React.CSSProperties}>\n <h3 style={{ fontSize: '1.25rem', fontWeight: 700, color: 'var(--dsa-text)', margin: '0 0 1rem' }}>{title}</h3>\n <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))', gap: '1rem' }}>\n {displayed.map((a) => (\n <div\n key={a.id}\n style={{ border: '1px solid var(--dsa-card-border)', borderRadius: '0.5rem', overflow: 'hidden', cursor: 'pointer', transition: 'box-shadow 0.2s', background: 'var(--dsa-card-bg)' }}\n onClick={() => onArticleClick?.(a.slug)}\n role=\"link\"\n tabIndex={0}\n onKeyDown={(e) => e.key === 'Enter' && onArticleClick?.(a.slug)}\n >\n {a.featured_image_url && (\n <img\n src={a.featured_image_url}\n alt={a.featured_image_alt || a.title}\n style={{ width: '100%', height: '140px', objectFit: 'cover' as const, display: 'block' }}\n loading=\"lazy\"\n />\n )}\n <div style={{ padding: '1rem' }}>\n <h4 style={{ fontSize: '0.9375rem', fontWeight: 600, color: 'var(--dsa-text)', margin: 0, lineHeight: 1.3 }}>{a.title}</h4>\n {a.excerpt && <p style={{ fontSize: '0.8125rem', color: 'var(--dsa-text-muted)', marginTop: '0.5rem', lineHeight: 1.4 }}>{a.excerpt}</p>}\n </div>\n </div>\n ))}\n </div>\n </section>\n );\n}\n","import type { Article } from '../types';\n\n/**\n * Generate Next.js App Router Metadata object from an Article.\n * Use in page.tsx generateMetadata():\n *\n * ```ts\n * import { generateArticleMetadata } from \"@dsa/content-sdk/server\";\n *\n * export async function generateMetadata({ params }) {\n * const article = await fetchArticleBySlug(config, params.slug);\n * return generateArticleMetadata(article, \"https://example.com\");\n * }\n * ```\n */\nexport function generateArticleMetadata(\n article: Article,\n siteUrl?: string,\n): Record<string, any> {\n const url = siteUrl\n ? `${siteUrl.replace(/\\/+$/, '')}/blog/${article.slug}`\n : undefined;\n\n return {\n title: article.meta_title || article.title,\n description: article.meta_description || article.excerpt || '',\n openGraph: {\n title: article.meta_title || article.title,\n description: article.meta_description || article.excerpt || '',\n type: 'article',\n publishedTime: article.published_at || undefined,\n modifiedTime: article.updated_at || undefined,\n ...(url ? { url } : {}),\n ...(article.featured_image_url\n ? {\n images: [\n {\n url: article.featured_image_url,\n alt: article.featured_image_alt || article.title,\n },\n ],\n }\n : {}),\n },\n twitter: {\n card: 'summary_large_image',\n title: article.meta_title || article.title,\n description: article.meta_description || article.excerpt || '',\n ...(article.featured_image_url ? { images: [article.featured_image_url] } : {}),\n },\n ...(article.canonical_url\n ? { alternates: { canonical: article.canonical_url } }\n : url\n ? { alternates: { canonical: url } }\n : {}),\n };\n}\n\n/**\n * Renders JSON-LD structured data for an article.\n * Include this component in your article page layout for SEO.\n *\n * ```tsx\n * <SeoMetaBridge article={article} siteUrl=\"https://example.com\" />\n * ```\n */\nexport function SeoMetaBridge({\n article,\n siteUrl,\n}: {\n article: Article;\n siteUrl?: string;\n}) {\n const schema = article.schema_json || {\n '@context': 'https://schema.org',\n '@type': 'Article',\n headline: article.meta_title || article.title,\n description: article.meta_description || article.excerpt || '',\n datePublished: article.published_at || undefined,\n dateModified: article.updated_at || article.published_at || undefined,\n ...(article.featured_image_url ? { image: article.featured_image_url } : {}),\n ...(siteUrl ? { url: `${siteUrl.replace(/\\/+$/, '')}/blog/${article.slug}` } : {}),\n ...(article.target_keyword\n ? { keywords: [article.target_keyword, ...(article.secondary_keywords || [])].join(', ') }\n : {}),\n };\n\n return (\n <script\n type=\"application/ld+json\"\n dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}\n />\n );\n}\n","'use client';\n\nimport React, { useState, type FormEvent } from 'react';\nimport { useDsaLeadForm } from '../lead-form-hook';\nimport type {\n DsaLeadFormConfig,\n LeadFormField,\n LeadFormFieldName,\n LeadFormPayload,\n LeadMagnetConfig,\n} from '../types';\n\nexport type { LeadFormField, LeadFormFieldName, LeadMagnetConfig };\n\n/** Theme for the lead form */\nexport type LeadFormTheme = 'light' | 'dark' | 'inherit';\n\nexport interface DsaLeadFormProps extends DsaLeadFormConfig {\n /** Form fields to display. Shorthand: pass an array of field names. */\n fields?: (LeadFormFieldName | LeadFormField)[];\n /** Lead magnet to promote above the form / show after submission */\n leadMagnet?: LeadMagnetConfig;\n /** CTA button text */\n ctaText?: string;\n /** Thank-you message shown after successful submission */\n thankYouMessage?: string;\n /** Theme: \"light\" | \"dark\" | \"inherit\" (no styles) */\n theme?: LeadFormTheme;\n /** Additional CSS class on the wrapper */\n className?: string;\n /** Called after successful submission */\n onSuccess?: (data: LeadFormPayload) => void;\n /** Called on submission error */\n onError?: (error: Error) => void;\n /** Override source_url (defaults to window.location.href) */\n sourceUrl?: string;\n /** Render prop for full custom rendering */\n children?: (state: {\n submitting: boolean;\n submitted: boolean;\n error: Error | null;\n submit: (data: LeadFormPayload) => void;\n reset: () => void;\n }) => React.ReactNode;\n}\n\ntype FieldType = NonNullable<LeadFormField['type']>;\n\nconst FIELD_DEFAULTS: Record<LeadFormFieldName, { label: string; placeholder: string; type: FieldType; required: boolean }> = {\n name: { label: 'Name', placeholder: 'Your name', type: 'text', required: false },\n email: { label: 'Email', placeholder: 'you@company.com', type: 'email', required: true },\n phone: { label: 'Phone', placeholder: '+1 (555) 000-0000', type: 'tel', required: false },\n company: { label: 'Company', placeholder: 'Company name', type: 'text', required: false },\n website: { label: 'Website', placeholder: 'https://...', type: 'url', required: false },\n message: { label: 'Message', placeholder: 'How can we help?', type: 'textarea', required: false },\n city: { label: 'City', placeholder: 'City', type: 'text', required: false },\n country: { label: 'Country', placeholder: 'Country', type: 'text', required: false },\n};\n\nfunction normalizeField(f: LeadFormFieldName | LeadFormField): LeadFormField & { name: LeadFormFieldName } {\n if (typeof f === 'string') {\n const def = FIELD_DEFAULTS[f];\n return { name: f, ...def };\n }\n const def = FIELD_DEFAULTS[f.name];\n return { ...def, ...f };\n}\n\n/**\n * Ready-to-use lead capture form with built-in DSA webhook integration.\n *\n * ```tsx\n * <DsaLeadForm\n * webhookUrl=\"https://api.example.com\"\n * projectSlug=\"my-project\"\n * webhookToken=\"abc123\"\n * fields={['name', 'email', 'company']}\n * ctaText=\"Get Free Audit\"\n * leadMagnet={{ title: \"SEO Audit Checklist\", description: \"47-point checklist\" }}\n * theme=\"dark\"\n * />\n * ```\n */\nexport function DsaLeadForm({\n webhookUrl,\n projectSlug,\n webhookToken,\n fields = ['name', 'email'],\n leadMagnet,\n ctaText = 'Submit',\n thankYouMessage,\n theme = 'light',\n className,\n onSuccess,\n onError,\n sourceUrl,\n children,\n}: DsaLeadFormProps) {\n const form = useDsaLeadForm({ webhookUrl, projectSlug, webhookToken });\n const [values, setValues] = useState<Record<string, string>>({});\n\n const normalizedFields = fields.map(normalizeField);\n\n // Render prop mode\n if (children) {\n return <>{children({ ...form })}</>;\n }\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n const payload: LeadFormPayload = {\n email: values.email || '',\n name: values.name,\n phone: values.phone,\n company: values.company,\n website: values.website,\n message: values.message,\n city: values.city,\n country: values.country,\n source_url: sourceUrl,\n };\n const result = await form.submit(payload);\n if (result.ok) {\n onSuccess?.(payload);\n } else if (result.error) {\n onError?.(new Error(result.error));\n }\n };\n\n const isInherit = theme === 'inherit';\n const isDark = theme === 'dark';\n\n const styles = isInherit ? {} : {\n wrapper: {\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n backgroundColor: isDark ? '#1e293b' : '#ffffff',\n border: `1px solid ${isDark ? '#334155' : '#e2e8f0'}`,\n borderRadius: '12px',\n padding: '24px',\n maxWidth: '480px',\n color: isDark ? '#f1f5f9' : '#0f172a',\n } as React.CSSProperties,\n heading: {\n margin: '0 0 4px 0',\n fontSize: '18px',\n fontWeight: 700,\n color: isDark ? '#f1f5f9' : '#0f172a',\n } as React.CSSProperties,\n description: {\n margin: '0 0 16px 0',\n fontSize: '14px',\n color: isDark ? '#94a3b8' : '#64748b',\n } as React.CSSProperties,\n label: {\n display: 'block',\n fontSize: '13px',\n fontWeight: 500,\n marginBottom: '4px',\n color: isDark ? '#cbd5e1' : '#374151',\n } as React.CSSProperties,\n input: {\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n fontSize: '14px',\n border: `1px solid ${isDark ? '#475569' : '#d1d5db'}`,\n borderRadius: '8px',\n backgroundColor: isDark ? '#0f172a' : '#ffffff',\n color: isDark ? '#f1f5f9' : '#0f172a',\n outline: 'none',\n boxSizing: 'border-box' as const,\n } as React.CSSProperties,\n textarea: {\n display: 'block',\n width: '100%',\n padding: '8px 12px',\n fontSize: '14px',\n border: `1px solid ${isDark ? '#475569' : '#d1d5db'}`,\n borderRadius: '8px',\n backgroundColor: isDark ? '#0f172a' : '#ffffff',\n color: isDark ? '#f1f5f9' : '#0f172a',\n outline: 'none',\n minHeight: '80px',\n resize: 'vertical' as const,\n fontFamily: 'inherit',\n boxSizing: 'border-box' as const,\n } as React.CSSProperties,\n button: {\n width: '100%',\n padding: '10px 20px',\n fontSize: '14px',\n fontWeight: 600,\n color: '#ffffff',\n backgroundColor: '#2563eb',\n border: 'none',\n borderRadius: '8px',\n cursor: 'pointer',\n marginTop: '4px',\n opacity: form.submitting ? 0.7 : 1,\n } as React.CSSProperties,\n fieldGroup: {\n marginBottom: '12px',\n } as React.CSSProperties,\n error: {\n fontSize: '13px',\n color: '#ef4444',\n marginTop: '8px',\n } as React.CSSProperties,\n success: {\n textAlign: 'center' as const,\n padding: '16px 0',\n } as React.CSSProperties,\n successTitle: {\n fontSize: '18px',\n fontWeight: 700,\n color: isDark ? '#34d399' : '#059669',\n marginBottom: '8px',\n } as React.CSSProperties,\n successText: {\n fontSize: '14px',\n color: isDark ? '#94a3b8' : '#64748b',\n marginBottom: '16px',\n } as React.CSSProperties,\n downloadLink: {\n display: 'inline-block',\n padding: '10px 24px',\n fontSize: '14px',\n fontWeight: 600,\n color: '#ffffff',\n backgroundColor: '#2563eb',\n borderRadius: '8px',\n textDecoration: 'none',\n } as React.CSSProperties,\n };\n\n // ── Success state ──\n if (form.submitted) {\n return (\n <div\n className={`dsa-lead-form dsa-lead-form--success ${className || ''}`}\n data-dsa-lead-form\n data-theme={theme}\n style={isInherit ? undefined : styles.wrapper}\n >\n <div style={isInherit ? undefined : styles.success}>\n <div style={isInherit ? undefined : styles.successTitle}>\n {thankYouMessage || 'Thank you!'}\n </div>\n {leadMagnet?.downloadUrl && (\n <>\n <p style={isInherit ? undefined : styles.successText}>\n Your download is ready:\n </p>\n <a\n href={leadMagnet.downloadUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"dsa-lead-form__download\"\n style={isInherit ? undefined : styles.downloadLink}\n >\n Download {leadMagnet.title}\n </a>\n </>\n )}\n </div>\n </div>\n );\n }\n\n // ── Form state ──\n return (\n <div\n className={`dsa-lead-form ${className || ''}`}\n data-dsa-lead-form\n data-theme={theme}\n style={isInherit ? undefined : styles.wrapper}\n >\n {/* Lead magnet promo header */}\n {leadMagnet && (\n <div className=\"dsa-lead-form__magnet\" style={{ marginBottom: '16px' }}>\n {leadMagnet.imageUrl && (\n <img\n src={leadMagnet.imageUrl}\n alt={leadMagnet.title}\n style={isInherit ? undefined : {\n width: '100%',\n borderRadius: '8px',\n marginBottom: '12px',\n display: 'block',\n }}\n className=\"dsa-lead-form__magnet-image\"\n />\n )}\n <h3 className=\"dsa-lead-form__magnet-title\" style={isInherit ? undefined : styles.heading}>\n {leadMagnet.title}\n </h3>\n {leadMagnet.description && (\n <p className=\"dsa-lead-form__magnet-description\" style={isInherit ? undefined : styles.description}>\n {leadMagnet.description}\n </p>\n )}\n </div>\n )}\n\n <form onSubmit={handleSubmit} className=\"dsa-lead-form__form\" noValidate>\n {normalizedFields.map((field) => (\n <div key={field.name} className=\"dsa-lead-form__field\" style={isInherit ? undefined : styles.fieldGroup}>\n <label className=\"dsa-lead-form__label\" style={isInherit ? undefined : styles.label}>\n {field.label}{field.required && ' *'}\n </label>\n {field.type === 'textarea' ? (\n <textarea\n name={field.name}\n placeholder={field.placeholder}\n required={field.required}\n value={values[field.name] || ''}\n onChange={(e) => setValues((v) => ({ ...v, [field.name]: e.target.value }))}\n className=\"dsa-lead-form__textarea\"\n style={isInherit ? undefined : styles.textarea}\n />\n ) : (\n <input\n type={field.type || 'text'}\n name={field.name}\n placeholder={field.placeholder}\n required={field.required}\n value={values[field.name] || ''}\n onChange={(e) => setValues((v) => ({ ...v, [field.name]: e.target.value }))}\n className=\"dsa-lead-form__input\"\n style={isInherit ? undefined : styles.input}\n />\n )}\n </div>\n ))}\n\n <button\n type=\"submit\"\n disabled={form.submitting}\n className=\"dsa-lead-form__submit\"\n style={isInherit ? undefined : styles.button}\n >\n {form.submitting ? 'Sending...' : ctaText}\n </button>\n\n {form.error && (\n <p className=\"dsa-lead-form__error\" style={isInherit ? undefined : styles.error}>\n {form.error.message}\n </p>\n )}\n </form>\n </div>\n );\n}\n"],"mappings":"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","names":["ContentClient","config","path","params","url","k","v","fetchOptions","res","text","article","filters","raw","slug","limit","createContext","useContext","useMemo","jsx","ContentContext","createContext","DsaContentProvider","config","children","client","useMemo","ContentClient","useDsaContent","useContext","useState","useEffect","useCallback","useArticles","filters","client","useDsaContent","state","setState","useState","fetch","useCallback","s","res","err","useEffect","useArticle","slug","article","useRelatedArticles","limit","articles","useCategories","categories","useState","useCallback","useDsaLeadForm","config","submitting","setSubmitting","submitted","setSubmitted","error","setError","submit","data","url","body","res","json","msg","err","e","reset","React","jsx","jsxs","themeVars","DefaultCard","article","layout","showExcerpt","showImage","showMeta","onClick","isGrid","hovered","setHovered","cardStyle","e","ArticleFeed","articles","columns","onArticleClick","className","theme","renderArticle","gridTemplateColumns","vars","React","useState","jsx","jsxs","themeVars","FaqItemComponent","item","collapsible","defaultOpen","open","setOpen","FaqBlock","items","className","title","theme","vars","schemaData","i","jsx","jsxs","themeVars","RelatedArticles","articles","title","limit","onArticleClick","className","theme","displayed","vars","a","e","Fragment","jsx","jsxs","themeVars","PROSE_STYLE_ID","proseCSS","useProseStyles","enabled","React","el","DefaultToc","headings","h","i","InheritToc","ArticlePage","article","showFaq","showTableOfContents","showMeta","showRelated","relatedArticles","onRelatedClick","className","contentClassName","theme","disableProseStyles","components","inherit","H1","children","Toc","FaqComponent","FaqBlock","vars","bodyClasses","RelatedArticles","jsx","generateArticleMetadata","article","siteUrl","url","SeoMetaBridge","schema","useState","Fragment","jsx","jsxs","FIELD_DEFAULTS","normalizeField","f","def","DsaLeadForm","webhookUrl","projectSlug","webhookToken","fields","leadMagnet","ctaText","thankYouMessage","theme","className","onSuccess","onError","sourceUrl","children","form","useDsaLeadForm","values","setValues","useState","normalizedFields","handleSubmit","e","payload","result","isInherit","isDark","styles","field","v"]}
|
package/dist/server.d.mts
CHANGED
|
@@ -42,10 +42,6 @@ interface Article {
|
|
|
42
42
|
pillar_name?: string;
|
|
43
43
|
cluster_name?: string;
|
|
44
44
|
content_type?: string;
|
|
45
|
-
/** Author info from site settings (E-E-A-T) */
|
|
46
|
-
author?: ArticleAuthor | null;
|
|
47
|
-
/** Publisher info from site settings (E-E-A-T) */
|
|
48
|
-
publisher?: ArticlePublisher | null;
|
|
49
45
|
}
|
|
50
46
|
/**
|
|
51
47
|
* Abbreviated article for lists
|
|
@@ -89,25 +85,6 @@ interface InternalLink {
|
|
|
89
85
|
slug: string;
|
|
90
86
|
anchor_text: string;
|
|
91
87
|
}
|
|
92
|
-
/**
|
|
93
|
-
* Author information (E-E-A-T) — populated from site settings
|
|
94
|
-
*/
|
|
95
|
-
interface ArticleAuthor {
|
|
96
|
-
name: string;
|
|
97
|
-
url?: string | null;
|
|
98
|
-
bio?: string | null;
|
|
99
|
-
image_url?: string | null;
|
|
100
|
-
job_title?: string | null;
|
|
101
|
-
socials?: Record<string, string>;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Publisher information (E-E-A-T) — populated from site settings
|
|
105
|
-
*/
|
|
106
|
-
interface ArticlePublisher {
|
|
107
|
-
name: string;
|
|
108
|
-
logo_url?: string | null;
|
|
109
|
-
url?: string | null;
|
|
110
|
-
}
|
|
111
88
|
/**
|
|
112
89
|
* Category with clusters
|
|
113
90
|
*/
|
package/dist/server.d.ts
CHANGED
|
@@ -42,10 +42,6 @@ interface Article {
|
|
|
42
42
|
pillar_name?: string;
|
|
43
43
|
cluster_name?: string;
|
|
44
44
|
content_type?: string;
|
|
45
|
-
/** Author info from site settings (E-E-A-T) */
|
|
46
|
-
author?: ArticleAuthor | null;
|
|
47
|
-
/** Publisher info from site settings (E-E-A-T) */
|
|
48
|
-
publisher?: ArticlePublisher | null;
|
|
49
45
|
}
|
|
50
46
|
/**
|
|
51
47
|
* Abbreviated article for lists
|
|
@@ -89,25 +85,6 @@ interface InternalLink {
|
|
|
89
85
|
slug: string;
|
|
90
86
|
anchor_text: string;
|
|
91
87
|
}
|
|
92
|
-
/**
|
|
93
|
-
* Author information (E-E-A-T) — populated from site settings
|
|
94
|
-
*/
|
|
95
|
-
interface ArticleAuthor {
|
|
96
|
-
name: string;
|
|
97
|
-
url?: string | null;
|
|
98
|
-
bio?: string | null;
|
|
99
|
-
image_url?: string | null;
|
|
100
|
-
job_title?: string | null;
|
|
101
|
-
socials?: Record<string, string>;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Publisher information (E-E-A-T) — populated from site settings
|
|
105
|
-
*/
|
|
106
|
-
interface ArticlePublisher {
|
|
107
|
-
name: string;
|
|
108
|
-
logo_url?: string | null;
|
|
109
|
-
url?: string | null;
|
|
110
|
-
}
|
|
111
88
|
/**
|
|
112
89
|
* Category with clusters
|
|
113
90
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsaplatform/content-sdk",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "React SDK for DSA Content Operating System — fetch and render SEO content
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "React SDK for DSA Content Operating System — fetch and render SEO content, embed lead capture forms",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -65,7 +65,10 @@
|
|
|
65
65
|
"seo",
|
|
66
66
|
"content-engine",
|
|
67
67
|
"headless-cms",
|
|
68
|
-
"ssr"
|
|
68
|
+
"ssr",
|
|
69
|
+
"lead-capture",
|
|
70
|
+
"forms",
|
|
71
|
+
"webhook"
|
|
69
72
|
],
|
|
70
73
|
"license": "MIT",
|
|
71
74
|
"sideEffects": false
|