Files
Hermes Agent 578f0a6690 SEO report 2026-10-24 as a styled HTML page
Self-contained (no external assets), dark theme matching the site accent, print
friendly. Carries a machine-readable <script id=seo-metrics> JSON block so next
week's run can diff against it instead of re-deriving last week's numbers.
The Friday job now renders from templates/seo-report.html.
2026-10-24 20:35:50 +00:00

257 lines
19 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
<title>SEO report — odoo-expertos.com — 2026-10-24</title>
<style>
:root{
--bg:#0e1116; --panel:#161b22; --line:#272d36; --text:#e6edf3; --muted:#8b949e;
--accent:#ff6b35; --good:#3fb950; --warn:#d29922; --bad:#f85149; --blue:#58a6ff;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--text);
font:15px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
-webkit-font-smoothing:antialiased}
.wrap{max-width:1080px;margin:0 auto;padding:40px 24px 80px}
header{border-bottom:1px solid var(--line);padding-bottom:24px;margin-bottom:32px}
.eyebrow{color:var(--accent);font-size:12px;letter-spacing:.14em;text-transform:uppercase;font-weight:700}
h1{font-size:30px;line-height:1.2;margin:8px 0 10px}
h2{font-size:19px;margin:40px 0 14px;padding-bottom:8px;border-bottom:1px solid var(--line)}
h3{font-size:15px;margin:24px 0 10px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}
p{margin:0 0 14px}
.meta{color:var(--muted);font-size:13px}
.chip{display:inline-block;padding:2px 9px;border:1px solid var(--line);border-radius:999px;
font-size:12px;color:var(--muted);margin:6px 6px 0 0}
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px;margin:24px 0 4px}
.kpi{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:16px}
.kpi .label{font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}
.kpi .value{font-size:26px;font-weight:700;margin-top:6px;font-variant-numeric:tabular-nums}
.kpi .sub{font-size:12px;color:var(--muted);margin-top:2px}
.flat{color:var(--muted)}
.na{color:var(--warn)}
table{width:100%;border-collapse:collapse;margin:14px 0 8px;font-size:14px}
th,td{text-align:left;padding:9px 10px;border-bottom:1px solid var(--line)}
th{color:var(--muted);font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.05em}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}
tbody tr:hover{background:#1b2029}
.bar{height:6px;background:var(--accent);border-radius:3px;min-width:2px;display:inline-block;vertical-align:middle}
.barwrap{width:120px;display:inline-block}
.callout{background:#1b2029;border-left:3px solid var(--accent);padding:14px 16px;border-radius:0 8px 8px 0;margin:16px 0}
.callout.warn{border-left-color:var(--warn)}
.action{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:16px 18px;margin:12px 0}
.action h4{margin:0 0 6px;font-size:15px}
.action .why{color:var(--muted);font-size:14px;margin:0 0 10px}
.action .row{display:flex;flex-wrap:wrap;gap:8px}
.pill{font-size:11.5px;padding:3px 9px;border-radius:999px;border:1px solid var(--line);color:var(--muted)}
.pill.s{color:var(--good);border-color:#1f6f3a}
.pill.m{color:var(--warn);border-color:#6b5320}
.pill.l{color:var(--bad);border-color:#7d2b28}
.pill.sched{color:var(--blue);border-color:#1f4b7a}
.num-badge{display:inline-flex;width:22px;height:22px;border-radius:50%;background:var(--accent);
color:#0e1116;font-weight:700;font-size:12px;align-items:center;justify-content:center;margin-right:8px}
ul.risks{padding-left:18px}
ul.risks li{margin:8px 0}
code{background:#21262d;padding:1px 6px;border-radius:4px;font-size:13px}
footer{margin-top:56px;padding-top:20px;border-top:1px solid var(--line);color:var(--muted);font-size:13px}
@media print{
body{background:#fff;color:#111}
.kpi,.action,.callout{border-color:#ddd;background:#fafafa}
h2{border-color:#ddd}
a{color:#111}
}
</style>
</head>
<body>
<div class="wrap">
<header>
<div class="eyebrow">SEO report</div>
<h1>odoo-expertos.com</h1>
<div class="meta">2026-10-24 · first report · Search Console range 2026-01-01 → 2026-10-24</div>
<div>
<span class="chip">website_stats.py — Plausible + GSC</span>
<span class="chip">audit_site.py</span>
<span class="chip">git log</span>
<span class="chip">live curl checks</span>
</div>
</header>
<div class="callout">
<strong>The number that matters:</strong> the money cluster (33 hosting queries, 538 impressions)
sits at <strong>position 27.5 with 1 click</strong>, while the site earns 4,745 impressions and
9 clicks overall at 0.19% CTR. Almost nobody who sees the site reaches a hosting page.
The technical cleanup landed — broken internal links fell from 4,029 to 1,370 — but this is the
first report, so no metric has had time to move.
</div>
<div class="kpis">
<div class="kpi"><div class="label">Impressions</div><div class="value">4,745</div><div class="sub flat">baseline — no prior period</div></div>
<div class="kpi"><div class="label">Clicks</div><div class="value">9</div><div class="sub flat">10 months</div></div>
<div class="kpi"><div class="label">CTR</div><div class="value">0.19%</div><div class="sub flat">page 1 would be 1.5%+</div></div>
<div class="kpi"><div class="label">Avg position</div><div class="value">24.7</div><div class="sub flat">money cluster 27.5</div></div>
<div class="kpi"><div class="label">Plausible visitors</div><div class="value">2</div><div class="sub flat">owner/test traffic</div></div>
<div class="kpi"><div class="label">Affiliate clicks</div><div class="value na">n/a</div><div class="sub">no goal configured</div></div>
</div>
<h2>Scorecard</h2>
<p class="meta">Baseline and “now” are the same snapshot, so the trend is flat by construction. This becomes a real trend table from the 2026-10-31 run.</p>
<table>
<thead><tr><th>Metric</th><th class="num">Baseline</th><th class="num">Now</th><th>Trend</th></tr></thead>
<tbody>
<tr><td>GSC impressions</td><td class="num">4,745</td><td class="num">4,745</td><td class="flat">flat — same snapshot</td></tr>
<tr><td>GSC clicks</td><td class="num">9</td><td class="num">9</td><td class="flat">flat — same snapshot</td></tr>
<tr><td>GSC CTR</td><td class="num">0.19%</td><td class="num">0.19%</td><td class="flat">flat — same snapshot</td></tr>
<tr><td>Average position</td><td class="num">24.7</td><td class="num">24.7</td><td class="flat">flat — same snapshot</td></tr>
<tr><td>Money cluster (<code>hosting*</code>)</td><td class="num">27.5</td><td class="num">27.5</td><td class="flat">33q · 538 impr · 1 click</td></tr>
<tr><td>Plausible visitors</td><td class="num">2</td><td class="num">2</td><td class="flat">2 visits · 3 pageviews</td></tr>
<tr><td>Affiliate clicks</td><td class="num">n/a</td><td class="num">n/a</td><td class="na">no <code>Affiliate Click</code> goal</td></tr>
</tbody>
</table>
<p class="meta">Affiliate clicks are unmeasured, not zero: the Plausible goal block returns only the page goal <code>Visit /</code> with 1 visitor. Commission attribution on odoo4projects.com is not visible from this environment and is not reported here.</p>
<h2>Technical progress</h2>
<p>Commit <code>a6cff06</code> is the change this section measures; <code>HEAD</code> is <code>0d2ecdb</code>.</p>
<table>
<thead><tr><th>Item</th><th class="num">Before</th><th class="num">After</th><th>Evidence</th></tr></thead>
<tbody>
<tr><td>Broken internal link occurrences</td><td class="num">4,029</td><td class="num">1,370</td><td class="flat">audit <code>broken_internal_count</code></td></tr>
<tr><td>Unique broken targets</td><td class="num">—</td><td class="num">679</td><td class="flat">full scan</td></tr>
<tr><td>Canonicals pointing at a 404</td><td class="num">136</td><td class="num">0</td><td class="flat">93 case-drift + 43 dead</td></tr>
<tr><td>Dead favicon / styles / analytics tags</td><td class="num">1,296</td><td class="num">0</td><td class="flat">1,197 + 96 + 3</td></tr>
<tr><td>Missing assets</td><td class="num">3</td><td class="num">0</td><td class="flat">audit <code>missing_assets_count</code></td></tr>
<tr><td>Bad in-page anchors</td><td class="num">—</td><td class="num">0</td><td class="flat">audit <code>bad_anchor_count</code></td></tr>
<tr><td>Duplicate titles / descriptions</td><td class="num">—</td><td class="num">0 / 0</td><td class="flat">audit</td></tr>
<tr><td>HTML pages</td><td class="num">1,208</td><td class="num">1,202</td><td class="flat">3 duplicate pages deleted</td></tr>
</tbody>
</table>
<p class="meta">Still broken and unfixable automatically: <code>/contacto/</code>, <code>/servicios</code>,
<code>/implementacion-odoo</code>, <code>/about</code> (old-site routes, 70 occurrences) and 35 locale
hosting pages that were never created (175 occurrences). <code>/odoo-ai/…</code> is not case drift —
the real section is <code>/odoo-ia/</code>, a different path.</p>
<h2>Ranking opportunities</h2>
<h3>Page 1, zero clicks — 17 queries, 1,090 impressions (23% of all)</h3>
<table>
<thead><tr><th>Query</th><th class="num">Impressions</th><th></th><th class="num">Position</th><th class="num">Clicks</th></tr></thead>
<tbody>
<tr><td>odo ia</td><td class="num">279</td><td><span class="barwrap"><span class="bar" style="width:100%"></span></span></td><td class="num">6.8</td><td class="num">0</td></tr>
<tr><td>odoo de donde es</td><td class="num">154</td><td><span class="barwrap"><span class="bar" style="width:55%"></span></span></td><td class="num">5.3</td><td class="num">0</td></tr>
<tr><td>de donde es odoo</td><td class="num">115</td><td><span class="barwrap"><span class="bar" style="width:41%"></span></span></td><td class="num">4.9</td><td class="num">0</td></tr>
<tr><td>odoo honduras</td><td class="num">81</td><td><span class="barwrap"><span class="bar" style="width:29%"></span></span></td><td class="num">9.4</td><td class="num">0</td></tr>
<tr><td>.odo ia</td><td class="num">66</td><td><span class="barwrap"><span class="bar" style="width:24%"></span></span></td><td class="num">7.6</td><td class="num">0</td></tr>
<tr><td>odoo origen</td><td class="num">60</td><td><span class="barwrap"><span class="bar" style="width:22%"></span></span></td><td class="num">7.7</td><td class="num">0</td></tr>
<tr><td>odoobot que es</td><td class="num">56</td><td><span class="barwrap"><span class="bar" style="width:20%"></span></span></td><td class="num">8.8</td><td class="num">0</td></tr>
<tr><td>docker odoo 20 · odoo 20 docker</td><td class="num">64</td><td><span class="barwrap"><span class="bar" style="width:23%"></span></span></td><td class="num">6.6</td><td class="num">0</td></tr>
<tr><td>odoo de que pais es</td><td class="num">32</td><td><span class="barwrap"><span class="bar" style="width:11%"></span></span></td><td class="num">6.8</td><td class="num">0</td></tr>
<tr><td>hosting economicos</td><td class="num">30</td><td><span class="barwrap"><span class="bar" style="width:11%"></span></span></td><td class="num">3.9</td><td class="num">0</td></tr>
<tr><td>odoo inmobiliaria</td><td class="num">27</td><td><span class="barwrap"><span class="bar" style="width:10%"></span></span></td><td class="num">9.4</td><td class="num">0</td></tr>
<tr><td>odoo bot</td><td class="num">25</td><td><span class="barwrap"><span class="bar" style="width:9%"></span></span></td><td class="num">8.3</td><td class="num">0</td></tr>
<tr><td>odoo de donde es originario</td><td class="num">25</td><td><span class="barwrap"><span class="bar" style="width:9%"></span></span></td><td class="num">4.5</td><td class="num">0</td></tr>
</tbody>
</table>
<p class="meta">At a 1.5% CTR these impressions would produce roughly 16 clicks over the same window.</p>
<h3>Positions 8–20 — 34 queries, 1,094 impressions</h3>
<table>
<thead><tr><th>Cluster</th><th class="num">Queries</th><th class="num">Impressions</th><th class="num">Clicks</th><th class="num">Avg pos</th><th>Example</th></tr></thead>
<tbody>
<tr><td>LatAm</td><td class="num">5</td><td class="num">214</td><td class="num">3</td><td class="num">9.7</td><td><code>odoo bolivia</code> 84 @ 8.4</td></tr>
<tr><td>AI / Odoo IA</td><td class="num">3</td><td class="num">183</td><td class="num">0</td><td class="num">14.0</td><td><code>odoo ia</code> 118 @ 15.0</td></tr>
<tr><td>Brand / company</td><td class="num">4</td><td class="num">176</td><td class="num">1</td><td class="num">13.0</td><td><code>odoo experts</code> 75 @ 13.7</td></tr>
<tr><td>Demo</td><td class="num">3</td><td class="num">145</td><td class="num">1</td><td class="num">15.1</td><td><code>demo odoo</code> 63 @ 12.4</td></tr>
<tr><td>Chatbot / OdooBot</td><td class="num">4</td><td class="num">138</td><td class="num">1</td><td class="num">9.0</td><td><code>odoobot</code> 34 @ 10.4</td></tr>
<tr><td>Hosting / deployment</td><td class="num">6</td><td class="num">104</td><td class="num">0</td><td class="num">15.4</td><td><code>odoo vps</code> 24 @ 14.6</td></tr>
</tbody>
</table>
<p class="meta">Head terms for later comparison: <code>odoo hosting</code> 298 impr · pos 31.5 · 1 click;
<code>hosting odoo</code> 85 · 28.5 · 0; <code>odoo beratung</code> 155 · 51.5 · 0.</p>
<h2>Action items</h2>
<div class="action">
<h4><span class="num-badge">1</span>Create the Affiliate Click and Outbound Click goals</h4>
<p class="why">The north-star metric cannot be read today — the goal block returns only <code>Visit /</code>. No traffic change, but it turns every later verdict from opinion into data. Proves it: the <code>event:goal</code> block returns both names with non-null events.</p>
<div class="row"><span class="pill s">Effort S</span><span class="pill">not scheduled</span><span class="pill">dashboard setting, not code</span></div>
</div>
<div class="action">
<h4><span class="num-badge">2</span>Rewrite title + meta for the page-1 zero-click queries</h4>
<p class="why">1,090 impressions already reach page 1 and earn 0 clicks — the snippet is failing, not the ranking. At 1.5% CTR that is ~16 clicks. Start with <code>odo ia</code>, <code>odoo de donde es</code>, <code>de donde es odoo</code>, <code>odoo honduras</code>.</p>
<div class="row"><span class="pill m">Effort M</span><span class="pill sched">PLAN weeks 3–6</span><span class="pill">metric: CTR on those 17</span></div>
</div>
<div class="action">
<h4><span class="num-badge">3</span>Strip the fabricated testimonials, ISO/SOC badges and placeholder phone</h4>
<p class="why">Invented proof is an E-E-A-T and legal liability. 3 testimonials, 113 pages claiming ISO 27001, 80 claiming SOC 2, 8 pages with a placeholder phone. Value is risk removal, not ranking.</p>
<div class="row"><span class="pill s">Effort S</span><span class="pill sched">PLAN week 2</span><span class="pill">guardrail: impressions must not fall</span></div>
</div>
<div class="action">
<h4><span class="num-badge">4</span>Consolidate the ~40 near-duplicate hosting pages per locale</h4>
<p class="why">They cannibalize the hub for the money terms. <code>odoo hosting</code> 31.5, <code>hosting odoo</code> 28.5. Check GSC per URL before deleting anything with impressions.</p>
<div class="row"><span class="pill l">Effort L</span><span class="pill sched">PLAN weeks 8–10</span><span class="pill">metric: position of both head terms</span></div>
</div>
<div class="action">
<h4><span class="num-badge">5</span>Fix the remaining 1,370 broken internal links (679 targets)</h4>
<p class="why">Dead ends waste crawl paths and send readers to 404s. <code>/servicios</code> and the <code>/odoo-ai/…</code> articles are live 404s now. Many are site-wide navigation links, so the fix is a handful of templates.</p>
<div class="row"><span class="pill m">Effort M</span><span class="pill">not scheduled</span><span class="pill">metric: broken_internal_count → 0</span></div>
</div>
<div class="action">
<h4><span class="num-badge">6</span>Fix the <code>odoo experts</code> brand query</h4>
<p class="why">75 impressions at position 13.7 with 0 clicks on a query that matches the domain name. Likely a title/H1 mismatch on the English homepage.</p>
<div class="row"><span class="pill s">Effort S</span><span class="pill">not scheduled</span><span class="pill">metric: position + CTR</span></div>
</div>
<div class="action">
<h4><span class="num-badge">7</span>Fill or remove the 0-byte PT page</h4>
<p class="why"><code>pt/odoo-ia/odoo-sistema-reservas-booking-ia-2025/</code> is 0 bytes, returns 200 with an empty body and sits in the PT sitemap. A soft-404 candidate.</p>
<div class="row"><span class="pill s">Effort S</span><span class="pill sched">PLAN week 7</span><span class="pill">metric: index coverage</span></div>
</div>
<div class="action">
<h4><span class="num-badge">8</span>Resolve 23 relative canonicals and 18 pages without one</h4>
<p class="why">Canonicals like <code>/odoo-ia/</code> carry no host, so they resolve to whichever host served the page — and apex and www both answer 200. Do not touch the cross-locale canonicals; that is intentional strategy.</p>
<div class="row"><span class="pill m">Effort M</span><span class="pill">not scheduled</span><span class="pill">metric: canonical_not_www → 0</span></div>
</div>
<h2>Open risks</h2>
<ul class="risks">
<li><strong>Empty page is indexable.</strong> 0 bytes on disk, HTTP 200 with an empty body live, listed in the PT sitemap.</li>
<li><strong>Relative canonicals lack a host.</strong> 23 of them, on <code>en/</code> and <code>fr/</code> pages.</li>
<li><strong>18 pages have no canonical</strong>, including the legal pages and some locale duplicates.</li>
<li><strong>hreflang coverage is 26%</strong> — 317 of 1,202 pages, while 153 pages canonicalise to another locale.</li>
<li><strong>1,370 broken internal links across 679 targets</strong>, with <code>/servicios</code> and one <code>/odoo-ai/…</code> article confirmed 404 live.</li>
<li><strong>Sitemap covers 1,191 of 1,202 pages</strong> — 11 pages are in no sitemap; some are legal/404 by design, unverified page by page.</li>
<li><strong>Internal strategy is publicly readable</strong> — <code>/growth/PLAN.md</code> returns 200 with 7,426 bytes. <code>Disallow: /*.md$</code> is advisory only.</li>
<li><strong>No attribution visibility.</strong> Nothing here is revenue evidence.</li>
</ul>
<footer>
Next review: <strong>2026-10-31</strong> — the first run with an elapsed week, and therefore the
first that can show a real trend instead of a same-snapshot comparison.<br>
Generated by the <code>seo</code> Hermes profile from live tool output. No estimated or invented figures.
</footer>
</div>
<script type="application/json" id="seo-metrics">
{
"date": "2026-10-24",
"gsc": {"impressions": 4745, "clicks": 9, "ctr": 0.19, "position": 24.7, "queries": 447},
"money_cluster": {"queries": 33, "impressions": 538, "clicks": 1, "position": 27.5},
"plausible": {"visitors": 2, "visits": 2, "pageviews": 3},
"affiliate_clicks": null,
"technical": {"broken_links": 1370, "broken_targets": 679, "canonicals_fixed": 136,
"pages": 1202, "hreflang_pages": 317, "no_canonical": 18,
"relative_canonicals": 23, "sitemap_urls": 1191},
"opportunities": {"page1_zero_click_queries": 17, "page1_zero_click_impressions": 1090,
"pos8_20_queries": 34, "pos8_20_impressions": 1094}
}
</script>
</body>
</html>