Metadata & SEO Management
Relevant source files
The following files were used as context for generating this wiki page:
Metadata & SEO Management in Farm.js controls the generation, merging, and reconciliation of document head elements and discovery files. The system manages page-level SEO attributes, Open Graph tags, Twitter cards, and structured data to ensure correct indexing and social sharing behavior across server-side rendering (SSR) and client-side navigation.
The framework provides specific utilities for technical SEO artifacts, including automated sitemaps, robots.txt generation, and AI-specific discovery via llms.txt. It uses a hierarchical merging strategy that allows layouts to define base metadata that specific pages then extend or override.
Metadata Rendering Architecture
The metadata system converts structured Metadata objects into HTML tags. It supports standard SEO tags, social media protocols, and structured JSON-LD data.
Core Rendering Logic
The renderMetadataHead function generates a RenderedMetadataHead object containing the final title and a string of HTML tags. It handles the following attributes:
- Standard SEO: Title, description, keywords, author, creator, and publisher.
- Robots: Controls indexing and following behavior via
normalizeRobots. - Canonicalization: Automatically defaults to a self-referential canonical URL based on the
pathnameif no explicit canonical link is provided. - Social Metadata: Processes
openGraphandtwitterconfigurations, providing safe defaults likeog:type="website"if omitted.
Sources: packages/farm/src/metadata.ts:114-162, packages/farm/src/metadata.ts:187-208
Metadata Merging Flow
Farm.js uses a recursive merge strategy to combine metadata from different levels of the application (e.g., from a Layout and a Page).
The merge process includes template resolution for titles. If a base metadata defines a template (e.g., %s | My App), the merging logic applies this template to the new page title.
Sources: packages/farm/src/metadata.ts:31-52, packages/farm/src/metadata.ts:54-70
Client-Side Reconciliation
During client-side navigation, the applyFarmMetadataToDocument function updates the document head to match the target route's metadata without a full page reload.
Reconciliation Process
- Title Update: Sets
document.titleusingresolveMetadataTitle. - Tag Sweeping: Removes "owned" selectors from the head to prevent tag duplication.
- Managed Attribute: Appends new tags with a
data-farm-metadataattribute to mark them for future reconciliation.
The reconciler distinguishes between "owned" tags (like descriptions and social tags) which are always replaced, and "default-able" tags (like icons and manifests) which are only replaced if the new metadata explicitly defines them.
Sources: packages/farm/src/client/metadata-reconciler.ts:35-66, packages/farm/src/client/metadata-reconciler.ts:10-33
Technical SEO Routes
Farm.js handles discovery files through dedicated metadata route handlers. These routes support GET and HEAD methods and implement automated serialization for various formats.
Supported Metadata Route Types
| Route Kind | Content-Type | Purpose |
|---|---|---|
sitemap | application/xml | Standard search engine index of URLs. |
robots | text/plain | Directives for crawlers (Allow/Disallow). |
manifest | application/manifest+json | PWA web app manifest. |
llms | text/plain | AI-readable index of site content. |
llms-full | text/plain | AI-readable index with inlined Markdown content. |
Sources: packages/farm/src/metadata-route.ts:186-218, packages/farm/src/metadata-route.ts:5-10
Robots and Sitemap Serialization
- Robots: The
serializeRobotsfunction validates that at least one rule exists and maps multiple user agents and sitemap references into the standard robots.txt format. - Sitemaps: The system automatically handles XML escaping and supports language alternates using
xmlns:xhtml.
Sources: packages/farm/src/metadata-route.ts:124-154, packages/farm/src/metadata-route.ts:88-120
AI & LLM Discovery (llms.txt)
The framework implements the llms.txt specification to assist Large Language Models in understanding the site structure and content.
llms.txt Generation Logic
The system generates a Markdown index at /llms.txt. It can also generate /llms-full.txt, which includes the actual Markdown content of all linked pages.
The collectFarmLlmsTxtPages function filters routes based on include and exclude patterns and links to Markdown mirrors (e.g., page.md) instead of HTML routes when available.
Sources: packages/farm/src/llms-txt.ts:133-167, packages/farm/src/llms-txt.ts:251-285
Markdown Metadata Extraction
For Markdown-based routes, metadata is extracted directly from file frontmatter.
- Frontmatter Parsing: The
parseMarkdownFrontmatterfunction identifies the YAML/JSON block between---delimiters. - Metadata Mapping:
createMarkdownMetadatamaps frontmatter fields liketitleanddescriptionto the internalMetadatastructure. - Title Fallback: If a title is missing from the frontmatter, the system attempts to extract it from the first H1 heading in the Markdown body.
Sources: packages/farm/src/app-markdown-runtime.ts:54-85, packages/farm/src/app-markdown-runtime.ts:93-110
Summary
Metadata & SEO Management in Farm.js provides a unified pipeline for both human-facing SEO (HTML head tags) and machine-facing discovery (Sitemaps, Robots, LLM indexes). By utilizing a hierarchical merge strategy and a managed client-side reconciler, the framework ensures metadata consistency across all rendering modes while automating the generation of complex technical SEO artifacts.