← Oleksii Turovskyi

llms.txt для Next.js: як додати його за 15 хвилин

· 12 хв читання · Оновлено

In English: How I Added llms.txt to My Next.js Blog in 15 Minutesread in English

Якщо ChatGPT і Perplexity не знаходять ваших найкращих статей, ви просто не дали їм мапи. llms.txt і є та мапа: звичайний Markdown-файл у корені сайту, без магії й без чорної скриньки, який каже моделі, які сторінки важливі, і з яких починати читання.

Головне#

  • llms.txt - це курований Markdown-індекс у корені сайту, який показує AI-агентам, які сторінки найважливіші. Формат запропонував Джеремі Говард з Answer.AI 3 вересня 2024 року.
  • За моїм скануванням у серпні 2026 року, з 93 сторінок у видачі за AEO- і GEO-запитами 52,7%, тобто 49 із 93, лежали на домені, який віддає робочий /llms.txt.
  • Розмір файлу гуляє від 648 байтів на llmstxt.org до 2 500 078 байтів на coursera.org. Медіана по 41 домену з файлом - 8 072 байти.
  • За тим же скануванням, 12,2% цих доменів (5 з 41) отримали файл автоматично, з оновленням SEO-плагіна, а не через редакційне рішення.
  • Route handler у Next.js генерує файл на білді хвилин за десять. Помилка, на яку варто дивитися, - неправильний Content-Type.

То що таке llms.txt насправді#

llms.txt - це не альтернатива robots.txt і не заміна sitemap.xml. Документація Google про сканування прямо каже, що robots.txt існує головно для того, щоб не перевантажувати сайт запитами, і що це не механізм тримати сторінку поза індексом. llms.txt розвʼязує зовсім іншу задачу: це окремий жанр, індекс від куратора для AI-агентів. Джеремі Говард, співзасновник Answer.AI, запропонував його 3 вересня 2024 року, а формальна специфікація живе на llmstxt.org. У вибірці, яку я сканував 2026-08-09, такий файл віддають 52,7% сторінок у видачі за AEO- і GEO-запитами. Задача тут вужча, ніж у розмітки контенту через JSON-LD за словником schema.org: та розмітка описує, чим є окрема сторінка, а llms.txt курує, які сторінки взагалі варті уваги.

Базова логіка проста. Контекстні вікна моделей замалі, щоб проковтнути більшість сайтів цілком, а перетворювати HTML - з навігацією, рекламою і JavaScript - на чистий текст дорого й ненадійно. Парсинг вашого HTML палить токени намарно. Замість цього ви даєте агенту чистий Markdown зі списком URL і однорядковими описами. Агент бачить структуру за дві секунди. І що куди важливіше - бачить її вашими очима, а не очима генератора сайтмапу, який вивантажує все підряд.

Чи справді llms.txt приживається#

Так, і це вже вимірюється. 9 серпня 2026 року я просканував 93 сторінки на 78 доменах, які ранжуються в англомовній видачі США за сімома запитами навколо AEO і GEO. Самі запити, винятки й перевірка кожного сигналу описані в AEO Adoption Scan, 2026; числа нижче - це llms.txt-зріз того сканування.

У тому ж скануванні 49 із 93 сторінок, тобто 52,7%, лежать на домені, який на GET /llms.txt відповідає статусом 200 і не-HTML типом вмісту. Це та сама перевірка, яку автоматично робить розширення AEO Checker. Ці 49 влучань на рівні сторінок згортаються до 41 унікального домену, бо один домен може ранжуватися за кількома запитами. Розмір файлу різниться страшенно: медіана - 8 072 байти, найменший - 648 байтів у самого llmstxt.org, сайту за специфікацією, найбільший - 2 500 078 байтів у coursera.org. Сама лише OpenAI тримає для такої роботи чотири окремі краулери, зокрема GPTBot для тренування моделей і ChatGPT-User для живого перегляду, обидва перелічені в її офіційному довіднику.

Для формату, якого до вересня 2024 року не існувало, це реальний рівень поширення. Але це не доказ, що з файлом вас цитуватимуть частіше. Сканування міряло наявність, а не вплив на відповідь AI; те, що затягує сторінку у відповідь ChatGPT чи Perplexity, - суміш десятків сигналів, і частину з них розібрано в the invisible tags shaping your AI citations.

Хто вже це зробив#

