SR
Get Started

Configuration

Learn about all available configuration options for the LLMify plugin.


Control Panel

You can manage configuration settings through the Control Panel by visiting Settings > LLMify.

Settings

You can define a multi-environment aware config in /config/llmify.php. Settings defined in the config file override control panel settings.

Caution

Config file settings will overwrite the settings from the control panel.

isEnabled

Master toggle for LLMify. When disabled, no Markdown is rendered or served, and every LLMify page in the control panel shows a warning so editors know the plugin is off.

return [
    '*' => [
        'isEnabled' => true, // default
    ],
];

headlessMode

Enable this when you use Craft headless. Markdown is then created by fetching your front-end URLs instead of rendering your Twig templates, and exposed through the API endpoints described in Headless. The auto-serve and discovery-tag features do not apply in this mode.

return [
    '*' => [
        'headlessMode' => false, // default
    ],
];

apiToken

Optional token that protects the headless API endpoints (only applies in headless mode). Set it to an environment variable holding a long random string, e.g. generated with openssl rand -hex 32. Requests must then send the same value in the X-Llmify-Token header; leave empty to keep the endpoints unprotected.

return [
    '*' => [
        'apiToken' => '$LLMIFY_API_TOKEN', // default: null
    ],
];

autoServeMarkdown

Automatically serve Markdown instead of HTML when the request contains an Accept: text/markdown header.

return [
    '*' => [
        'autoServeMarkdown' => true, // default
    ],
];

enableBotDetection

Detect known AI bots (GPTBot, ClaudeBot, ChatGPT-User, etc.) by their user agent and automatically serve Markdown to them. See Auto-Serve Markdown for the full list of detected bots.

This is disabled by default: it forces Markdown on crawlers that did not ask for it, which some search engines consider cloaking. Content negotiation via the Accept: text/markdown header (autoServeMarkdown) stays the recommended way to serve Markdown, because there the crawler explicitly requests it.

return [
    '*' => [
        'enableBotDetection' => false, // default
    ],
];

additionalBotUserAgents

Add custom bot user agents to detect in addition to the built-in list.

return [
    '*' => [
        'additionalBotUserAgents' => [
            ['userAgent' => 'MyCustomBot'],
            ['userAgent' => 'AnotherBot'],
        ],
    ],
];

autoInjectDiscoveryTag

Inject discovery links into the HTML head: <link rel="describedby"> pointing to llms.txt on every page (when llms.txt is enabled), and <link rel="alternate" type="text/markdown"> on every page that has Markdown available.

return [
    '*' => [
        'autoInjectDiscoveryTag' => true, // default
    ],
];

enableWebMcp

Expose your enabled content to in-browser AI agents (e.g. Gemini in Chrome) via the experimental WebMCP standard. When enabled, every front-end page loads a script that registers read-only search, page, section, and navigation tools with the visitor's browser agent.

return [
    '*' => [
        'enableWebMcp' => false, // default
    ],
];

isRealUrlLlm

Whether to use real page URLs or Markdown URLs in the llms.txt file. Recommended to enable together with autoServeMarkdown.

return [
    '*' => [
        'isRealUrlLlm' => false, // default
    ],
];

markdownUrlPrefix

URL prefix for individual Markdown pages. Leave empty to serve Markdown at the original URL with .md appended (e.g. https://example.com/about.md, homepage at https://example.com/index.md), as the llms.txt spec expects. Set a prefix only if .md URLs conflict with existing routes (e.g. raw results in https://example.com/raw/about.md).

return [
    '*' => [
        'markdownUrlPrefix' => '', // default
    ],
];
Note

The default changed from raw to an empty string. Existing installs that never saved this setting keep raw after updating, so their URLs don't change. While a prefix is set, the LLMify dashboard shows a warning.

excludeClasses

CSS classes that should be excluded from the Markdown generation. Elements with these classes will be stripped before conversion.

return [
    '*' => [
        'excludeClasses' => [
            ['classes' => 'exclude-llmify'], // default
        ],
    ],
];

markdownConfig

Configuration passed to the HTML-to-Markdown converter. See the library docs for all available options.

return [
    '*' => [
        'markdownConfig' => [
            'strip_tags' => true,
            'header_style' => 'atx',
            'remove_nodes' => 'img picture style form button input select option svg script nav noscript video audio source',
        ], // default
    ],
];

cacheDuration

The longest time in seconds a page's Markdown stays cached. A page is invalidated earlier as soon as it or anything it shows changes, so this mainly limits how long Markdown can lag behind changes that Craft's element cache tags do not see, e.g. content pulled from an external API. 0 keeps the Markdown until it gets invalidated.

In headless mode this is how long a fetched front-end page is kept before it is fetched again.

return [
    '*' => [
        'cacheDuration' => 86400, // default
    ],
];

concurrentRequests

Maximum number of concurrent HTTP requests when warming the cache. Valid range: 1 to 100.

Each request renders one of your pages, so warming the cache puts the same load on the server as that many simultaneous visitors. On small or shared hosting, lower this to 1 or 2 if a full run pushes CPU or memory too hard.

return [
    '*' => [
        'concurrentRequests' => 3, // default
    ],
];

requestTimeout

Maximum number of seconds each request can take while warming the cache or fetching a headless front end.

return [
    '*' => [
        'requestTimeout' => 100, // default
    ],
];

basicAuthUsername and basicAuthPassword

Warming the cache requests your own pages, and in headless mode LLMify fetches your front end. If the site is protected with HTTP Basic Auth (common on staging), set the credentials here so those requests get through. Use environment variables so the password does not end up in project config. Leave both empty when the site is not protected.

return [
    'staging' => [
        'basicAuthUsername' => '$LLMIFY_AUTH_USER', // default: null
        'basicAuthPassword' => '$LLMIFY_AUTH_PASS', // default: null
    ],
];

Multi-Environment Example

A complete example showing environment-specific configuration:

<?php
// config/llmify.php

return [
    '*' => [
        'isEnabled' => true,
        'autoServeMarkdown' => true,
        'enableBotDetection' => true,
        'autoInjectDiscoveryTag' => true,
        'isRealUrlLlm' => true,
        'markdownUrlPrefix' => '',
        'cacheDuration' => 86400,
        'concurrentRequests' => 5,
        'requestTimeout' => 120,
    ],
    'dev' => [
        'isEnabled' => false,
    ],
    'staging' => [
        'basicAuthUsername' => '$LLMIFY_AUTH_USER',
        'basicAuthPassword' => '$LLMIFY_AUTH_PASS',
    ],
    'production' => [
        'concurrentRequests' => 10,
    ],
];

Copyright © 2026 Samuel Reichör