[{"data":1,"prerenderedAt":75},["ShallowReactive",2],{"help-article-connect-strapi":3},{"data":4},{"title":5,"excerpt":6,"content":7,"help_category":8,"seo":11},"Connect Strapi (CMS)","Connect your Strapi instance to m18t: generate an API token, set the Base URL, map content types to collections, and allow m18t through CORS so pushes land","\u003Cp>\u003Cstrong>What you&#39;ll learn\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Where Strapi fits in m18t — and why m18t pushes \u003Cem>to\u003C\u002Fem> a CMS rather than hosting your site.\u003C\u002Fli>\n\u003Cli>How to generate a Strapi API token and wire it into m18t.\u003C\u002Fli>\n\u003Cli>How to map an m18t content type to a Strapi collection.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Chr>\n\u003Ch2>Why Strapi\u003C\u002Fh2>\n\u003Cp>m18t is an operations workspace, not a website host. It doesn&#39;t render pages for your visitors. When you draft a blog post or web page in the \u003Ca href=\"\u002Fhelp\u002Fthe-unified-content-table\">content workspace\u003C\u002Fa>, it eventually needs to land in a headless CMS that serves your site. Strapi is that CMS.\u003C\u002Fp>\n\u003Cp>Strapi is the CMS m18t supports natively today — self-hosted or Strapi Cloud both work. Other vendors (WordPress, Sanity, Contentful, Payload) are on the roadmap, not available yet; if you&#39;re not on Strapi, this is the one to know about.\u003C\u002Fp>\n\u003Cp>It&#39;s \u003Ca href=\"\u002Fhelp\u002Fbyok-why-we-do-this\">BYOK\u003C\u002Fa>: you point m18t at \u003Cem>your\u003C\u002Fem> Strapi instance with \u003Cem>your\u003C\u002Fem> API token.\u003C\u002Fp>\n\u003Ch2>Step 1 — Generate a Strapi API token\u003C\u002Fh2>\n\u003Cp>In your own Strapi admin (the interface changes across Strapi versions, so follow the intent):\u003C\u002Fp>\n\u003Col>\n\u003Cli>Open \u003Cstrong>Settings → API Tokens\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003Cli>Create a new token. Set the duration to unlimited so it doesn&#39;t expire on you.\u003C\u002Fli>\n\u003Cli>For type, \u003Cstrong>Full access\u003C\u002Fstrong> is simplest. A custom-scoped token also works, but it must allow create, update, and publish on every collection you&#39;ll push to — otherwise publishes fail with a permissions error.\u003C\u002Fli>\n\u003Cli>Copy the token. Strapi shows it once.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2>Step 2 — Wire it into m18t\u003C\u002Fh2>\n\u003Col>\n\u003Cli>Go to \u003Cstrong>Business Settings → Connections\u003C\u002Fstrong> (\u003Ccode>\u002Fstudio\u002Fbusiness\u002Fconnections\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>Click \u003Cstrong>Add Connection\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Pick a brand\u003C\u002Fstrong> — connections are per brand. Choose the brand this CMS belongs to. (One Strapi for several brands? See \u003Ca href=\"\u002Fhelp\u002Fper-brand-integrations\">Per-Brand Integrations\u003C\u002Fa>.)\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Pick a provider\u003C\u002Fstrong> — under CMS, choose \u003Cstrong>Strapi CMS\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003Cli>On the setup step, set the \u003Cstrong>Environment\u003C\u002Fstrong> (Production\u002FDevelopment\u002FLocal — this is how you run Strapi-prod and Strapi-staging side by side), confirm the \u003Cstrong>Label\u003C\u002Fstrong>, and set the \u003Cstrong>Base URL\u003C\u002Fstrong> to your Strapi instance, e.g. \u003Ccode>https:\u002F\u002Fcms.yourdomain.com\u003C\u002Fcode>. Don&#39;t add a trailing slash.\u003C\u002Fli>\n\u003Cli>On the \u003Cstrong>Authentication\u003C\u002Fstrong> step, choose \u003Cstrong>+ Add new vault key\u003C\u002Fstrong>. The wizard suggests \u003Ccode>CMS_PROD_API_TOKEN\u003C\u002Fcode>; paste your token. It&#39;s encrypted in the \u003Ca href=\"\u002Fhelp\u002Fthe-secret-vault\">Vault\u003C\u002Fa> before storage.\u003C\u002Fli>\n\u003Cli>Continue to \u003Cstrong>Outlets\u003C\u002Fstrong> (Step 3 below), then \u003Cstrong>Create connection\u003C\u002Fstrong>.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2>Step 3 — Map a content type to a Strapi collection\u003C\u002Fh2>\n\u003Cp>Because m18t lets you \u003Ca href=\"\u002Fhelp\u002Fregistering-a-custom-content-type\">define custom content types\u003C\u002Fa>, it needs to know which Strapi collection each one targets. You configure this on the \u003Cstrong>Outlets\u003C\u002Fstrong> step of the wizard:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Give the outlet an \u003Cstrong>Outlet label\u003C\u002Fstrong> (e.g. &quot;Acme Production CMS&quot;).\u003C\u002Fli>\n\u003Cli>Set the \u003Cstrong>Content type slug\u003C\u002Fstrong> — the Strapi collection this outlet routes to (e.g. \u003Ccode>blog\u003C\u002Fcode> or \u003Ccode>web-page\u003C\u002Fcode>). The publisher uses the connection&#39;s \u003Ccode>type_map\u003C\u002Fcode> config to route m18t content types to the right Strapi endpoint.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>So when you push a blog post, m18t sends the payload to the matching collection on your Strapi instance.\u003C\u002Fp>\n\u003Ch2>Step 4 — Allow m18t through Strapi&#39;s CORS\u003C\u002Fh2>\n\u003Cp>Strapi blocks unknown origins by default. Add your m18t Studio origin to your Strapi instance&#39;s CORS configuration, or every push will fail before it reaches the API. This is configured on \u003Cem>your\u003C\u002Fem> Strapi server, not in m18t.\u003C\u002Fp>\n\u003Ch2>FAQ\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Pushes fail with a 403 \u002F permissions error.\u003C\u002Fstrong>\nYour token is missing create\u002Fupdate\u002Fpublish rights on the target collection. Use a Full access token, or widen the custom token&#39;s scope, then rotate the value on the \u003Ca href=\"\u002Fhelp\u002Fthe-secret-vault\">Vault\u003C\u002Fa> tab.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Pushes fail with a CORS or origin error.\u003C\u002Fstrong>\nStrapi is rejecting the m18t origin. Add it to your Strapi CORS allowlist (Step 4).\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Content lands in the wrong collection — or nowhere.\u003C\u002Fstrong>\nThe \u003Cstrong>Content type slug\u003C\u002Fstrong> on the outlet doesn&#39;t match a real Strapi collection, or the type isn&#39;t mapped. Edit the outlet\u002Fconnection so the slug matches the Strapi endpoint exactly.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Can I connect both production and staging Strapi?\u003C\u002Fstrong>\nYes. Create two Strapi connections for the brand with different \u003Cstrong>Environment\u003C\u002Fstrong> values. The credential tuple is per (brand, service, environment), so they coexist.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Does m18t support WordPress \u002F Sanity \u002F Contentful?\u003C\u002Fstrong>\nNot yet — Strapi is the only native CMS today. Others are on the roadmap.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>What&#39;s next\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>What gets pushed (and how SEO\u002Fi18n travel with it): \u003Ca href=\"\u002Fhelp\u002Fpushing-to-your-cms\">Pushing to Your CMS\u003C\u002Fa>.\u003C\u002Fli>\n\u003Cli>Define the types you&#39;ll push: \u003Ca href=\"\u002Fhelp\u002Fregistering-a-custom-content-type\">Registering a Custom Content Type\u003C\u002Fa>.\u003C\u002Fli>\n\u003Cli>Credential storage and brand mapping: \u003Ca href=\"\u002Fhelp\u002Fthe-secret-vault\">The Secret Vault\u003C\u002Fa> · \u003Ca href=\"\u002Fhelp\u002Fper-brand-integrations\">Per-Brand Integrations\u003C\u002Fa>.\u003C\u002Fli>\n\u003C\u002Ful>\n",{"slug":9,"title":10},"connections-and-keys","Connections & API Keys",{"meta_title":12,"meta_description":6,"keywords":13,"canonical_url":14,"og_title":5,"og_description":15,"og_image":16,"robots":17,"json_ld":18},"Connect Strapi (CMS) | m18t Help","connect strapi, strapi api token, headless cms, content type mapping, strapi cors, push to cms, m18t strapi","https:\u002F\u002Fm18t.com\u002Fhelp\u002Fconnect-strapi","Generate a Strapi token, set the Base URL, map content types to collections, and clear CORS so pushes land.","https:\u002F\u002Fm18t.com\u002Fog-default.png","index, follow",{"@context":19,"@graph":20},"https:\u002F\u002Fschema.org",[21,34,59],{"@type":22,"headline":5,"description":6,"articleSection":10,"inLanguage":23,"datePublished":24,"dateModified":24,"image":16,"author":25,"publisher":29,"mainEntityOfPage":32},"Article","en","2026-06-25",{"@type":26,"name":27,"url":28},"Organization","m18t","https:\u002F\u002Fm18t.com",{"@type":26,"name":27,"url":28,"logo":30},{"@type":31,"url":16},"ImageObject",{"@type":33,"@id":14},"WebPage",{"@type":35,"mainEntity":36},"FAQPage",[37,43,47,51,55],{"@type":38,"name":39,"acceptedAnswer":40},"Question","Pushes fail with a 403 \u002F permissions error.",{"@type":41,"text":42},"Answer","Your token is missing create\u002Fupdate\u002Fpublish rights on the target collection. Use a Full access token, or widen the custom token's scope, then rotate the value on the Vault tab.",{"@type":38,"name":44,"acceptedAnswer":45},"Pushes fail with a CORS or origin error.",{"@type":41,"text":46},"Strapi is rejecting the m18t origin. Add it to your Strapi CORS allowlist (Step 4).",{"@type":38,"name":48,"acceptedAnswer":49},"Content lands in the wrong collection — or nowhere.",{"@type":41,"text":50},"The Content type slug on the outlet doesn't match a real Strapi collection, or the type isn't mapped. Edit the outlet\u002Fconnection so the slug matches the Strapi endpoint exactly.",{"@type":38,"name":52,"acceptedAnswer":53},"Can I connect both production and staging Strapi?",{"@type":41,"text":54},"Yes. Create two Strapi connections for the brand with different Environment values. The credential tuple is per (brand, service, environment), so they coexist.",{"@type":38,"name":56,"acceptedAnswer":57},"Does m18t support WordPress \u002F Sanity \u002F Contentful?",{"@type":41,"text":58},"Not yet — Strapi is the only native CMS today. Others are on the roadmap.",{"@type":60,"itemListElement":61},"BreadcrumbList",[62,66,70,73],{"@type":63,"position":64,"name":65,"item":28},"ListItem",1,"Home",{"@type":63,"position":67,"name":68,"item":69},2,"Help","https:\u002F\u002Fm18t.com\u002Fhelp",{"@type":63,"position":71,"name":10,"item":72},3,"https:\u002F\u002Fm18t.com\u002Fhelp\u002Fcategories\u002Fconnections-and-keys",{"@type":63,"position":74,"name":5,"item":14},4,1786312169475]