Skip to main content
Wildo.ai Coming soon

Marketing site and brand

Describe the product in machine-readable terms

Sections can publish structured descriptions of products, offers and other content alongside the visible page. A shared catalogue defines the supported entity contracts, while the application supplies its own factual values.

An authored product card and price card become small structured entity cards carrying same facts

Describe the product in machine-readable terms

Sections can publish structured descriptions of products, offers and other content alongside the visible page. A shared catalogue defines the supported entity contracts, while the application supplies its own factual values.

Example — One pricing story for people and tools

A pricing section describes the product and its offers in readable copy and structured data. Both should reflect the same accepted commercial facts.

For engineers

A section definition can return one payload, several, or no structured data through getStructuredData. It receives its page: the locale, the page’s URL in that locale, and label(slot), the section’s own words. A question section therefore publishes the questions it shows, in the language the page is in. The route passes that context, and the payloads that belong to the whole page beside it:

const structuredDataHtml = renderPageStructuredData({
  sections: PRICING_SECTIONS,
  context: runtime.structuredData,
  pagePayloads,
});

renderPageStructuredData is exported by @wildo-ai/saas-website/astro, and runtime is what loadWebsitePageRuntime returns for the request. The application injects the output into the page head. The renderer supplies the vocabulary when absent, deduplicates entities by identifier and escapes output for its script context. A word a section asks for that the language has no translation for stops the render: structured data never publishes a raw key.

Emit both ends of the relationship

Wonder Todos’ pricing page publishes the application it sells beside the company that publishes it, and the offers that name that application. The application, from page-structured-data.ts:

{
  '@type': 'SoftwareApplication',
  '@id': SCHEMA_ORG_IDS.softwareApplication,
  name: 'Wonder Todos',
  applicationCategory: 'BusinessApplication',
  operatingSystem: 'Web',
  url: MARKETING_SITE_URL,
  description: word(input.labelPack, 'website.chrome.footer.tagline'),
  publisher: { '@id': SCHEMA_ORG_IDS.organization },
}

Its offers come from buildWebsitePricingOfferStructuredData, which reads the billing catalogue the application sells from and names SCHEMA_ORG_IDS.softwareApplication as each offer’s itemOffered. It publishes only plans on sale at a listed price, so no price on the page is typed by hand. Every @id the page references is defined on the same page; emitting the offers without the application would leave a relationship without its target, which the structured-data audit reports.

Keep entity relationships explicit

Wonder Todos links its offers to the application, and the application to its publisher, through the same @id on every page that names them. The catalogue supplies supported types and field expectations. An application that declares no catalogue is checked against the engine’s; one that declares its own may override an engine entry’s field expectations for a type the catalogue already names, and the audit reports each override. Adding a new type is a framework change. Neither the catalogue nor the renderer invents truthful prices, reviews or availability. Derive values from the page’s factual source, keep related entity IDs consistent, and run the structured-data audit before accepting a change.

Building a B2B product or an internal tool?

Wildo is not self-service yet. Tell us what you have in mind and we will say plainly whether it fits, and what happens next.