/ llmtxt.info

llms.txt for Gatsby

Two approaches for Gatsby: a zero-config static file in static/, or programmatic generation in gatsby-node.js using the GraphQL data layer to build links from your content.

Last updated:

Option 1: static file in static/

Gatsby copies everything in the static/ directory directly into the public/ build output. Place your file at static/llms.txt and it will be available at /llms.txt after gatsby build.

static/llms.txt, directory structure
# Gatsby static file approach
#
# Place your file at: static/llms.txt
# Gatsby copies everything in static/ directly to the public/ build output.
#
# Project structure:
# your-gatsby-site/
# ├── static/
# │   └── llms.txt   ← add this
# ├── src/
# └── gatsby-config.js

This approach requires no code changes and works with all Gatsby deployment targets: Netlify, Vercel, Cloudflare Pages, AWS Amplify, and self-hosted.

Option 2: generate in gatsby-node.js

For sites where documentation pages are sourced from Markdown, MDX, or a CMS via the Gatsby data layer, use the onPostBuild lifecycle hook in gatsby-node.js to generate llms.txt after the build completes. This ensures the link list is always in sync with your content.

gatsby-node.js
// gatsby-node.js
// Generate llms.txt from your GraphQL data layer
const { writeFileSync } = require('fs');
const { resolve } = require('path');

exports.onPostBuild = async ({ graphql }) => {
  // Query your documentation pages (adjust the query to your data model)
  const result = await graphql(`
    query {
      allMarkdownRemark(
        filter: { frontmatter: { collection: { eq: "docs" } } }
        sort: { frontmatter: { order: ASC } }
      ) {
        nodes {
          frontmatter {
            title
            description
          }
          fields {
            slug
          }
        }
      }
    }
  `);

  if (result.errors) {
    throw result.errors;
  }

  const docs = result.data.allMarkdownRemark.nodes;
  const siteUrl = 'https://yoursite.com';

  const links = docs
    .map(
      (doc) =>
        `- [${doc.frontmatter.title}](${siteUrl}/docs/${doc.fields.slug}/): ${doc.frontmatter.description ?? ''}`
    )
    .join('\n');

  const content = [
    '# Your Site',
    '',
    '> One-sentence description of your project.',
    '',
    '## Documentation',
    '',
    links,
    '',
    '## Optional',
    '',
    `- [Changelog](${siteUrl}/changelog/): Release history.`,
  ].join('\n');

  // Write to public/ (Gatsby's build output directory)
  writeFileSync(resolve(__dirname, 'public', 'llms.txt'), content, 'utf-8');
};

The onPostBuild hook receives the same graphql function used in page queries. Adjust the query to match your data model, the example uses allMarkdownRemark but you can query any Gatsby source plugin (allMdx, allContentfulPage, etc.).

Gatsby plugin approach

If you prefer a plug-and-play solution, several community plugins generate llms.txt automatically. Search npm for gatsby-plugin-llms-txt. Alternatively, the approach above in gatsby-node.js is straightforward enough that a custom plugin adds little value for most projects.

You can also use gatsby-plugin-sitemap as a reference, it uses the same onPostBuild pattern to write an XML file to public/.

Verify

Build and verify
# Build
gatsby build

# Check generated file
cat public/llms.txt | head -10

# After deploying, verify the live URL
curl -I https://yoursite.com/llms.txt
# Expected: content-type: text/plain; charset=utf-8

Related guides

Sources