Skip to content

Theme

A theme is a set of brand values — colours, logo URL, social-link URLs, and font styles — that applyTheme() stamps onto an RCML document in a single call. The result is a predictable set of default-attribute nodes and named rc-class entries written into rc-head.

Without a theme, every brand colour, font setting, and social link URL would need to be set on individual elements scattered across every template. Changing a primary colour would mean finding every button in every template and updating it. A theme collects brand values into a single object. applyTheme() writes those values into rc-head as default-attribute nodes and named classes — elements then inherit those values automatically.

The mechanism works in two ways. Default-attribute nodes inside rc-attributes act like CSS property defaults: an rc-button node with background-color: "#05CC87" makes every button in the document inherit that colour unless it overrides it explicitly. Named classes (rcml-brand-color, rcml-p-style, etc.) require elements to opt in via their rc-class attribute, which gives more targeted control over which elements use the branded typography or accent colour.

What rc-head looks like after applyTheme()

After calling applyTheme(doc, theme), rc-head always contains these nodes in this fixed order:

rc-head
  ├── rc-brand-style                       ← always first
  ├── rc-attributes                        ← always second
  │    ├── rc-body                         ← background color (background slot)
  │    ├── rc-section                      ← body color (body slot)
  │    ├── rc-button                       ← primary color (primary slot)
  │    ├── rc-class "rcml-brand-color"     ← secondary color
  │    ├── rc-class "rcml-logo-style"      ← logo URL (only if a logo is set)
  │    ├── rc-class "rcml-p-style"         ┐
  │    ├── rc-class "rcml-h1-style"        │
  │    ├── rc-class "rcml-h2-style"        │ font-style slots
  │    ├── rc-class "rcml-h3-style"        │
  │    ├── rc-class "rcml-h4-style"        │
  │    ├── rc-class "rcml-label-style"     ┘
  │    └── rc-social                       ← social link URLs (6 children, always present)
  └── rc-font ...                          ← one per web font (absent if no custom fonts)

Here is a complete annotated example of the resulting rc-head:

