Class: Seo::LlmsTxtBuilder
- Inherits:
-
BaseService
- Object
- BaseService
- Seo::LlmsTxtBuilder
- Defined in:
- app/services/seo/llms_txt_builder.rb
Overview
Renders the llmstxt.org-style discovery manifest from the SiteMap
canonical source of truth — same table that backs the XML sitemaps and
schema.org rendering. No second hand-edited file to drift.
Per the llmstxt.org spec, llms.txt is a curated decision-helper for
AI agents, not a comprehensive URL index. Crawlers that want every URL
should follow sitemap.xml. This builder therefore surfaces:
- The product-line hub for each catalog area (with an inline list of
subpage slugs, so agents know what's drillable without crawling). - Standalone tools (calculators, design tool, quote builder).
- The top reference articles by seo_traffic — pages an agent should
consult for buying-decision questions. - A pointer to the full XML sitemap.
Output is bilingual: every entry shows both the en-US and en-CA URL.
Constant Summary collapse
- TOP_POSTS =
Top posts.
10- TOP_TECH_ARTICLES =
Top tech articles.
5- PRODUCT_LINE_SLUGS =
Curated product-line hubs surfaced to agents, in display order. This
is an explicit allow-list rather than a skip-list — partner-facing
(/trade, /retailer), promotional (/sales, /referral-program), and
transactional (/payment, /tell-us-about-your-project) hubs add noise
for agents trying to answer end-customer questions and don't belong
in a discovery manifest. %w[ floor-heating snow-melting towel-warmer infrared-heating-panels roof-and-gutter-deicing pipe-freeze-protection mirror-defogger led-mirror countertop-heater ].freeze
- SUPPLEMENTARY_SLUGS =
Non-product entry points worth surfacing — educational and
cross-product content. Display order matters here too. %w[ radiant-heating design-guides products case-studies2 ].freeze
- SECTION_OVERRIDES =
Cosmetic touch-ups where humanizing the slug looks awkward. Keep
this list small — every entry is a hand-edited deviation. { 'led-mirror' => 'LED Mirrors', 'mirror-defogger' => 'Mirror Defoggers', 'towel-warmer' => 'Towel Warmers', 'infrared-heating-panels' => 'Infrared Heating Panels', 'roof-and-gutter-deicing' => 'Roof and Gutter De-icing', 'pipe-freeze-protection' => 'Pipe-Freeze Protection', 'countertop-heater' => 'Countertop Heaters' }.freeze
- TOOL_PATHS =
Standalone tool paths — calculators and configurators that agents
should be able to deep-link into without traversing the hub. %w[ /floor-heating/cost-calculator /floor-heating/quote-builder /snow-melting/cost-calculator /snow-melting/quote-builder /tools/online-design-tool ].freeze
Instance Attribute Summary
Attributes inherited from BaseService
Instance Method Summary collapse
-
#last_modified ⇒ Time?
Latest last_mod across input rows, for HTTP cache freshness.
- #process ⇒ Object
Methods inherited from BaseService
#initialize, #log_debug, #log_error, #log_info, #log_warning, #logger, #tagged_logger
Constructor Details
This class inherits a constructor from BaseService
Instance Method Details
#last_modified ⇒ Time?
Latest last_mod across input rows, for HTTP cache freshness.
94 95 96 97 98 99 100 101 |
# File 'app/services/seo/llms_txt_builder.rb', line 94 def last_modified [ static_page_scope(:'en-US').maximum(:last_mod), static_page_scope(:'en-CA').maximum(:last_mod), post_scope(:'en-US').maximum(:last_mod), tech_article_scope(:'en-US').maximum(:last_mod) ].compact.max end |
#process ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'app/services/seo/llms_txt_builder.rb', line 77 def process sections = [ header, product_hubs_section, supplementary_section, tools_section, top_posts_section, top_tech_articles_section, sitemap_pointer_section, contact_section ].compact_blank "#{sections.join("\n\n")}\n" end |