B Blengi docs

Operate

Marketing reference pages

Marketing reference pages

The nav and footer of the marketing site promise a set of pages beyond the seven the theme registry owns: the /solutions family, /compare, the /integrations children, and the company and trust pages. There are fourteen of them and they share one shape, so they are data rather than fourteen controllers and fourteen components.

Where a page lives

  • app/Support/MarketingLandingPages.php — the URL map. One entry per page: its meta title and description, the eyebrow shown above the heading, and an optional parent used to build the breadcrumb.
  • app/Support/MarketingLandingCopy.php — the body copy, split out purely so the URL map stays readable.
  • app/Http/Controllers/MarketingLandingController.php — one action for all of them.
  • The theme component for the landing page key. Harvest renders pages/marketing/landing.tsx; a theme that declares landing in its theme.json renders its own.

Section types

A page is a heading, a one-line lede, and a list of typed sections. Adding a page is a data edit. Adding a section type is a change in every theme's landing component, so prefer composing from what exists.

  • prose — a title and a list of paragraphs.
  • cards — a title, an optional description, and items of {title, description}.
  • bullets — a title, an optional description, and plain strings.
  • faq — items of {question, answer}. A page carrying one automatically emits FAQPage structured data, the same builder the home page uses.
  • cta — a title, an optional description, and one button.

Routing

All fourteen are served by a single wildcard route registered inside the localised marketing group, so each one gets its /nl/… twin, its .l route name, and the marketing-site kill switch without any per-page work.

The route's where constraint is a regex alternation of the exact registered paths, built by routePattern(). This matters: an unconstrained /{path} would happily answer /pricing and /privacy depending on registration order. With the constraint, an unregistered URL is a router 404 and the rest of the marketing site is untouchable. A test asserts exactly that.

The footer's Developers column points at /docs, which is a permanent redirect to /documentation rather than a second copy of this site.

Things that are wired for you

  • The sitemap. SeoController derives the entries from MarketingLandingPages::paths(), so a page added to the registry cannot be forgotten there.
  • Structured data. Every page emits BreadcrumbList from its parent chain, and FAQPage when it has an FAQ section.
  • Translation. Every string is collected by MarketingCopy, so it appears in the Translation Manager and can be localised without a deploy, exactly like the editable home and pricing copy.
  • White-labelling. Write {brand} in copy rather than a product name. The registry interpolates it before the text reaches the page, the meta tags or the structured data. A test fails if the token or the source product name ever reaches a rendered page.

Adding a page

  1. Add an entry to MarketingLandingPages::all() with a unique meta title, a description, an eyebrow, and a parent when it sits under a section.
  2. Add its copy to MarketingLandingCopy.
  3. Link it from the nav or footer. A link with an empty or # href is dropped by the footer renderer, so an unlinked page is an invisible page.
  4. Run the suite. The route list, the sitemap and the private-install guard are all derived, so nothing else needs editing.