Developers

SEO marking

Mark page SEO fields with data-macro-seo, identify the page with data-macro-page, and let editors manage title, OG, canonical, and robots in the overlay.

Page-scoped SEO
SEO values are stored as content nodes such as page.contact.seo.title. Locale lives in Macrocontent’s i18n layer — not inside the key — same as body content.

Page identity

Macrocontent needs a stable page slug to scope SEO keys. Resolution order:

  1. data-macro-page on <html>

    Preferred. Use a decoded slug; nested paths are fine (blog/2026/post).

    html
    <html lang="en" data-macro-page="contact">
  2. resolvePageSlug in config

    Optional function when the URL shape does not match your content model.

    macro.config.jsjavascript
    export const macroConfig = {
      // ...
      resolvePageSlug: (pathname) => {
        if (pathname.startsWith('/blog/')) return pathname.slice(1).replace(/\.html$/, '')
        return pathname.replace(/^\/|\.html$/g, '') || 'home'
      },
    }
  3. URL heuristic

    Fallback: /contact.html → contact, / → home.

Slugs that contain / are encoded in keys: blog/2026/macro-seo → page.blog__2026__macro-seo.seo.title.

Head markup

Mark each SEO field with data-macro-seo. Fallback text/attributes ship in HTML and are overwritten when Macrocontent has a value. Unmarked developer tags are never touched.

Bridge + Overlay tabs
Overlay SEO uses Search (classic + Twitter) and Structured (JSON-LD). Macro is only a bridge — developers can hardcode the same tags. Without marks, the SDK may managed-inject Macro-owned nodes (data-macro-managed) when values exist; it will not overwrite unmarked developer HTML.
contact.htmlhtml
<html lang="en" data-macro-page="contact">
  <head>
    <title data-macro-seo="title">Contact — Example</title>
    <meta
      name="description"
      data-macro-seo="description"
      content="Default description"
    />
    <meta property="og:title" data-macro-seo="ogTitle" content="Contact — Example" />
    <meta
      property="og:description"
      data-macro-seo="ogDescription"
      content="Default OG description"
    />
    <meta
      property="og:image"
      data-macro-seo="ogImage"
      content="https://example.com/og.jpg"
    />
    <link
      rel="canonical"
      data-macro-seo="canonical"
      href="https://example.com/contact.html"
    />
    <meta name="robots" data-macro-seo="robots" content="index,follow" />
    <meta name="twitter:card" data-macro-seo="twitterCard" content="summary" />
    <meta name="twitter:title" data-macro-seo="twitterTitle" content="Contact — Example" />
    <meta
      name="twitter:description"
      data-macro-seo="twitterDescription"
      content="Default Twitter description"
    />
    <script type="application/ld+json" data-macro-seo="jsonLd">
      {"@context":"https://schema.org","@type":"WebPage","name":"Contact"}
    </script>
  </head>
  <body>
    <!-- page body -->
  </body>
</html>

Injection contract

NameTypeDescription
title<title>Written to textContent
description<meta>Written to content
ogTitle<meta>property="og:title" → content
ogDescription<meta>property="og:description" → content
ogImage<meta>property="og:image" → content (absolute https URL)
canonical<link>rel="canonical" → href
robots<meta>name="robots" → content
twitterTitle<meta>name="twitter:title" → content
twitterDescription<meta>name="twitter:description" → content
twitterCard<meta>name="twitter:card" → summary | summary_large_image
jsonLd<script>type="application/ld+json" → textContent (JSON object/array)
  • ogImage must resolve to an absolute https:// URL in production HTML.
  • Empty canonical in Macrocontent → the HTML fallback is left alone.
  • robots values: index,follow · noindex,follow · index,nofollow · noindex,nofollow.
  • twitterCard: summary or summary_large_image.
  • jsonLd: valid JSON object/array → <script type="application/ld+json">.

Runtime vs build

At runtime the SDK hydrates SEO (including managed inject) from GET /content/seo with the public key. For crawler-ready HTML at first byte, use Prerender (or Bake for offline exit).

Related