Create Accountor Login
Docs

Custom Sections

Part of the MountDev Ops Websites documentation. Updated November 13, 2026

MountDev Ops Websites documentation | Updated November 13, 2026

Our Commitment

MountDev Ops is built security first. Your business data belongs to you, and you can export all of it at any time. We never use analytics or tracking of any kind inside MountDev Ops.

A Custom Section is a section of a page that holds your own HTML and your own CSS. It is drawn as you wrote it, inside the page, with your theme's colors and fonts available to its styles. It is the same for every account, and it is how a website you built by hand can come into Websites looking exactly as it does today.

Every update passes all 3,859 automated checks before it ships, and every screen change is walked through before release.

What It Is

A Custom Section has a name (the label you see in the builder), its HTML, its CSS, and its text fields. Add one from Add Section, Custom Section. Nothing about it is special to any account: every website can use it.

Text Fields

Put {{headline}} in the HTML wherever a piece of copy goes, and the section gets a text field named headline. Change the text in the field and the page shows it, without touching the HTML. This is where you or an AI agent edit the words.

  • A field name starts with a lowercase letter and uses lowercase letters, numbers, and underscores, up to 40 characters, like hero_title or plan_2_price.
  • A field holds plain text up to 5,000 characters, and a section can hold up to 80 fields.
  • The text is shown as typed. A less-than sign or an ampersand is shown as itself, never as markup.
  • A name with no field draws as empty.
  • A link can be a field too: href="{{cta_url}}" works when the field holds a link to a page on your website, an anchor, an https address, an email, or a phone number. Anything else becomes a plain #.

What Is Allowed

