The age of AI search is here. ChatGPT web search, Perplexity, Google AI Overviews -- as more users get information through AI, making sure AI understands your site correctly has become critically important.

That is where llms.txt comes in. If robots.txt tells crawlers "you may / may not crawl this page," llms.txt is a signpost that tells AI "here is what this site covers, and here is where to read the details." There is, however, no evidence that publishing one gets you cited in AI answers, and in this site's own access logs no AI crawler fetched it even once over three and a half days. This guide covers what kind of site it is actually worth adding to.

This article covers everything: the llms.txt format specification, what information to include, the criteria for choosing between static and dynamic generation, and implementation code for major frameworks.

1. What Is llms.txt?

llms.txt is a plain text file (in Markdown format) placed in the root directory of your website, designed to communicate your site's overview, structure, and content catalog to LLMs (Large Language Models).

Basic Information

ItemDetails
File Namellms.txt
LocationDomain root (https://example.com/llms.txt). Since v2 it can also sit in a subpath (/docs/llms.txt), covering the pages under it
FormatMarkdown (plain text)
EncodingUTF-8
Proposed Byllmstxt.org (Jeremy Howard et al.)
StandardizationDe facto standard (not a formal RFC or specification). Current version: v2 (revised August 2026)
Main ReadersAI agents that need information while helping a user (the spec's intended use, especially coding agents navigating documentation). No vendor has officially stated that training or search crawlers such as GPTBot read it

In One Sentence

robots.txt = "Keep out" / llms.txt = "Here's what our site is about"

While robots.txt is an access control file (allow/deny), llms.txt is a content description file (self-introduction). The two don't conflict -- they're actually meant to be used together.

2. Why You Need It -- How It Differs from robots.txt

You might think, "Can't AI understand my site from sitemaps and meta tags?" That's true to an extent, but llms.txt offers distinct advantages.

Comparing robots.txt / sitemap.xml / llms.txt

FilePurposeTargetContent
robots.txtAllow/deny crawlingAll crawlersAllow/Disallow rules
sitemap.xmlProvide page listSearch enginesURLs, update dates, priority
llms.txtDescribe site contentLLM crawlersOverview, structure, content summaries

Three Reasons You Need llms.txt

Reason 1: LLMs Can't Efficiently Crawl an Entire Site

While Googlebot crawls billions of pages to build a massive index, LLM crawlers don't cover sites as comprehensively. By placing an llms.txt file, you can efficiently tell AI, "Here's the most important content on this site."

Reason 2: It gets you cited in AI answers -- a common claim with no evidence behind it

You will often read that llms.txt makes ChatGPT or Perplexity more likely to cite your site, but there is no data or official vendor statement showing that. Google explicitly says you do not need AI text files to appear in AI Overviews or AI Mode (Google Search Central). It is more accurate to treat llms.txt as a table of contents that helps agents reach the right information quickly than as a way to earn citations; Section 9 checks this against real logs.

For a detailed explanation of LLMO, see "What Is LLMO?"

Reason 3: It Conveys Meta Information That sitemap.xml Can't

sitemap.xml is just a list of URLs. With llms.txt, you can also communicate:

  • Your site's theme and areas of expertise
  • Summaries and categories for each piece of content
  • Your site's update frequency and scale
  • Whether you offer multilingual support
  • Contact information

3. Format Specification -- What to Write and How

llms.txt Format Structure

H1 site name → blockquote summary → H2 section group

1. Header Required
# Site Name
> Brief site description (1-2 sentences)
Introduce the site with H1 + blockquote
2. Section list Recommended
## Section List
- [Section Name](URL): Description
- [Section Name](URL): Description
H2 grouping + link list
3. Content list Recommended
## Content List
- [Title](URL): Summary [Category]
- [Title](URL): Summary [Category]
 ... (list all content)
Helps AI grasp each article via 1-line summaries
4. Categories / Tags Optional
## Categories / Tag Structure
- category-slug: Description
- category-slug: Description
Information structure becomes explicit
5. Site info Recommended
## Site Information
- URL: https://example.com
- Sitemap: .../sitemap.xml
- Contact: email@example.com
Show the operator and canonical URL

llms.txt is written in Markdown format. Here's the format based on the llmstxt.org specification.

Basic Structure

# Site Name

> A brief description of the site. 1-3 sentences covering the site's theme, audience, and value proposition.

## Section Name 1

- [Page Title](URL): Brief summary of the page

## Section Name 2

- [Page Title](URL): Brief summary of the page
- [Page Title](URL): Brief summary of the page

Format Rules

ElementMarkdown SyntaxPurpose
H1 Heading# Site NameThe site's official name. Only one per file
Blockquote> Overview textSite description. Placed right after H1
H2 Heading## Section NameContent grouping
List Link- [Title](URL): DescriptionIndividual content information

Practical Example

# My Tech Blog

> My Tech Blog is a software engineering blog covering web development, cloud infrastructure, and AI tools. Updated weekly with practical tutorials and comparisons.

## Main Sections

- [Articles](https://example.com/articles): 50+ in-depth technical articles
- [Tutorials](https://example.com/tutorials): Step-by-step coding tutorials

## Popular Articles

- [React vs Vue in 2026](https://example.com/articles/react-vs-vue): A detailed comparison of React and Vue.js for modern web development, covering performance, ecosystem, and learning curve.
- [Docker for Beginners](https://example.com/articles/docker-beginners): Complete guide to Docker containers for developers who have never used containerization.

## Site Information

- URL: https://example.com
- Sitemap: https://example.com/sitemap.xml
- Languages: en, ja
- Contact: admin@example.com

Important Notes

  • Write in English by default. The llms.txt specification and examples are all in English, making it the best practice. For multilingual sites, write in English and specify supported languages with Languages: ja, en, es, .... However, for single-language sites (e.g., a site entirely in French, entirely in Russian, etc.), writing in the site's language is perfectly acceptable. Major LLMs (GPT, Claude, Gemini, etc.) process most languages with high accuracy, and users of such sites will query in the same language, ensuring consistent responses
  • Always use UTF-8 encoding. Other encodings like Shift-JIS may cause character corruption
  • Use absolute URLs (complete URLs starting with https://)
  • Only one H1 per file. Use H2 for section divisions

4. What Information to Include -- Required, Recommended, and Optional

Many people get stuck deciding what to write, so here's a breakdown by priority.

Note that the specification (llmstxt.org) requires only the H1 with the site name; the summary blockquote and the H2 link lists are formally optional. "Required" below means the minimum this guide considers necessary for the file to be worth having.

Required Information (Without These, llms.txt Serves No Purpose)

InformationWhere to Write ItExample
Site NameH1 heading# AI Arte
Site OverviewBlockquote> AI learning platform...
Main SectionsH2 + link list- [Articles](URL): Description

Recommended Information (Improves AI Understanding)

InformationWhy It Matters
Full Content ListLets AI grasp the full scope of your site
One-Line Summary per ContentGives AI a preview of each page's content
Category/Tag StructureShows the site's information architecture
Site URLDeclares the canonical URL
Sitemap URLPoints to the detailed URL list
Supported LanguagesImportant for multilingual sites
Contact InfoEstablishes the site operator's identity

Optional Information (Nice to Have, but Not Essential)

  • Tech Stack: What the site is built with (frameworks, etc.)
  • Update Frequency: How often new content is added
  • Total Content Count: Number of articles, etc.
  • License/Citation Policy: Whether AI is allowed to cite your content
  • API Information: If programmatic access is available

Information You Should NOT Include

  • Sensitive Information: Admin panel URLs, internal API endpoints, etc.
  • Personal Information: Unnecessarily detailed personal data (addresses, phone numbers, etc.)
  • Credentials: API keys, passwords, etc.

5. llms.txt vs llms-full.txt

llms-full.txt puts a site's entire content into a single file. It is not part of the llmstxt.org specification; it is a convention that spread because documentation platforms such as Mintlify generate it automatically alongside llms.txt (Mintlify docs). Specification v2 instead recommends providing a Markdown version of each page (page.md or page.html.md) and linking to those from llms.txt, rather than bundling everything into one file.

FileContentSize EstimatePurpose
llms.txtSite overview, structure, link list1-50KBA "table of contents" for the entire site
llms-full.txtFull text of all content100KB - several MBProviding full content text to AI

When You Need llms-full.txt

  • Technical Documentation: API references and library docs where providing the full text to AI improves answer accuracy
  • Knowledge Bases: FAQ collections and glossaries -- content that's frequently cited in fragments

When You Don't Need llms-full.txt

  • Blogs and Media Sites: With many articles, combining everything into one file would be too large. The summaries in llms.txt are sufficient
  • E-commerce Sites: Product information is better served through structured data (JSON-LD, etc.)
  • Corporate Sites: With few pages, llms.txt alone covers everything

For most blogs and media sites, llms.txt alone is enough. Think of llms-full.txt as something designed for technical documentation.

6. Static File vs Dynamic Generation -- Which Should You Choose?

Static File vs Dynamic Generation — which to choose

Trade-off: implementation effort vs ongoing updates

Static File
Place public/llms.txt directly
+ Simple (just place the file)
+ Zero server load
+ No framework needed
- Gets outdated if not updated
- Manual edit on every new post
- Counts and categories drift
Best For
Little content (10 or fewer)
Low update frequency (monthly or less)
Dynamic Generation
Auto-generate from DB (via route)
+ Always up to date
+ New posts auto-reflected
+ Counts and categories accurate
- More implementation effort
- DB access on each request
- Requires a framework
Best For
Lots of content (10+ items)
High update frequency (weekly+)
When in doubt, Dynamic Generation — "set and forget" lowers ops cost

There are two main approaches to maintaining llms.txt.

Approach 1: Static File

Place a text file directly at public/llms.txt (or an equivalent path).

Pros:

  • Simplest implementation (just drop the file in)
  • Zero server load
  • Works without any framework

Cons:

  • Every time you add or update content, you need to manually update the file
  • Forgetting to update means stale information is served to AI
  • Content counts and categories can drift from reality

Approach 2: Dynamic Generation

The application intercepts requests to /llms.txt, fetches the latest data from the database, and dynamically generates the text.

Pros:

  • Always reflects the latest information
  • Adding an article automatically updates llms.txt
  • Content counts and category names are always accurate

Cons:

  • Requires more implementation effort (route definition + controller)
  • Each request triggers a database query (mitigated with caching)
  • Requires a framework

Decision Criteria

ConditionRecommendation
10 or fewer content items, rarely updatedStatic file is fine
10+ content items or updated monthly or moreDynamic generation recommended
Using WordPress / Laravel / Django, etc.Dynamic generation is easy to implement
Static site (Hugo, Jekyll, Astro, etc.)Auto-generation at build time is ideal
Solo operation, want minimal maintenanceDynamic generation (set it up once and forget it)

Bottom line: when in doubt, go dynamic. The initial implementation cost is higher, but since you can "set it and forget it," long-term maintenance costs are lower. The worst-case scenario is using a static file and forgetting to update it, leaving AI with outdated information.

7. Implementation -- Code Examples by Framework

Let's look at how to implement dynamic llms.txt generation in major frameworks.

Laravel (PHP)

Route Definition (routes/web.php):

use App\Http\Controllers\LlmsTxtController;

Route::get('/llms.txt', [LlmsTxtController::class, 'index']);

Controller (app/Http/Controllers/LlmsTxtController.php):

class LlmsTxtController extends Controller
{
    public function index()
    {
        $articles = Article::published()
            ->with(['translations' => fn($q) => $q->where('locale', 'en')])
            ->orderBy('published_at')
            ->get();

        $lines = [];
        $lines[] = '# My Site Name';
        $lines[] = '';
        $lines[] = '> Site description here.';
        $lines[] = '';
        $lines[] = '## All Articles (' . $articles->count() . ')';
        $lines[] = '';

        foreach ($articles as $article) {
            $t = $article->translations->first();
            if (!$t) continue;
            $url = 'https://example.com/en/articles/' . $article->slug;
            $lines[] = '- [' . $t->title . '](' . $url . '): ' . $t->meta_description;
        }

        $content = implode("\n", $lines);
        return response($content, 200)
            ->header('Content-Type', 'text/plain; charset=utf-8');
    }
}

The key point is to explicitly set Content-Type: text/plain; charset=utf-8. Without it, the response might be interpreted as HTML.

Django (Python)

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('llms.txt', views.llms_txt, name='llms_txt'),
]

# views.py
from django.http import HttpResponse
from .models import Article

def llms_txt(request):
    articles = Article.objects.filter(
        status='published'
    ).order_by('published_at')

    lines = ['# My Site', '', '> Description.', '', '## Articles', '']
    for a in articles:
        lines.append(f'- [{a.title}](https://example.com/articles/{a.slug}): {a.meta_description}')

    content = '\n'.join(lines)
    return HttpResponse(content, content_type='text/plain; charset=utf-8')

Next.js (TypeScript)

// app/llms.txt/route.ts (App Router)
import { NextResponse } from 'next/server'

export async function GET() {
  // Fetch data from DB or CMS
  const posts = await getAllPosts()

  const lines = [
    '# My Site',
    '',
    '> Description.',
    '',
    '## Articles',
    '',
    ...posts.map(p =>
      `- [${p.title}](https://example.com/posts/${p.slug}): ${p.description}`
    ),
  ]

  return new NextResponse(lines.join('\n'), {
    headers: { 'Content-Type': 'text/plain; charset=utf-8' },
  })
}

WordPress (PHP)

Add to functions.php or as a plugin:

// functions.php
add_action('init', function() {
    add_rewrite_rule('^llms\.txt$', 'index.php?llms_txt=1', 'top');
});

add_filter('query_vars', function($vars) {
    $vars[] = 'llms_txt';
    return $vars;
});

add_action('template_redirect', function() {
    if (!get_query_var('llms_txt')) return;

    header('Content-Type: text/plain; charset=utf-8');
    $posts = get_posts(['numberposts' => -1, 'post_status' => 'publish']);

    echo "# " . get_bloginfo('name') . "\n\n";
    echo "> " . get_bloginfo('description') . "\n\n";
    echo "## Articles (" . count($posts) . ")\n\n";

    foreach ($posts as $post) {
        $url = get_permalink($post);
        $desc = get_the_excerpt($post);
        echo "- [{$post->post_title}]({$url}): {$desc}\n";
    }
    exit;
});

For WordPress, don't forget to re-save your permalink settings (flush rewrite rules) after adding the code.

Static Site Generators (Hugo / Astro, etc.)

Write a script to auto-generate it at build time.

# build-llms-txt.sh (example for Hugo)
#!/bin/bash
echo "# My Site" > public/llms.txt
echo "" >> public/llms.txt
echo "> Site description." >> public/llms.txt
echo "" >> public/llms.txt
echo "## Articles" >> public/llms.txt
echo "" >> public/llms.txt

for file in content/posts/*.md; do
  title=$(grep '^title:' "$file" | sed 's/title: //')
  slug=$(basename "$file" .md)
  desc=$(grep '^description:' "$file" | sed 's/description: //')
  echo "- [${title}](https://example.com/posts/${slug}): ${desc}" >> public/llms.txt
done

Run this before builds in your CI pipeline (GitHub Actions, etc.) and it will auto-update with every deployment.

8. Post-Setup Verification and Testing

After setting up llms.txt, verify the following.

Basic Checklist

Check ItemHow to Verify
Accessible via URLcurl https://yoursite.com/llms.txt
Correct Content-TypeUse curl -I to confirm text/plain; charset=utf-8
No character encoding issuesOpen it directly in a browser and check for correct display
Links are validConfirm all listed URLs are actually accessible
HTTP status is 200curl -o /dev/null -w "%{http_code}"
Not blocked by robots.txtEnsure robots.txt doesn't contain Disallow: /llms.txt

Additional Checks for Dynamic Generation

  • Check llms.txt after adding a new article: Is the new article reflected?
  • Content count is correct: Does "All Articles (27)" match the actual number of published articles?
  • Unpublished articles are excluded: Confirm that drafts and scheduled posts don't appear

Validation Tools

There is no official validator for the llms.txt format (as of September 29, 2026). Chrome's Lighthouse has an llms.txt item among its "agentic browsing" audits, but it only checks whether fetching the file returns a server error; if the file does not exist (404), the audit is marked not applicable (Chrome for Developers). Check the contents with the methods below.

  • Have ChatGPT or Claude read it: Ask "Read https://yoursite.com/llms.txt and tell me about this site"
  • Markdown previewer: Paste the llms.txt content into a Markdown previewer to check that the structure renders correctly
  • SEO audit tools: Some SEO audit tools have begun supporting llms.txt presence checks

9. Measured: Do AI Crawlers Actually Fetch llms.txt?

People often say "publish it and AI will read it," but whether anything actually fetches it is something you can check in your own server's access logs. This site (arte.itlibra.com) serves a dynamically generated /llms.txt, so we counted requests by User-Agent from September 26, 07:20 to September 29, 12:54 UTC (about three and a half days, 86,696 requests in total).

Crawler (User-Agent)All requests in the periodrobots.txtllms.txt
OAI-SearchBot (OpenAI search)866200
ChatGPT-User (ChatGPT opening a page for a user)1,27520
ClaudeBot (Anthropic)502290
Claude-User (Claude opening a page for a user)438700
PerplexityBot1,086190
Googlebot2,186140
bingbot4,362210

/llms.txt was requested only three times in that period: twice from the command line (curl) and once by a site-audit tool. AI crawlers read articles hundreds of times but never opened llms.txt. Many of them did check robots.txt, so it is not that they skip small files; they simply do not look for llms.txt.

This is three and a half days of logs from one site, and other sites or longer periods may look different. Combined with the official statements, though, the picture is clear.

  • Google: states that "You don't need to create new machine readable files, AI text files, or markup" to appear in AI Overviews or AI Mode (AI features and your website)
  • The specification (v2, August 2026): expects llms.txt to be used at inference time, when an agent needs information while helping a user, rather than for training, and says it is used most heavily by coding agents navigating software documentation (llmstxt.org)
  • Chrome Lighthouse: its "agentic browsing" audits include llms.txt, but a page fails only if fetching the file returns a server error. A missing file (404) is marked not applicable and costs nothing (Chrome for Developers)

Deciding Whether to Add One

Type of siteVerdictWhy
API or library documentationAdd it (plus Markdown versions of each page)Coding agents really do follow it; this is the main use the specification has in mind
Blog or media siteHarmless to add, but do not expect more traffic or citationsIn this site's logs, AI crawlers read the articles directly. What matters first is the quality of the articles and not blocking AI crawlers in robots.txt
Small corporate siteNo rushWith few pages, the homepage and sitemap are enough

If you do add one, your own logs are the reliable way to see whether it is used. For access logs in the standard nginx or Apache format (combined), this one line counts the User-Agents that requested /llms.txt, most frequent first.

grep ' /llms.txt ' access.log | awk -F'"' '{print $6}' | sort | uniq -c | sort -rn

10. Real-World llms.txt Examples

OpenAI, Anthropic and Google (Gemini API) publish llms.txt files for their own developer documentation (listed on the specification page). We found no statistics on adoption rates, so treat the table below as a rough indication of trends.

Types of Sites Leading Adoption

Site TypeAdoption RateReason
AI-Related Services and ToolsHighThe AI industry itself is highly LLMO-conscious
Technical DocumentationHighStrong demand for AI to accurately understand their content
Tech BlogsModerateHigh sensitivity to technical trends
Corporate SitesLowAwareness is still limited
E-commerce SitesLowStructured data (JSON-LD) is the priority

What Makes a Good llms.txt

  • Clear, concise overview -- the site's area of expertise is immediately apparent
  • All content listed with summaries -- AI can grasp the full picture
  • Category structure is explicit -- the information architecture is clear
  • Dynamically generated -- always reflects the latest state

What Makes a Bad llms.txt

  • Only site name and contact info -- too little information to help AI understand anything meaningful
  • Full content text copied in -- llms.txt is a "table of contents," not a "full text." Full text belongs in llms-full.txt
  • Left outdated -- claiming "10 articles" when there are actually 50 undermines credibility
  • Contains sensitive information -- admin panel URLs or API keys exposed

FAQ

Q. Will my site not appear in AI search results without llms.txt?

No. AI systems can read your pages directly and cite them without llms.txt. Google explicitly says no AI text files are needed to appear in AI Overviews or AI Mode, and in this site's logs AI crawlers read articles hundreds of times but never opened llms.txt. It is not something you lose out by skipping; it is an optional file for when you want to guide agents.

Q. Does llms.txt matter if I'm blocking AI crawlers in robots.txt?

If you're blocking bots like User-agent: GPTBot with Disallow in robots.txt, those bots won't crawl your site. However, llms.txt operates independently of robots.txt rules. AI might still access llms.txt through other means (such as a user directly pasting the URL). If you're intentionally blocking AI crawlers, not placing an llms.txt file is the consistent approach.

Q. What language should llms.txt be written in?

For multilingual sites, English. For single-language sites, the site's language is also fine. The specification and examples are predominantly in English, making it the most logical choice for multilingual sites as a neutral language. However, if a site's content is entirely in one language, writing llms.txt in that language is acceptable. Major LLMs process most languages with high accuracy, and users will query in the same language as the site, resulting in consistent responses.

Q. Is there a file size limit for llms.txt?

The specification sets no limit; it only says the file should stay small enough to fit in context. For reference, this site's llms.txt lists 225 articles and 40 course chapters, one line each, and comes to about 116 KB (as of September 29, 2026). If yours grows large, shorten the one-line summaries, move secondary links to ## Optional, or split it into separate llms.txt files per subpath as v2 allows. To provide full text, link to Markdown versions of individual pages.

Q. How often should I update it?

With dynamic generation, you don't need to worry -- the latest information is returned with every request. For static files, updating whenever you add or modify content is ideal. At minimum, review and update monthly. If stale information is likely to linger, switching to dynamic generation is recommended.

Q. Does it affect SEO?

It does not affect Google rankings. Google says that, including for AI Overviews and AI Mode, no AI text files or special markup are needed and the usual SEO fundamentals apply (Google Search Central). There is also no evidence that it increases citations in ChatGPT or Perplexity. If you want to know whether it does anything, check your own access logs, as in Section 9.

Q. Are there WordPress plugins for this?

Yes. The llmstxt.org list includes Yoast SEO and AIOSEO as WordPress plugins with llms.txt generation (as of September 29, 2026). Whichever you use, always review the generated output. You can also do it yourself with a few dozen lines in functions.php, so a plugin is not strictly necessary.