Чесна відповідь ділиться навпіл: сайти, які додали файл свідомо, і сайти, яким його додав плагін. І ті, і ті входять у ті самі 52,7%, і різниця між ними важливіша за сам заголовний відсоток.

За тим же скануванням, пʼять із 41 домену з робочим файлом, тобто 12,2%, отримали його побічним ефектом оновлення SEO-плагіна, а не за рішенням. Усі пʼять - це два плагіни:

  • All in One SEO: aioseo.com і visiblefactors.com на Pro v5; fasturtle.com на безкоштовній v5.
  • Yoast SEO v27: boralagency.com і yoghurtdigital.com.

Жоден із цих пʼяти сайтів не обирав стратегію курації. Плагін випустив фічу, згенерував файл з наявних метаданих постів - і домен став одиницею статистики в кожному майбутньому огляді llms.txt, зокрема й у цьому. Це варто тримати в голові, перш ніж читати цифру поширення як доказ свідомого наміру.

Мій власний файл зібраний руками, а не плагіном: приблизно 12 КБ на момент написання, побудований навколо каталогу WebMCP-інструментів поряд зі звичними посиланнями на статті й проєкти. Точну кількість байтів не наводжу, бо вона змінюється з кожною публікацією - файл генерується з контенту, тож його розмір це наслідок, а не налаштування. Прочитати можна просто тут: alexturik.com/llms.txt.

Чим llms.txt відрізняється від sitemap.xml#

Критерій sitemap.xml llms.txt
Аудиторія Пошукові краулери (Google, Bing) LLM-агенти (ChatGPT, Perplexity, Claude)
Формат XML, тільки для машин Markdown, гібрид (люди теж читають)
Повнота Усі публічні URL Курована вибірка
Описи сторінок Немає (лише lastmod, priority) Однорядкове резюме на кожне посилання
Логіка пріоритету Вирішує алгоритм пошуковика Вирішуєте ви
Розмір Десятки тисяч URL - норма Короткий курований список, не вичерпний індекс

Сайтмап каже: «ось усе, що в мене є». llms.txt каже: «ось заради чого я існую».

Структура: три секції вирішують усе#

# Назва сайту
 
> Однорядкове резюме
 
## Назва секції
 
- [Заголовок сторінки](url): Однорядковий опис
- [Інша сторінка](url): Інший опис
 
## Optional
 
- [Менш критичний ресурс](url): Чому він необовʼязковий

H1 з назвою. blockquote з одним реченням про те, чим є сайт. Далі H2-секції зі списками. Секція Optional явно позначає менш критичні ресурси, які агент може пропустити, коли бюджет контексту тисне. Це формальна частина специфікації, тож її не ламайте.

Дві реалізації для Next.js#

Два шляхи. Вибір залежить від того, як часто ви публікуєте: файл, який ви ведете руками, або route handler, що працює як ваш власний генератор llms.txt.

Варіант A: статичний (5 хвилин)#

Створіть public/llms.txt. Заповніть руками. Задеплойте.

# alexturik.com
 
> Practical notes on Next.js, AEO tooling, and shipping side projects fast.
 
## Featured Posts
 
