@@ -32,22 +32,22 @@ const catalogFiles = import.meta.glob<string>('/src/examples/catalog/*.json', {
3232 import : 'default'
3333} ) ;
3434
35- const BASE_URL = 'https://layerchart.com' ;
36-
3735/** Generate URL for a docs page */
38- function docsUrl ( type : 'components' | 'utils' | 'guides' , slug : string ) : string {
36+ function docsUrl ( baseUrl : string , type : 'components' | 'utils' | 'guides' , slug : string ) : string {
3937 if ( type === 'guides' ) {
40- return `${ BASE_URL } /docs/${ slug } ` ;
38+ return `${ baseUrl } /docs/${ slug } ` ;
4139 }
42- return `${ BASE_URL } /docs/${ type } /${ slug } ` ;
40+ return `${ baseUrl } /docs/${ type } /${ slug } ` ;
4341}
4442
4543/** Generate URL for an llms.txt endpoint */
46- function llmsUrl ( type : 'components' | 'utils' | 'guides' , slug : string ) : string {
47- return `${ docsUrl ( type , slug ) } /llms.txt` ;
44+ function llmsUrl ( baseUrl : string , type : 'components' | 'utils' | 'guides' , slug : string ) : string {
45+ return `${ docsUrl ( baseUrl , type , slug ) } /llms.txt` ;
4846}
4947
5048interface GenerateMarkdownOptions {
49+ /** Base URL for the site (e.g. 'https://layerchart.com') */
50+ baseUrl : string ;
5151 /** Heading level for the title. 1 = "#", 2 = "##", etc. Default: 1 */
5252 headingLevel ?: number ;
5353 /** Whether to inline all example code blocks. Default: false */
@@ -61,7 +61,8 @@ interface GenerateMarkdownOptions {
6161function inlineExampleDirectives (
6262 content : string ,
6363 slug : string ,
64- type : 'components' | 'utils'
64+ type : 'components' | 'utils' ,
65+ baseUrl : string
6566) : string {
6667 // Remove HTML comments first to avoid inlining commented-out examples
6768 content = content . replace ( / < ! - - [ \s \S ] * ?- - > / g, '' ) ;
@@ -75,7 +76,7 @@ function inlineExampleDirectives(
7576 if ( raw ) {
7677 return '```svelte\n' + trimCode ( raw ) + '\n```' ;
7778 }
78- return `See example: [${ component } /${ name } ](${ docsUrl ( 'components' , component ) } /${ name } )` ;
79+ return `See example: [${ component } /${ name } ](${ docsUrl ( baseUrl , 'components' , component ) } /${ name } )` ;
7980 }
8081 ) ;
8182
@@ -94,7 +95,7 @@ function inlineExampleDirectives(
9495/**
9596 * Process markdown content for LLMs by removing custom syntax and converting to vanilla markdown
9697 */
97- function processMarkdownContent ( content : string ) : string {
98+ function processMarkdownContent ( content : string , baseUrl : string ) : string {
9899 // Remove frontmatter (YAML between --- markers at start of file)
99100 content = content . replace ( / ^ - - - \n [ \s \S ] * ?\n - - - \n * / , '' ) ;
100101
@@ -187,7 +188,7 @@ function processMarkdownContent(content: string): string {
187188 content = content . replace (
188189 / : e x a m p l e \{ c o m p o n e n t = " ( [ ^ " ] + ) " \s + n a m e = " ( [ ^ " ] + ) " [ ^ } ] * \} / g,
189190 ( _match , comp : string , name : string ) =>
190- `See example: [${ comp } /${ name } ](${ docsUrl ( 'components' , comp ) } /${ name } )`
191+ `See example: [${ comp } /${ name } ](${ docsUrl ( baseUrl , 'components' , comp ) } /${ name } )`
191192 ) ;
192193
193194 // Convert remaining :example directives (same-component, not inlined) to plain text
@@ -242,9 +243,9 @@ ${rows.join('\n')}`;
242243 */
243244export function generateComponentMarkdown (
244245 component : ( typeof allComponents ) [ number ] ,
245- options : GenerateMarkdownOptions = { }
246+ options : GenerateMarkdownOptions
246247) : string {
247- const { headingLevel = 1 , inlineExamples : shouldInlineExamples = false } = options ;
248+ const { baseUrl , headingLevel = 1 , inlineExamples : shouldInlineExamples = false } = options ;
248249 const h = ( level : number ) => '#' . repeat ( level ) ;
249250
250251 const sections : string [ ] = [ ] ;
@@ -267,9 +268,9 @@ export function generateComponentMarkdown(
267268 if ( component . content ) {
268269 let rawContent = component . content ;
269270 if ( shouldInlineExamples ) {
270- rawContent = inlineExampleDirectives ( rawContent , component . slug , 'components' ) ;
271+ rawContent = inlineExampleDirectives ( rawContent , component . slug , 'components' , baseUrl ) ;
271272 }
272- const processed = processMarkdownContent ( rawContent ) ;
273+ const processed = processMarkdownContent ( rawContent , baseUrl ) ;
273274 if ( processed ) {
274275 sections . push ( processed ) ;
275276 }
@@ -303,46 +304,17 @@ export function generateComponentMarkdown(
303304 if ( examples && examples . length > 0 ) {
304305 sections . push ( `${ h ( headingLevel + 1 ) } Examples` ) ;
305306 const exampleLinks = examples
306- . map ( ( ex ) => `- [${ ex . name } ](${ docsUrl ( 'components' , component . slug ) } /${ ex . name } )` )
307+ . map ( ( ex ) => `- [${ ex . name } ](${ docsUrl ( baseUrl , 'components' , component . slug ) } /${ ex . name } )` )
307308 . join ( '\n' ) ;
308309 sections . push ( exampleLinks ) ;
309310 }
310-
311- // TODO: should we include usage examples?
312- // Additional usage in other component examples (deduplicated)
313- // const usage = catalog.usage as Array<{ example: string; component: string; path: string }>;
314- // if (usage && usage.length > 0) {
315- // const exampleNames = new Set(examples?.map((ex) => ex.name) ?? []);
316- // const seen = new Set<string>();
317- // const uniqueUsage = usage.filter((item) => {
318- // // Exclude if already shown in main examples
319- // if (item.component === catalog.component && exampleNames.has(item.example)) {
320- // return false;
321- // }
322- // const key = `${item.component}::${item.example}`;
323- // if (seen.has(key)) return false;
324- // seen.add(key);
325- // return true;
326- // });
327-
328- // if (uniqueUsage.length > 0) {
329- // sections.push(`${h(headingLevel + 1)} Additional Usage`);
330- // const usageLinks = uniqueUsage
331- // .map(
332- // (u) =>
333- // `- [${u.component}/${u.example}](${BASE_URL}/docs/components/${u.component}/${u.example})`
334- // )
335- // .join('\n');
336- // sections.push(usageLinks);
337- // }
338- // }
339311 }
340312
341313 // Related
342314 if ( component . related && component . related . length > 0 ) {
343315 sections . push ( `${ h ( headingLevel + 1 ) } Related` ) ;
344316 const relatedLinks = component . related
345- . map ( ( r ) => `- [${ r } ](${ docsUrl ( 'components' , r ) } )` )
317+ . map ( ( r ) => `- [${ r } ](${ docsUrl ( baseUrl , 'components' , r ) } )` )
346318 . join ( '\n' ) ;
347319 sections . push ( relatedLinks ) ;
348320 }
@@ -355,9 +327,9 @@ export function generateComponentMarkdown(
355327 */
356328export function generateUtilMarkdown (
357329 util : ( typeof allUtils ) [ number ] ,
358- options : GenerateMarkdownOptions = { }
330+ options : GenerateMarkdownOptions
359331) : string {
360- const { headingLevel = 1 , inlineExamples : shouldInlineExamples = false } = options ;
332+ const { baseUrl , headingLevel = 1 , inlineExamples : shouldInlineExamples = false } = options ;
361333 const h = ( level : number ) => '#' . repeat ( level ) ;
362334
363335 const sections : string [ ] = [ ] ;
@@ -372,9 +344,9 @@ export function generateUtilMarkdown(
372344 if ( util . content ) {
373345 let rawContent = util . content ;
374346 if ( shouldInlineExamples ) {
375- rawContent = inlineExampleDirectives ( rawContent , util . slug , 'utils' ) ;
347+ rawContent = inlineExampleDirectives ( rawContent , util . slug , 'utils' , baseUrl ) ;
376348 }
377- const processed = processMarkdownContent ( rawContent ) ;
349+ const processed = processMarkdownContent ( rawContent , baseUrl ) ;
378350 if ( processed ) {
379351 sections . push ( processed ) ;
380352 }
@@ -383,7 +355,7 @@ export function generateUtilMarkdown(
383355 // Related
384356 if ( util . related && util . related . length > 0 ) {
385357 sections . push ( `${ h ( headingLevel + 1 ) } Related` ) ;
386- const relatedLinks = util . related . map ( ( r ) => `- [${ r } ](${ docsUrl ( 'utils' , r ) } )` ) . join ( '\n' ) ;
358+ const relatedLinks = util . related . map ( ( r ) => `- [${ r } ](${ docsUrl ( baseUrl , 'utils' , r ) } )` ) . join ( '\n' ) ;
387359 sections . push ( relatedLinks ) ;
388360 }
389361
@@ -450,7 +422,7 @@ export function generateGuideMarkdown(options: {
450422 . join ( ' ' ) ;
451423 }
452424
453- const content = processMarkdownContent ( raw ) ;
425+ const content = processMarkdownContent ( raw , '' ) ;
454426 return `# ${ title } \n\n${ content } ` ;
455427}
456428
@@ -486,6 +458,7 @@ function getAllExamplePaths(): string[] {
486458}
487459
488460interface CollectionListOptions {
461+ baseUrl : string ;
489462 title : string ;
490463 items : Array < { slug : string ; name : string ; description ?: string } > ;
491464 type : 'components' | 'utils' | 'guides' ;
@@ -495,7 +468,7 @@ interface CollectionListOptions {
495468 * Generate a markdown section listing collection items as links to their llms.txt endpoints.
496469 */
497470function generateCollectionListSection ( options : CollectionListOptions ) : string {
498- const { title, items, type } = options ;
471+ const { baseUrl , title, items, type } = options ;
499472
500473 const fallbackLabel =
501474 type === 'components' ? 'component' : type === 'utils' ? 'utility' : 'guide' ;
@@ -505,7 +478,7 @@ function generateCollectionListSection(options: CollectionListOptions): string {
505478 . sort ( ( a , b ) => a . name . localeCompare ( b . name ) )
506479 . map ( ( item ) => {
507480 const description = item . description || `Documentation for ${ item . name } ${ fallbackLabel } ` ;
508- return `- [${ item . name } ](${ llmsUrl ( type , item . slug ) } ): ${ description } ` ;
481+ return `- [${ item . name } ](${ llmsUrl ( baseUrl , type , item . slug ) } ): ${ description } ` ;
509482 } ) ;
510483
511484 return `## ${ title } \n\n${ lines . join ( '\n' ) } ` ;
@@ -514,7 +487,7 @@ function generateCollectionListSection(options: CollectionListOptions): string {
514487/**
515488 * Generate markdown for a single component example
516489 */
517- export function generateExampleMarkdown ( componentSlug : string , exampleName : string ) : string | null {
490+ export function generateExampleMarkdown ( baseUrl : string , componentSlug : string , exampleName : string ) : string | null {
518491 const raw = getExampleSource ( 'components' , componentSlug , exampleName ) ;
519492 if ( ! raw ) return null ;
520493
@@ -547,7 +520,7 @@ export function generateExampleMarkdown(componentSlug: string, exampleName: stri
547520 if ( usedComponents . length > 0 ) {
548521 sections . push ( '## Components' ) ;
549522 const links = usedComponents
550- . map ( ( comp ) => `- [${ comp . name } ](${ llmsUrl ( 'components' , comp . slug ) } )` )
523+ . map ( ( comp ) => `- [${ comp . name } ](${ llmsUrl ( baseUrl , 'components' , comp . slug ) } )` )
551524 . join ( '\n' ) ;
552525 sections . push ( links ) ;
553526 }
@@ -558,7 +531,7 @@ export function generateExampleMarkdown(componentSlug: string, exampleName: stri
558531/**
559532 * Generate the llms.txt index with links to all documentation
560533 */
561- export function generateLlmsTxt ( ) : string {
534+ export function generateLlmsTxt ( baseUrl : string ) : string {
562535 const sections : string [ ] = [ ] ;
563536
564537 // Header
@@ -570,12 +543,13 @@ This file contains links to LLM-optimized documentation in markdown format.`);
570543
571544 // Guides
572545 sections . push (
573- generateCollectionListSection ( { title : 'Guides' , items : getSortedGuides ( ) , type : 'guides' } )
546+ generateCollectionListSection ( { baseUrl , title : 'Guides' , items : getSortedGuides ( ) , type : 'guides' } )
574547 ) ;
575548
576549 // Components
577550 sections . push (
578551 generateCollectionListSection ( {
552+ baseUrl,
579553 title : 'Components' ,
580554 items : allComponents ,
581555 type : 'components'
@@ -584,7 +558,7 @@ This file contains links to LLM-optimized documentation in markdown format.`);
584558
585559 // Utilities
586560 sections . push (
587- generateCollectionListSection ( { title : 'Utilities' , items : allUtils , type : 'utils' } )
561+ generateCollectionListSection ( { baseUrl , title : 'Utilities' , items : allUtils , type : 'utils' } )
588562 ) ;
589563
590564 // Examples
@@ -595,7 +569,7 @@ This file contains links to LLM-optimized documentation in markdown format.`);
595569 if ( match ) {
596570 const [ , componentName , exampleName ] = match ;
597571 examples . push (
598- `- [${ componentName } /${ exampleName } ](${ llmsUrl ( 'components' , `${ componentName } /${ exampleName } ` ) } ): Example code for ${ componentName } `
572+ `- [${ componentName } /${ exampleName } ](${ llmsUrl ( baseUrl , 'components' , `${ componentName } /${ exampleName } ` ) } ): Example code for ${ componentName } `
599573 ) ;
600574 }
601575 }
@@ -609,7 +583,7 @@ This file contains links to LLM-optimized documentation in markdown format.`);
609583/**
610584 * Generate the full llms.txt with all components and utilities
611585 */
612- export function generateFullLlmsTxt ( ) : string {
586+ export function generateFullLlmsTxt ( baseUrl : string ) : string {
613587 const sections : string [ ] = [ ] ;
614588
615589 // Header
@@ -620,7 +594,7 @@ export function generateFullLlmsTxt(): string {
620594This file contains the complete LLM-optimized documentation for all components and utilities.` ) ;
621595
622596 sections . push (
623- generateCollectionListSection ( { title : 'Guides' , items : getSortedGuides ( ) , type : 'guides' } )
597+ generateCollectionListSection ( { baseUrl , title : 'Guides' , items : getSortedGuides ( ) , type : 'guides' } )
624598 ) ;
625599
626600 // Components section - full content
@@ -632,7 +606,7 @@ This file contains the complete LLM-optimized documentation for all components a
632606 . sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ;
633607
634608 for ( const component of sortedComponents ) {
635- sections . push ( generateComponentMarkdown ( component , { headingLevel : 2 } ) ) ;
609+ sections . push ( generateComponentMarkdown ( component , { baseUrl , headingLevel : 2 } ) ) ;
636610 }
637611
638612 // Utilities section - full content
@@ -644,7 +618,7 @@ This file contains the complete LLM-optimized documentation for all components a
644618 . sort ( ( a , b ) => a . name . localeCompare ( b . name ) ) ;
645619
646620 for ( const util of sortedUtils ) {
647- sections . push ( generateUtilMarkdown ( util , { headingLevel : 2 } ) ) ;
621+ sections . push ( generateUtilMarkdown ( util , { baseUrl , headingLevel : 2 } ) ) ;
648622 }
649623
650624 return sections . join ( '\n\n' ) ;
0 commit comments