Stage 5: SEO and languages
Goal: search engines and AI assistants understand every page. Old URLs land in the right place. Each extra language is as correct as the original.
SEO steps
- One owner per job.
- The SEO plugin (Rank Math by default) owns titles, meta, sitemaps and the main schema graph.
- The core's
schema.phpadds the site's own types to that graph. - Silence any domain plugin that prints its own schema, so there is one graph, not two that disagree.
- Every page in
tests/helpers/site.tspassesnpm run test:seo:- title 10–65 characters;
- description 50–160;
- absolute canonical;
- one H1;
langattribute;- zero Google Fonts requests.
Checklist and writing rules:
references/seo-checklist.md.
- Structured data:
- Organization (or LocalBusiness) once.
- The item type per page (Service, Product, TouristTrip, Course, …).
- Breadcrumbs.
- FAQ only for questions really answered on the page.
- Never an
Offerwithout a price. - Validate with Google's Rich Results Test and the Schema.org validator.
- Robots, sitemap, llms.txt:
- live allows crawling and lists the sitemap; staging blocks everything (the core does this);
/llms.txtis served by the core;- decide on purpose whether AI crawlers may read the site, then check the edge isn't blocking them by default (
wp-ship>cloudflare-edge.md).
- Redirects: follow the project's
docs/reference/REDIRECT_RULES.md. Map every old URL that has traffic or backlinks to its closest new page (301, one hop), and test each one. - Parity before big changes. Before a redesign, migration or language launch, capture title, description, canonical and H1 for every URL. After each step, compare. Re-capture only for intended changes, with the reason in the commit.
- Search Console and Bing:
- verify both;
- submit the sitemap;
- watch page indexing weekly for the first month;
- Search Console keeps only 16 months of data, so export or turn on the bulk export early.
Language steps (each language is a pilot first)
Follow references/multilingual.md. In short:
- Rule zero: the original language doesn't change. Its URLs, titles, canonical tags and text stay identical (the parity check proves it).
- Pilot: the language foundation (Polylang, the switcher, hreflang, strings in
.po/.mo), then the key pages and the top items. Then a native-speaker review on staging, then publish. - The rest comes in batches, each through the same review.
- A language that isn't published yet answers 302 to the original language, and appears nowhere: not in sitemaps, hreflang, menus or the switcher.
Gate (tick in SITE_STATUS.md)
-
npm run test:seogreen on staging; Rich Results test clean on one page of each type - Sitemap, robots.txt and llms.txt correct for live
- Old-URL redirect map in place and tested (or "n/a")
- Each extra language: pilot passed, native review done, hreflang pairs complete, canonical per language
Bugs we shipped once, so check for them
- The translated home page's canonical pointed at the original home page, so Google would drop
/fr/from French results. The canonical of a translated page is the translated URL. - English JSON-LD on French pages: the schema must follow the page's language, or be left out until it is translated.
- A gate that 301'd an unpublished language to the home page. Gates are 302s.