Hugo Module for llms.txt and llms-full.txt

Hi everyone,
With the rise of AI agents and LLMs browsing the web, providing a machine-readable version of your site’s content is becoming increasingly useful.
To make this easier for the Hugo community, we’ve created a module that automatically generates /llms.txt and /llms-full.txt following the llmstxt.org specification.

What it does

The module creates two new output formats:

  • /llms.txt: A concise, Markdown-formatted index of your site’s pages, grouped by section. Perfect for providing a “map” to LLMs.
  • /llms-full.txt: A full-content dump of your pages separated by clean dividers. This is ideal for LLMs that need the full context without crawling every individual link.

Installation

Step 1: Add the module to your config/_default/module.toml

[[imports]]
path = "github.com/gethugothemes/hugo-modules/llms-txt"

Step 2: Add the output formats to your hugo.toml


[outputs]
  home = ["...rest", "llms", "llmsfull"]
  # Add any other output formats your site already uses


[outputFormats.llms]
  baseName    = "llms"
  mediaType   = "text/plain"
  isPlainText = true
  notAlternative = true

[outputFormats.llmsfull]
  baseName    = "llms-full"
  mediaType   = "text/plain"
  isPlainText = true
  notAlternative = true


Note: …rest is a placeholder for any other output formats you may already have configured (e.g. “HTML”, “RSS”, etc.). Make sure to include those as well to avoid breaking existing functionality.

Configuration

Add an [llms] block to your config/_default/params.toml:

[llms]
  # Set to false to disable /llms.txt generation
  enable = true

  # Set to false to disable /llms-full.txt generation
  enable_full = true

  # Include only specific pages or directories.
  # If empty, all pages are included by default.
  # If populated, ONLY paths matching the list will be generated.
  # Both llms.txt and llms-full.txt respect this setting.
  # Examples:
  #   "/about/"      → include strictly the /about/ page
  #   "/blog/*"     → include immediate children of /blog/ (e.g. /blog/post-1/)
  #   "/blog/**"    → include /blog/ and all nested pages and directories
  include = []

  # Exclude specific pages or directories.
  # Follows the same wildcard formats as include.
  # Conflict handling: If the EXACT same path string is put in both include and exclude,
  # the include rule has higher priority (the exclude rule is ignored).
  # Both llms.txt and llms-full.txt respect this setting.
  # Examples:
  #   "/about/"       → exclude exactly /about/
  #   "/blog/**"     → exclude all pages under /blog/
  #   "/blog/post-1/"   → exclude a specific page
  exclude = []

Configuration reference

Key Type Default Description
llms.enable bool true Enable/disable /llms.txt
llms.enable_full bool true Enable/disable /llms-full.txt
llms.include list [] URL patterns to include (overrides default all)
llms.exclude list [] URL patterns to exclude (supports * and **)

How It Works

llms.txt

Follows the llmstxt.org specification:

# Site Title

> Site description

## Pages
- [About](https://example.com/about/): About page description
- [Pricing](https://example.com/pricing/): Pricing page description

## Blog
- [Post Title](https://example.com/blog/my-post/): Post summary...

## Docs
- [Getting Started](https://example.com/docs/getting-started/): ...

llms-full.txt

Contains the complete content of every page separated by 80-dash dividers:

# Site Title

> Site description

--------------------------------------------------------------------------------
title: "About Us"
url: https://example.com/about/
description: Learn about our company
--------------------------------------------------------------------------------
[full page content]

--------------------------------------------------------------------------------
title: "My Blog Post"
url: https://example.com/blog/my-post/
date: "2024-01-15"
description: Post description
--------------------------------------------------------------------------------
[full post content]

:backhand_index_pointing_right: Here is the source code.

We’d love to hear your thoughts or any suggestions for improvements.

3 Likes