jsonc
{
  "tagName": "rc-head",
  "children": [

    // ─── ① Brand style reference — always first ────────────────────────────
    {
      "tagName": "rc-brand-style",
      "attributes": { "brand-style-id": 10457 }
    },

    // ─── ② rc-attributes — always second ───────────────────────────────────
    {
      "tagName": "rc-attributes",
      "children": [

        // Color: background slot → default background-color for every rc-body
        { "tagName": "rc-body",    "attributes": { "background-color": "#F3F3F3" } },

        // Color: body slot → default background-color for every rc-section
        { "tagName": "rc-section", "attributes": { "background-color": "#FFFFFF" } },

        // Color: primary slot → default background-color for every rc-button
        { "tagName": "rc-button",  "attributes": { "background-color": "#05CC87" } },

        // Color: secondary slot — apply manually with rc-class="rcml-brand-color"
        { "tagName": "rc-class", "attributes": { "name": "rcml-brand-color", "background-color": "#F6F8F9" } },

        // Image: logo slot — also patches src onto body rc-logo elements (see below)
        { "tagName": "rc-class", "attributes": { "name": "rcml-logo-style", "src": "https://cdn.example.com/logo.png" } },

        // Font style: p slot
        {
          "tagName": "rc-class",
          "attributes": {
            "name": "rcml-p-style",
            "font-family": "'Helvetica', sans-serif",
            "font-size": "16px", "color": "#0F0F1F", "line-height": "120%",
            "letter-spacing": "0em", "font-style": "normal", "font-weight": "400", "text-decoration": "none"
          }
        },

        // Font style: h1 slot
        {
          "tagName": "rc-class",
          "attributes": {
            "name": "rcml-h1-style",
            "font-family": "'Helvetica', sans-serif",
            "font-size": "36px", "color": "#0F0F1F", "line-height": "120%",
            "letter-spacing": "0em", "font-style": "normal", "font-weight": "700", "text-decoration": "none"
          }
        },

        // Font style: h2 slot
        {
          "tagName": "rc-class",
          "attributes": {
            "name": "rcml-h2-style",
            "font-family": "'Helvetica', sans-serif",
            "font-size": "28px", "color": "#0F0F1F", "line-height": "120%",
            "letter-spacing": "0em", "font-style": "normal", "font-weight": "700", "text-decoration": "none"
          }
        },

        // Font style: h3 slot
        {
          "tagName": "rc-class",
          "attributes": {
            "name": "rcml-h3-style",
            "font-family": "'Helvetica', sans-serif",
            "font-size": "24px", "color": "#0F0F1F", "line-height": "120%",
            "letter-spacing": "0em", "font-style": "normal", "font-weight": "700", "text-decoration": "none"
          }
        },

        // Font style: h4 slot
        {
          "tagName": "rc-class",
          "attributes": {
            "name": "rcml-h4-style",
            "font-family": "'Helvetica', sans-serif",
            "font-size": "18px", "color": "#0F0F1F", "line-height": "120%",
            "letter-spacing": "0em", "font-style": "normal", "font-weight": "700", "text-decoration": "none"
          }
        },

        // Font style: label slot (note: default color is #FFFFFF, not #0F0F1F)
        {
          "tagName": "rc-class",
          "attributes": {
            "name": "rcml-label-style",
            "font-family": "'Helvetica', sans-serif",
            "font-size": "14px", "color": "#FFFFFF", "line-height": "120%",
            "letter-spacing": "0em", "font-style": "normal", "font-weight": "400", "text-decoration": "none"
          }
        },

        // Social links — always exactly 6 children, one per network slot
        {
          "tagName": "rc-social",
          "children": [
            { "tagName": "rc-social-element", "attributes": { "name": "facebook",  "href": "https://facebook.com/yourbrand" } },
            { "tagName": "rc-social-element", "attributes": { "name": "instagram", "href": "https://instagram.com/yourbrand" } },
            { "tagName": "rc-social-element", "attributes": { "name": "linkedin",  "href": "https://linkedin.com/company/yourbrand" } },
            { "tagName": "rc-social-element", "attributes": { "name": "tiktok",    "href": "https://tiktok.com/@yourbrand" } },
            { "tagName": "rc-social-element", "attributes": { "name": "x",         "href": "https://x.com/yourbrand" } },
            { "tagName": "rc-social-element", "attributes": { "name": "website",   "href": "https://example.com" } }
          ]
        }
      ]
    },

    // ─── ③ Web font declarations — one per font, after rc-attributes ────────
    // Absent when no custom fonts are included in the theme.
    {
      "tagName": "rc-font",
      "attributes": { "name": "'Lato'", "href": "https://fonts.googleapis.com/css2?family=Lato" }
    }

  ]
}

Logo propagation into the body

applyTheme() also walks the body and patches src onto every rc-logo whose rc-class is "rcml-logo-style" or "rc-initial-logo". If width is not already set, it adds "width": "96px" as a default. Logos without one of these class names are left unchanged.

Slot-to-node reference

Theme slotNode path in the output
brandStyleIdrc-head > rc-brand-style > attributes.brand-style-id
Color backgroundrc-head > rc-attributes > rc-body > attributes.background-color
Color bodyrc-head > rc-attributes > rc-section > attributes.background-color
Color primaryrc-head > rc-attributes > rc-button > attributes.background-color
Color secondaryrc-head > rc-attributes > rc-class[name="rcml-brand-color"] > attributes.background-color
Image logorc-head > rc-attributes > rc-class[name="rcml-logo-style"] > attributes.src + body rc-logo
Font style prc-head > rc-attributes > rc-class[name="rcml-p-style"]
Font style h1h4rc-head > rc-attributes > rc-class[name="rcml-{h1..h4}-style"]
Font style labelrc-head > rc-attributes > rc-class[name="rcml-label-style"]
Social linksrc-head > rc-attributes > rc-social > rc-social-element children
Custom fontsrc-head > rc-font (direct children, after rc-attributes)

API

Three functions form the theme API:

FunctionPurpose
createEmailTheme(overrides?)Build a fresh EmailTheme from defaults plus optional overrides.
applyTheme(doc, theme)Write theme values into a document's rc-head; returns a new document (input not mutated).
getTheme(doc)Extract the current EmailTheme from a document's rc-head.

See the API reference pages for full parameter details and default values.