SEO and discovery Apply Core's search, metadata, structured-data, and discovery contracts. next core preview site-builderscore-developersintegratorsai-agents
Unreleased documentation This page can change before the next stable Distribution bundle.
unreleased core preview Public

SEO and discovery

Apply Core's search, metadata, structured-data, and discovery contracts.

Owner
Foundry Core
Source
core/docs/SEO.md
Ref
782f49b97d862e640e87c870178e600f9ce5cf83
Policy
release-bound
Component pins for v0.2.6
ComponentRoleVersion
coreruntimev0.1.24
theme-shieldthemev0.1.15
starterreferencev0.1.3
docsreferencev0.1.4
distributiontoolingv0.3.4
restricted-component-1consumer-referencev0.1.22
restricted-component-2consumer-referencev1.1.21

Foundry now emits shared SEO from partial "foundry/seo/render.html" ..

Downstream themes should call that partial from baseof.html, not from a site overrideable head-end.html file. This keeps canonical tags, alternates, metadata, and schema from drifting between core, theme, and project repos.

What core renders

  • Canonical URL, including paginator-aware URLs after list page one
  • Meta description
  • Robots and googlebot tags when robots, noindex, or private are set
  • Open Graph and Twitter metadata
  • Source-visible generator markers:
    • LikeStyle Foundry Core <version> (Hugo <version>)
    • a dedicated foundry-core-version meta value
  • hreflang alternate links for multilingual pages
  • JSON-LD for:
    • WebSite plus the home route’s WebPage
    • WebPage or CollectionPage
    • MedicalWebPage for medical treatment/article pages when the site declares a medical local business
    • BreadcrumbList
    • BlogPosting
    • Service
    • Person
    • FAQPage
    • optional Organization / LocalBusiness

Theme responsibility

Theme head-end.html files should only add theme or brand assets such as:

  • dark-mode anti-flash scripts
  • theme CSS bundles
  • favicons
  • theme color
  • project-specific preconnects

Shared SEO should not be reimplemented there.

Foundry attribution

Core owns a required bottom-of-page attribution hook at layouts/_partials/hooks/body-end/foundry-attribution.html. It renders the linked wording Built with LikeStyle Foundry Core, pointing to https://likestyle.com/foundry/. The link uses a self-contained dark badge with white text so site and theme footer colors cannot make the wording unreadable.

Sites may opt into the public Foundry Attribution Control Runtime. The browser can then apply an exact show or hide decision from Foundry Control. The badge remains visible on missing configuration, service failure, timeout, or an invalid response; source-visible generator and version markers are never removed.

The SEO partial emits generator metadata, a dedicated Core-version meta tag, and an HTML comment naming LikeStyle Foundry Core. The attribution wrapper also includes data-foundry-core-version, so the framework and build version remain identifiable in generated source.

Core resolves the version from the pinned github.com/jerrybroughton/likestyle-foundry-core entry exposed by hugo.Deps. Sites may set params.foundry.core_version to an explicit value such as dev+59a7b8f when a local replacement or release materializer needs to override the dependency version. If neither source provides a version, Core reports dev instead of claiming a release. Custom shells that do not automatically collect Hugo Blox body-end hooks must call partial "hooks/body-end/foundry-attribution.html" . before </body>.

Site config fields

Supported site params:

params:
  description: "Site-wide fallback description"
  og_image: "/images/og-default.jpg"
  social:
    instagram: "https://instagram.com/example"
    facebook: "https://facebook.com/example"
  contact:
    phone: "(555) 555-5555"
    email: "info@example.com"
    hours: "By appointment only"
  seo:
    author: "Site Author"
    reviewed_by_default: "author-key"
    twitter_handle: "@example"
    og_image_default: "/images/og-default.jpg"
    organization:
      name: "Example Company"
      logo: "/images/logo.png"
      same_as:
        - "https://linkedin.com/company/example"
    local_business:
      types:
        - "LocalBusiness"
      name: "Example Company"
      price_range: "$$"
      address:
        street_address: "123 Main St"
        city: "Anywhere"
        region: "CA"
        postal_code: "90210"
        country: "US"

Supported page params:

canonical: "https://example.com/custom-url/"
robots: "noindex,nofollow"
noindex: true
author: "author-key"
author_name: "Author Name"
author_role: "Medical Reviewer"
reviewed_by: "reviewer-key"
reviewed_on: 2026-03-04
seo:
  schema_title: "Visible page heading"
  image: "/images/page-social-card.jpg"
  image_alt: "Concise description of the social image"
  person:
    key: "author-key"
  service:
    type: "Service"
    service_type: "Primary service label"

seo.schema_title is the semantic title used by WebPage, article, and Service JSON-LD. Set it when the editorial <h1> intentionally differs from the SEO-oriented front matter title; it should exactly match the visible heading. Open Graph and Twitter titles continue to use the page title.

For a custom paginated list, initialize the exact paginator before calling the SEO partial and store its URL in the page scratch as foundry_seo_canonical. Foundry uses that value for canonical, Open Graph, and schema URLs. This avoids Core instantiating a second paginator with a different collection or page size.

Foundry emits article schema only for leaf content pages. Section, taxonomy, archive, and other list pages keep their WebPage/CollectionPage schema even when they live under an article section.

seo.image is the canonical page-level SEO/social image field advertised by the page manifest. og_image remains a compatibility alias. The resolved precedence is seo.image, og_image, the shared discovery image, the site-level params.og_image, and then params.seo.og_image_default.

reviewed_on is the canonical editorial review-date field used by the shared article shell and JSON-LD resolver. It emits lastReviewed on the page schema, and the date must remain visible in rendered content. reviewed_at, reviewed, and last_reviewed remain compatibility aliases.

The discovery model infers search.kind: service for the services section and search.kind: treatment for the treatments section. Explicit search.kind remains preferred when a service lives elsewhere. Both service and treatment kinds can emit Service JSON-LD; seo.service can supply the visible service type and other supported service facts.

Robots

Set enableRobotsTXT: true in each downstream site config. Shared and site-owned theme repos can expose layouts/robots.txt wrappers that call the shared Foundry robots partial.

Projects with their own custom base layout and no theme layouts/robots.txt wrapper should add a local layouts/robots.txt file that calls:

{{ partial "foundry/seo/robots.txt" . }}

The wildcard contract remains backward compatible:

params:
  seo:
    robots_txt:
      disallow:
        - /private/
      allow:
        - /private/public-guide/
      extra: |-
        Crawl-delay: 2

Foundry also supports opt-in purpose-aware crawler profiles and per-crawler overrides:

params:
  seo:
    robots_txt:
      profile: search-visible-no-training
      crawlers:
        gptbot: inherit
        perplexitybot: disallow

Crawler override keys come from data/foundry/crawler-policy-registry.json; valid values are inherit, allow, and disallow. An allow rule preserves the wildcard path rules for that crawler rather than bypassing site-wide private paths. A disallow rule blocks / for that crawler. Unknown profiles safely fall back to inherit, and unknown crawler keys produce no group.

See AI Discovery for profile intent, crawler-purpose boundaries, user-fetch limitations, and the rendered discoverability validator.

Static Pagefind search

Search Foundry documentation

Type at least two characters
Search the full documentation system

Results stay inside this build profile and can be filtered by version, component, audience, and lifecycle.