@seoengine.ai/next-llm-ready 1.0.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.
@@ -0,0 +1,850 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { NextRequest, NextResponse } from 'next/server';
3
+
4
+ /**
5
+ * next-llm-ready - TypeScript Type Definitions
6
+ * Make your Next.js content AI-ready
7
+ */
8
+ /**
9
+ * Content metadata for LLM-ready output
10
+ */
11
+ interface LLMContent {
12
+ /** Page/post title */
13
+ title: string;
14
+ /** Main content (HTML or Markdown) */
15
+ content: string;
16
+ /** Short description/excerpt */
17
+ excerpt?: string;
18
+ /** Canonical URL */
19
+ url: string;
20
+ /** Publication date (ISO 8601) */
21
+ date?: string;
22
+ /** Last modified date (ISO 8601) */
23
+ modifiedDate?: string;
24
+ /** Author name */
25
+ author?: string;
26
+ /** Categories/sections */
27
+ categories?: string[];
28
+ /** Tags/keywords */
29
+ tags?: string[];
30
+ /** Custom prompt prefix for AI context */
31
+ promptPrefix?: string;
32
+ /** Featured image URL */
33
+ image?: string;
34
+ /** Reading time in minutes */
35
+ readingTime?: number;
36
+ }
37
+ /**
38
+ * Generated markdown output
39
+ */
40
+ interface MarkdownOutput {
41
+ /** Raw markdown string */
42
+ markdown: string;
43
+ /** Word count */
44
+ wordCount: number;
45
+ /** Estimated reading time */
46
+ readingTime: number;
47
+ /** Extracted headings for TOC */
48
+ headings: TOCHeading[];
49
+ }
50
+ /**
51
+ * Position options for UI elements
52
+ */
53
+ type ButtonPosition = 'floating' | 'inline' | 'next-to-heading' | 'below-heading';
54
+ /**
55
+ * TOC position options
56
+ */
57
+ type TOCPosition = 'left' | 'right' | 'inline-start' | 'inline-end';
58
+ /**
59
+ * Heading levels to include in TOC
60
+ */
61
+ type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
62
+ /**
63
+ * Copy action types for analytics
64
+ */
65
+ type CopyAction = 'copy' | 'view' | 'download';
66
+ /**
67
+ * CopyButton component props
68
+ */
69
+ interface CopyButtonProps {
70
+ /** Content to copy (LLMContent object or markdown string) */
71
+ content: LLMContent | string;
72
+ /** Button text */
73
+ text?: string;
74
+ /** Show dropdown with additional options */
75
+ showDropdown?: boolean;
76
+ /** Button position */
77
+ position?: ButtonPosition;
78
+ /** Enable keyboard shortcut (Ctrl+Shift+C / Cmd+Shift+C) */
79
+ keyboardShortcut?: boolean;
80
+ /** Custom class name */
81
+ className?: string;
82
+ /** Toast message on copy */
83
+ toastMessage?: string;
84
+ /** Toast duration in ms */
85
+ toastDuration?: number;
86
+ /** Callback on successful copy */
87
+ onCopy?: (action: CopyAction) => void;
88
+ /** Callback on error */
89
+ onError?: (error: Error) => void;
90
+ /** Analytics tracking function */
91
+ onAnalytics?: (event: AnalyticsEvent) => void;
92
+ /** Custom styles */
93
+ style?: React.CSSProperties;
94
+ /** Disable the button */
95
+ disabled?: boolean;
96
+ }
97
+ /**
98
+ * CopyDropdown component props (split button with menu)
99
+ */
100
+ interface CopyDropdownProps extends Omit<CopyButtonProps, 'showDropdown'> {
101
+ /** Dropdown menu items */
102
+ menuItems?: DropdownMenuItem[];
103
+ }
104
+ /**
105
+ * Dropdown menu item
106
+ */
107
+ interface DropdownMenuItem {
108
+ /** Unique identifier */
109
+ id: string;
110
+ /** Display label */
111
+ label: string;
112
+ /** Icon component */
113
+ icon?: React.ReactNode;
114
+ /** Action to perform */
115
+ action: CopyAction | (() => void);
116
+ /** Keyboard shortcut hint */
117
+ shortcut?: string;
118
+ }
119
+ /**
120
+ * TOC (Table of Contents) component props
121
+ */
122
+ interface TOCProps {
123
+ /** Content to extract headings from (HTML string or ref to content element) */
124
+ content?: string;
125
+ /** Reference to content container element */
126
+ contentRef?: React.RefObject<HTMLElement>;
127
+ /** Manually provided headings */
128
+ headings?: TOCHeading[];
129
+ /** Position of TOC */
130
+ position?: TOCPosition;
131
+ /** Heading levels to include */
132
+ levels?: HeadingLevel[];
133
+ /** Title for TOC section */
134
+ title?: string;
135
+ /** Sticky behavior */
136
+ sticky?: boolean;
137
+ /** Sticky offset from top (px) */
138
+ stickyOffset?: number;
139
+ /** Custom class name */
140
+ className?: string;
141
+ /** Smooth scroll behavior */
142
+ smoothScroll?: boolean;
143
+ /** Highlight active heading */
144
+ highlightActive?: boolean;
145
+ /** Collapsible on mobile */
146
+ collapsible?: boolean;
147
+ /** Initially collapsed */
148
+ defaultCollapsed?: boolean;
149
+ /** Custom styles */
150
+ style?: React.CSSProperties;
151
+ }
152
+ /**
153
+ * Single TOC heading item
154
+ */
155
+ interface TOCHeading {
156
+ /** Heading ID (for anchor links) */
157
+ id: string;
158
+ /** Heading text content */
159
+ text: string;
160
+ /** Heading level (1-6) */
161
+ level: number;
162
+ /** Child headings (for nested structure) */
163
+ children?: TOCHeading[];
164
+ }
165
+ /**
166
+ * LLMBadge component props (shows AI-ready indicator)
167
+ */
168
+ interface LLMBadgeProps {
169
+ /** Badge text */
170
+ text?: string;
171
+ /** Show tooltip with info */
172
+ showTooltip?: boolean;
173
+ /** Tooltip content */
174
+ tooltipContent?: string;
175
+ /** Badge size */
176
+ size?: 'sm' | 'md' | 'lg';
177
+ /** Custom class name */
178
+ className?: string;
179
+ }
180
+ /**
181
+ * useLLMCopy hook options
182
+ */
183
+ interface UseLLMCopyOptions {
184
+ /** Content to copy */
185
+ content: LLMContent | string;
186
+ /** Success callback */
187
+ onSuccess?: (action: CopyAction) => void;
188
+ /** Error callback */
189
+ onError?: (error: Error) => void;
190
+ /** Analytics callback */
191
+ onAnalytics?: (event: AnalyticsEvent) => void;
192
+ }
193
+ /**
194
+ * useLLMCopy hook return value
195
+ */
196
+ interface UseLLMCopyReturn {
197
+ /** Copy to clipboard function */
198
+ copy: () => Promise<boolean>;
199
+ /** View markdown function (returns markdown string) */
200
+ view: () => string;
201
+ /** Download markdown function */
202
+ download: (filename?: string) => void;
203
+ /** Generated markdown */
204
+ markdown: string;
205
+ /** Copy in progress */
206
+ isCopying: boolean;
207
+ /** Last copy was successful */
208
+ isSuccess: boolean;
209
+ /** Last error */
210
+ error: Error | null;
211
+ }
212
+ /**
213
+ * useTOC hook options
214
+ */
215
+ interface UseTOCOptions {
216
+ /** Content container ref */
217
+ contentRef: React.RefObject<HTMLElement>;
218
+ /** Heading levels to track */
219
+ levels?: HeadingLevel[];
220
+ /** Root margin for intersection observer */
221
+ rootMargin?: string;
222
+ /** Threshold for intersection observer */
223
+ threshold?: number | number[];
224
+ }
225
+ /**
226
+ * useTOC hook return value
227
+ */
228
+ interface UseTOCReturn {
229
+ /** Extracted headings */
230
+ headings: TOCHeading[];
231
+ /** Currently active heading ID */
232
+ activeId: string | null;
233
+ /** Scroll to heading function */
234
+ scrollTo: (id: string) => void;
235
+ }
236
+ /**
237
+ * useAnalytics hook options
238
+ */
239
+ interface UseAnalyticsOptions {
240
+ /** API endpoint for tracking */
241
+ endpoint?: string;
242
+ /** Include page URL */
243
+ includeUrl?: boolean;
244
+ /** Include timestamp */
245
+ includeTimestamp?: boolean;
246
+ /** Custom metadata */
247
+ metadata?: Record<string, unknown>;
248
+ }
249
+ /**
250
+ * useAnalytics hook return value
251
+ */
252
+ interface UseAnalyticsReturn {
253
+ /** Track an event */
254
+ track: (event: AnalyticsEvent) => Promise<void>;
255
+ /** Track copy action */
256
+ trackCopy: () => Promise<void>;
257
+ /** Track view action */
258
+ trackView: () => Promise<void>;
259
+ /** Track download action */
260
+ trackDownload: () => Promise<void>;
261
+ }
262
+ /**
263
+ * Analytics event
264
+ */
265
+ interface AnalyticsEvent {
266
+ /** Event type */
267
+ action: CopyAction;
268
+ /** Page/content identifier */
269
+ contentId?: string;
270
+ /** Page URL */
271
+ url?: string;
272
+ /** Timestamp */
273
+ timestamp?: string;
274
+ /** Additional metadata */
275
+ metadata?: Record<string, unknown>;
276
+ }
277
+ /**
278
+ * Analytics handler config
279
+ */
280
+ interface AnalyticsConfig {
281
+ /** Enable analytics */
282
+ enabled?: boolean;
283
+ /** API endpoint */
284
+ endpoint?: string;
285
+ /** Storage type */
286
+ storage?: 'memory' | 'localStorage' | 'custom';
287
+ /** Custom storage adapter */
288
+ storageAdapter?: AnalyticsStorageAdapter;
289
+ /** Batch events before sending */
290
+ batchSize?: number;
291
+ /** Flush interval in ms */
292
+ flushInterval?: number;
293
+ }
294
+ /**
295
+ * Custom analytics storage adapter
296
+ */
297
+ interface AnalyticsStorageAdapter {
298
+ /** Save event */
299
+ save: (event: AnalyticsEvent) => Promise<void>;
300
+ /** Get all events */
301
+ getAll: () => Promise<AnalyticsEvent[]>;
302
+ /** Clear events */
303
+ clear: () => Promise<void>;
304
+ }
305
+ /**
306
+ * LLMs.txt endpoint configuration
307
+ */
308
+ interface LLMsTxtConfig {
309
+ /** Site name */
310
+ siteName: string;
311
+ /** Site description */
312
+ siteDescription?: string;
313
+ /** Site URL */
314
+ siteUrl: string;
315
+ /** Content items to include */
316
+ content: LLMsTxtItem[];
317
+ /** Custom header text */
318
+ headerText?: string;
319
+ /** Custom footer text */
320
+ footerText?: string;
321
+ }
322
+ /**
323
+ * Single item in LLMs.txt listing
324
+ */
325
+ interface LLMsTxtItem {
326
+ /** Content title */
327
+ title: string;
328
+ /** Page URL */
329
+ url: string;
330
+ /** Content type (post, page, etc.) */
331
+ type?: string;
332
+ /** Publication date */
333
+ date?: string;
334
+ /** Short description */
335
+ description?: string;
336
+ }
337
+ /**
338
+ * Markdown API handler options
339
+ */
340
+ interface MarkdownHandlerOptions {
341
+ /** Function to fetch content by slug/id */
342
+ getContent: (slug: string) => Promise<LLMContent | null>;
343
+ /** Cache control header value */
344
+ cacheControl?: string;
345
+ /** Enable CORS */
346
+ cors?: boolean;
347
+ }
348
+ /**
349
+ * Analytics API handler options
350
+ */
351
+ interface AnalyticsHandlerOptions {
352
+ /** Storage adapter */
353
+ storage: AnalyticsStorageAdapter;
354
+ /** Rate limiting (requests per minute) */
355
+ rateLimit?: number;
356
+ /** Enable CORS */
357
+ cors?: boolean;
358
+ }
359
+ /**
360
+ * Global LLM Ready configuration
361
+ */
362
+ interface LLMReadyConfig {
363
+ /** Default button position */
364
+ defaultPosition?: ButtonPosition;
365
+ /** Default TOC position */
366
+ defaultTOCPosition?: TOCPosition;
367
+ /** Enable keyboard shortcuts globally */
368
+ keyboardShortcuts?: boolean;
369
+ /** Default prompt prefix */
370
+ promptPrefix?: string;
371
+ /** Analytics configuration */
372
+ analytics?: AnalyticsConfig;
373
+ /** Custom theme variables */
374
+ theme?: ThemeConfig;
375
+ }
376
+ /**
377
+ * Theme configuration (CSS variables)
378
+ */
379
+ interface ThemeConfig {
380
+ /** Primary color */
381
+ primaryColor?: string;
382
+ /** Primary hover color */
383
+ primaryHover?: string;
384
+ /** Text color */
385
+ textColor?: string;
386
+ /** Background color */
387
+ backgroundColor?: string;
388
+ /** Border color */
389
+ borderColor?: string;
390
+ /** Border radius */
391
+ borderRadius?: string;
392
+ /** Font family */
393
+ fontFamily?: string;
394
+ /** Shadow */
395
+ shadow?: string;
396
+ }
397
+ /**
398
+ * HTML to Markdown conversion options
399
+ */
400
+ interface HTMLToMarkdownOptions {
401
+ /** Preserve line breaks */
402
+ preserveLineBreaks?: boolean;
403
+ /** Convert images to markdown */
404
+ convertImages?: boolean;
405
+ /** Convert links to markdown */
406
+ convertLinks?: boolean;
407
+ /** Strip scripts and styles */
408
+ stripScripts?: boolean;
409
+ /** Custom element handlers */
410
+ customHandlers?: Record<string, (element: Element) => string>;
411
+ }
412
+ /**
413
+ * Download options
414
+ */
415
+ interface DownloadOptions {
416
+ /** Filename (without extension) */
417
+ filename?: string;
418
+ /** File extension */
419
+ extension?: 'md' | 'txt';
420
+ /** Include metadata header */
421
+ includeMetadata?: boolean;
422
+ }
423
+
424
+ /**
425
+ * Simple copy button component
426
+ *
427
+ * @example
428
+ * ```tsx
429
+ * <CopyButton
430
+ * content={{
431
+ * title: "My Article",
432
+ * content: "<p>Article content...</p>",
433
+ * url: "https://example.com/article",
434
+ * }}
435
+ * text="Copy for AI"
436
+ * />
437
+ * ```
438
+ */
439
+ declare function CopyButton({ content, text, position, keyboardShortcut, className, toastMessage, toastDuration, onCopy, onError, onAnalytics, style, disabled, }: CopyButtonProps): react_jsx_runtime.JSX.Element;
440
+
441
+ /**
442
+ * Split button with dropdown for copy/view/download actions
443
+ *
444
+ * @example
445
+ * ```tsx
446
+ * <CopyDropdown
447
+ * content={{
448
+ * title: "My Article",
449
+ * content: "<p>Article content...</p>",
450
+ * url: "https://example.com/article",
451
+ * }}
452
+ * text="Copy for AI"
453
+ * />
454
+ * ```
455
+ */
456
+ declare function CopyDropdown({ content, text, menuItems, position, keyboardShortcut, className, toastMessage, toastDuration, onCopy, onError, onAnalytics, style, disabled, }: CopyDropdownProps): react_jsx_runtime.JSX.Element;
457
+
458
+ /**
459
+ * Table of Contents component
460
+ *
461
+ * @example
462
+ * ```tsx
463
+ * function Article() {
464
+ * const contentRef = useRef<HTMLDivElement>(null);
465
+ *
466
+ * return (
467
+ * <div className="article-layout">
468
+ * <TOC
469
+ * contentRef={contentRef}
470
+ * position="right"
471
+ * levels={['h2', 'h3']}
472
+ * sticky
473
+ * />
474
+ * <article ref={contentRef}>
475
+ * <h2 id="intro">Introduction</h2>
476
+ * <p>Content...</p>
477
+ * </article>
478
+ * </div>
479
+ * );
480
+ * }
481
+ * ```
482
+ */
483
+ declare function TOC({ content, contentRef, headings: providedHeadings, position, levels, title, sticky, stickyOffset, className, smoothScroll, highlightActive, collapsible, defaultCollapsed, style, }: TOCProps): react_jsx_runtime.JSX.Element | null;
484
+ /**
485
+ * Mobile TOC with slide-up panel
486
+ */
487
+ declare function TOCMobile(props: TOCProps): react_jsx_runtime.JSX.Element;
488
+
489
+ /**
490
+ * Badge showing content is LLM-ready
491
+ *
492
+ * @example
493
+ * ```tsx
494
+ * <LLMBadge
495
+ * text="AI Ready"
496
+ * showTooltip
497
+ * size="sm"
498
+ * />
499
+ * ```
500
+ */
501
+ declare function LLMBadge({ text, showTooltip, tooltipContent, size, className, }: LLMBadgeProps): react_jsx_runtime.JSX.Element;
502
+
503
+ /**
504
+ * Hook for LLM copy/view/download operations
505
+ *
506
+ * @example
507
+ * ```tsx
508
+ * function MyComponent() {
509
+ * const { copy, view, download, markdown, isCopying, isSuccess } = useLLMCopy({
510
+ * content: {
511
+ * title: 'My Article',
512
+ * content: '<p>Article content...</p>',
513
+ * url: 'https://example.com/article',
514
+ * },
515
+ * onSuccess: () => console.log('Copied!'),
516
+ * });
517
+ *
518
+ * return (
519
+ * <div>
520
+ * <button onClick={copy} disabled={isCopying}>
521
+ * {isSuccess ? 'Copied!' : 'Copy'}
522
+ * </button>
523
+ * <button onClick={download}>Download</button>
524
+ * <pre>{view()}</pre>
525
+ * </div>
526
+ * );
527
+ * }
528
+ * ```
529
+ */
530
+ declare function useLLMCopy(options: UseLLMCopyOptions): UseLLMCopyReturn;
531
+
532
+ /**
533
+ * Hook for Table of Contents functionality
534
+ *
535
+ * @example
536
+ * ```tsx
537
+ * function ArticlePage() {
538
+ * const contentRef = useRef<HTMLDivElement>(null);
539
+ * const { headings, activeId, scrollTo } = useTOC({
540
+ * contentRef,
541
+ * levels: ['h2', 'h3'],
542
+ * });
543
+ *
544
+ * return (
545
+ * <div>
546
+ * <nav>
547
+ * {headings.map(h => (
548
+ * <a
549
+ * key={h.id}
550
+ * href={`#${h.id}`}
551
+ * onClick={(e) => { e.preventDefault(); scrollTo(h.id); }}
552
+ * className={activeId === h.id ? 'active' : ''}
553
+ * >
554
+ * {h.text}
555
+ * </a>
556
+ * ))}
557
+ * </nav>
558
+ * <div ref={contentRef}>
559
+ * <h2 id="intro">Introduction</h2>
560
+ * <p>Content...</p>
561
+ * </div>
562
+ * </div>
563
+ * );
564
+ * }
565
+ * ```
566
+ */
567
+ declare function useTOC(options: UseTOCOptions): UseTOCReturn;
568
+ /**
569
+ * Build nested TOC structure from flat headings
570
+ */
571
+ declare function buildNestedTOC(headings: TOCHeading[]): TOCHeading[];
572
+ /**
573
+ * Hook for keyboard navigation in TOC
574
+ */
575
+ declare function useTOCKeyboard(headings: TOCHeading[], activeId: string | null, scrollTo: (id: string) => void): void;
576
+
577
+ /**
578
+ * Hook for analytics tracking
579
+ *
580
+ * @example
581
+ * ```tsx
582
+ * function MyComponent() {
583
+ * const { track, trackCopy, trackView, trackDownload } = useAnalytics({
584
+ * endpoint: '/api/analytics',
585
+ * metadata: { contentId: 'article-123' },
586
+ * });
587
+ *
588
+ * return (
589
+ * <button onClick={trackCopy}>Copy</button>
590
+ * );
591
+ * }
592
+ * ```
593
+ */
594
+ declare function useAnalytics(options?: UseAnalyticsOptions): UseAnalyticsReturn;
595
+ /**
596
+ * Create a simple analytics tracker function (non-hook version)
597
+ */
598
+ declare function createAnalyticsTracker(endpoint: string): (action: CopyAction, contentId?: string, metadata?: Record<string, unknown>) => Promise<void>;
599
+
600
+ /**
601
+ * HTML to Markdown Converter
602
+ * Converts HTML content to clean markdown format
603
+ */
604
+
605
+ /**
606
+ * Convert HTML string to Markdown
607
+ */
608
+ declare function htmlToMarkdown(html: string, options?: HTMLToMarkdownOptions): string;
609
+
610
+ /**
611
+ * Clipboard Utilities
612
+ * Cross-browser clipboard operations
613
+ */
614
+ /**
615
+ * Copy text to clipboard
616
+ * Uses modern Clipboard API with fallback for older browsers
617
+ */
618
+ declare function copyToClipboard(text: string): Promise<boolean>;
619
+
620
+ /**
621
+ * Download Utilities
622
+ * File download functionality
623
+ */
624
+
625
+ /**
626
+ * Download content as a file
627
+ */
628
+ declare function downloadAsFile(content: string, options?: DownloadOptions): void;
629
+
630
+ /**
631
+ * Server-side Markdown Generation
632
+ * Generate LLM-ready markdown from content
633
+ */
634
+
635
+ /**
636
+ * Generate complete markdown output from LLM content
637
+ */
638
+ declare function generateMarkdown(content: LLMContent): MarkdownOutput;
639
+ /**
640
+ * Generate markdown string only (without metadata)
641
+ */
642
+ declare function generateMarkdownString(content: LLMContent): string;
643
+ /**
644
+ * Convert LLMContent to plain text (for previews, etc.)
645
+ */
646
+ declare function contentToPlainText(content: LLMContent): string;
647
+
648
+ /**
649
+ * LLMs.txt Generator
650
+ * Generate sitemap-style content listing for AI crawlers
651
+ * Follows the llms.txt specification
652
+ */
653
+
654
+ /**
655
+ * Generate llms.txt content
656
+ */
657
+ declare function generateLLMsTxt(config: LLMsTxtConfig): string;
658
+
659
+ /**
660
+ * LLMs.txt API Route Handler
661
+ * Creates an API route handler for serving /llms.txt
662
+ */
663
+
664
+ interface LLMsTxtHandlerOptions {
665
+ /** Function to get site configuration */
666
+ getSiteConfig: () => Promise<{
667
+ siteName: string;
668
+ siteDescription?: string;
669
+ siteUrl: string;
670
+ }>;
671
+ /** Function to get all content items */
672
+ getContent: () => Promise<LLMsTxtItem[]>;
673
+ /** Cache control header (default: 1 hour) */
674
+ cacheControl?: string;
675
+ /** Custom header text */
676
+ headerText?: string;
677
+ /** Custom footer text */
678
+ footerText?: string;
679
+ }
680
+ /**
681
+ * Create an API route handler for /llms.txt
682
+ *
683
+ * @example
684
+ * ```ts
685
+ * // app/llms.txt/route.ts
686
+ * import { createLLMsTxtHandler } from 'next-llm-ready/api';
687
+ *
688
+ * export const GET = createLLMsTxtHandler({
689
+ * getSiteConfig: async () => ({
690
+ * siteName: 'My Site',
691
+ * siteDescription: 'A great website',
692
+ * siteUrl: 'https://example.com',
693
+ * }),
694
+ * getContent: async () => {
695
+ * const posts = await getAllPosts();
696
+ * return posts.map(post => ({
697
+ * title: post.title,
698
+ * url: `https://example.com/blog/${post.slug}`,
699
+ * type: 'post',
700
+ * date: post.date,
701
+ * }));
702
+ * },
703
+ * });
704
+ * ```
705
+ */
706
+ declare function createLLMsTxtHandler(options: LLMsTxtHandlerOptions): (request: NextRequest) => Promise<NextResponse>;
707
+ /**
708
+ * Create a Pages Router API handler for /api/llms.txt
709
+ *
710
+ * @example
711
+ * ```ts
712
+ * // pages/api/llms.txt.ts
713
+ * import { createLLMsTxtPageHandler } from 'next-llm-ready/api';
714
+ *
715
+ * export default createLLMsTxtPageHandler({
716
+ * getSiteConfig: async () => ({ ... }),
717
+ * getContent: async () => { ... },
718
+ * });
719
+ * ```
720
+ */
721
+ declare function createLLMsTxtPageHandler(options: LLMsTxtHandlerOptions): (req: {
722
+ method?: string;
723
+ }, res: {
724
+ status: (code: number) => {
725
+ end: (body?: string) => void;
726
+ json: (body: unknown) => void;
727
+ };
728
+ setHeader: (name: string, value: string) => void;
729
+ }) => Promise<void>;
730
+
731
+ /**
732
+ * Markdown API Route Handler
733
+ * Serves markdown content for ?llm=1 requests
734
+ */
735
+
736
+ /**
737
+ * Create middleware to handle ?llm=1 query parameter
738
+ *
739
+ * @example
740
+ * ```ts
741
+ * // middleware.ts
742
+ * import { withLLMParam } from 'next-llm-ready/api';
743
+ *
744
+ * export default withLLMParam({
745
+ * getContent: async (pathname) => {
746
+ * // Extract slug and fetch content
747
+ * const slug = pathname.split('/').pop();
748
+ * const post = await getPostBySlug(slug);
749
+ * if (!post) return null;
750
+ * return {
751
+ * title: post.title,
752
+ * content: post.content,
753
+ * url: `https://example.com${pathname}`,
754
+ * date: post.date,
755
+ * };
756
+ * },
757
+ * });
758
+ * ```
759
+ */
760
+ declare function withLLMParam(options: MarkdownHandlerOptions): (request: NextRequest) => Promise<NextResponse | undefined>;
761
+ /**
762
+ * Create an API route handler for markdown endpoints
763
+ *
764
+ * @example
765
+ * ```ts
766
+ * // app/api/content/[slug]/route.ts
767
+ * import { createMarkdownHandler } from 'next-llm-ready/api';
768
+ *
769
+ * export const GET = createMarkdownHandler({
770
+ * getContent: async (slug) => {
771
+ * const post = await getPostBySlug(slug);
772
+ * if (!post) return null;
773
+ * return {
774
+ * title: post.title,
775
+ * content: post.content,
776
+ * url: `https://example.com/blog/${slug}`,
777
+ * };
778
+ * },
779
+ * });
780
+ * ```
781
+ */
782
+ declare function createMarkdownHandler(options: Omit<MarkdownHandlerOptions, 'getContent'> & {
783
+ getContent: (slug: string) => Promise<LLMContent | null>;
784
+ }): (request: NextRequest, { params }: {
785
+ params: {
786
+ slug?: string;
787
+ };
788
+ }) => Promise<NextResponse>;
789
+ /**
790
+ * Helper to check if request has ?llm=1 parameter
791
+ */
792
+ declare function hasLLMParam(request: NextRequest): boolean;
793
+
794
+ /**
795
+ * Analytics API Route Handler
796
+ * Tracks copy/view/download events
797
+ */
798
+
799
+ /**
800
+ * In-memory analytics storage (for development/testing)
801
+ */
802
+ declare function createInMemoryStorage(): AnalyticsStorageAdapter;
803
+ /**
804
+ * Create an API route handler for analytics tracking
805
+ *
806
+ * @example
807
+ * ```ts
808
+ * // app/api/analytics/route.ts
809
+ * import { createAnalyticsHandler, createInMemoryStorage } from 'next-llm-ready/api';
810
+ *
811
+ * const storage = createInMemoryStorage();
812
+ *
813
+ * export const POST = createAnalyticsHandler({
814
+ * storage,
815
+ * rateLimit: 100,
816
+ * });
817
+ *
818
+ * export const GET = async () => {
819
+ * const events = await storage.getAll();
820
+ * return NextResponse.json({ events });
821
+ * };
822
+ * ```
823
+ */
824
+ declare function createAnalyticsHandler(options: AnalyticsHandlerOptions): (request: NextRequest) => Promise<NextResponse>;
825
+ /**
826
+ * Create a Pages Router API handler for analytics
827
+ */
828
+ declare function createAnalyticsPageHandler(options: AnalyticsHandlerOptions): (req: {
829
+ method?: string;
830
+ body?: unknown;
831
+ headers?: {
832
+ [key: string]: string | string[] | undefined;
833
+ };
834
+ }, res: {
835
+ status: (code: number) => {
836
+ end: (body?: string) => void;
837
+ json: (body: unknown) => void;
838
+ };
839
+ setHeader: (name: string, value: string) => void;
840
+ }) => Promise<void>;
841
+ /**
842
+ * Aggregate analytics events by action type
843
+ */
844
+ declare function aggregateEvents(storage: AnalyticsStorageAdapter): Promise<Record<string, number>>;
845
+ /**
846
+ * Get events for a specific content ID
847
+ */
848
+ declare function getEventsForContent(storage: AnalyticsStorageAdapter, contentId: string): Promise<AnalyticsEvent[]>;
849
+
850
+ export { type AnalyticsConfig, type AnalyticsEvent, type AnalyticsHandlerOptions, type AnalyticsStorageAdapter, type CopyAction, CopyButton, type CopyButtonProps, CopyDropdown, type CopyDropdownProps, type DownloadOptions, type DropdownMenuItem, type HTMLToMarkdownOptions, LLMBadge, type LLMBadgeProps, type LLMContent, type LLMReadyConfig, type LLMsTxtConfig, type LLMsTxtHandlerOptions, type LLMsTxtItem, type MarkdownHandlerOptions, type MarkdownOutput, TOC, type TOCHeading, TOCMobile, type TOCProps, type ThemeConfig, type UseAnalyticsOptions, type UseAnalyticsReturn, type UseLLMCopyOptions, type UseLLMCopyReturn, type UseTOCOptions, type UseTOCReturn, aggregateEvents, buildNestedTOC, contentToPlainText, copyToClipboard, createAnalyticsHandler, createAnalyticsPageHandler, createAnalyticsTracker, createInMemoryStorage, createLLMsTxtHandler, createLLMsTxtPageHandler, createMarkdownHandler, downloadAsFile, generateLLMsTxt, generateMarkdown, generateMarkdownString, getEventsForContent, hasLLMParam, htmlToMarkdown, useAnalytics, useLLMCopy, useTOC, useTOCKeyboard, withLLMParam };