32 "summary": "POST /promote/seo/v1/seo-patterns/{pageType} fails with 409 PATTERN_ALREADY_EXISTS when the site already has its own pattern for that page type, and PATCH on the same path fails with 404 PATTERN_NOT_FOUND when it does not. `source` on the object says which is the case (the site's own pattern versus the Wix default). Read first, then branch; do not retry the other verb blindly."
33 },
34 {
35 "code": "variables-are-per-page-type",
36 "severity": "blocker",
37 "summary": "A pattern may reference only the variables its page type offers ({{product.name}} style, double braces). Anything else fails with INVALID_PATTERN, whose message lists the permitted variables. Call List SEO Pattern Variables (GET /promote/seo/v1/seo-patterns/{pageType}/variables) for the page type before translating a source template; a WordPress template variable such as %%title%% %%sep%% %%sitename%% (Yoast) or %title% %sep% %sitename% (Rank Math) has no automatic equivalent and must be mapped variable by variable, with anything unmappable resolved to a literal or ledgered."
38 },
39 {
40 "code": "page-type-availability-is-per-site",
41 "severity": "warning",
42 "summary": "UNSUPPORTED_PAGE_TYPE (400) means Wix does not recognise the page type at all; PAGE_TYPE_NOT_ON_SITE (404) means it is valid but the business solution providing it is not installed. These are different problems - the second is a setup ordering bug (install the app first), not a mapping gap. Only WIX_DATA_PAGE_ITEM supports a per-page pattern via pageId; passing pageId for any other type fails with PAGE_ID_NOT_SUPPORTED, and passing collectionName fails with COLLECTION_NAME_NOT_SUPPORTED."
43 },
44 {
45 "code": "pattern-write-is-blast-radius",
46 "severity": "warning",
47 "summary": "A pattern applies to EVERY item of its page type that has no override, so one bad write changes the title of every product or post on the site at once, with no revision check to stop a concurrent dashboard edit. `defaultPattern` is always returned so a reset target is known - record it before writing."
52 "summary": "A tag whose `disabled` or `custom` value is itself a variable is returned with that value UNSET (they are booleans), even though the behaviour still applies at render time. A read-modify-write round trip therefore silently drops such a variable; re-send the intended value rather than echoing what was read."
57 "summary": "a robots tag in a pattern de-indexes every item of the page type. ensureSeoPattern strips it into `exclusions` (pattern-robots-not-written) and the builders refuse it; a robots tag already in the site's pattern is kept unchanged."
58 },
59 {
60 "code": "needs-an-html-web-site",
61 "severity": "blocker",
62 "summary": "[LIVE 2026-10-27] The SEO services need a site with an HtmlWeb (editor) instance. On a site created by Create Project (type WIX, no template), every SEO surface failed with no typed error: Get/Create SEO Pattern returned an HTML 400, Set Site SEO Tags an HTML 500, Get Item SEO Tags an HTML 428, and Bulk Set returned per-entry BULK_ENTRY_FAILED 'FAILED_PRECONDITION ... Missing HtmlWeb instance in MetaSite'. The same calls succeeded on a site created from the blank Editor template. Headless sites are NEEDS-VERIFICATION. The executors surface these as unknown-outcome errors or failed entries; treat them as a site precondition, not a mapping gap."
63 }
64 ],
65 "mappingGuidance": [
66 "Writer : ensureSeoPattern(wix, { pageType, tags }). Reads the pattern, checks every {{variable}} against List SEO Pattern Variables (an unknown one returns `invalid-variable` and writes nothing for that page type), merges the source tags over the site's own pattern or, when there is none, the Wix default, then creates or sets and reads back. a site-owned pattern is overwritten for the tag identities the source brings; the old pattern is returned as `previousSitePattern` and `defaultPattern` is always returned, so either can be restored. PAGE_TYPE_NOT_ON_SITE returns `setup-missing-app`. WIX_DATA_PAGE_ITEM patterns have no writer.",
67 "Dependencies: no other modeled record must exist first; page types are site configuration, while a dynamic-page ID is only needed for the optional unmodeled dynamic-page case.",
68 "This is where a WordPress SEO plugin's per-post-type TITLE and META DESCRIPTION TEMPLATES belong - Yoast's Settings > Content Types templates (wpseo_titles option) and Rank Math's equivalent. Migrating those as patterns reproduces the source's SEO conventions in one write per page type instead of one write per item, which is exactly the split the Wix SEO introduction asks for.",
69 "The source side is the hard half: those templates live in wp_options, which WordPress REST does not expose, so they arrive only from a user-supplied export or by asking. No plugin profile claims content.seo-patterns today for that reason; the capability is here so the surface has an owner and the mapping is written down.",
70 "Pattern id is the page type (`{pageType}`), or `{pageType}:{pageId}` for a single Wix Data dynamic page. No crosswalk is needed for the page type itself, but WIX_DATA_PAGE_ITEM patterns need the created page's GUID.",
71 "The tag shape is identical to seo/item-seo-tags (`{type, props, children, meta, custom, disabled}`); only the values differ, in that they may contain {{variables}}.",
72 "Precedence: the site's own pattern beats the Wix default pattern, and both are beaten by the host page and the item. Import patterns BEFORE per-item overrides so that a later item write is a deliberate exception rather than an accidental duplicate of the pattern's output."
73 ],
74 "setupRequirements": [
75 "SCOPE.PROMOTE.MANAGE-SEO (writes)",
76 "SCOPE.PROMOTE.VIEW-SEO (reads, incl. List SEO Pattern Variables)",
77 "The business solution that provides each page type must be installed before its pattern is written"
83 "note": "object page: id {pageType} / {pageType}:{pageId}, pattern vs defaultPattern, source, boolean-variable caveat, language is the primary language (read 2026-08-16)"
98 "note": "GET https://www.wixapis.com/promote/seo/v1/seo-patterns/{pageType}/variables - the only authoritative source of the variables a page type offers (read 2026-08-16)"
99 },
100 {
101 "type": "live-run",
102 "path": "anonymized-live-verification",
103 "note": "2026-10-27, throwaway editor site: ensureSeoPattern created a BLOG_POST pattern merged over the Wix default (default tags such as {{@TITLE}} og:title kept), a re-run returned already-present, an unknown {{post.nope}} returned invalid-variable with no write, and a second source title PATCHed the site-owned pattern with previousSitePattern returned and robots stripped. List SEO Pattern Variables returns variables[].key."
104 }
105 ],
106 "notes": "Authored 2026-08-16 with the seo domain. Docs-verified only. Unclaimed by any WordPress plugin profile today because the source templates are in wp_options and unreadable over REST - the honest verdict for the Yoast/Rank Math template settings is reconfigure-in-wix unless the user supplies an export, and this entity is where that reconfiguration lands if it is ever automated. 2026-10-27 : reviewed writer ensureSeoPattern. 2026-10-27: verified live."