Files
odoo-expertos.com/growth/SEO-REPORT-2026-10-24.md
Hermes Agent 1dde14a821 Add first SEO report (2026-10-24)
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).
2026-10-24 19:41:03 +00:00

13 KiB
Raw Permalink Blame History

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, returns 200 with size_download 0 live, 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 on en/ and fr/ 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), including 404.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 hreflang tag, 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: /servicios and /odoo-ai/odoo-chatbot-ai-atencion-client-2025/. The audit also reports h1_not_one: 19 and pages_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: 1191 against 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.md returns HTTP 200 with 7,426 bytes. robots.txt carries Disallow: /*.md$, which is advisory only and does not restrict direct access. Anything committed under growth/ 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.