Designer API: How to create inline links and formatting within Paragraph/Text Block elements?

I need to programmatically create a paragraph with inline links and formatting, like:

<p>Text with <a href="#">link</a> and <strong>bold</strong> inside</p>

The UI allows this, but via the API I can only find setText() on StringElement - no methods for:

  • Text selection/ranges

  • Inserting inline elements mid-text

  • Splitting text to add formatting

Trying para.append(webflow.elementPresets.TextLink) fails with “Elements cannot be added to Paragraph elements.”

Is there a way to achieve inline formatting programmatically, or is this not yet exposed in the Designer API?

I haven’t tested this in the Designer API, but the Webflow Expert GPT had some promising suggestions so I’ll share the response here.

Summary

Right now, Paragraph/Text Block inline formatting (ranges, inline elements mid-text, split/merge) is not exposed in the Designer API — those inline parts you can create in the UI (nested Text Link / Bold) aren’t currently constructible via the Paragraph element API.

What you can do today

  1. Treat this as a current Designer API limitation

    1. In the Designer API, an element can only accept children if its metadata supports it (element.children === true). The API docs show that String elements are text-only and children: false, and you’ve already hit the same constraint on Paragraph.append(...). (Webflow Developers)

    2. The only officially documented text operation for text content is overwriting via setText() / setTextContent() — no selection/range or inline insertion APIs exist in the docs. (Webflow Developers)

  2. Use a Custom Element (DOM Element) as the workaround for “inline HTML”
    If your goal is programmatically produce semantic-ish markup with inline children, build it using DOM Elements, because they can have children and you can set their tag + text. (Webflow Developers)

    • Create a DOM Element and set its tag to p

    • Append DOM Element children for a, strong, and (optionally) span wrappers for the plain text runs

    • Set text on those children via setTextContent

    • Set href on the a via setAttribute

    Example (Designer Extension JS-ish pseudocode):

    const parent = await webflow.getSelectedElement();
    
    // 1) Create <p> as a DOM Element
    const p = await parent.append(webflow.elementPresets.DOMElement);
    await p.setHTMLTag("p");
    
    // 2) "Text with "
    const t1 = await p.append(webflow.elementPresets.DOMElement);
    await t1.setHTMLTag("span");
    await t1.setTextContent("Text with ");
    
    // 3) <a href="#">link</a>
    const a = await p.append(webflow.elementPresets.DOMElement);
    await a.setHTMLTag("a");
    await a.setAttribute("href", "#");
    await a.setTextContent("link");
    
    // 4) " and "
    const t2 = await p.append(webflow.elementPresets.DOMElement);
    await t2.setHTMLTag("span");
    await t2.setTextContent(" and ");
    
    // 5) <strong>bold</strong>
    const strong = await p.append(webflow.elementPresets.DOMElement);
    await strong.setHTMLTag("strong");
    await strong.setTextContent("bold");
    
    // 6) " inside"
    const t3 = await p.append(webflow.elementPresets.DOMElement);
    await t3.setHTMLTag("span");
    await t3.setTextContent(" inside");
    
    

    Notes:

    • This will output extra spans for the text runs (since you can’t create raw text nodes directly).

    • Webflow will strip invalid child structures inside Custom Elements, so keep the HTML valid. (Webflow Help Center)

  3. Alternative: use Rich text content if the source is CMS
    If the “inline formatting” comes from content (e.g., CMS rich text), the usual approach is: store rich content in a Rich text field and render with a Rich text element (since it’s designed for mixed inline markup). (Webflow Help Center)
    This doesn’t solve “build arbitrary inline markup inside a Paragraph via Designer API,” but it often solves the actual product need (formatted text coming from data).

Further reading (official)

If you tell me whether your target output must be clean <p>Text <a>…</a> <strong>…</strong></p> with no extra spans, I can suggest the least-bad structure given the current API constraints.

Thank you for your time and help. I was aware of webflow.elementPresets.DOM (aka Custom Elements). But… selecting part of a headline as a span to change its color, adding a link inside a paragraph, italics or bold inside a text block, highlighting part of a <p> with a different background via a span — all of this is pretty basic, and basically necessary stuff, right? That’s why I was hoping there might be some undocumented way to make it work with native text elements.

Hey, do you know if the AI-IDE + WF MCP + WF Bridge app runs through the Designer API? That is — does it have the same functional limitations as the API?

It’s a bit more specialized than standard operations- basic element hierarchy, style management, variables, because it conceptually involves splitting and merging element hierarchies. But in general yeah. The designer API is still maturing but ideally it works in concert with the designers themselves and will eventually be able to work efficiently with the same constructions they do.

There’s a very good chance that I don’t know some tricks here.

@zachplata do you have any insights on this?

To my knowledge, yes- the MCP uses the Data API and Designer API, and has precisely the same limits.

Hey @marekroszko - there isn’t a way to do this today via Designer APIs, but definitely something we’ll look at as we try to get it to parity with what you can do in Webflow. I’ll raise this with our teams!

Also Michael above already answered, but I can confirm the MCP server uses our current set of Designer APIs so will also be limited there, at least for now.