Three stills from the thumbnail-designer render pipeline, copied byte-identical
(md5 verified against the handoff) into images/black-friday/ so the two BF
pipeline records can reference stable public URLs. WebP siblings added to match
how the site serves images. Not referenced from any page yet — hosting only.
bf2026-hosting-og.png 1200x630
bf2026-hosting-linkedin.png 1200x627
bf2026-bootcamp-lastcall-linkedin.png 1200x627
Modelled on odoo-community-upgrade.html (top bar, band rhythm, FAQ details).
Copy published verbatim from the copywriter's 2026-10-28 file: 58-char title,
157-char meta, the six outbound internal links and the WebPage+Article+FAQPage+
BreadcrumbList @graph. Nine FAQ questions marked plausible-event-name=FAQ (no
event fires on page load). Sitemap + llms.txt list the new URL. Inbound links:
one from the homepage FAQ card, one from the support FAQ answer. Nothing else
moves; no footer change.
Mark the six conversion goals on the self-hosted Plausible instance so the
events match the goals to be registered in Plausible. Event names verbatim:
Trial, FAQ, Buy, Custom Quote, search posts, Project Plan.
CSS-class markings (work without JS logic, on the clickable element):
- FAQ -> index/de/es index .faq-card; odoo-hosting-2027 + odoo-community-upgrade
(de/es twins) and australia <summary>; support.html .faq-question
- Buy -> index/de/es index .btn-buy anchors; australia + bootcamp native
post_basket submit buttons (forms stay native POST)
JS call markings in script.js (loaded by index, de/index, es/index):
- Trial on the successful trial-form POST (.then branch)
- Custom Quote on the successful custom-quote POST (.then branch)
- Project Plan on the successful business-wizard submit
- search posts on the FIRST input of #blogSearch only (guard flag, one per
pageview, not on every keystroke, not on #ocaSearch)
Nothing fires on page load; the 'Start the free trial' anchors that only
scroll to #trialCard are deliberately not tagged. One goal per topic across
all languages, no language suffix. No visual, behavioural or request change.
From seo/out/site-seo-ai-search-audit-2026-10-27.md (§6 items 1, 2, 3a, 5).
- canonical: 10 blog posts declared https://odooprojects.com/... — a live parked
third-party domain — as their canonical. Now self-referencing on
https://odoo4projects.com/blog/posts/<slug>.html (1 line each, nothing else).
- sitemap.xml: 27 -> 33 URLs. Added the 6 live pages that were missing
(support.html, legal.html, community-vs-enterprise-cost, 6-tips,
odoocommunity-agents, odoo-20-is-live); corrected 13 lastmod values to the
real last content commit (homepage was 4 months stale); /de/ and /es/
priority 1.0 -> 0.7 so a translation does not outrank its original.
- blog/index.json: 7 -> 15 posts. The 8 orphan posts are now listed, so every
post is reachable from the homepage grid.
- llms.txt: removed the link to /blog/ (that URL returns 403) and added a
"## Blog posts" section listing all 15 posts with date and summary.
Not changed on purpose: FAQPage on support.html, the homepage "price": ">950.00",
the bootcamp start-date conflict, and the blog post chrome (15 files).
New EN landing page for the head term "ODOO Community Upgrade": hero, what an
upgrade is, the 10-step published process, a developer-labelled technical section
with four sourced command blocks and their substitution notes, the ODOO4projects
migration service (new database on our servers), the self-hosting cost honesty
section, an 8-question FAQ and a final CTA. House CI only, page-scoped CSS, no
new blocking resources.
- CTAs are plain links to the real flows: /support.html#contact (opens the
migration ticket) and /index.html#pricing. No basket POST and no product id:
no price is published for the migration service, so wiring a buy would invent one.
- JSON-LD: WebPage + Service + FAQPage (8 questions), no Offer node.
- sitemap.xml: new URL added; llms.txt: page listed under Key pages.
- support.html: the "older version" FAQ answer now links the new page so it is not orphaned.
Copy: copywriter/out/odoo-community-upgrade-page-copy-2026-10-27.md. The 7
NOT PUBLISHED gaps (G1-G7) are not in the build.