Structure a new Email Component’s MJML, mark its EDIT and LOCKED boundary, and know when a Liquid citation belongs in one.
Writing a component starts with a decision. What may a future editor change, and what must stay fixed so the block works everywhere it is used? This article covers that decision, the MJML itself, and the one place Liquid belongs in a component.Prerequisites
Familiarity with the MJML tags mj-section, mj-column, mj-text, mj-button, and mj-image. If they are new to you, read How MJML works. For allGood’s EDIT and LOCKED convention, read Email components.
Access to a component library’s Workshop in allGood. This is where you write and save a component.
A component earns a place in the library when it does one nameable job, such as a hero, a footer, or a two-column offer row. Describe it in plain language so that someone choosing between it and a similar block on Overview picks correctly the first time. A component that covers three loosely related layouts is usually two or three components that have not been split yet.
Decide what is EDIT and what is LOCKED before you write markup
EDIT is anything a send genuinely varies: copy, links, colors, and padding. LOCKED is the element tree. That means which sections and columns exist, what is nested inside them, and their order. Decide this first. The markup and its documenting comment both follow from it.
2
Build the structure from MJML tags, not raw HTML
Use mj-section and mj-column for layout, mj-text for copy, mj-button for any call to action, and mj-image for images. Put real placeholder copy directly in the tags. Write a headline that reads like a headline and a button labeled like a button, not a note about what should go there:
<mj-section background-color="#1a1a1a"> <mj-column> <mj-text font-size="18px" color="#ffffff"> "Best decision we made this quarter." </mj-text> <mj-text font-size="14px" color="#999999"> — Placeholder Name, Placeholder Title </mj-text> </mj-column></mj-section>
3
Document the EDIT and LOCKED boundary in an ag: comment
Put the comment at the top of the file. Say what the component is for, then list what is editable and what is fixed:
<!-- ag: pull quote on a dark panel. One quote, one attribution line. EDIT: the quote text, the attribution line, background-color and the two text colors. LOCKED: the element tree. One section, one column, two text blocks in this order. Adding, removing or re-nesting an element is drift, and the validator flags it on every email built from this block. -->
A future editor, human or allGood’s AI, reads this comment before touching the component. A boundary that is not documented here does not exist for anyone else.The EDIT: and LOCKED: labels are not the only acceptable style. Plain-language guidance works if it is unambiguous. The library’s own hero block documents itself this way:
The hero block's MJML source, with its inline ag: comment describing what is safe to change.
4
Use Liquid only for values that must resolve at send time
An unsubscribe link, a postal address, and a copyright year come from the send itself, not from a person filling in a field. Cite them instead of typing placeholder copy:
Keep everything else as plain text, including headlines, button labels, and body copy. A component is not where per-send personalization happens. That belongs to a template’s copySchema, which sits on top once components are composed.
5
Preview and iterate in the Workshop
Open the component in the Workshop. Describe changes to Ask Mary in plain language. You can view a component’s MJML, but you can’t edit it by hand. Each save creates a new version. A version does not affect a live email until it is published, so iterating costs nothing.
6
Track the component through publishing
In the History tab, confirm your new version shows a Published entry. For History, rollback, and checking what a component is used by, see Setting up and reviewing email components.
The component is ready when it appears on Overview with an accurate description and preview, and its status shows the version you published.
The validator flags your component every time it is used. Something inside the LOCKED boundary changed. An element was added, removed, or re-nested. Revert the structural change, and limit your edit to what the ag: comment lists as EDIT.A Liquid token renders literally instead of resolving. allGood does not resolve that token at the component level. Use confirmed system values only, such as send.unsubscribeUrl, sender.postalAddress, or a "now" | date filter. Anything else belongs in plain text, or in a template’s copySchema if it needs to vary per send.If neither fix explains what you see, contact the team that maintains allGood’s email tooling. Include the component’s name and the version you are comparing against.
{"docsConfig":{"theme":"luma","$schema":"https://mintlify.com/docs.json","name":"allGood Docs","colors":{"primary":"#dc4393","light":"#ea7cb9","dark":"#b12563"},"logo":{"light":"https://mintcdn.com/allgoodtechnologyinc/QQ498qL6_aJdv7lm/logo/light.svg?fit=max\u0026auto=format\u0026n=QQ498qL6_aJdv7lm\u0026q=85\u0026s=0a6e25720e392678288f3d5e92580677","dark":"https://mintcdn.com/allgoodtechnologyinc/QQ498qL6_aJdv7lm/logo/dark.svg?fit=max\u0026auto=format\u0026n=QQ498qL6_aJdv7lm\u0026q=85\u0026s=d68d3e70bcb0adf89895e438a7dd3dd1"},"favicon":"https://mintcdn.com/allgoodtechnologyinc/QQ498qL6_aJdv7lm/favicon.svg?fit=max\u0026auto=format\u0026n=QQ498qL6_aJdv7lm\u0026q=85\u0026s=393be1889fc5f811dc575e9e7c4aa16f","background":{"decoration":"gradient"},"navbar":{"links":[{"href":"mailto:support@allgoodhq.com","label":"Support"}],"primary":{"type":"button","label":"App","href":"https://allgoodhq.app"}},"icons":{"library":"lucide"},"contextual":{"options":["copy","view","chatgpt","claude","mcp"],"display":"header"},"interaction":{"drilldown":true},"styling":{"latex":true},"navigation":{"global":{"anchors":[{"anchor":"Welcome","icon":"house","href":"/"},{"anchor":"Release Notes","icon":"list","href":"/release-notes"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"allgoodtechnologyinc","hasAudioNarration":false,"actualSubdomain":"allgoodtechnologyinc","customDomains":["docs.allgoodhq.com"],"gitSource":{"type":"github","owner":"allgoodhq","repo":"mint","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae89845ed2f58cb10ee7f21","collectionId":"ded4f481-a124-4f34-9b5d-99e441c864c1","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae89845ed2f58cb10ee7f21"},"feedback":{"thumbs":true,"agentFeedback":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6aee4936ccb0d32d838b1741","clientVersion":"0.0.4076","searchFilterCounts":[{"language":"default","tag":"allGood","count":127},{"language":"default","tag":"Use Cases","count":68},{"language":"default","tag":"Email Reply Management","count":65},{"language":"default","tag":"Error Codes","count":38},{"language":"default","tag":"Marketing Kernel","count":20},{"language":"default","tag":"Marketo","count":18},{"language":"default","tag":"Integrations","count":17},{"language":"default","tag":"Settings","count":16},{"language":"default","tag":"Email Builder","count":12},{"language":"default","tag":"HubSpot","count":11}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true,"deflection":{"enabled":true,"email":"support@allgoodhq.com","showHelpButton":true}},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":":root{--sidebar-width: 18rem}.frame{padding:0}.frame>.relative>*[data-as=\"p\"]{margin:0!important}div:has(>.frame){margin:0.5rem 0}.frame [data-component-part=\"frame-caption\"]{margin:0.5rem 0;margin-left:1rem;padding:0;text-align:left}"}],"page":{"pagePath":"mk/developer/email/how-to-write-email-components","slug":"/mk/developer/email/how-to-write-email-components","pageMetadata":{"title":"Write an email component","sidebarTitle":"Writing components","noindex":true,"description":"Structure a new Email Component's MJML, mark its EDIT and LOCKED boundary, and know when a Liquid citation belongs in one.","lifecycle":"activation","owner":"TBD","reviewed":"2026-10-27","href":"/mk/developer/email/how-to-write-email-components"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Structure a new Email Component’s MJML, mark its EDIT and LOCKED boundary, and know when a Liquid citation belongs in one.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Frame,Heading,OptimizedImage,Step,Steps}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Frame)_missingMdxReference(`Frame`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!OptimizedImage)_missingMdxReference(`OptimizedImage`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`Writing a component starts with a decision. What may a future editor change, and what must stay fixed so the block works everywhere it is used? This article covers that decision, the MJML itself, and the one place Liquid belongs in a component.`}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Prerequisites`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Familiarity with the MJML tags `,_jsx(_components.code,{children:`mj-section`}),`, `,_jsx(_components.code,{children:`mj-column`}),`, `,_jsx(_components.code,{children:`mj-text`}),`, `,_jsx(_components.code,{children:`mj-button`}),`, and `,_jsx(_components.code,{children:`mj-image`}),`. If they are new to you, read `,_jsx(_components.a,{href:`/mk/developer/email/how-mjml-works`,children:`How MJML works`}),`. For allGood’s EDIT and LOCKED convention, read `,_jsx(_components.a,{href:`/mk/content/email/components/index`,children:`Email components`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`Access to a component library’s `,_jsx(_components.strong,{children:`Workshop`}),` in allGood. This is where you write and save a component.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`what-makes-a-component-worth-adding`,children:`What makes a component worth adding`}),`\n`,_jsxs(_components.p,{children:[`A component earns a place in the library when it does one nameable job, such as a hero, a footer, or a two-column offer row. Describe it in plain language so that someone choosing between it and a similar block on `,_jsx(_components.strong,{children:`Overview`}),` picks correctly the first time. A component that covers three loosely related layouts is usually two or three components that have not been split yet.`]}),`\n`,_jsx(Heading,{level:`2`,id:`steps`,children:`Steps`}),`\n`,_jsxs(Steps,{children:[_jsx(Step,{id:`decide-edit-vs-locked`,title:`Decide what is EDIT and what is LOCKED before you write markup`,children:_jsx(_components.p,{children:`EDIT is anything a send genuinely varies: copy, links, colors, and padding. LOCKED is the element tree. That means which sections and columns exist, what is nested inside them, and their order. Decide this first. The markup and its documenting comment both follow from it.`})}),_jsxs(Step,{id:`build-the-structure`,title:`Build the structure from MJML tags, not raw HTML`,children:[_jsxs(_components.p,{children:[`Use `,_jsx(_components.code,{children:`mj-section`}),` and `,_jsx(_components.code,{children:`mj-column`}),` for layout, `,_jsx(_components.code,{children:`mj-text`}),` for copy, `,_jsx(_components.code,{children:`mj-button`}),` for any call to action, and `,_jsx(_components.code,{children:`mj-image`}),` for images. Put real placeholder copy directly in the tags. Write a headline that reads like a headline and a button labeled like a button, not a note about what should go there:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`10`,language:`xml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`xml`,children:_jsxs(_components.code,{language:`xml`,numberOfLines:`10`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-section`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` background-color`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"#1a1a1a\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-column`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-text`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` font-size`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"18px\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` color`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"#ffffff\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` \"Best decision we made this quarter.\"`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-text`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-text`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` font-size`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"14px\"`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` color`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"#999999\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` — Placeholder Name, Placeholder Title`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-text`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-column`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-section`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`]})})})]}),_jsxs(Step,{id:`document-the-boundary`,title:`Document the EDIT and LOCKED boundary in an ag: comment`,children:[_jsx(_components.p,{children:`Put the comment at the top of the file. Say what the component is for, then list what is editable and what is fixed:`}),_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`xml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`xml`,children:_jsxs(_components.code,{language:`xml`,numberOfLines:`8`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`\u003c!-- ag: pull quote on a dark panel. One quote, one attribution line.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` EDIT: the quote text, the attribution line, background-color and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` the two text colors.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` LOCKED: the element tree. One section, one column, two text`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` blocks in this order. Adding, removing or re-nesting an element`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` is drift, and the validator flags it on every email built from`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` this block. -->`})}),`\n`]})})}),_jsx(_components.p,{children:`A future editor, human or allGood’s AI, reads this comment before touching the component. A boundary that is not documented here does not exist for anyone else.`}),_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`EDIT:`}),` and `,_jsx(_components.code,{children:`LOCKED:`}),` labels are not the only acceptable style. Plain-language guidance works if it is unambiguous. The library’s own `,_jsx(_components.code,{children:`hero`}),` block documents itself this way:`]}),_jsx(Frame,{caption:`The hero block's MJML source, with its inline ag: comment describing what is safe to change.`,children:_jsx(OptimizedImage,{src:`https://mintcdn.com/allgoodtechnologyinc/vWyFubp1-YTCUXDt/images/mk/content/email/components/hero-mjml-source.png?fit=max\u0026auto=format\u0026n=vWyFubp1-YTCUXDt\u0026q=85\u0026s=12a4709412c9965192e75c9f1cb0c4ea`,alt:`The hero block's MJML source, with its inline ag: comment describing what is safe to change.`,\"data-og-width\":`776`,width:`776`,\"data-og-height\":`461`,height:`461`,\"data-path\":`images/mk/content/email/components/hero-mjml-source.png`,\"data-optimize\":`true`,\"data-opv\":`3`,srcset:`https://mintcdn.com/allgoodtechnologyinc/vWyFubp1-YTCUXDt/images/mk/content/email/components/hero-mjml-source.png?w=280\u0026fit=max\u0026auto=format\u0026n=vWyFubp1-YTCUXDt\u0026q=85\u0026s=c8d85dd6f2c7ff9b76beb15bb2933efb 280w, https://mintcdn.com/allgoodtechnologyinc/vWyFubp1-YTCUXDt/images/mk/content/email/components/hero-mjml-source.png?w=560\u0026fit=max\u0026auto=format\u0026n=vWyFubp1-YTCUXDt\u0026q=85\u0026s=6d88c424937e343d285424379cd37b33 560w, https://mintcdn.com/allgoodtechnologyinc/vWyFubp1-YTCUXDt/images/mk/content/email/components/hero-mjml-source.png?w=840\u0026fit=max\u0026auto=format\u0026n=vWyFubp1-YTCUXDt\u0026q=85\u0026s=0bf94ad72344604553cf43e5b945bd30 840w, https://mintcdn.com/allgoodtechnologyinc/vWyFubp1-YTCUXDt/images/mk/content/email/components/hero-mjml-source.png?w=1100\u0026fit=max\u0026auto=format\u0026n=vWyFubp1-YTCUXDt\u0026q=85\u0026s=01e79bd23781721a665d0a43e16459a6 1100w, https://mintcdn.com/allgoodtechnologyinc/vWyFubp1-YTCUXDt/images/mk/content/email/components/hero-mjml-source.png?w=1650\u0026fit=max\u0026auto=format\u0026n=vWyFubp1-YTCUXDt\u0026q=85\u0026s=3f3c2490d34e6037a968943ee46132f7 1650w, https://mintcdn.com/allgoodtechnologyinc/vWyFubp1-YTCUXDt/images/mk/content/email/components/hero-mjml-source.png?w=2500\u0026fit=max\u0026auto=format\u0026n=vWyFubp1-YTCUXDt\u0026q=85\u0026s=6c6c7b0cca922672434f01dae6a5d9cb 2500w`})})]}),_jsxs(Step,{id:`reserve-liquid-for-system-values`,title:`Use Liquid only for values that must resolve at send time`,children:[_jsx(_components.p,{children:`An unsubscribe link, a postal address, and a copyright year come from the send itself, not from a person filling in a field. Cite them instead of typing placeholder copy:`}),_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`xml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`xml`,children:_jsxs(_components.code,{language:`xml`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-text`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` font-size`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"12px\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {{ sender.postalAddress }} — {{ \"now\" | date: \"%Y\" }}`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-text`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-text`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` font-size`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"12px\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:` \u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`a`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` href`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"{{ send.unsubscribeUrl }}\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Unsubscribe`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`a`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c/`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mj-text`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`]})})}),_jsxs(_components.p,{children:[`Keep everything else as plain text, including headlines, button labels, and body copy. A component is not where per-send personalization happens. That belongs to a template’s `,_jsx(_components.code,{children:`copySchema`}),`, which sits on top once components are composed.`]})]}),_jsx(Step,{id:`preview-in-workshop`,title:`Preview and iterate in the Workshop`,children:_jsxs(_components.p,{children:[`Open the component in the `,_jsx(_components.strong,{children:`Workshop`}),`. Describe changes to `,_jsx(_components.strong,{children:`Ask Mary`}),` in plain language. You can view a component’s MJML, but you can’t edit it by hand. Each save creates a new version. A version does not affect a live email until it is published, so iterating costs nothing.`]})}),_jsx(Step,{id:`track-through-approval`,title:`Track the component through publishing`,children:_jsxs(_components.p,{children:[`In the `,_jsx(_components.strong,{children:`History`}),` tab, confirm your new version shows a `,_jsx(_components.strong,{children:`Published`}),` entry. For History, rollback, and checking what a component is used by, see `,_jsx(_components.a,{href:`/mk/content/email/components/setting-up-and-reviewing-email-components`,children:`Setting up and reviewing email components`}),`.`]})})]}),`\n`,_jsxs(_components.p,{children:[`The component is ready when it appears on `,_jsx(_components.strong,{children:`Overview`}),` with an accurate description and preview, and its status shows the version you published.`]}),`\n`,_jsx(Heading,{level:`2`,id:`if-something-is-not-working`,children:`If something is not working`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`The validator flags your component every time it is used.`}),` Something inside the LOCKED boundary changed. An element was added, removed, or re-nested. Revert the structural change, and limit your edit to what the `,_jsx(_components.code,{children:`ag:`}),` comment lists as EDIT.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`A Liquid token renders literally instead of resolving.`}),` allGood does not resolve that token at the component level. Use confirmed system values only, such as `,_jsx(_components.code,{children:`send.unsubscribeUrl`}),`, `,_jsx(_components.code,{children:`sender.postalAddress`}),`, or a `,_jsx(_components.code,{children:`\"now\" | date`}),` filter. Anything else belongs in plain text, or in a template’s `,_jsx(_components.code,{children:`copySchema`}),` if it needs to vary per send.`]}),`\n`,_jsx(_components.p,{children:`If neither fix explains what you see, contact the team that maintains allGood’s email tooling. Include the component’s name and the version you are comparing against.`}),`\n`,_jsx(Heading,{level:`2`,id:`related-articles`,children:`Related articles`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/mk/content/email/components/index`,children:`Email components`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/mk/developer/email/how-mjml-works`,children:`How MJML works`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/mk/content/email/components/setting-up-and-reviewing-email-components`,children:`Setting up and reviewing email components`})}),`\n`,_jsx(_components.li,{children:_jsx(_components.a,{href:`/mk/developer/email/compare-mjml-with-other-tools`,children:`Compare MJML with other email tools`})}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Write an email component","sidebarTitle":"Writing components","noindex":true,"description":"Structure a new Email Component's MJML, mark its EDIT and LOCKED boundary, and know when a Liquid citation belongs in one.","lifecycle":"activation","owner":"TBD","reviewed":"2026-10-27","href":"/mk/developer/email/how-to-write-email-components"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"What makes a component worth adding","slug":"what-makes-a-component-worth-adding","depth":2,"children":[]},{"title":"Steps","slug":"steps","depth":2,"children":[]},{"title":"If something is not working","slug":"if-something-is-not-working","depth":2,"children":[]},{"title":"Related articles","slug":"related-articles","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"allgoodtechnologyinc","siteName":"allGood Docs","title":"Write an email component - allGood Docs","relatedPagesConfig":{"enabled":false,"limit":5,"mode":"automatic"},"navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-02T14:04:04.052Z","originalFileLocation":"mk/developer/email/how-to-write-email-components.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Structure a new Email Component\u0026#x27;s MJML, mark its EDIT and LOCKED boundary, and know when a Liquid citation belongs in one.\">\u003cmeta data-mint-head name=\"application-name\" content=\"allGood Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003cmeta data-mint-head name=\"robots\" content=\"noindex\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/allgoodtechnologyinc/_ALjgld6m1uJaRhW/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/allgoodtechnologyinc/_ALjgld6m1uJaRhW/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/allgoodtechnologyinc/_ALjgld6m1uJaRhW/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/allgoodtechnologyinc/_ALjgld6m1uJaRhW/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/allgoodtechnologyinc/_ALjgld6m1uJaRhW/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/allgoodtechnologyinc/_ALjgld6m1uJaRhW/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/allgoodtechnologyinc/_ALjgld6m1uJaRhW/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/allgoodtechnologyinc/_ALjgld6m1uJaRhW/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/allgoodtechnologyinc/_ALjgld6m1uJaRhW/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Write an email component - allGood Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Structure a new Email Component\u0026#x27;s MJML, mark its EDIT and LOCKED boundary, and know when a Liquid citation belongs in one.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"allGood Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.allgoodhq.com/mk/developer/email/how-to-write-email-components\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://allgoodtechnologyinc.mintlify.site/_mintlify/api/og/v2?division=Email+components+for+developers\u0026amp;title=Write+an+email+component\u0026amp;description=Structure+a+new+Email+Component%27s+MJML%2C+mark+its+EDIT+and+LOCKED+boundary%2C+and+know+when+a+Liquid+citation+belongs+in+one.\u0026amp;theme=1dffc1444f7b7db60f57189e\u0026amp;signature=4b4f17912c8781db25d45fb9cf3a729e4e8b578ab1ec8b8eaf144bab15cbb7f5\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Write an email component - allGood Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Structure a new Email Component\u0026#x27;s MJML, mark its EDIT and LOCKED boundary, and know when a Liquid citation belongs in one.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://allgoodtechnologyinc.mintlify.site/_mintlify/api/og/v2?division=Email+components+for+developers\u0026amp;title=Write+an+email+component\u0026amp;description=Structure+a+new+Email+Component%27s+MJML%2C+mark+its+EDIT+and+LOCKED+boundary%2C+and+know+when+a+Liquid+citation+belongs+in+one.\u0026amp;theme=1dffc1444f7b7db60f57189e\u0026amp;signature=4b4f17912c8781db25d45fb9cf3a729e4e8b578ab1ec8b8eaf144bab15cbb7f5\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/allgoodtechnologyinc/_ALjgld6m1uJaRhW/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"allGood Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#dc4393\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.allgoodhq.com/mk/developer/email/how-to-write-email-components\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/mk/developer/email/how-to-write-email-components.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"allGood Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"allGood Docs","nav":{"global":{"anchors":[{"anchor":"Welcome","icon":"house","href":"/"},{"anchor":"Release Notes","icon":"list","href":"/release-notes"}]},"tabs":[{"tab":"allGood","icon":"book-open","pages":[{"title":"allGood","href":"/use-cases/email-builder"}]},{"tab":"Marketing Kernel","icon":"layers","groups":[{"group":"Marketing Kernel","pages":[{"title":"Marketing Kernel","sidebarTitle":"Overview","href":"/mk"},{"group":"Content","pages":[{"title":"Content","sidebarTitle":"Overview","href":"/mk/content/index"},{"title":"Getting started with Content","sidebarTitle":"Getting Started","href":"/mk/content/getting-started"},{"group":"Set up once","pages":[{"title":"Brand guidelines","sidebarTitle":"Brand Guidelines","href":"/mk/content/brand-guidelines"},{"title":"Component libraries","sidebarTitle":"Component Libraries","href":"/mk/content/component-libraries"},{"title":"Templates","sidebarTitle":"Templates","href":"/mk/content/templates"}]},{"group":"Visual assets","pages":[{"title":"Visual assets","sidebarTitle":"Overview","href":"/mk/content/visual-assets/index"},{"title":"Using an image in an email or page","sidebarTitle":"In an email or page","href":"/mk/content/visual-assets/using-an-image-in-an-email-or-page"},{"title":"Using an image you host elsewhere","sidebarTitle":"Images hosted elsewhere","href":"/mk/content/visual-assets/images-hosted-elsewhere"},{"title":"Visual assets FAQ","sidebarTitle":"FAQ","href":"/mk/content/visual-assets/faq"}]},{"title":"Hosted files","sidebarTitle":"Hosted Files","href":"/mk/content/hosted-files"},{"group":"Landing pages","pages":[{"title":"Landing pages","sidebarTitle":"Overview","href":"/mk/content/landing-pages/index"},{"title":"What a landing page is","sidebarTitle":"What a landing page is","href":"/mk/content/landing-pages/what-a-landing-page-is"},{"title":"Creating a landing page","sidebarTitle":"Creating a landing page","href":"/mk/content/landing-pages/creating-a-landing-page"},{"title":"Making a page from a template","sidebarTitle":"From a template","href":"/mk/content/landing-pages/making-a-page-from-a-template"},{"title":"Page components","sidebarTitle":"Page Components","href":"/mk/content/landing-pages/page-components"},{"title":"Editing a landing page's code","sidebarTitle":"Editing the code","href":"/mk/content/landing-pages/editing-the-code"},{"title":"Previewing a landing page","sidebarTitle":"Previewing","href":"/mk/content/landing-pages/previewing-a-landing-page"},{"title":"Checks before a page goes live","sidebarTitle":"Checks before publishing","href":"/mk/content/landing-pages/checks-before-publishing"},{"title":"Publishing a landing page","sidebarTitle":"Publishing and taking down","href":"/mk/content/landing-pages/publishing-a-landing-page"},{"title":"Showing different versions of a page","sidebarTitle":"Different versions","href":"/mk/content/landing-pages/testing-versions-of-a-page"},{"title":"Using a page you host elsewhere","sidebarTitle":"External pages","href":"/mk/content/landing-pages/using-an-external-page"},{"title":"Coming from Marketo or HubSpot: landing pages","sidebarTitle":"Coming from Marketo/HubSpot","href":"/mk/content/landing-pages/coming-from-marketo-hubspot"},{"title":"Landing page not showing or not saving?","sidebarTitle":"Troubleshooting","href":"/mk/content/landing-pages/troubleshooting"},{"title":"Landing pages FAQ","sidebarTitle":"FAQ","href":"/mk/content/landing-pages/faq"}]},{"group":"Email","pages":[{"title":"Email","sidebarTitle":"Overview","href":"/mk/content/email/index"},{"group":"Components","pages":[{"title":"Email components","sidebarTitle":"Overview","href":"/mk/content/email/components/index"},{"title":"Editing an email component","sidebarTitle":"Editing a component","href":"/mk/content/email/components/editing-an-email-component"},{"title":"Setting up and reviewing email components in allGood","sidebarTitle":"Setting up and reviewing","href":"/mk/content/email/components/setting-up-and-reviewing-email-components"},{"title":"What MJML is","sidebarTitle":"What MJML is","href":"/mk/content/email/components/what-mjml-is"}]},{"group":"Email templates","pages":[{"title":"Email templates","sidebarTitle":"Overview","href":"/mk/content/email/templates/index"},{"title":"What an email template is","sidebarTitle":"What a template is","href":"/mk/content/email/templates/what-an-email-template-is"},{"title":"Creating an email template","sidebarTitle":"Creating a template","href":"/mk/content/email/templates/creating-an-email-template"},{"title":"Decide what writers fill in","sidebarTitle":"What writers fill in","href":"/mk/content/email/templates/writing-the-copy-schema"},{"title":"Changing an email template","sidebarTitle":"Changing a template","href":"/mk/content/email/templates/changing-an-email-template"}]},{"group":"Emails","pages":[{"title":"Emails","sidebarTitle":"Overview","href":"/mk/content/email/emails/index"},{"title":"What an email is","sidebarTitle":"What an email is","href":"/mk/content/email/emails/what-an-email-is"},{"title":"Creating an email","sidebarTitle":"Creating an email","href":"/mk/content/email/emails/creating-an-email"},{"title":"Previewing and testing an email","sidebarTitle":"Previewing and testing","href":"/mk/content/email/emails/previewing-and-testing-an-email"},{"title":"Editing an email's code","sidebarTitle":"Editing the code","href":"/mk/content/email/emails/editing-the-code"},{"title":"Personalizing an email","sidebarTitle":"Personalizing","href":"/mk/content/email/emails/personalizing-an-email"},{"title":"Merge field reference","sidebarTitle":"Merge field reference","href":"/mk/content/email/emails/merge-field-reference"},{"title":"Show content conditionally and repeat a list","sidebarTitle":"Conditional content","href":"/mk/content/email/emails/conditional-content-and-lists"},{"title":"Liquid recipes for emails","sidebarTitle":"Liquid recipes","href":"/mk/content/email/emails/liquid-recipes"},{"title":"Before an email can send","sidebarTitle":"Before it can send","href":"/mk/content/email/emails/before-an-email-can-send"},{"title":"How unsubscribes work","sidebarTitle":"How unsubscribes work","href":"/mk/content/email/emails/how-unsubscribes-work"},{"title":"Email not sending or rendering wrong?","sidebarTitle":"Troubleshooting","href":"/mk/content/email/emails/troubleshooting"}]},{"title":"Email FAQ","sidebarTitle":"FAQ","href":"/mk/content/email/faq"},{"title":"Coming from Marketo or HubSpot: email","sidebarTitle":"Coming from Marketo or HubSpot","href":"/mk/content/email/coming-from-marketo-hubspot"}]},{"group":"Forms","pages":[{"title":"Forms","sidebarTitle":"Overview","href":"/mk/content/forms/index"},{"title":"What a form is","sidebarTitle":"What a form is","href":"/mk/content/forms/what-a-form-is"},{"title":"Creating a form","sidebarTitle":"Creating a form","href":"/mk/content/forms/creating-a-form"},{"title":"Testing a form","sidebarTitle":"Testing a form","href":"/mk/content/forms/testing-a-form"},{"title":"Adding a form to a page","sidebarTitle":"Adding a form to a page","href":"/mk/content/forms/adding-a-form-to-a-page"},{"title":"What protects a form","sidebarTitle":"What protects a form","href":"/mk/content/forms/what-protects-a-form"},{"title":"See how a form is performing","sidebarTitle":"Seeing performance","href":"/mk/content/forms/seeing-form-performance"},{"title":"Find where a form is used","sidebarTitle":"Finding where it's used","href":"/mk/content/forms/finding-where-a-form-is-used"},{"title":"Form not capturing submissions?","sidebarTitle":"Troubleshooting","href":"/mk/content/forms/troubleshooting"},{"title":"Forms FAQ","sidebarTitle":"FAQ","href":"/mk/content/forms/faq"},{"title":"Coming from Marketo or HubSpot: forms","sidebarTitle":"Coming from Marketo/HubSpot","href":"/mk/content/forms/coming-from-marketo-hubspot"}]},{"title":"Copy and variants","sidebarTitle":"Copy and Variants","href":"/mk/content/copy-and-variants"},{"title":"Publishing and versions","sidebarTitle":"Publishing and Versions","href":"/mk/content/approvals"},{"title":"Marketo to MK","icon":"arrow-right-left","href":"/mk/content/marketo-to-mk"}]},{"group":"Data Platform","pages":[{"title":"MK Data Platform","sidebarTitle":"Overview","href":"/mk/data/index"},{"title":"Data Sharing","sidebarTitle":"Data Sharing","href":"/mk/data/sharing"},{"title":"Data Architecture","href":"/mk/data/architecture"},{"title":"Orchestration","sidebarTitle":"Orchestration","href":"/mk/data/orchestration"}]},{"group":"Formulas","pages":[{"title":"Formulas in MK","sidebarTitle":"Overview","href":"/mk/formulas/index"},{"title":"What formulas are and when to use one","sidebarTitle":"What formulas are","href":"/mk/formulas/what-formulas-are"},{"title":"How formulas find your data","sidebarTitle":"How formulas find your data","href":"/mk/formulas/how-formulas-find-your-data"},{"title":"Filter a list with a formula","sidebarTitle":"Filter a list","href":"/mk/formulas/filter-a-list"},{"title":"Add a calculated column to a list","sidebarTitle":"Add a calculated column","href":"/mk/formulas/add-a-calculated-column"},{"title":"Handle blank and messy values in formulas","sidebarTitle":"Handle blank values","href":"/mk/formulas/handle-blank-values"},{"title":"Formula recipes","sidebarTitle":"Recipes","href":"/mk/formulas/recipes"},{"title":"Where you can use formulas in MK","sidebarTitle":"Where you can use formulas","href":"/mk/formulas/where-you-can-use-formulas"},{"title":"Formula reference: functions and operators","sidebarTitle":"Reference","href":"/mk/formulas/reference"},{"title":"Formula gives a blank, wrong, or error result","sidebarTitle":"Formula not working","href":"/mk/formulas/not-working"},{"title":"Formulas FAQ","sidebarTitle":"FAQ","href":"/mk/formulas/faq"},{"title":"Coming from Marketo: formulas in MK","sidebarTitle":"Coming from Marketo","href":"/mk/formulas/coming-from-marketo"}]},{"group":"Motions","pages":[{"title":"Motions","sidebarTitle":"Overview","href":"/mk/motions/index"},{"title":"Motion types","sidebarTitle":"Motion Types","href":"/mk/motions/motion-types"},{"title":"Gated content","sidebarTitle":"Gated Content","href":"/mk/motions/gated-content"},{"title":"Webinars","sidebarTitle":"Webinars","href":"/mk/motions/webinars"},{"title":"Launching a motion","sidebarTitle":"Launching","href":"/mk/motions/launching"}]},{"group":"Web Edge for developers","pages":[{"title":"Add Web Edge to your website","sidebarTitle":"Overview","href":"/mk/developer/web-edge/index"},{"group":"Add it to your website","pages":[{"title":"Create a form","sidebarTitle":"Create a Form","href":"/mk/developer/web-edge/create-a-form"},{"title":"Install the tag","sidebarTitle":"Install the Tag","href":"/mk/developer/web-edge/install-the-tag"},{"title":"Install with Google Tag Manager","sidebarTitle":"Install with GTM","href":"/mk/developer/web-edge/install-with-gtm"},{"title":"Capture a form","sidebarTitle":"Capture a Form","href":"/mk/developer/web-edge/capture-a-form"},{"title":"Identify and track","sidebarTitle":"Identify and Track","href":"/mk/developer/web-edge/identify-and-track"},{"title":"Track custom events on your website","sidebarTitle":"Track Custom Events","href":"/mk/developer/web-edge/track-custom-events"},{"title":"What consent gates","sidebarTitle":"Consent Behavior","href":"/mk/developer/web-edge/consent-behavior"},{"title":"A complete example page","sidebarTitle":"Worked Example","href":"/mk/developer/web-edge/worked-example"},{"title":"Test your setup","sidebarTitle":"Test Your Setup","href":"/mk/developer/web-edge/test-your-setup"},{"title":"Troubleshooting","sidebarTitle":"Troubleshooting","href":"/mk/developer/web-edge/troubleshooting"},{"title":"Coming from Marketo: Web Edge for developers","sidebarTitle":"Coming from Marketo","href":"/mk/developer/web-edge/from-marketo"}]},{"group":"Reference","pages":[{"title":"Form capture API","sidebarTitle":"Form Capture API","href":"/mk/developer/web-edge/reference/form-api"},{"title":"Event capture API","sidebarTitle":"Event Capture API","href":"/mk/developer/web-edge/reference/event-api"},{"title":"Endpoint reference","sidebarTitle":"Endpoints","href":"/mk/developer/web-edge/reference/endpoints"},{"title":"Reason codes","sidebarTitle":"Reason Codes","href":"/mk/developer/web-edge/reference/reason-codes"},{"title":"Settings reference","sidebarTitle":"Settings","href":"/mk/developer/web-edge/reference/settings"},{"title":"Glossary","sidebarTitle":"Glossary","href":"/mk/developer/web-edge/reference/glossary"}]}]}]},{"group":"Platform","pages":[{"group":"Integrations","pages":[{"title":"The Integrations screen","sidebarTitle":"Overview","href":"/mk/integrations/index"},{"title":"Add your Anthropic API key","sidebarTitle":"Anthropic","href":"/mk/integrations/anthropic"},{"title":"How allGood connects with your other marketing tools","href":"/mk/integrations/how-allgood-connects"},{"title":"Understanding incoming and outgoing webhooks","href":"/mk/integrations/webhooks"}]},{"group":"Email components for developers","pages":[{"title":"How MJML works","sidebarTitle":"How MJML works","description":"What MJML is, why email HTML needs a compiler, and how allGood turns MJML tags into Outlook-safe markup.","href":"/mk/developer/email/how-mjml-works"},{"title":"Write an email component","sidebarTitle":"Writing components","href":"/mk/developer/email/how-to-write-email-components"},{"title":"Compare MJML with other email tools","sidebarTitle":"Compare MJML with other tools","description":"How allGood's MJML components and copy schema map to Marketo templates, HubSpot modules, and hand-coded email HTML.","href":"/mk/developer/email/compare-mjml-with-other-tools"},{"title":"Move your Marketo unsubscribes to allGood","sidebarTitle":"Move Marketo unsubscribes","href":"/mk/developer/email/move-your-marketo-unsubscribes"}]},{"group":"Landing pages for developers","pages":[{"title":"Write a landing page by hand","sidebarTitle":"Write a page by hand","href":"/mk/developer/landing-pages/write-a-landing-page"},{"title":"Retire your Marketo landing page subdomain","sidebarTitle":"Retire Marketo landing pages","href":"/mk/developer/landing-pages/retire-marketo-landing-pages"}]},{"group":"API and Webhooks","pages":[{"title":"API and Webhooks","sidebarTitle":"Overview","href":"/mk/developer/api/index"}]}]},{"group":"Enterprise","pages":[{"title":"Enterprise","sidebarTitle":"Overview","href":"/mk/enterprise/index"},{"title":"MCP usage","sidebarTitle":"MCP Usage","href":"/mk/enterprise/mcp-usage"},{"title":"Data privacy","sidebarTitle":"Data Privacy","href":"/mk/enterprise/data-privacy"}]},{"group":"Settings","pages":[{"group":"Web Edge","pages":[{"title":"Web Edge","sidebarTitle":"Overview","href":"/mk/settings/web-edge/index"},{"title":"How Web Edge keeps your domain secure","sidebarTitle":"How it works","href":"/mk/settings/web-edge/how-it-works"},{"title":"Connect a subdomain","sidebarTitle":"Connect a subdomain","href":"/mk/settings/web-edge/connect-a-subdomain"},{"title":"Set your allowed origins","sidebarTitle":"Allowed origins","href":"/mk/settings/web-edge/allowed-origins"},{"title":"Connect your consent platform","sidebarTitle":"Consent provider","href":"/mk/settings/web-edge/consent-provider"},{"title":"Set up Web Tracking","sidebarTitle":"Web Tracking","href":"/mk/settings/web-edge/tracking-setup"},{"title":"Turn on bot protection for a form","sidebarTitle":"Bot protection","href":"/mk/settings/web-edge/bot-protection"},{"title":"Review your form processing settings","sidebarTitle":"Form processing","href":"/mk/settings/web-edge/form-processing"},{"title":"Manage your landing page settings","sidebarTitle":"Landing page settings","href":"/mk/settings/web-edge/landing-page-settings"},{"title":"Saved vs live at the edge","sidebarTitle":"Saved vs live","href":"/mk/settings/web-edge/edge-sync"},{"title":"Web Edge setup checklist","sidebarTitle":"Setup checklist","href":"/mk/settings/web-edge/setup-checklist"},{"title":"Coming from Marketo: Web Edge for admins","sidebarTitle":"Coming from Marketo","href":"/mk/settings/web-edge/coming-from-marketo"},{"title":"Web Edge FAQ","sidebarTitle":"FAQ","href":"/mk/settings/web-edge/faq"}]},{"group":"Email","pages":[{"title":"Set up an email domain","href":"/mk/settings/email/domains-setup"},{"title":"Web Edge domain vs. email domain","href":"/mk/settings/email/domains-vs-web-edge"},{"title":"Authenticate your sending domain: SPF, DKIM, DMARC, BIMI, and VMC","href":"/mk/settings/email/authentication"},{"title":"Your sending IP: shared pool or dedicated","href":"/mk/settings/email/sending-ip"},{"title":"Set up your Subscription Center","sidebarTitle":"Subscription Center","href":"/mk/settings/email/subscription-center"},{"title":"Email Frequently Asked Questions","href":"/mk/settings/email/faq"}]}]}]}]},"basePath":"","title":"Write an email component - allGood Docs","buildId":"dpl_8LJbrAiZvr1K98WQNZXCyY5AvT34","deploymentId":"dpl_8LJbrAiZvr1K98WQNZXCyY5AvT34","dynamics":["07c022d89b","a74be98ba7"],"chunks":["Frame-NdetNziF.js","DynamicMarkdown-CD8713Yy.js","zoom-image-lightbox-DMoL6lHz.js","lightbox-handle-r17bVUz3.js"]}