- [How I Added llms.txt to My Next.js Blog in 15 Minutes](https://alexturik.com/blog/how-i-added-llms-txt-to-my-nextjs-blog-in-15-minutes): Curator's index for AI crawlers — implementation walkthrough.
- [The 3-Word Tag That Hides Your Best Pages from AI](https://alexturik.com/blog/the-3-word-tag-that-hides-your-best-pages-from-ai): How `noindex` silently kills AI traffic.
 
## About
 
- [Author bio](https://alexturik.com): Who I am and what I build.

Працює. Просто. І безнадійно мертве через тиждень, бо оновити його ви гарантовано забудете.

Варіант B: динамічний, через route handler (10 хвилин)#

Саме він працює на цьому сайті. Route handler в App Router читає frontmatter кожної статті й генерує markdown на білді. Пишете один раз - далі воно тримає себе в актуальному стані само.

src/app/llms.txt/route.ts
import { getAllPosts } from '@/lib/posts';
import { siteConfig } from '@/lib/site-config';
 
export const dynamic = 'force-static';
 
const HEADER = (url: string) => `# Oleksii Turovskyi
 
> Full-stack developer specializing in Next.js, React, Node.js, and WordPress. Builds rapid MVPs and maintains high-load systems.
 
## About
 
- **Name:** Oleksii Turovskyi
- **Role:** Full-stack developer
- **Email:** alexturik@gmail.com
- **Website:** ${url}
 
## Pages
 
- [Homepage](${url})
- [Blog](${url}/blog)
- [Sitemap](${url}/sitemap.xml)
`;
 
const FOOTER = `## Optional
 
- [GitHub](https://github.com/turovskiy)
- [LinkedIn](https://linkedin.com/in/alexturik)
- [X / Twitter](https://x.com/alexturik)
`;
 
export async function GET() {
  const url = siteConfig.url;
  const posts = await getAllPosts();
 
  const writingSection = posts.length === 0 ? '' :
    '\n## Writing\n\n' +
    posts
      .map((p) => {
        const html = `${url}/blog/${p.slug}`;
        const md = `${url}/blog/${p.slug}.md`;
        return `- [${p.frontmatter.title}](${html}) ([Markdown](${md})) — ${p.frontmatter.description}`;
      })
      .join('\n') +
    '\n';
 
  const body = `${HEADER(url)}${writingSection}\n${FOOTER}`;
 
  return new Response(body, {
    status: 200,
    headers: {
      'Content-Type': 'text/plain; charset=utf-8',
      'Cache-Control': 'public, max-age=3600, s-maxage=86400',
    },
  });
}

Файл лежить у src/app/llms.txt/route.ts. Next.js сам віддає його на /llms.txt, без rewrites і без ручного конфігу. Кожна стаття отримує два посилання: HTML-версію і Markdown-версію (/blog/<slug>.md), тож агент, який любить сирий текст, забирає контент без парсингу HTML.

Такий .md-двійник на кожну статтю трапляється рідше, ніж здається. За тим же скануванням, лише 8,6% з 93 сторінок у видачі віддають сиру Markdown-версію себе за відповідним URL, тоді як мій сайт має їх 15. Це коштує одного зайвого рядка в лоадері вище й дає агентам версію, яку можна читати, не знімаючи жодного HTML-тега.

Один нюанс: якщо джерело ваших статей - Contentlayer, Velite, Notion API чи Sanity, просто підміняєте лоадер getAllPosts(). Решта архітектури не змінюється.

Що йде всередину, а що лишається зовні#

llms.txt - це не сайтмап. Дублювати його як сайтмап означає провалити курацію. Логіка протилежна: сюди йде тільки те, що ви хочете бачити в цитатах AI.

Варто включати:

  • Вічнозелені статті: ті, що старіють повільно й роками накопичують трафік.
  • Інструменти й калькулятори, які ви зробили. Агенти охоче лінкують конкретні утиліти.
  • Сторінку про автора. Ваше позиціювання, а не запис для галочки.
  • Сторінки цін і послуг, якщо сайт комерційний.

Не варто:

  • Юридичні сторінки (умови, приватність). Агентам байдуже, користувачам чатбота теж.
  • Сторінки-переліки (/blog, /tags/foo). Це робота класичного сайтмапу.
  • Логін, акаунт, дашборд: приватна зона за автентифікацією.
  • Індекси категорій без вашої доданої вартості.

Коротка перевірка: «Чи хочу я, щоб саме цю сторінку процитували як авторитетне джерело у відповіді ChatGPT?» Якщо відповідь не «так» - викидайте.

Бонусний рівень: llms-full.txt#

Якщо llms.txt - це зміст, то llms-full.txt - уся книжка одним файлом. Mintlify генерує обидва формати автоматично, щоб документацію можна було читати моделями без додаткових запитів. Агент отримує весь контекст одразу.

Чи варто це робити? На малому архіві коштує дрібницю й віддає агенту повний текст за один запит. На великому - зважайте на ліміти контексту: найбільший файл у моєму скануванні, на coursera.org, займає 2 500 078 байтів проти медіани 8 072, і файл такого розміру агент обрізає, так і не дочитавши хвіст. У мене такий є: alexturik.com/llms-full.txt - один route handler, який перевикористовує індекс вище, а тоді зчіплює сирий Markdown кожної сторінки й статті. Той самий патерн, що у варіанті B, тільки з тілом тексту замість резюме. Сьогодні це близько 240 КБ проти 12 КБ індексу, і в цьому весь компроміс одним рядком: один запит замість двох десятків, ціною вдвадцятеро більших токенів.

Що ламає llms.txt тихо#

Сервер має віддавати llms.txt з Content-Type text/plain або text/markdown. Цей заголовок позначає тип вмісту ресурсу, і якщо там стоїть text/html, агенти можуть тихо пропустити файл.

У route handler вище це прописано в заголовках. У статичному варіанті з public/ більшість CDN, зокрема Vercel, самі ставлять text/plain для розширення .txt, але перевірити варто. Заразом переконайтеся, що жодну зі статей, на які ви посилаєтесь, не ховає випадкова директива noindex: llms.txt корисний рівно настільки, наскільки агент справді може дістати те, на що ви вказали.

Перевірка одною командою в терміналі:

curl -I https://yoursite.com/llms.txt

Шукайте Content-Type: text/plain або text/markdown у відповіді. Якщо бачите text/html - у вас проблема з конфігом. Заводьте задачу.

Не хочеться ганяти команду в терміналі на кожен деплой? Розширення AEO Checker робить ту саму перевірку MIME-типу llms.txt автоматично, поруч з аудитом дозволів для ботів у robots.txt.

Це той збій, який найлегше задеплоїти й найважче помітити. Кладете файл у public/, а CDN усе одно віддає його як HTML - і від першого дня він невидимий для агентів, тоді як у браузері все виглядає добре.

Частина кластера Answer Engine Optimization - повний порядок читання і глосарій усіх термінів, що трапляються в цих статтях.


Готові перевірити свій?

Ця стаття входить до llms.txt на alexturik.com - достатньо мета для вас?

Якщо ви на Next.js і ще не викотили цей стандарт, годинник цокає. Пʼятнадцять хвилин роботи. Нуль ризику. Нагорода - ваші найкращі матеріали видимі для цілого покоління AI-трафіку, яке формується просто зараз.

Підписуйтесь у LinkedIn. Потрібен AEO-аудит або допомога з упровадженням на вашій платформі - напишіть.

FAQ#

Що таке файл llms.txt#

llms.txt - це звичайний Markdown-файл у корені сайту, наприклад yoursite.com/llms.txt, який дає AI-агентам курований список найважливіших сторінок з однорядковим описом кожної. Формат запропонував Джеремі Говард з Answer.AI 3 вересня 2024 року. Він існує тому, що розбирати повні HTML-сторінки в чистий текст повільно й затратно за токенами.

llms.txt - це реальна річ чи хайп#

Реальна. У нього є публічна специфікація на llmstxt.org, і його наявність вимірюється. У скануванні 93 сторінок, які в серпні 2026 року ранжувалися в США за AEO- і GEO-запитами, 49, тобто 52,7%, лежали на домені з робочим /llms.txt, і це 41 унікальний домен. Не містифікація й не маргінальний експеримент.

Чи вартий llms.txt зусиль#

Спробувати варто, зусиль небагато: статична версія займає близько пʼяти хвилин, динамічний route handler на Next.js - близько десяти. Доведеного приросту цитувань немає; сканування міряло поширення, а не вплив на ранжування. Але приблизно половина сторінок у видачі за AEO- і GEO-запитами вже віддає такий файл, а неправильний MIME-тип зробить його невидимим, не піднявши жодної помилки.

Що має бути в llms.txt#

Тримайте коротко: H1 з назвою сайту, однорядкове резюме в blockquote, далі H2-секції з ключовими сторінками й однорядковим описом кожної. Включіть вічнозелені статті, зроблені вами інструменти й сторінку про автора. Лишіть поза файлом юридичні сторінки, переліки тегів і категорій та все, що за логіном. Секція Optional наприкінці позначає посилання нижчого пріоритету, які агент може пропустити.

Чи llms.txt обовʼязковий#

Жоден окремий файл не є обовʼязковим. Ніщо в SEO чи видимості для AI не ламається без llms.txt: це шар зручності поверх сканування, не більш обовʼязковий, ніж robots.txt, без якого, за словами Google, сайт сканується нормально. Але це дешева страховка: близько пʼятнадцяти хвилин налаштування, жодного навантаження на сервер, і замість здогадок із сайтмапу, зробленого для пошуковиків, а не для мовних моделей, агент отримує готовий список для читання.

Нові статті на пошту

Одна стаття раз на два тижні - про AI-пошук і код за ним. Підтвердження листом, відписка в один клік.