Same defect the bootcamp carried (2aa9b19), fixed site-wide in one mechanical pass.
P0 (17 pages): /style.css was deferred via media="print" onload=... -> unstyled
first paint -> a BODY layout shift. Now a normal render-blocking
<link rel="stylesheet">; the now-redundant no-JS <noscript> for style.css is
dropped. Web fonts + Font Awesome keep their legitimate deferral.
Pages: index.html, odoo-black-friday/, odoo-hosting-offers/, de/index.html,
es/index.html, odoo-hosting-2027.html (+de/+es), odoo-community-upgrade.html
(+de/+es), odoo-staging-environment/, odoo-community-ai/,
odoo-n8n-masterclass/, australia.html, workshops/, what-can-i-use-odoo-for/.
P1 (1 page): /odoo-black-friday/ footer form action mailto: -> CRM webhook
(Lighthouse is-on-https). Changed only because the page already loads a handler
for #footerContactForm (static/black-friday.js). The other 13 mailto-form pages
load no handler and are left alone on purpose (no drive-by handler copy-in).
Added the no-JS <noscript> fallback so a JS-off visitor keeps a path.
P2 (35 pages): add a single <main> landmark wrapping the primary content; top
bar and footer stay outside. Additive only, no redesign.
Guards held: bootcamp EN/DE/ES and every JS/static file untouched; Buy forms
product_id 4/17 intact; one [data-bc-seats]; ads-consent gate intact.
verify-html.py PROBLEMS 0; competitor QC 74 pre-existing, 0 added.
The ODOO ERP Automation Bootcamp price is now USD 595.00 (shop product
already set). Every printed EN bootcamp price now reads 595.00 so the page
no longer loses the sale at the cart (page said 465.00, cart charged 595.00).
EN surfaces changed (price strings only — term, dates, six-seat cap and the
one-year hosted Odoo Community wording untouched):
- odoo-erp-automation-bootcamp/index.html: 3 buy buttons, JSON-LD Offer
price, .bc-price sentence
- odoo-black-friday/index.html: Bootcamp box JSON-LD Offer price, bf-teaser,
bf-price
- workshops/index.html: both meta descriptions, JSON-LD Offer price,
.bc-card-price, comparison-table cell
- what-can-i-use-odoo-for/index.html: the line naming the bootcamp
- llms.txt: workshops line
verify-html.py 0 problems, node --check script.js clean; competitor checker
unchanged (74 pre-existing Odoo Online hits, 0 added by this diff).
- bootcamp page: Class size fact row (Limited to 6 participants), a cap line by
the price, JSON-LD CourseInstance maximumAttendeeCapacity: 6, and a compact
Black Friday call-out (16-30 Nov 2026, second hosted year + $100 off BF2026,
six seats) with the landing-page slot left open for olchi
- workshops page: the cap on the bootcamp card and a Class size comparison row
- llms.txt: durable 'limited to six participants per cohort' on the bootcamp line
(evergreen - no dated Black Friday offer in llms.txt)
The blog was an island: zero post→page links to hosting/upgrade/support/courses,
and only one page→post link in the whole site. Posts ranked for nothing while the
old blog host ranked for our long-tail queries.
Posts → pages (26 new in-body contextual links across 17 posts):
each post now carries one or two links to the page that answers its reader's next
question — odoo-hosting-2027, odoo-community-upgrade, support, the workshops hub,
the n8n masterclass, and the plan pricing on index.html#pricing.
Pages → posts (7 pages, one contextual link each):
index.html (OCA section), odoo-hosting-2027, odoo-community-upgrade, support,
workshops/, odoo-n8n-masterclass/, odoo-erp-automation-bootcamp/ now link into the
post that fits their own subject. The clearest miss is fixed — the
community-vs-enterprise-cost post and the odoo-community-upgrade page now link
to each other.
Anchors wrap existing sentences where the text already said the thing; four short
linking sentences were added (index OCA section, support first-steps FAQ, masterclass
lessons, bootcamp included section). No new components, no related-posts widget,
in-body anchors only. English pages only; DE/ES untouched (translator follow-up).
Two directory URLs Google still has indexed were 404ing after the old site was
torn down. Both are rebuilt as trailing-slash directories (same model as
/odoo-erp-automation-bootcamp/, so the non-slash form 301s to the slash form).
odoo-n8n-masterclass/index.html
- copy from copywriter, structure and page-scoped CSS reused from the bootcamp page
- next session: four Thursdays of February 2027, 17:00 Central Time (hero eyebrow,
price and booking, JSON-LD startDate 2027-02-04)
- booking: native POST form to 20.odoo4projects.com/shop/post_basket, basket
product_id 44, zero JavaScript, three CTAs
- n8n environment corrected: we do not hand out n8n workspaces; the participant
uses n8n's own free plan. Body, hero fact, FAQ and JSON-LD say so plainly.
- JSON-LD Course + FAQPage; Plausible snippet; FAQ and Buy markings
workshops/index.html
- hub page, two cards (masterclass USD 120.00 / bootcamp USD 465.00), pull quote,
routing section, FAQ, comparison table
- the bootcamp card carries no term or date; the "ERP Automation Quick Wins" free
offer is gone entirely (no card, no 1-hour format, no /free-webinar link)
- JSON-LD ItemList; Plausible snippet; FAQ markings
SEO: canonical to the slash URL, OG tags, the bootcamp's font/style.css loading
pattern, sitemap.xml (+2 urls, lastmod 2026-10-28, bootcamp lastmod bumped for the
two links added there), llms.txt (+2 lines). Cross-linked both ways and both to the
bootcamp; the bootcamp page gains the inbound links.
English only. No DE/ES twins yet - translator follow-up.
Checks: verify-html.py 0 problems, check-links.py clean, check-links-2026-10-28.py
56 PASS / 0 FAIL, verify-plausible-events 71 PASS / 0 FAIL, JSON-LD parses.