Docs SEO NEO Version 1.x Migrating from MarkupSEO or Seo Maestro

Migrating from MarkupSEO or Seo Maestro

Field-name mapping, template API swap ($page->seo to $page->seoneo), running the migration script, testing, and uninstalling the legacy module.

Before you start

Migration takes about 20 minutes on a typical site. The steps below work for both MarkupSEO and Seo Maestro. Read through the whole page before starting — the order matters.

Step 1 — Install SEO NEO alongside the existing module

Don't uninstall MarkupSEO or Seo Maestro yet. Install SEO NEO first (see Installation), then run both in parallel briefly while you migrate content and update templates.

During migration you may see two tabs both labelled SEO. SEO NEO adds a NEO badge by default so editors can tell them apart. You can also change the tab label in module config.

Step 2 — Add SEO NEO fields and copy data

Add seoneo_tab to each template that needs SEO NEO. From version 1.1.0, saving the template auto-inserts the remaining SEO fields.

Copy legacy field values into the SEO NEO fields at your own pace. For one-off bulk tasks (copying summary to seoneo_description, bulk noindex on login pages, etc.), use Tracy Console with a site-specific script or the ProcessWire API directly.

Disable auto-inject on whichever module is not yet authoritative for frontend output. Running both with auto-inject enabled produces doubled meta tags in the page source.

Step 3 — Rewrite template API calls

Both legacy modules expose SEO data via $page->seo. SEO NEO uses $page->seoneo. The namespace shape mirrors Seo Maestro, so the rewrite is usually a find-replace.

From Seo Maestro

// Full render
echo $page->seo;                       → echo $page->seoneo;
echo $page->seo->render();             → echo $page->seoneo->render();

// Per-group partials (namespace shape is identical)
echo $page->seo->opengraph->render();  → echo $page->seoneo->opengraph->render();
                                          // or: $page->seoneo->og->render()
echo $page->seo->twitter->render();    → echo $page->seoneo->twitter->render();

From MarkupSEO

// Full render
echo $config->seo->render();      → echo $page->seoneo->render();

// Value getters
echo $config->seo->title;         → echo $page->seoneo->title;
echo $config->seo->description;   → echo $page->seoneo->description;

Step 4 — Field name mapping

Old field (MarkupSEO / Seo Maestro) SEO NEO field
seo_title / seomaestro_titleseoneo_title
seo_description / seomaestro_descriptionseoneo_description
seo_keywordsseoneo_keywords
seo_canonicalseoneo_canonical
seo_noindex / seomaestro_robots_noindexseoneo_noindex
seo_nofollow / seomaestro_robots_nofollowseoneo_nofollow
seo_og_image / seomaestro_opengraph_imageseoneo_og_image
seo_og_typeseoneo_og_type
seo_authorseoneo_author (optional — add to templates that need per-page authors)

If your old templates use different field names, the Field mapping section in module config lets you point each role at any field name. See Configuration.

Step 5 — Test on a staging environment

View a representative sample of pages and check the rendered <head> source on each. Confirm title, canonical, og:image, hreflang, and noindex behaviour.

Step 6 — Uninstall the legacy module

Once testing is complete, uninstall MarkupSEO or Seo Maestro. Old fields remain on the page tree until you remove them manually from Setup > Fields.

If your old module handled sitemap, redirects, or analytics, install recommended companion modules before uninstalling — see Why SEO NEO.

Common gotchas

  • Double meta tags in source. Disable auto-inject on one module during migration.
  • Seo Maestro value getters return null after migration. Replace $page->seo->opengraph->image with $page->seoneo->og->image.
  • MarkupSEO's $config->seo throws an error. Replace all references with $page->seoneo.

See also

Last updated