{"id":284683,"date":"2026-02-26T22:11:21","date_gmt":"2026-02-26T22:11:21","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/llm-markdown-expose-content-as-md\/"},"modified":"2026-08-11T21:48:00","modified_gmt":"2026-08-11T21:48:00","slug":"llm-markdown","status":"publish","type":"plugin","link":"https:\/\/kin.wordpress.org\/plugins\/llm-markdown\/","author":22011829,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.2","stable_tag":"1.0.2","tested":"7.0.4","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"LLM Markdown \u2013 Expose Content as .md","header_author":"Compiled Rogue","header_description":"Exposes public WordPress content as clean .md routes with front matter, designed for LLMs, AI crawlers, and headless workflows.","assets_banners_color":"656a6e","last_updated":"2026-08-11 21:48:00","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/www.paypal.com\/donate\/?hosted_button_id=EUHE8NXYEXJJ6","header_plugin_uri":"https:\/\/compiledrogue.com\/","header_author_uri":"https:\/\/compiledrogue.com","rating":5,"author_block_rating":0,"active_installs":400,"downloads":1744,"num_ratings":5,"support_threads":2,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"michaelsablone","date":"2026-02-26 22:46:14"},"1.0.1":{"tag":"1.0.1","author":"michaelsablone","date":"2026-05-28 02:05:00"},"1.0.2":{"tag":"1.0.2","author":"michaelsablone","date":"2026-08-11 21:48:00"}},"upgrade_notice":[],"ratings":{"1":0,"2":0,"3":0,"4":0,"5":5},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3642537,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3642537,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3642537,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3642537,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.0.1","1.0.2"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3642537,"resolution":"1","location":"assets","locale":"","width":2400,"height":2400},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3642537,"resolution":"2","location":"assets","locale":"","width":2400,"height":2400},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3642537,"resolution":"3","location":"assets","locale":"","width":2400,"height":2400}},"screenshots":{"1":"Basic Settings Panel","2":"DOM &amp; Selectors Settings Panel","3":"Advanced Settings Panel"}},"plugin_section":[],"plugin_tags":[2353,226492,141196,226124,4608],"plugin_category":[],"plugin_contributors":[226696],"plugin_business_model":[],"class_list":["post-284683","plugin","type-plugin","status-publish","hentry","plugin_tags-ai","plugin_tags-content-export","plugin_tags-headless","plugin_tags-llm","plugin_tags-markdown","plugin_contributors-michaelsablone","plugin_committers-michaelsablone"],"banners":{"banner":"https:\/\/ps.w.org\/llm-markdown\/assets\/banner-772x250.png?rev=3642537","banner_2x":"https:\/\/ps.w.org\/llm-markdown\/assets\/banner-1544x500.png?rev=3642537","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/llm-markdown\/assets\/icon-128x128.png?rev=3642537","icon_2x":"https:\/\/ps.w.org\/llm-markdown\/assets\/icon-256x256.png?rev=3642537","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/llm-markdown\/assets\/screenshot-1.png?rev=3642537","caption":"Basic Settings Panel"},{"src":"https:\/\/ps.w.org\/llm-markdown\/assets\/screenshot-2.png?rev=3642537","caption":"DOM &amp; Selectors Settings Panel"},{"src":"https:\/\/ps.w.org\/llm-markdown\/assets\/screenshot-3.png?rev=3642537","caption":"Advanced Settings Panel"}],"raw_content":"<!--section=description-->\n<p>LLM Markdown gives supported public WordPress content a clean Markdown representation at a predictable <code>.md<\/code> URL. Append <code>.md<\/code> to a post, page, or enabled public post-type URL:<\/p>\n\n<pre><code>https:\/\/example.com\/my-post.md\n<\/code><\/pre>\n\n<p>The plugin renders the canonical front-end page, selects the part of the document that contains the primary content, removes configured elements, and converts the result to Markdown. Blocks, shortcodes, and other server-rendered content are therefore represented after WordPress and the active theme have processed them. The original post is never changed and no duplicate Markdown post is stored.<\/p>\n\n<h4>Structured Markdown output<\/h4>\n\n<p>Each document begins with YAML front matter containing the title, post ID, content type, slug, publication and modification dates, canonical URL, Markdown URL, excerpt, and terms from public taxonomies when available.<\/p>\n\n<p>The converter handles headings, paragraphs, emphasis, links, ordered and unordered lists, blockquotes, inline and fenced code, horizontal rules, deletion text, figures and captions, and simple tables. Images can be included as an option, with support for common lazy-loading source attributes.<\/p>\n\n<h4>Content selection and access control<\/h4>\n\n<p>Choose which public post types expose Markdown. Simple CSS selectors determine the main content container and which elements should be excluded before conversion. Password-protected and non-public content is rejected, and Yoast SEO noindex values can be honored. Developers can apply an additional access-control filter for membership, privacy, or custom publishing rules.<\/p>\n\n<h4>Discovery, delivery, and caching<\/h4>\n\n<p>Eligible HTML pages advertise their Markdown counterpart with a <code>&lt;link rel=\"alternate\" type=\"text\/markdown\"&gt;<\/code> element. Documents generated for anonymous requests are cached for performance and automatically invalidated after relevant settings, theme, or navigation changes; a manual cache control is available under Tools.<\/p>\n\n<p>An advanced, disabled-by-default content-negotiation option can also return Markdown from the normal canonical URL when a client explicitly requests <code>Accept: text\/markdown<\/code>. This mode sends <code>Vary: Accept<\/code>, but it should be enabled only after confirming every cache and CDN in front of the site honors that header correctly.<\/p>\n\n<p>LLM Markdown has no Gutenberg lock-in, does not duplicate content, and supports public custom post types without requiring one.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code><\/li>\n<li>Activate the plugin<\/li>\n<li>Visit Settings \u2192 Markdown Output to configure options<\/li>\n<\/ol>\n\n<p>After activation, append <code>.md<\/code> to supported post URLs.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20help%20llms%20index%20my%20content%3F\"><h3>Does this help LLMs index my content?<\/h3><\/dt>\n<dd><p>It gives crawlers and other clients a predictable, structured Markdown representation and advertises that representation from eligible HTML pages. It cannot guarantee that a particular model, crawler, or search engine will discover, index, or use it.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20create%20physical%20.md%20files%3F\"><h3>Does the plugin create physical .md files?<\/h3><\/dt>\n<dd><p>No. The <code>.md<\/code> URLs are WordPress rewrite routes generated on demand. Cached documents are stored temporarily for performance, but the plugin does not create a parallel file tree or require you to synchronize exported files.<\/p><\/dd>\n<dt id=\"does%20this%20modify%20my%20content%3F\"><h3>Does this modify my content?<\/h3><\/dt>\n<dd><p>No. It reads the rendered public page and generates a separate response. Posts, blocks, templates, and database content are not rewritten.<\/p><\/dd>\n<dt id=\"does%20it%20support%20custom%20post%20types%3F\"><h3>Does it support custom post types?<\/h3><\/dt>\n<dd><p>Yes. Any public post type can be enabled under Content Types. Attachments are excluded. Leaving every content type unchecked disables Markdown output entirely.<\/p><\/dd>\n<dt id=\"how%20do%20i%20access%20a%20static%20front%20page%3F\"><h3>How do I access a static front page?<\/h3><\/dt>\n<dd><p>Append <code>.md<\/code> to its normal permalink. The <code>\/index.md<\/code> alias is also available when WordPress is configured to use a static front page.<\/p><\/dd>\n<dt id=\"does%20it%20expose%20private%20content%3F\"><h3>Does it expose private content?<\/h3><\/dt>\n<dd><p>The plugin serves only publicly viewable content from an enabled public post type. Password-protected content is rejected. The optional Honor Noindex setting also rejects posts marked noindex by Yoast SEO, and integrations can impose additional restrictions with the <code>llm_markdown_can_serve_post<\/code> filter.<\/p><\/dd>\n<dt id=\"how%20does%20the%20rendered%20theme%20affect%20markdown%3F\"><h3>How does the rendered theme affect Markdown?<\/h3><\/dt>\n<dd><p>Markdown is built from the server-rendered canonical page, so blocks, shortcodes, and template output can be included. Browser-only content inserted later by JavaScript is not available. Use Main Content Selectors and Excluded Content Selectors when the theme includes navigation, banners, related content, or other unwanted elements around the article.<\/p><\/dd>\n<dt id=\"which%20css%20selectors%20are%20supported%3F\"><h3>Which CSS selectors are supported?<\/h3><\/dt>\n<dd><p>The selector fields intentionally support a practical subset: element names, IDs, classes, combined forms such as <code>article.entry-content<\/code>, descendant selectors, and direct-child selectors. Separate alternatives with commas or new lines. Attribute selectors, pseudo-classes, and sibling combinators are not supported.<\/p><\/dd>\n<dt id=\"can%20images%20be%20included%3F\"><h3>Can images be included?<\/h3><\/dt>\n<dd><p>Yes. Enable Images in Markdown on the Options tab. Images inside the selected content area are converted using their source, alt text, and title; common lazy-loading attributes are recognized. Images are excluded by default.<\/p><\/dd>\n<dt id=\"is%20this%20intended%20for%20seo%3F\"><h3>Is this intended for SEO?<\/h3><\/dt>\n<dd><p>It provides an alternate representation and adds a discovery link to eligible HTML pages, but it makes no ranking or indexing promises. The Markdown response identifies the HTML URL as canonical. Search-engine and AI-crawler behavior varies.<\/p><\/dd>\n<dt id=\"why%20does%20unexpected%20output%20appear%20before%20the%20markdown%20document%3F\"><h3>Why does unexpected output appear before the Markdown document?<\/h3><\/dt>\n<dd><p>Some themes, plugins, or hosting layers emit HTML, notices, or other output before <code>.md<\/code> or negotiated Markdown responses. Enable <strong>Response Cleanup<\/strong> on the Options tab under Settings \u2192 Markdown Output to remove that unwanted pre-output. This compatibility option is disabled by default.<\/p>\n\n<p>If the plugin cannot retrieve or extract the rendered page, it returns a non-cacheable <code>503 Markdown temporarily unavailable<\/code> response rather than caching an empty or incomplete document. Unsupported, disabled, or protected <code>.md<\/code> routes return <code>404 Not Found<\/code>.<\/p><\/dd>\n<dt id=\"can%20clients%20request%20markdown%20from%20the%20normal%20post%20url%3F\"><h3>Can clients request Markdown from the normal post URL?<\/h3><\/dt>\n<dd><p>Yes. Enable <strong>Header-Based Markdown<\/strong> on the Advanced tab under Settings \u2192 Markdown Output. Supported public post URLs can then return Markdown for <code>GET<\/code> and <code>HEAD<\/code> requests that explicitly prefer <code>text\/markdown<\/code>. Both HTML and Markdown responses include <code>Vary: Accept<\/code> so compliant caches can keep the representations separate.<\/p>\n\n<p>This is an advanced, disabled-by-default feature. A CDN, proxy, server cache, or page-cache plugin that does not honor <code>Vary: Accept<\/code> may serve the wrong representation. Negotiated Markdown also bypasses browser-side analytics and JavaScript. Clear every cache and test both representations after enabling it.<\/p>\n\n<p>Conservative matching requires an explicit <code>text\/markdown<\/code> media range. The separate <strong>Wildcard Accept Headers<\/strong> option can also permit <code>text\/*<\/code>; <code>*\/*<\/code> alone never requests Markdown.<\/p>\n\n<p>Test HTML:<\/p>\n\n<pre><code>curl -i -H \"Accept: text\/html\" https:\/\/example.com\/my-post\/\n<\/code><\/pre>\n\n<p>Test Markdown:<\/p>\n\n<pre><code>curl -i -H \"Accept: text\/markdown\" https:\/\/example.com\/my-post\/\n<\/code><\/pre><\/dd>\n<dt id=\"how%20do%20i%20refresh%20cached%20markdown%20after%20changing%20my%20theme%20or%20site%20layout%3F\"><h3>How do I refresh cached Markdown after changing my theme or site layout?<\/h3><\/dt>\n<dd><p>Use <strong>Clear Markdown Cache<\/strong> on the Tools tab under Settings \u2192 Markdown Output after changing templates, navigation, widgets, shortcodes, or other content that affects the rendered page. Saving the plugin settings, switching themes, and updating navigation menus also invalidate the Markdown cache automatically.<\/p>\n\n<p>Developers can use the <code>llm_markdown_cache_ttl<\/code> filter to change the default 12-hour cache duration or return <code>0<\/code> to disable document caching.<\/p><\/dd>\n<dt id=\"what%20developer%20filters%20are%20available%3F\"><h3>What developer filters are available?<\/h3><\/dt>\n<dd><p>Use <code>llm_markdown_can_serve_post<\/code> for access rules, <code>llm_markdown_is_noindex_post<\/code> for additional noindex providers, <code>llm_markdown_include_taxonomy<\/code> to control public taxonomy fields, <code>llm_markdown_front_matter<\/code> to modify metadata, <code>llm_markdown_markdown_document<\/code> to filter the completed document, and <code>llm_markdown_cache_ttl<\/code> to control caching.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20plugin%20data%20when%20i%20remove%20it%3F\"><h3>What happens to plugin data when I remove it?<\/h3><\/dt>\n<dd><p>Deactivation preserves settings. Uninstalling or deleting the plugin removes its settings, cache-generation option, and generated Markdown transients. On multisite, cleanup runs for every site in the network.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Added advanced, opt-in Markdown content negotiation for normal singular URLs using <code>Accept: text\/markdown<\/code>.<\/li>\n<li>Added quality-aware Accept-header matching, optional <code>text\/*<\/code> support, GET\/HEAD restrictions, and <code>Vary: Accept<\/code> signaling for eligible HTML and Markdown responses.<\/li>\n<li>Added a disabled-by-default Response Cleanup option for unwanted output emitted before Markdown and Markdown-route error responses.<\/li>\n<li>Reorganized the settings screen into Options, DOM &amp; Selectors, Advanced, and Tools tabs with clearer labels, guidance, and operational warnings.<\/li>\n<li>Added manual cache invalidation and automatic generation changes after settings updates, theme switches, and navigation-menu updates.<\/li>\n<li>Added the <code>llm_markdown_cache_ttl<\/code> filter and expanded cache keys to account for conversion version, relevant options, site, locale, and content modification time.<\/li>\n<li>Changed failed or empty loopback renders to return a non-cacheable 503 response instead of caching incomplete output.<\/li>\n<li>Added <code>llm_markdown_can_serve_post<\/code> for membership and access-control integrations.<\/li>\n<li>Restricted front-matter taxonomy data to public taxonomies and added <code>llm_markdown_include_taxonomy<\/code> for further control.<\/li>\n<li>Allowed an intentionally empty content-type selection to disable all Markdown output.<\/li>\n<li>Fixed HTML entity decoding and Markdown code delimiters when source code contains backticks.<\/li>\n<li>Added Markdown conversion for horizontal rules, deletion text, figures, and figure captions, and made simple table output safer for uneven rows and pipe characters.<\/li>\n<li>Expanded uninstall cleanup to remove all plugin options and generated Markdown transients across single-site and multisite installations.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Added support for tables.<\/li>\n<li>Added optional support for images.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Expose WordPress posts and pages as real .md URLs with YAML front matter for LLMs, AI ingestion, and headless workflows.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/284683","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=284683"}],"author":[{"embeddable":true,"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/michaelsablone"}],"wp:attachment":[{"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=284683"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=284683"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=284683"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=284683"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=284683"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/kin.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=284683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}