Produced by the new 'seo' profile from live data: webhook (Plausible + Search Console), audit_site.py, git log. Scorecard, technical progress, ranking opportunities, 8 action items, open risks. All figures cross-checked against the scripts (317 hreflang pages, 679 broken targets, 1,370 occurrences, 23 relative canonicals, 18 missing canonicals, sitemap 1,191 of 1,202).
13 KiB
SEO report — odoo-expertos.com — 2026-10-24
Data sources: website_stats.py (n8n webhook: Plausible + Search Console, range
2026-01-01 → 2026-10-24), audit_site.py . /tmp/seo_audit.json, git log, and live
curl checks. Baseline: growth/BASELINE.md, captured the same day.
Executive summary
Across 4,745 impressions in ten months the site earned 9 clicks (CTR 0.19%, average position 24.7), and the money cluster — 33 hosting queries, 538 impressions — sits at position 27.5 with 1 click, so almost nobody who sees the site reaches a hosting page. The technical cleanup did land: broken internal link occurrences fell from 4,029 to 1,370 and 136 canonicals that pointed at dead URLs were repaired. But this first report has no elapsed time — the baseline was captured today — so every Search Console and Plausible number below is identical by construction; the only measured change is technical. Two things are therefore unknown rather than good: affiliate clicks have no Plausible goal, and Plausible recorded 2 visitors, both owner/test traffic, which is too small to read as demand.
Scorecard
Baseline and "now" are the same snapshot (both 2026-10-24), so "trend" is flat by definition. This table becomes a trend table from the 2026-10-31 run onward.
| metric | baseline (2026-10-24) | now (2026-10-24) | trend |
|---|---|---|---|
| GSC impressions | 4,745 | 4,745 | flat — same snapshot |
| GSC clicks | 9 | 9 | flat — same snapshot |
| GSC CTR | 0.19% | 0.19% | flat — same snapshot |
| GSC average position | 24.7 | 24.7 | flat — same snapshot |
Money-cluster position (hosting*) |
27.5 (33q, 538 impr, 1 click) | 27.5 (33q, 538 impr, 1 click) | flat — same snapshot |
| Plausible visitors | 2 | 2 (2 visits, 3 pageviews) | flat — same snapshot |
| Affiliate clicks | n/a | n/a | n/a — no Affiliate Click goal exists |
Why affiliate clicks are n/a: the Plausible goal block (event:goal) returns only one row,
the page goal Visit / with 1 visitor. No Affiliate Click or Outbound Click goal is
configured, so the custom events are not countable in the payload even if they fire. The
north-star metric is currently unmeasured, not zero. Separately, commission attribution on
odoo4projects.com is not visible from this environment and is not reported here.
Context for the 2 visitors: both are in the week of 2026-10-19 (United States and Paraguay), consistent with owner/test traffic. No organic traffic signal exists yet.
Technical progress
Commit a6cff06 ("Cleanup: fix 2,659 dead internal URLs…", 2026-10-24 19:25 UTC) is the
change this section measures. It is pushed: HEAD and origin/main are both 8b80c6c.
| item | before | after | evidence |
|---|---|---|---|
| Broken internal link occurrences | 4,029 | 1,370 | commit a6cff06 body; audit broken_internal_count: 1370 |
| Unique broken targets remaining | — | 679 | full scan with audit_site.resolve/exists: 1,370 occurrences across 679 targets; audit JSON details only the top 60 |
| Canonicals pointing at a case variant that 404s | 93 | 0 | commit a6cff06 body |
| Canonicals pointing at a deleted path | 43 | 0 (now self-canonical) | commit a6cff06 body |
Dead <link rel=alternate icon href=/favicon.ico> |
1,197 | 0 | commit a6cff06 body |
Dead /styles/*.css (Next.js leftovers) |
96 | 0 | commit a6cff06 body |
/_vercel/insights scripts (previous host) |
3 | 0 | commit a6cff06 body |
| Missing assets | — | 0 | audit missing_assets_count: 0 |
| Bad in-page anchors | — | 0 | audit bad_anchor_count: 0 |
| Duplicate titles / descriptions | — | 0 / 0 | audit duplicate_titles: [], duplicate_descriptions: [] |
| Images without alt | — | 0 | audit img_without_alt: 0 |
| HTML files | 1,208 | 1,202 | audit pages: 1202; 1,208 minus 3 duplicate pages deleted and 3 archived audit HTML files the audit excludes |
Remaining broken targets, first entries in the audit's capped list: /contacto/,
/servicios, /servicios-implementacion-odoo, /servicios-consulta-odoo,
/implementacion-odoo, /about, /odoo-ai/odoo-chatbot-ai-atencion-client-2025/,
/odoo-ai/odoo-dashboard-ai-paneles-smarts-2025/, plus cross-locale links into French and
German 2026 hosting pages (/fr/odoo-hosting/meilleur-hebergement-odoo-2026/,
/de/odoo-hosting/odoo-sh-alternativen-2026/, and others). Two were confirmed live:
https://www.odoo-expertos.com/servicios → HTTP 404, and
https://www.odoo-expertos.com/odoo-ai/odoo-chatbot-ai-atencion-client-2025/ → HTTP 404.
Note that /odoo-ai/ failures are not case drift — the real section is /odoo-ia/, a
different path, so the case-insensitive rewrite could not fix them.
Ranking opportunities
Page-1 zero-click queries
17 queries rank on page 1 (position ≤ 10) with zero clicks and ≥ 20 impressions, holding
1,090 impressions — 23.0% of all impressions (per website_stats.py).
| query | impressions | position | clicks |
|---|---|---|---|
| odo ia | 279 | 6.8 | 0 |
| odoo de donde es | 154 | 5.3 | 0 |
| de donde es odoo | 115 | 4.9 | 0 |
| odoo honduras | 81 | 9.4 | 0 |
| .odo ia | 66 | 7.6 | 0 |
| odoo origen | 60 | 7.7 | 0 |
| odoobot que es | 56 | 8.8 | 0 |
| ,odo ia | 32 | 6.9 | 0 |
| docker odoo 20 | 32 | 6.6 | 0 |
| odoo 20 docker | 32 | 6.5 | 0 |
| odoo de que pais es | 32 | 6.8 | 0 |
| hosting economicos | 30 | 3.9 | 0 |
| odoo inmobiliaria | 27 | 9.4 | 0 |
| odoo bot | 25 | 8.3 | 0 |
| odoo de donde es originario | 25 | 4.5 | 0 |
| odoo empresa de donde es | 23 | 5.4 | 0 |
| quien creo odoo | 21 | 6.4 | 0 |
At a 1.5% CTR these impressions would produce roughly 16 clicks over the same window, taking site-wide CTR from 0.19% to about 0.53% (25 clicks / 4,745 impressions). That is arithmetic on current impressions, not a forecast of ranking movement.
Position 8–20 clusters
34 queries with ≥10 impressions rank between positions 8 and 20, totaling 1,094 impressions. Grouped by topic (a query appears in one group only):
| cluster | queries | impressions | clicks | avg position | examples |
|---|---|---|---|---|---|
| LatAm | 5 | 214 | 3 | 9.7 | odoo bolivia (84 @ 8.4, 3 clicks), odoo honduras (81 @ 9.4, 0) |
| AI / Odoo IA | 3 | 183 | 0 | 14.0 | odoo ia (118 @ 15.0), ia odoo (43 @ 12.5) |
| Brand / company | 4 | 176 | 1 | 13.0 | odoo experts (75 @ 13.7, 0 clicks) |
| Demo | 3 | 145 | 1 | 15.1 | demo odoo (63 @ 12.4), odoo demo (63 @ 17.0) |
| Chatbot / OdooBot | 4 | 138 | 1 | 9.0 | odoobot (34 @ 10.4), odoo bot (25 @ 8.3) |
| Hosting / deployment | 6 | 104 | 0 | 15.4 | odoo vps (24 @ 14.6), odoo digitalocean (22 @ 17.5), odoo docker (20 @ 14.1) |
The LatAm group already converts (3 of the 9 site-wide clicks); the AI and hosting groups
sit one page short of visibility with no clicks. odoo experts is the clearest brand
miss: the domain is odoo-expertos.com but the query ranks 13.7 with 75 impressions and 0
clicks.
Head-term anchors for later comparison: odoo hosting 298 impressions, 1 click, position
31.5; hosting odoo 85 impressions, 0 clicks, position 28.5; odoo beratung 155
impressions, 0 clicks, position 51.5.
Action items
Ordered by expected value. "Scheduled" means it already appears in PLAN.md weeks 2–7.
1. Create the Affiliate Click and Outbound Click goals in Plausible — S — not scheduled.
Why: the plan's north-star metric cannot be read today; the goal block returns only
Visit /. Expected effect: no traffic change, but it turns every later verdict from
opinion into data. Proves it: the event:goal block returns rows named Affiliate Click
and Outbound Click with non-null events. Note the skill documents that adding a partner
is one line in js/plausible-events.js; the goals themselves are dashboard settings, not a
code change.
2. Rewrite title + meta description for the page-1 zero-click queries — M — scheduled weeks 3–6.
Why: 1,090 impressions already reach page 1 and get 0 clicks; the snippet, not the
ranking, is failing. Expected effect: at 1.5% CTR, ~16 clicks over an equivalent window.
Proves it: CTR on those 17 queries. Start with odo ia (279), odoo de donde es (154),
de donde es odoo (115), odoo honduras (81). Four pages per week as planned.
3. Strip the fabricated testimonials, ISO 27001 / SOC 2 / "200+ proyectos" badges and the placeholder phone — S — scheduled week 2.
Why: invented proof is an E-E-A-T and legal liability and weakens the affiliate pitch.
Expected effect: no ranking gain assumed; the value is risk removal and trust. Proves it:
impressions on the affected URLs must not fall (guardrail), with outbound CTR as the
secondary read. There are 3 testimonials and 8 pages with the placeholder phone per
BASELINE.md; remove rather than replace with new claims, and use the host's real customer
list only if each site still loads.
4. Consolidate the ~40 near-duplicate /odoo-hosting/* pages per locale — L — scheduled weeks 8–10 (outside 2–7).
Why: they cannibalize the hub for the money terms; odoo hosting is at 31.5 and
hosting odoo at 28.5. Expected effect: consolidating authority should move the surviving
hub toward page 2 and then page 1. Proves it: position of hosting odoo and odoo hosting,
plus hub impressions. Do not delete any URL with impressions before checking it in GSC.
5. Fix the remaining 1,370 broken internal link occurrences (679 unique targets) — M — not scheduled.
Why: 1,370 dead ends waste crawl paths and send readers to 404s; /servicios and the
/odoo-ai/... articles are live 404s today. Expected effect: no direct ranking number —
it removes 1,370 failure points and restores internal link flow to real pages. Proves it:
broken_internal_count from audit_site.py reaches 0. Many targets are site-wide
navigation links, so the fix is a handful of templates, not 1,370 edits.
6. Fix the odoo experts brand query — S — not scheduled.
Why: 75 impressions at position 13.7 with 0 clicks from a query that matches the domain
name is a lost brand click. Expected effect: page-1 entry for the brand query; small
volume, high relevance. Proves it: position and CTR for odoo experts. Likely a
title/H1 mismatch on the English homepage.
7. Fill or remove the 0-byte PT page — S — scheduled week 7.
Why: pt/odoo-ia/odoo-sistema-reservas-booking-ia-2025/index.html is 0 bytes, returns
HTTP 200 with 0 bytes, and is in the PT sitemap. Expected effect: removes one empty
soft-404 and an index-coverage defect. Proves it: the URL either has substantial content
or is gone from sitemap-pt.xml after ./generate_sitemap.sh.
8. Resolve the 23 relative canonicals and 18 pages without a canonical — M — not scheduled.
Why: 23 canonicals on en/ and fr/ pages are host-relative (e.g. en/odoo-ia/index.html
→ /odoo-ia/), so the canonical host depends on which host served the page, and apex and
www both serve 200 without redirecting. Expected effect: removes ambiguity about which URL
is canonical; protects the 153 cross-locale canonicals that are intentional strategy.
Proves it: canonical_not_www and no_canonical in the audit reach 0 (excluding the
legal/404 pages deliberately left without one). Do not change cross-locale canonicals
themselves — that is a strategy, and touching it re-indexes ~150 pages.
Open risks
- Empty page is indexable.
pt/odoo-ia/odoo-sistema-reservas-booking-ia-2025/is 0 bytes on disk, returns200withsize_download 0live, and is listed in the PT sitemap. That is a soft-404 candidate. - Relative canonicals lack a host. Audit
canonical_not_www: 23; all are onen/andfr/pages and use paths such as/odoo-ia/. Because the apex serves the same bytes as www with no redirect, the canonical resolves to whichever host the crawler used. - 18 pages have no canonical at all (
no_canonical: 18), including404.html,cookie-policy.html,terms-of-use.html,privacy-policy.html, and locale duplicates of the same article. - hreflang coverage is 26%. 317 of 1,202 audited HTML files contain an
hreflangtag, while 153 pages canonicalise to another locale. Pages that are cross-locale canonicalised without hreflang give Google no signal that a translation exists. - 1,370 broken internal links across 679 unique targets. Confirmed live 404s:
/serviciosand/odoo-ai/odoo-chatbot-ai-atencion-client-2025/. The audit also reportsh1_not_one: 19andpages_without_title: 1/pages_without_description: 1; the 0-byte PT page would produce the latter. - Sitemap does not cover the site.
sitemap_url_count: 1191against 1,202 audited HTML pages, so 11 pages are not in any sitemap. Some are legal/404 pages by design; that has not been verified page by page. - Internal strategy is publicly readable.
https://www.odoo-expertos.com/growth/PLAN.mdreturns HTTP 200 with 7,426 bytes.robots.txtcarriesDisallow: /*.md$, which is advisory only and does not restrict direct access. Anything committed undergrowth/is public. - No attribution visibility. Affiliate clicks are unmeasured (no goal) and commission reported by odoo4projects.com is not accessible here. Nothing in this report should be read as revenue evidence.
Next review date
2026-10-31. The 2026-10-31 run is the first one with an elapsed week, so it is the first that can show a real trend rather than a same-snapshot comparison.