The HTML is cleaned when you save, with an allow list.

  • Tags: a, abbr, article, aside, b, blockquote, br, caption, cite, code, dd, details, div, dl, dt, em, figcaption, figure, footer, h1 to h6, header, hr, i, img, input (radio and checkbox only), label, li, main, nav, ol, output, p, picture, pre, q, section, small, span, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, time (with a datetime), tr, u, and ul, plus the drawing tags under Inline Drawings.
  • Attributes: class, id, lang, title, role, aria-anything, data-anything (except the builder's own names, and the data-mdo names listed under Interactive Pieces), alt, width, height, loading, for, name, type, checked, open, colspan, rowspan, scope, and href and src as below.
  • Links (href) go to a page on your website like /contact, an anchor like #plans, an https address, an email (mailto:), or a phone number (tel:).
  • Pictures (src) come only from your own website, an address that starts with a slash such as a picture from your Files. A picture from another website is not allowed.
  • Tabs and toggles without script: a radio or checkbox input with a label and your CSS makes tabs, accordions, and switches that need no script.
  • CSS can use selectors, media and container queries, @supports, @layer, keyframes, custom properties, and @font-face with a font from your own website. Fixed positions are fine.

Your CSS is scoped to its section: every rule only reaches inside the section, and :root, html, and body in it mean the section itself. Ids you use for tabs and anchors are renamed per section, so the same section can be used twice on a page without clashing.

Inline Drawings

A drawing (svg) can sit in a section, for a logo or icons. It keeps its shapes and drops anything that could reach outside it.

  • Shapes and structure: svg, g, path, circle, ellipse, rect, line, polyline, polygon, title, desc, linearGradient, radialGradient, stop, defs, clipPath, and mask. A drawing inside a drawing is not allowed.
  • Settings: viewBox, width, height, fill, stroke, stroke-width, stroke-linecap, stroke-linejoin, transform, opacity, fill-rule, clip-rule, d, points, positions and sizes, class, id, role, aria-label, aria-hidden, focusable, and the gradient settings. Each value is checked: numbers are numbers, a path is drawing commands, and a color is a name, a hex code, rgb or hsl, or var(--name) from your theme.
  • Gradients and clips: fill="url(#id)", stroke="url(#id)", clip-path, and mask work only when the id is inside the same drawing.
  • Words inside a drawing are kept only in its title and description.
  • Ids in a drawing are renamed per section, together with what points at them, like the other ids.

What Is Removed, and Why

When you save, what was removed is listed with a plain reason. Nothing else is changed.

  • Scripts (the script tag and every event handler such as onclick): scripts cannot run in a page. Use the built-in menu or form script, or the Interactive Pieces below, for anything interactive.
  • Frames, objects, embeds, math, video, and audio players: they load other websites or can carry script. Use the Video section, or a picture from your Files.
  • Parts of a drawing that reach outside it (use, image, foreignObject, style, script, animation, links, and any address or reference to another file): the rest of the drawing stays. See Inline Drawings.
  • Forms, text fields, and selects: they send data elsewhere. Use the Form section, which sends to your own Forms.
  • Buttons are kept only when written as type="button" (see Interactive Pieces), with only class, id, title, aria attributes, and the interactive attributes. Any other button is removed and its text stays.
  • data-mdo names other than the nine listed under Interactive Pieces, and a listed one with a value that is not allowed.
  • Style tags, link tags, meta tags, and base tags: put the styling in the CSS tab or the theme stylesheet.
  • Inline style attributes: put the styling in the CSS tab.
  • Links that run script (javascript: and data: addresses) and outside pictures.
  • Unknown tags: the tag goes and its text stays.
  • In CSS: @import, any file that is not on your own website (a picture, a font, or an address in url()), expression(), behaviors and bindings, and rules inside rules.
  • Comments are dropped. Tags left open are closed. A stray less-than sign in text is shown as text.

Cleaning runs every time a section is saved, whether a person or an AI agent saves it, and again every time a page is drawn.

Interactive Pieces

A custom section can have four small interactive pieces with no script of its own: a theme choice, a menu button, a show and hide control, and a switcher. You only add attributes; the website's own first-party script (/_mdo/menu.js, the same for every website) does the rest. A page loads it only when a section, or the website's custom header or footer, uses one of these attributes. It sends and reads nothing, uses no cookies, and does no tracking. The only thing it remembers is a visitor's own theme choice, in their own browser, under one fixed name, and it never leaves the browser. Without the script the page still shows, and the pieces simply do nothing.

Every piece needs a real button, written as <button type="button">. The attributes below are the only data-mdo- names allowed. Any other data-mdo- name, or a value that does not fit, is removed when you save, with a reason. Names (ids and groups) start with a lowercase letter and use lowercase letters, numbers, dashes, and underscores, up to 40 characters. Values use lowercase letters, numbers, dashes, and underscores, 1 to 40 characters.

Theme Choice

data-mdo-theme="system", "light", or "dark" on a button. A click sets data-theme on the page (system removes it) and remembers the choice, which is applied on the visitor's next visit. The active button gets aria-pressed="true". Put the dark colors in the theme stylesheet, for example html[data-theme="dark"]{--bg:#0f1c2e}, because a section's own CSS is scoped to the section and cannot see the page's data-theme; colors set on the page reach every section as variables. Without a saved choice the visitor's device setting applies, as long as your CSS uses prefers-color-scheme.

<button type="button" data-mdo-theme="system">System</button>
<button type="button" data-mdo-theme="light">Light</button>
<button type="button" data-mdo-theme="dark">Dark</button>

data-mdo-menu-button on a button and data-mdo-menu-panel on the panel it opens. A click sets data-mdo-open="true" on the panel and aria-expanded on the button; another click, the Esc key, a click outside, or a click on a link inside the panel closes it. Point the button at its panel with aria-controls="<the panel's id>"; without it, the first panel in the same section is used. Show the open state with CSS: [data-mdo-menu-panel]{display:none} and [data-mdo-menu-panel][data-mdo-open]{display:block}.

<button type="button" aria-controls="menu" aria-expanded="false" data-mdo-menu-button>Menu</button>
<div id="menu" data-mdo-menu-panel><a href="/pricing/">Pricing</a></div>

Show and Hide

data-mdo-toggle="<id>" on a button. A click adds or removes the class is-open on the element with that id and sets aria-expanded on the button; Esc closes it. The id is renamed per section together with the element's own id, so the same section can be used twice. Style it with .more.is-open{display:block}.

<button type="button" aria-expanded="false" data-mdo-toggle="more">More</button>
<div id="more">The rest of the answer.</div>

Switcher and Before and After

data-mdo-group="<group>" on a container, and buttons inside it with data-mdo-switch="<group>" and data-mdo-value="<value>". A click sets data-mdo-state="<value>" on the nearest container for that group and marks the active button with aria-pressed="true". Give the container a starting data-mdo-state. Your CSS reacts to the state, for example [data-mdo-state="after"] .before{display:none}. A brand switcher is one group with a value for each sample agency, where each agency's color, name, and initial are drawn and shown by state ([data-mdo-state="pine"] .name-harbor{display:none}); a before and after toggle is a group with the values before and after. Groups do not affect each other, so a page can have several.

<div data-mdo-group="speed" data-mdo-state="after">
  <button type="button" data-mdo-switch="speed" data-mdo-value="before">Before</button>
  <button type="button" data-mdo-switch="speed" data-mdo-value="after">After</button>
  <p class="before">4.2 s</p><p class="after">1.1 s</p>
</div>

The Attribute List

AttributeOnAllowed value
data-mdo-themebuttonsystem, light, or dark
data-mdo-menu-buttonbuttonnone
data-mdo-menu-panelany elementnone
data-mdo-openthe panel (set by the script)none or true
data-mdo-togglebuttonthe id of the element to open
data-mdo-switchbuttona group name
data-mdo-valuebuttonthe value to set
data-mdo-groupcontainera group name
data-mdo-statecontainer (set by the script)the current value

Page Titles and Page Width

  • A page or doc whose Custom Section holds its own h1 shows no automatic title, so there is never a second one. A page with no h1 in a Custom Section keeps its title. A post always keeps its title.
  • A page made only of Custom Sections has no wrapper of its own: its sections run edge to edge, and your CSS sets any width and padding. A page with any other kind of section keeps the usual page width.

The Theme Stylesheet

A theme can also hold a Stylesheet for the whole website, cleaned the same way and not scoped. See Themes. A section's CSS and the stylesheet can use these names from the theme: var(--bg), var(--ink), var(--muted), var(--card), var(--line), var(--accent), var(--accent-ink), var(--radius), and var(--font).

Screens Hidden by Size

A Custom Section can be hidden on desktop, tablet, or phone like any section. Its spacing, alignment, and background settings do not apply: it is drawn exactly as you wrote it.

Preview, Build, and Publish

The builder canvas, the preview, the built website, and the live website all draw a Custom Section with the same drawing, so what you see is what a visitor sees. Existing websites with no Custom Section and no stylesheet are drawn exactly as before.

AI Agents

An AI agent connected to your workspace can read a Custom Section, change its text fields, HTML, or CSS, add one, move one, and remove one, with the page and section tools. It is held to the same cleaning and the same permission as a person, and what it saves is a draft: nothing reaches visitors until a person publishes. Changing only a field's text is the safest way for an agent to edit copy.

Limits

HTML up to 60,000 characters and CSS up to 60,000 characters per section, and a theme stylesheet up to 100,000 characters. Over the limit, the save is refused with a plain message and nothing is stored.

Ask Us Anything

We’d love to hear from you!