[3.x] Support pages with more output file extensions (Add a llms.txt generator)#2534
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… default Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…e method Removes HydePage::showInLlmsTxt() and its test contract entry. The generator now reads `llms` front matter defaulting to the page's sitemap inclusion, which already excludes generated non-HTML pages and redirects, keeping per-page control without adding public API to every page class. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The page types Hyde ships are known to the framework, so grouping them needed no user input to be correct. Dropping the config removes its validation, exception path, and drift guard, and leaves the llms config at two keys. Custom sections remain available by overriding the generator and rebinding it in the container. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drops the `llms` front matter key introduced alongside the generator. Leaving a page out of llms.txt does not stop AI services from reading it, as crawler access is governed by robots.txt, so the key could only ever mean "curate my index" — which is what `sitemap: false` already means. Front matter is public API we support for the life of the major version, and reintroducing the key later stays additive. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A page titled "Arrays [Advanced]" previously emitted a malformed Markdown link. Also documents and tests the ordering contract: sections in declaration order, pages in route order, which keeps numerically prefixed docs in their reading order. Makes the section map a method so generator overrides can compute it at runtime. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## v3/non-html-pages #2534 +/- ##
=====================================================
Coverage 100.00% 100.00%
- Complexity 1760 1787 +27
=====================================================
Files 177 179 +2
Lines 4395 4463 +68
=====================================================
+ Hits 4395 4463 +68 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Pins the documented answer to the one case the sitemap-derived rule cannot express: a page kept out of the sitemap for SEO reasons that should still reach an agent index. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
emmadesilva
commented
Jul 14, 2026
| } | ||
| } | ||
|
|
||
| /** Add the generated robots.txt page unless the route is user-defined. */ |
Member
Author
There was a problem hiding this comment.
I double checked this and yeah this is the proper way. Because a user may register a page in a booting callback so we have to check we don't delete it
This reverts commit 57b5c74.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deep Research of llms.txt and HydePHP
Executive summary
llms.txtis an emerging, non-IETF proposal for publishing a small, curated, Markdown file at/llms.txtso language models and AI agents can find the most important material on a site without trawling full HTML navigation, scripts, and boilerplate. The proposal was published by Jeremy Howard on 3 September 2024 and is maintained publicly through the AnswerDotAI GitHub repository and llmstxt.org, with the authors explicitly inviting community input rather than claiming formal standards status. citeturn5view0turn6view0turn7view0For a HydePHP site,
llms.txtis relevant because Hyde sites are often documentation-heavy and static by design: exactly the kind of content where a concise, plain-text, agent-friendly index is useful. The uploaded HydePHP v3 planning document is especially relevant: it says there is currently “no easy way” to add plain-text files likerobots.txtorllms.txt, and it proposes first-class non-HTML pages plus a generatedllms.txtfeature in the v3 branch. That document also shows Hyde’s direction of travel: route-native non-HTML output, generator-backed pages, and user override paths. fileciteturn0file0L11-L18 fileciteturn0file0L29-L31 fileciteturn0file0L515-L529The practical conclusion is straightforward. For today’s typical static Hyde deployment, the safest approach is a build-time generated root file, ideally from site metadata and per-page front matter. For a future Hyde v3-style implementation, a first-class
llms.txtpage is cleaner because it participates in routing, build manifests, local serve, and extension points. A fully dynamic endpoint is possible, but it is a poor fit for “typical static hosting” unless you deliberately add an edge/serverless layer. fileciteturn0file0L5-L7 fileciteturn0file0L48-L55llms.txtshould not be confused with a control plane. It does not replacerobots.txt, access control, authentication, or contractual/licensing terms. The llmstxt.org proposal frames it as an inference-time aid, whilerobots.txtremains an advisory crawler-access mechanism andsecurity.txtremains a separate RFC-backed disclosure-contact format. If you care about blocking or monetising AI crawlers, you still need crawler controls, logs, and enforcement outsidellms.txt. citeturn7view0turn12view0turn13view0turn20view0What llms.txt is and where it comes from
The official llmstxt.org proposal describes
llms.txtas a Markdown file placed at/llms.txtto “provide information to help LLMs use a website at inference time”. Its rationale is that LLMs increasingly rely on website information, but full websites are often too large and noisy for context windows, whereas a single concise, curated file can point them to the right materials. citeturn5view0turn7view0The primary sources worth bookmarking are the llmstxt.org proposal, the public AnswerDotAI GitHub repository, the
llms-txtparser/CLI documentation, and the HydePHP planning note you supplied. The llmstxt.org page names Jeremy Howard as author and 3 September 2024 as publication date, while the site’s “Next steps” section says the specification is open for community input and points to the GitHub repository and Discord for discussion. citeturn5view0turn7view0turn6view0Two clarifications matter:
First,
llms.txtis a proposal and an emerging convention, not a formal web standard. The proposal language is explicit, and there is no RFC or W3C Recommendation defining it. By contrast,robots.txtis standardised in RFC 9309 andsecurity.txtis defined in RFC 9116. citeturn5view0turn12view0turn25view0Second, the proposal is intentionally narrow. It does not prescribe how an agent must process the file; it says processing depends on the application. That means adoption can be useful even before universal support exists, but it also means interoperability is partly conventional rather than guaranteed. citeturn6view0turn7view0
For HydePHP specifically, the uploaded v3 draft is unusually aligned with the proposal. It explicitly calls out
robots.txtandllms.txtas target outputs, says non-HTML pages should become first-class pages rather than post-build side effects, and sketches a generatedllms.txtaction with route links, page titles, and descriptions/abstracts. It also emphasises that the default enable/disable decision should be deliberate because some users will have privacy or OPSEC concerns. fileciteturn0file0L5-L7 fileciteturn0file0L29-L31 fileciteturn0file0L515-L529Format, syntax, and how it differs from robots.txt and security.txt
The llmstxt.org format is Markdown-based. The proposal says a conforming file is normally located at
/llms.txtand contains, in order: an optional BOM, a single H1 with the project/site name, a blockquote summary, optional free-form non-heading detail sections, and then zero or more H2 sections containing lists of links. Each list item contains a required Markdown link and may optionally add a colon and short description. The only required element is the H1. An H2 section namedOptionalhas special semantics: agents may skip it when they need a shorter context. citeturn7view0The proposal also recommends, where useful, that pages expose clean Markdown versions by appending
.mdto the page URL, because Markdown is easier for models to consume than HTML. This is important for documentation sites, but it is a recommendation, not a hard dependency. In practice, implementations vary: Cloudflare heavily uses Markdown-addressable pages and even tells agents to prefer the Markdown version orAccept: text/markdown, whereas Vercel’sllms.txtpoints at ordinary documentation URLs and separately advertisesllms-full.txt. citeturn6view0turn20view0turn20view1turn15view0The following comparison summarises the practical differences. It is derived from the llmstxt.org proposal, RFC 9309, RFC 9116, and Google’s robots guidance. citeturn7view0turn12view0turn13view0turn25view0turn13view2
llms.txt/llms.txtrobots.txt/robots.txtUser-agent,Allow,Disallowsecurity.txt/.well-known/security.txtpreferred; root allowed for legacy compatibilityContact,Expires,CanonicalA few practical consequences flow from this comparison.
robots.txtis about crawler access, not explanation. Google says it tells search engine crawlers which URLs they can access, mainly to manage crawl load, and also warns that it is not a mechanism for keeping a page out of Google by itself. RFC 9309 likewise says the rules are not a form of access authorisation. citeturn13view0turn13view1turn12view0security.txtis about security disclosure contacts, not AI guidance. RFC 9116 requires a machine-parsable text file, mandates anExpiresfield, recommends HTTPS, defines specific fields such asContact,Canonical, andPreferred-Languages, and assigns a well-known URI. citeturn13view2turn13view3turn13view4turn25view3turn25view4llms.txtis closer to a curated documentation index than to either control file. It is unusual in using Markdown instead of a classic structured format because the proposal expects the file itself to be read directly by language models and agents. citeturn7view0An illustrative
llms.txtfor a Hyde site might look like this:That sample follows the official ordering and the special
Optionalconvention from llmstxt.org. citeturn7view0Adoption, common use cases, and implications
Adoption is now real enough to matter for documentation tooling, even though the standard remains informal. The llmstxt.org site itself lists integrations including a Python parser/CLI, a JavaScript implementation, a VitePress plugin, a Docusaurus plugin, a Drupal recipe, and a PHP library. Public directories also list many deployed
llms.txtfiles and manyllms-full.txtcompanions across documentation sites and commercial domains. citeturn5view0turn7view1turn22view2turn22view3turn22view4turn22view0turn19view0turn19view2Among major companies and platforms, the strongest primary-source examples are documentation ecosystems:
Cloudflare publishes a top-level documentation
llms.txt, many product-levelllms.txtfiles, and correspondingllms-full.txtresources. Its docs also explicitly instruct agents to fetch Markdown instead of HTML and to usellms.txtas the documentation index. citeturn14view0turn20view0turn20view1turn26view3Stripe serves
docs.stripe.com/llms.txt, and its content is clearly agent-oriented: it includes operational guidance such as checking package registries for current versions rather than trusting memorised version numbers. That is a useful signal thatllms.txtis already being used for more than a passive site map. citeturn14view1Vercel serves
vercel.com/llms.txtand prominently points to allms-full.txtfile containing its full documentation content. Anthropic’s developer documentation also exposes a rootllms.txt, and Meta’s Horizon developer docs publish a large documentation index inllms.txtform. citeturn15view0turn26view2turn15view1turn24view0The most common use cases are therefore documentation discovery, curated agent context, and easier retrieval for AI assistants. The llmstxt.org proposal itself emphasises developer documentation, software APIs, e-commerce/product explanation, legislation, personal websites, and institutional information. citeturn5view0turn6view0
The security, privacy, and legal picture is more modest than the marketing around the concept sometimes suggests.
llms.txtis public by design. It should therefore contain only public URLs and public summaries; do not place secrets, unpublished materials, admin paths, preview URLs, or anything whose mere disclosure would be sensitive. This is an inference from the proposal’s public-root-file design and the general limitations shared with advisory text files. citeturn7view0turn12view0turn13view0It is not an enforcement mechanism. If your aim is “do not crawl this” or “do not train on this”,
llms.txtalone is too weak. The llmstxt.org proposal frames the file mainly as an inference-time aid; RFC 9309 and Google both make clear that evenrobots.txtis only advisory and not authorisation or robust secrecy. Cloudflare’s AI Crawl Control documentation reinforces this by offering separate monitoring, allow/block policies, robots compliance tracking, and even monetisation for AI crawling. citeturn7view0turn12view0turn13view0turn20view0Legally, because no jurisdiction was specified, the safest general position is this: treat
llms.txtas notice and guidance, not as a substitute for terms, licences, authentication, rate limits, or contractual controls. If you need stronger legal signalling, put the real terms in your existing legal documents and link them as public resources; if you need stronger technical control, use robots directives, auth, WAF/CDN controls, logging, and bot management. That conclusion is an inference from the proposal’s non-standard status and the enforcement limits of comparable files. citeturn5view0turn12view0turn25view0turn20view0HydePHP implementation strategy
The exact HydePHP version was unspecified, so the right recommendation depends on whether you are working with current static-site workflows or the v3 draft direction in the uploaded planning note. That note says the v3 branch wants non-HTML outputs like
robots.txt,llms.txt, sitemap, RSS, and JSON pages to become first-class pages in routing and the build pipeline, and it proposes a generatedllms.txtfeature with route grouping and exclusions. fileciteturn0file0L1-L7 fileciteturn0file0L19-L31 fileciteturn0file0L515-L529flowchart LR A[Hyde content and front matter] --> B[llms metadata selection] B --> C[Generator or Blade template] C --> D[/llms.txt in build output] D --> E[Static host or CDN] E --> F[LLM or agent fetches /llms.txt] F --> G[Follows curated links] G --> H[Markdown pages if available]The key architectural choice is when generation happens.
A build-time file is the best default for a typical Hyde deployment because it works everywhere Hyde does: local builds, GitHub Pages, Netlify, Cloudflare Pages, S3-style static hosting, and CDN-only stacks. A route-native page is cleaner, but only if your Hyde version actually supports non-HTML pages cleanly. The uploaded draft suggests Hyde v3 aims to make that the canonical approach. fileciteturn0file0L11-L18 fileciteturn0file0L48-L55
The following table compares the realistic options for HydePHP. It synthesises the llmstxt.org requirements with the HydePHP planning note and the static-hosting assumption. citeturn7view0 fileciteturn0file0L11-L18 fileciteturn0file0L184-L200
A sensible application-level config file might look like this. This is illustrative, not current Hyde core API:
A metadata-driven Blade template is a good middle path because it lets maintainers curate output without hand-editing the final text:
{{-- resources/views/llms-txt.blade.php --}} # {{ $title }} > {{ $summary }} @if (!empty($details)) {{ $details }} @endif @foreach ($sections as $sectionName => $links) ## {{ $sectionName }} @foreach ($links as $link) - [{{ $link['title'] }}]({{ $link['url'] }})@if (!empty($link['description'])): {{ $link['description'] }}@endif @endforeach @endforeachA simple generator service can then render that template and write the final file during build:
If your Hyde version still treats non-HTML outputs as awkward post-build artefacts, write
_site/llms.txtafter the page collection has been built. If Hyde v3 lands as described in the planning note, the cleaner design is a first-class page that compiles lazily and resolves its generator from the container, matching the draft’s approach for generated non-HTML pages. fileciteturn0file0L15-L27 fileciteturn0file0L184-L200A future-facing v3-style sketch would look roughly like this:
And registration would ideally happen through Hyde’s boot/extension mechanism, because the planning note explicitly points to
Hyde::kernel()->booting()callbacks andHydeExtensionas the user-land extension points, and says user-defined pages should beat framework-generated ones when route keys collide. fileciteturn0file0L53-L57 fileciteturn0file0L223-L254For a dynamic endpoint, only use it if you knowingly accept non-static infrastructure. An illustrative PHP route might be:
That approach is technically fine, but it is not a natural fit for the assumed “typical static hosting” environment.
Deployment, validation, interoperability, and recommended defaults
Operationally, the most important serving rule is simple: publish a UTF-8 plain-text file at the root path
/llms.txt. The official proposal targets that location, and major implementations from Cloudflare, Stripe, Vercel, Anthropic, and Meta all expose plain-text root or documentation-index files that way. Hyde’s v3 note is also helpful here because it says the realtime compiler already maps.txt,.xml, and.jsonoutput paths to correct content types. citeturn7view0turn14view0turn14view1turn14view2turn15view1turn24view0 fileciteturn0file0L48-L49On static hosting and CDNs, treat
llms.txtlike any other generated public artefact: publish it at the origin root, cache it normally, and purge/invalidate it whenever docs or key pages change. Because the file is small and low-risk, short-to-moderate cache TTLs are usually more useful than aggressive long-lived caching; the value of the file depends on freshness. That is an implementation recommendation rather than a standard requirement.Interoperability is currently best thought of in layers.
At the broadest layer, old browsers and legacy crawlers are unaffected:
llms.txtis just another public text file, so publishing it is backwards-compatible by default. citeturn7view0At the agent layer, support is uneven but improving. Some vendors and docs platforms clearly use it operationally, and tooling exists to parse it, generate context bundles, and validate structure. The official Python tooling parses the file and can expand it into XML context for models such as Claude; the PHP library supports creating, reading, and validating files; and ecosystem plugins generate both
llms.txtand, in some cases,llms-full.txt. citeturn7view1turn22view0turn22view2turn22view3At the control layer, do not assume compliance. If you need to manage AI crawlers, pair
llms.txtwithrobots.txt, logs, and enforcement. Cloudflare’s AI Crawl Control is a good illustration: it separately tracks AI crawler activity, allows/block rules, monitors robots compliance, and can monetise crawl access. citeturn20view0turn20view1For HydePHP sites, the recommended default content is conservative:
Use the site/project name as the H1. Use the Hyde description as the summary. Provide one short explanatory paragraph if needed. Then publish a small number of sections such as
Docs,Reference,Blog, andOptional. Within those sections, prefer stable, canonical pages with strong titles and strong descriptions. Exclude search indexes, feeds, sitemaps, tag archives, pagination artefacts, media files, drafts, previews, and machine-only outputs. The HydePHP planning note explicitly associatesllms.txtgeneration with page titles and documentation abstracts, which is exactly the right default. citeturn7view0turn6view0 fileciteturn0file0L519-L524A good maintainer checklist is therefore:
/llms.txtexists at the site root and is served as plain text. citeturn7view0turn14view0turn14view1robots.txt, access control, and bot management where policy matters. citeturn13view0turn20view0For automated tests, I would add both content tests and behaviour tests. The llmstxt.org guidance explicitly recommends expanding the file into an LLM context file and then testing models against real questions. The official parser/CLI and the PHP library make that easy. citeturn7view0turn7view1turn22view0
A practical PHPUnit-style test might be:
I would also add a link-check test that every URL listed in
llms.txtresolves successfully after build, plus a snapshot/regression test to catch accidental churn in headings, section names, or excluded paths. For a higher-level test, run the generated file throughllms_txt2ctxand verify that a model or parser can answer a few deterministic site questions from the expanded context. citeturn7view1turn22view0