Skip to content

SEO and the document head ​

What Evolve puts into <head>, which of it an editor controls, and the three endpoints search engines read: the sitemap, robots.txt and security.txt.

The head of a page ​

Every frontend page starts from the head defaults: the title, charset and viewport, the CSRF token, a canonical link to the current URL, and on staging and development a robots tag with noindex, nofollow. The theme adds author and generator tags, the site verification tags and, once the company identity is set, the site-wide Organization block (see Structured data). For a routed page, the route adds:

TagSource
<title>, og:title, twitter:titlethe route's page title
description, og:description, twitter:descriptionthe route's meta description. No fallback. An empty description renders no tag at all, because a boilerplate description on hundreds of pages is worse than letting Google write its own snippet.
og:type, og:url, og:site_namewebsite, the current URL, the site name (Settings > General, fallback APP_NAME)
canonicalthe route's canonical when set, otherwise the current URL
og:image (1200 by 630), twitter:image (1200 by 628), twitter:image:altthe page's share image: its image field, cropped. Alt text from the image description, then the meta description, then the file name.
twitter:cardsummary_large_image
robots noindex, nofollowwhen the page is not public (unpublished or hidden)
hreflang alternates and x-defaultone per active language the page exists in, only when there are at least two. Regions narrow the set to the locales a region allows.

Blog posts add article:author. Pages whose model implements the head contract add their own tags.

What editors control ​

Per page: the title, the meta description, the share image, and whether the page is published or hidden. There is no per-page "noindex" switch; a page that must not be indexed stays hidden or unpublished (a curated metadata contract is tracked in evolve-cms issue #175). Site-wide: the site name (Settings > General), the site verifications below and the company identity (Settings > Company).

Site verification ​

Setting.env fallbackTag
GoogleGOOGLE_SITE_VERIFICATIONgoogle-site-verification
BingBING_SITE_VERIFICATIONmsvalidate.01
PinterestPINTEREST_SITE_VERIFICATIONp:domain_verify

Edited in the panel under Settings > SEO since 2.18, saved to the settings store group seo. The variables are the fallback for an empty field. (Before 2.18 the fields sat on the Tracking tab and wrote the .env.) The tags render on every environment.

Environments and indexing ​

Staging and development always carry noindex, nofollow in the HTML. The tag travels inside cached pages too, which an X-Robots-Tag header could not, because page-cache hits never reach PHP. Staging additionally sits behind the preview password. See Environments.

Sitemap ​

/sitemap.xml lists every public route whose language is active: pages and routeable module records (posts, projects, events, vehicles and so on). Hidden routes are left out, because advertising a page that carries noindex sends contradictory signals. Each URL carries lastmod from the record's last change and hreflang alternates for its siblings. changefreq and priority are omitted on purpose; search engines ignore them.

The sitemap is cached for a day when APP_URL names a real host. Without a canonical host it is rebuilt per request, so that a request on a preview host cannot fix every crawler's URLs to that host for a day. The same guard protects the page cache.

robots.txt ​

The starter ships public/robots.txt with User-agent: * and an empty Disallow, which allows everything. Evolve does not generate it. Non-live environments are kept out of the index by the noindex tag and the preview password, not by robots.txt.

security.txt ​

/.well-known/security.txt (RFC 9116) tells security researchers where to report an issue. It is served when evolve.security.contact in config/evolve.php holds an address or URL, with evolve.security.policy_url as the optional policy link. Unset, it falls back to the sender address in MAIL_FROM_ADDRESS once that differs from the seeded one, and otherwise answers 404 on a live site: a security.txt that names somebody who does not run the site is worse than none.

Structured data ​

Two kinds of JSON-LD blocks reach the page.

The site-wide Organization 2.18. Every page carries one Organization block (id="jsonld-organization") built from Settings > Company: name (brand name, else legal name), legal name, URL, logo, founding date, phone, email, postal address and the sameAs profiles. Its @id is https://<site>/#organization, so other blocks can point at it. The logo is the one picked on the Company tab. Without a legal name there is no Organization at all: Evolve does not guess a company from the site name or a theme logo.

The record's own block. Records whose model implements the structured data contract add theirs: jobs produce JobPosting and members Person (both from the Company module), blog posts, projects and FAQ entries their own types. Only CreativeWork types (Article, BlogPosting, NewsArticle, WebPage and similar) get author and publisher, and those are the Organization: a compact node with its @id, name, URL and logo. Person, JobPosting and Product get neither. Without a company identity the block ships without them.

Empty values are left out of every block: no empty image, no null address lines. Before 2.18 author and publisher came from a company.name translation that most projects never defined; projects that relied on such a lang file enter the company identity in the Company tab instead.

Tools ​

  • The AI page report on each page's screen reviews content and structure for SEO, see Editor AI.
  • Over MCP, get-seo-meta-tool returns title, description, Open Graph tags, canonical, hreflang alternates and indexing status for a route; it is one of the three tools an anonymous HTTP caller may use, so an external audit needs no token. See MCP Server.
  • curl -s https://<domain>/<path> | grep -E '<title>|name="description"|rel="canonical"|hreflang' shows what a crawler sees, including the noindex tag on staging.