jixoai-ui
the terminal design language
loading the style sheet…
Skip to content
docs · print medium: screen

registry:file · Docs Tooling

llms-txt — the AI export pass

jixoai sites are AI-friendly by design, so the scaffold ships the export natively: after the final static build, one pass scans the published HTML and writes llms.txt, llms-full.txt and a .md mirror beside every page. No routing takeover — the generator consumes the artifact agents will actually fetch.

llmstxt.org proposal v2 zero deps absolute URLs locale splitting

llms-txt

One deterministic pass over the final dist: extract each page's main content, whitelist-convert it to Markdown, mirror it beside the HTML, and compose the index (plus the single-file llms-full.txt).

pipeline · no routing takeover

What one build pass does

The generator never touches the routing layer or the source tree — it reads what the site actually published.

final dist/                      outputs (same tree)
├── index.html        ─┐          ├── index.md
├── components/*.html  ├─ extract ├── components/*.md
│    <main> → markdown  │          ├── llms.txt        (index, absolute URLs)
│    strip nav/forms   │          └── llms-full.txt    (cap-guarded)
└── en/… zh/… (i18n)  ─┘              └── en/llms.txt … (locale split)
  • content root — each page's <main> (body fallback); chrome stripped by platform semantics only: nav/forms/scripts, button controls, aria-hidden decoration, inert collapsed panels
  • whitelist converter — a stack-based tokenizer, not regex chains: headings, lists, tables (colspan degrades instead of lying), fenced code with language detection, entity decoding, and dangerous links dropped
  • agent-first links — the index links each page's .md mirror by absolute URL; linkStyle: 'root-relative' exists for preview builds
  • machine-readable registry — this site's own index also points agents at /r/registry.json under an Optional section
llms-txt.mjs js
/* the installed generator (npx jixoai-ui add llms-txt) */

wiring

Two shapes, one core

generateLlmsTxt(distDir, config) is the only implementation. The vite adapter exists for plain-build sites; orchestrated sites call the core directly as their last step.

Plain vite build sites (the openspecui pattern) use the plugin — it runs exactly once, in the SSR build's closeBundle, after SvelteKit's adapter has written the final dist:

vite.config.ts
// vite.config.ts — plain vite build sites (one plugin line)
import { sveltekit } from '@sveltejs/kit/vite';
import { llmsTxt } from './vite-plugins/llms-txt.mjs';

export default {
  plugins: [
    sveltekit(),
    llmsTxt({
      distDir: 'dist',
      siteUrl: 'https://myproject.jixoai.com',
      title: 'myproject',
      summary: 'What this site is, for agents.',
    }),
  ],
};

Orchestrated sites (the unipty pattern — build scripts that inject artifacts after vite) call the core on the final output:

scripts/build.mjs
// scripts/build.mjs — orchestrated sites call the core directly,
// as the LAST step, on the FINAL output directory:
import { generateLlmsTxt } from './vite-plugins/llms-txt.mjs';

// …vite build, artifact copies, CNAME gating all done…
const report = generateLlmsTxt(distDir, {
  siteUrl: 'https://myproject.jixoai.com',
  title: 'myproject',
  summary: 'What this site is, for agents.',
  exclude: ['404.html'],
  full: { enabled: true, maxBytes: 10_000_000 },
});
console.log('llms-txt:', report.pages, 'pages,', report.files.length, 'files');

law

The laws

The generator is a guest in your dist: it only touches what it declares, it never guesses, and it fails loudly rather than shipping something subtly wrong.

  • scan the final artifact — what agents fetch is what got published, not what the source tree promised
  • declared outputs only — llms.txt, llms-full.txt, and .md mirrors; nothing is deleted, robots.txt and sitemap are never touched
  • hand-written .md is sacred — every generated mirror starts with a provenance marker; a conflicting file aborts the run
  • byte-deterministic — same dist in, same bytes out; re-runs converge, never duplicate
  • llms-full.txt is capped — over full.maxBytes the run fails naming the size; no silent truncation
jixoai-ui ui.jixoai.com the jixoai design language

Theme

Brand hue

0°

Auto cycle · 24h