Files
2026-08-28 10:11:11 -03:00

282 lines
27 KiB
Markdown
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.
# Full SEO Audit — odoo-expertos.com
**Date:** 2026-05-27
**Auditor:** claude-seo v2.0.0 (AgriciDaniel) — orchestrated multi-agent audit
**Host:** Vercel (canonical host `www.odoo-expertos.com`)
**Site type:** Odoo ERP consulting, multilingual (ES root + EN/DE/FR/PT/AR), ~1,210 pages, static HTML
**Output location:** this folder only (`seo-audit-2026-05-27/`). Nothing was written to any other project.
---
## Scope (read first)
This is a **bounded, representative audit**, not a 500-page crawl. Analyzed:
- All site-wide files: `robots.txt`, sitemap index + all 6 language sitemaps, `llms.txt`, `llms-full.txt`
- 6 language homepages (es/en/de/fr/pt/ar)
- Category index pages across all 6 languages (`/odoo/`, `/odoo-hosting/`, `/odoo-ia/`)
- Representative deep article pages in ES/EN/DE
- Homepage screenshots (desktop + mobile, in `screenshots/`)
The structural problems found replicate across language siblings and the ~1,210-page template, so the sample is representative of systemic issues. Raw fetched data is in `raw/`.
> **PageSpeed note:** Google PSI/CrUX was rate-limited (no API key on the shared quota) at audit time, so Core Web Vitals numbers below are **ESTIMATED from HTML signals**, not measured field/lab data. Re-run with a PSI API key for exact CWV.
---
## Executive Summary
**Overall SEO Health Score: ~44/100 — Poor. Significant, systemic issues.**
| Category | Weight | Score | Verdict |
|---|---|---|---|
| Technical SEO | 22% | 54 | Hreflang broken on inner pages; 3 category pages 404 in sitemaps |
| Content Quality / E-E-A-T | 23% | 25 | 400+ EN/DE pages serve untranslated/garbled Spanish; fabricated authors |
| On-Page SEO | 20% | 35 | 270300+ char keyword-stuffed titles; orphan articles |
| Schema / Structured Data | 10% | 45 | Broken logo domain, www mismatch, DE page ships Spanish schema |
| Performance (CWV) | 10% | ~65 (est) | Real optimizations present; CWV not measured (PSI rate-limited) |
| AI Search Readiness (GEO) | 10% | 50 | Excellent crawler posture; homepage hype suppresses citability |
| Images | 5% | ~60 (est) | Lazy-load claimed; not fully verified |
### Top 5 Critical Issues (fix immediately)
1. **400+ EN/DE pages are not translated** — they serve Spanish (or broken machine-mixed Spanish/German like "Inteligencai Artificail", "ueber", "fuer") under `lang="en"`/`lang="de"`. This is a site-wide quality/deception signal that risks a domain-level downgrade.
2. **3 category index pages 404 while listed in their sitemaps**`/en/odoo-hosting/`, `/fr/odoo-hosting/`, `/pt/odoo-hosting/` all return 404 but appear as `<loc>` entries → poisons sitemap trust + breaks the hub for ~200 pages each.
3. **Hreflang broken on inner pages** — EN inner pages omit `pt` + `ar` (non-reciprocal); DE inner pages point `hreflang="es"` and `x-default` to non-existent `/de/`-prefixed Spanish slugs (404). Category index pages have **zero** hreflang.
4. **Broken/inconsistent Organization logo + URL in schema** — logo points to `www.odooexpertos.com` (no hyphen — domain does not resolve); CollectionPage/breadcrumb URLs use non-www while canonicals use www → entity-consolidation failure.
5. **Homepage is anti-E-E-A-T and anti-citation** — fear/combat hype ("Tus Competidores Usan IA Para Robarte Clientes", CTA "DESTRUIR COMPETENCIA AHORA"), unsourced stats (280% ROI), publisher entity "Apex AI Research Labs LLC", no About/Contact page.
### Top 5 Quick Wins
1. Remove the three 404 `<loc>` entries from `sitemap-en/fr/pt.xml` (stops sitemap poisoning today) — then build the missing index pages.
2. Fix the schema logo URL site-wide (`odooexpertos.com``www.odoo-expertos.com/favicon.svg`) and switch all schema `url`/`item` to the www host.
3. Add the missing security headers via `vercel.json` (`X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`).
4. Collapse the duplicate robots.txt groups, merge the useful `Disallow: /*?` `/*&` into the FIRST `User-agent: *` group, delete `Disallow: /*#`.
5. Fix `og:locale` on DE/FR/PT category pages (currently `es_ES`) and the truncated `dateModified` in Article schema.
### What's genuinely good
- **Canonicalization is correct**: apex `odoo-expertos.com` → 301 → `www`; `http` → 308 → `https`; self-referencing canonicals on www; HSTS present (2-year max-age).
- **Homepage hreflang is complete and reciprocal** across all 6 languages incl. `x-default`.
- **AI-crawler posture is exemplary** — robots.txt explicitly allows GPTBot, ClaudeBot, PerplexityBot, OAI-SearchBot, Google-Extended, CCBot, Applebot-Extended, etc., and routes them to `llms.txt`. SEO scrapers (Ahrefs/Semrush/MJ12/Bytespider) correctly blocked.
- **Static HTML on Vercel** = best possible crawl/AI-ingestion foundation.
- **Arabic RTL** done correctly (`<html lang="ar" dir="rtl">` + Noto Sans Arabic).
- **Critical CSS inlined + async minified CSS** — real performance work shipped.
- **Sitemaps comprehensive**: 1,210 URLs (es 201 / en 206 / de 205 / fr 199 / pt 199 / ar 200) with xhtml:link hreflang annotations.
---
## 1. Technical SEO & Hreflang — Score 54/100
### [Critical] Three category index pages 404 while listed in their sitemaps
`/en/odoo-hosting/`, `/fr/odoo-hosting/`, `/pt/odoo-hosting/` all return **HTTP 404**, yet each appears as a `<loc>` entry in its language sitemap. (ES, DE, AR versions return 200; `/en/odoo/`, `/en/odoo-ia/`, `/de/odoo/`, `/de/odoo-ia/` return 200.)
- **Why:** Submitting 404s in a sitemap degrades trust in the whole sitemap and can suppress crawl priority. These are hub pages — without them, ~200 inner pages per language lose their category link root.
- **Fix now:** Remove the 3 dead `<loc>` entries from `sitemap-en/fr/pt.xml` today. **Fix properly:** build the missing index pages (mirror the working DE/AR versions).
### [Critical] Hreflang broken on inner pages (reciprocity + wrong targets)
- EN inner pages (e.g. `/en/odoo-hosting/best-odoo-hosting-2026/`) declare only es/en/de/fr/x-default — **`pt` and `ar` are missing**, so ES→PT/AR is not reciprocated. Google discards a non-reciprocal hreflang cluster entirely.
- DE inner pages (e.g. `/de/odoo-hosting/bestes-odoo-hosting-2026/`) set `hreflang="es"` and `x-default` to `https://www.odoo-expertos.com/de/odoo-hosting/mejor-hosting-odoo-2026/` — a `/de/`-prefixed Spanish slug that **404s**. Correct target is the root `https://www.odoo-expertos.com/odoo-hosting/mejor-hosting-odoo-2026/`.
- **Fix:** Templated fix across the EN template (add pt+ar) and DE template (build es/x-default hrefs from the root, no `/de/` prefix). Affects ~200 pages each.
### [Critical] Category index pages have ZERO hreflang
`/odoo-hosting/`, `/de/odoo-hosting/`, `/odoo-ia/` (and likely all category hubs) return 0 hreflang `<link>` tags. Google cannot connect the language versions of these high-equity hubs → they compete with each other.
- **Fix:** Add the full 7-entry block (es,en,de,fr,pt,ar,x-default) to every category index `<head>`.
### [High] robots.txt structural errors
- **Two `User-agent: *` groups.** Per RFC 9309, only the FIRST matching group applies — so the second block's useful rules (`Disallow: /*?`, `/*&`) are **silently ignored**. Parameterized/duplicate URLs you intended to block are being crawled.
- **Duplicate `User-agent: Bingbot`** (Bing section vs AI section, with different Allow rules) and **duplicate `User-agent: CCBot`** — dead/conflicting config.
- **`Disallow: /*#`** is meaningless (fragments never reach the server).
- **Fix:** One group per agent. Merge `Disallow: /*?` `/*&` into the FIRST `User-agent: *`. Delete the second `*` block, the duplicate Bingbot/CCBot groups, and `/*#`.
### [Medium] Missing security headers
Present: `Strict-Transport-Security: max-age=63072000` (good). Missing: `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`, `Permissions-Policy`, CSP.
- **Fix (`vercel.json` headers):** add `X-Content-Type-Options: nosniff`, `X-Frame-Options: SAMEORIGIN`, `Referrer-Policy: strict-origin-when-cross-origin`.
### [Low] http→https→www = 2 redirect hops
`http://odoo-expertos.com` → 308 → `https://odoo-expertos.com` → 301 → `https://www…`. Standard, not penalized, but a direct `http-apex → https-www` rule would save one hop.
### What's already good (technical)
- Apex→www 301 and http→https 308 correct; **www is the single canonical host**; self-referencing canonicals; HSTS 2yr.
- **Homepage hreflang complete + reciprocal** across all 6 languages incl. x-default; valid ISO codes; www hosts.
- No `noindex` on any sampled page; viewport tag everywhere; **Arabic RTL** (`dir="rtl"` + Noto Sans Arabic) correct.
- Sitemap index → 6 language sitemaps with xhtml:link hreflang annotations; 1,210 URLs total.
- robots.txt correctly blocks SEO scrapers (Ahrefs/Semrush/MJ12/Dot) while allowing all search + AI bots.
## 2. Content Quality & On-Page SEO — Score ~30/100 (E-E-A-T 18/100)
### [Critical] 400+ EN/DE pages serve untranslated / garbled content under the wrong `lang`
- `/en/odoo/odoo-hosting-cloud-infraestructura-2025/` declares `lang="en"` but H1, H2s, body and meta are **entirely Spanish**.
- `/de/odoo-hosting/` ships broken machine-mixed text: title "…Vollstaendiger Leitfaden **de** Lieferanten Cloud … fuer ERP…", body "…necesitas saber **ueber** infraestructura, Lieferanten…", H2 "100+ **Leitfadens** Especializadas".
- `/en/odoo-ia/` H1/title/meta all read "**Inteligencai Artificail**" (misspelled, mixed ES/EN: "RPA y Chatbots Smarts", "Predicción of Sales").
- **Why:** Declared-language ≠ content-language is a deception signal; at 400+ pages it risks a **site-wide quality downgrade** and breaks hreflang (language signals contradict content). These pages give zero value to EN/DE users and near-duplicate the Spanish originals.
- **Fix (pick one, sitewide):** (a) genuinely translate EN/DE pages; (b) remove EN/DE article pages and keep Spanish-only with hreflang back to ES; (c) 301 untranslated EN/DE paths → Spanish canonical. Only (a) preserves the multilingual investment. **Do not generate more Spanish-slug EN/DE pages.**
### [Critical] Category/directory titles are 270300+ chars of keyword stuffing
e.g. `/odoo-hosting/` title is 271 chars: "Directorio de Artículos Odoo Hosting - Guía Completa de Proveedores Cloud | AWS, Azure, DigitalOcean para ERP | … | 50+ Tutoriales… | Odoo Expertos". `/odoo/` ~250+, `/odoo-ia/` 273, `/de/odoo-hosting/` 277 (and Spanish/German mixed).
- **Why:** Google truncates/rewrites at ~60 chars; a 270+ char pipe-stuffed title is a manipulation signal under the Sep-2025 QRG.
- **Fix:** Rewrite to 5060 chars in the target language: `[Primary keyword] — [value] | Odoo Expertos`.
### [High] Article pages are orphans — zero in-body internal links
`/odoo/odoo-hosting-cloud-infraestructura-2025/` has 4 hrefs total (favicon ×2, self-canonical, CSS) — **no related-article links, no rendered breadcrumb, no link to parent category**. PageRank cannot flow; with 1,210 pages the architecture is a flat spike.
- **Fix:** Add rendered HTML breadcrumb (not just schema), a parent-category link, and ≥3 related-article links per article (templated).
### [High] Homepage copy destroys E-E-A-T
H1 "Mientras Lees Esto, Tus Competidores Usan IA Para Robarte Clientes"; H2s "⚔️ ELIGE TU ARMA DE DOMINACIÓN", "🔥 COMPETIDORES SIENDO DESTRUIDOS EN VIVO", CTA "DESTRUIR COMPETENCIA AHORA"; "¡ALERTA! …ROBANDO tus mejores clientes" (confirmed in screenshot). Unsourced "280% ROI" in the title tag; publisher meta = "Apex AI Research Labs LLC".
- **Why:** Combat/fear hype + unsourced superlatives is the pattern QRG raters flag as low-trust lead-gen for a B2B ERP buyer.
- **Fix:** Factual, keyword-led H1 (e.g. "Consultoría e Implementación Odoo ERP para Empresas — LATAM"); benefit-framed H2s; move urgency to a secondary CTA; source or drop the ROI claim.
### [High] Non-localized URL slugs on EN/DE
`/en/odoo-ia/` ("IA" is Spanish), `/en/odoo/…infraestructura…` (Spanish slug). Localized equivalents `/en/odoo-ai/`, `/de/odoo-ki/` 404.
- **Fix:** Localized slug convention for new pages; 301 once content is translated.
### [Medium] Thin article bodies (~400450 words of real content)
`/odoo/odoo-hosting-cloud-infraestructura-2025/` ≈610 words incl. chrome → ~400450 body words on a complex technical topic. H2 outline is good; sections are 12 sentences.
- **Fix:** Expand each H2 to 200300 words of genuine guidance.
### [Low] Trust gaps
No `/contacto/` or `/sobre-nosotros/` page (both 404); only footer legal links + a Wyoming LLC shell address. Author "Dr. María Elena Rodríguez" has no author page (`/autor/…` 404); homepage author meta = "Apex AI Research Labs LLC" (different entity). Odoo-partner claim unverified.
- **Fix:** Real About + Contact pages in nav; verifiable author pages or attribute to the org; link/verify Odoo partner badge.
### What's already good (content)
- Homepage hreflang + canonicals correct; page-level `lang` attribute is correct even where content isn't (so the fix is content, not template structure).
- Spanish article title/meta well-formed; Spanish article H2 hierarchy is logical and citable.
- Legal pages (privacy/terms/legal-notice) + footer address/email present.
- Critical CSS inlined + async minified CSS shipped.
## 3. Schema / Structured Data — Score 45/100
What exists: Homepages have `Organization` + `WebSite` (+SearchAction). Category pages have `CollectionPage` (inline `BreadcrumbList` + `Organization` publisher). Article pages have `Article` (JSON-LD) **plus** duplicate Microdata. All use `https://schema.org` (correct).
### [Critical] Broken logo domain — `www.odooexpertos.com` (no hyphen) does not resolve
CollectionPage publisher logo = `https://www.odooexpertos.com/assets/logo.png`. The Article publisher uses yet another (`…/logo.png` non-www). Homepage uses `favicon.svg`. → 3 different logo URLs, one pointing at a **dead domain**. No logo passes validation.
- **Fix:** One absolute logo URL on the real domain, site-wide (e.g. `https://www.odoo-expertos.com/favicon.svg` or a real 112px+ PNG).
### [Critical] German page ships Spanish schema
`/de/odoo-hosting/` (`lang="de"`) CollectionPage `name`="Centro de Recursos Hosting Odoo", breadcrumb "Inicio"/"Hosting Odoo", no `inLanguage`. Misleads entity understanding.
- **Fix:** Translate schema strings to German; add `"inLanguage":"de"` (breadcrumb "Inicio"→"Startseite").
### [Critical] Article schema missing required `image` (+ `mainEntityOfPage`)
`/odoo/odoo-hosting-cloud-infraestructura-2025/` Article has headline/author/dates but **no `image`** → ineligible for Google Article rich results. `dateModified` is also truncated/invalid ("202…") → Google ignores the block.
- **Fix:** Add absolute `image` (≥1200px) + `mainEntityOfPage`; populate a valid ISO `dateModified`.
### [High] Schema URLs use non-www while canonicals use www
CollectionPage `url`/breadcrumb `item` = `https://odoo-expertos.com/…`; canonical = `https://www…`. Entity-consolidation mismatch.
- **Fix:** Use the www host in all schema `url`/`item`.
### [High] Duplicate Article markup (JSON-LD + Microdata) on same page → remove Microdata `itemtype`.
### [High] Organization differs ES vs EN homepage with no shared `@id` → define once at root with `"@id":"…/#organization"` and reference it elsewhere (EN's richer address/founder data is otherwise invisible site-wide).
### [Medium] `sameAs: []` empty on all Org blocks → populate (LinkedIn, YouTube, directories) — high value for Knowledge Panel + AI entity resolution.
### [Medium] `WebSite` SearchAction points to `?s=` search that likely doesn't exist on a static site → remove if non-functional.
### Missing opportunities: `BreadcrumbList` on ~240 deep pages; `Service` on homepage; `FAQPage` where question-H2s exist; `inLanguage` on ES/DE blocks.
### What's good (schema): correct `@context`; EN Org is rich (address/founder/parentOrganization/availableLanguage); absolute URLs; ISO dates; no deprecated types.
---
## 4. AI Search Readiness (GEO) — Score 50/100
### [Critical] Homepage is anti-citation
Caps-lock urgency, military metaphors, unsourced stats (280%/65%/400%), no schema/date/author on the highest-authority page → LLMs deprioritize the domain as a source. **Fix:** factual entity-style homepage (see Content §).
### [High] `llms.txt` is spec-valid but link-thin — claims "1,185+ guides" but lists only ~9 URLs; "Key Topics"/"Content Quality" sections are link-free prose. **Fix:** add 812 representative URLs per `##` section.
### [High] `llms-full.txt` is ~11 KB (a longer index, not a content dump) — tools that auto-ingest it cache a directory, not substance. **Fix:** generate a real per-language full-text dump (`llms-full-es.txt`, …) with H1 + intro + tables per page.
### [High] No authors/dates on content pages; 2025 vs "2026" freshness inconsistency; missing `Article`/`FAQPage` JSON-LD (overlaps Schema §). **Fix:** bylines + datePublished/dateModified + Article/FAQ schema.
### [Medium] Long interlocked passages — apply "direct answer first" in 134167-word self-contained blocks (the ES "¿Odoo Cloud vs Hosting Propio?" H2 already does this — extend it).
### [Medium] No off-site entity signals (YouTube/Reddit/Wikipedia). YouTube mentions correlate strongest with AI citations — 36 month play.
### [Low] D3 visualizations are client-rendered → invisible to non-JS AI crawlers. Add an accessible HTML data table beside each chart.
### What's exemplary (GEO): robots.txt allows every major answer engine and routes to llms.txt; static HTML = ideal ingestion; llms.txt structurally compliant; 6-language sitemap discovery.
Platform estimates: Google AIO 45 · ChatGPT/SearchGPT 50 · Perplexity 55 · Bing Copilot 45.
---
## 5. Performance / Core Web Vitals — Score ~65/100 (ESTIMATED — PSI rate-limited, no field/lab data)
> CWV could not be measured (Google PSI/CrUX returned HTTP 429 on the shared quota). Numbers are estimated from HTML/headers. Re-run with a PSI API key or `npx lighthouse <url>` for real values.
Estimated (mobile): Homepage LCP ~2.02.8s · INP ~150300ms · CLS ~0.05. D3 page LCP ~1.52.0s · INP ~100200ms.
### [Critical] `document.write()` injects header/footer/eeat on every content page
`<script>document.write(createHeader())</script>` (×3) is parser-blocking, defeats the preload scanner, and causes layout shift when the header pops in. Affects ~990 content pages. **Fix:** render into a pre-sized placeholder div via `insertAdjacentHTML`, `defer` the component scripts, reserve header height (`min-height`).
### [High] 32 KB inline `<style>` on homepage — only ~1.2 KB is true critical CSS; the rest (animations, cards, carousel) is non-critical and delays style recalc/LCP. **Fix:** move non-critical rules to `main.min.css`; keep inline <14 KB.
### [High] Content pages load `main.min.css` render-blocking (no async pattern, no critical CSS) — apply the homepage's `preload…onload`+`<noscript>` pattern in the page generator (~990 pages).
### [High] D3.js loaded from `d3js.org` at runtime on the homepage (no preconnect), while the D3 *content page* has a `preconnect` to d3js.org but doesn't use D3. **Fix:** self-host `d3.v7.min.js`, preload only where used, remove the misplaced preconnect, defer D3 init until in-viewport (a static SVG already covers first paint).
### [High] Large unthrottled inline JS on homepage — mousemove particle trail creates a DOM node per move (INP risk). **Fix:** externalize + `defer`; throttle with rAF; disable particle trail on mobile.
### [Medium] `Cache-Control: public, max-age=0, must-revalidate` on all assets — every repeat visit revalidates CSS/JS. **Fix:** `max-age=31536000, immutable` for hashed/versioned `/css`,`/js`,`/components` in `vercel.json`; keep short TTL on HTML.
### [Medium] Continuous CSS animations (kenBurns/shimmer) run off-screen → wrap in IntersectionObserver.
### What's good (performance): Brotli on all assets (HTML 109KB→~23KB); Vercel edge HTTP/2; HSTS; critical CSS inlined + async CSS on homepage (correct pattern); **system font stack (no web fonts)**; no hero image (text LCP from inline CSS); all external scripts `defer`; inlined SVG icon sprite; lightweight D3 content page (~17KB).
---
## 6. Images — Score ~60/100 (not deeply crawled this pass)
Deployment notes claim lazy-loading + 1-year image cache, but the homepage uses CSS gradients + inline SVG (no raster hero). Not verified at scale.
- **To check next:** alt-text coverage on content-page images, webp/avif vs png/jpg, explicit width/height (CLS), and that `loading="lazy"` is NOT applied to above-the-fold images. Run `seo-images`/`seo-visual` on a deep-page sample with a PSI key.
---
## Methodology & Artifacts
- Tool: claude-seo v2.0.0, 6 parallel specialist agents (technical, content, schema, geo, performance) + site-wide PowerShell/curl probes.
- Raw data: `raw/` (robots.txt, 6 sitemaps, llms.txt/full, homepage HTML, redirect map, PSI attempt log).
- Screenshots: `screenshots/` (homepage desktop + mobile).
- Limits: bounded ~20-URL sample (representative of the 1,210-page templates); CWV estimated (PSI 429); image audit deferred.
---
---
# PART B — DEEP AUDIT (Google Search Console + live measurement, 2026-05-27)
Added after reviewing real GSC index-coverage exports (`Downloads\website issu oddo expertos\`) + live crawl/measurement. **This is the most important section** — it explains *why the site barely ranks*.
## B0. The headline: ~72% of the site is NOT indexed
From GSC index-coverage exports (status as of 21.05.26):
| GSC status | Pages | What it means | Dominant root cause |
|---|---:|---|---|
| **Gecrawlt zurzeit nicht indexiert** (Crawled, not indexed) | **587** | Google crawled them and *chose not to index* | Thin / templated / low-value content |
| **Gefunden nicht indexiert** (Discovered, not indexed) | **134** | Found in sitemap, not even crawled | Crawl budget starved by low site quality + weak internal linking |
| **Duplikat, Google wählte anderen Canonical** | **103** | Google treats them as duplicates of another page | **Untranslated** PT/FR/EN pages = duplicates of the Spanish original |
| **Alternative Seite mit kanonischem Tag** | **31** | Canonicalized away (mostly `/en/odoo/…`) | Correct canonical, but page adds no unique value |
| **Seite mit Weiterleitung** (redirect) | **~45** | URL redirects | Country-variant + `/index.html` URLs **still listed in sitemaps** |
| **Nicht gefunden (404)** | **12** | Dead | Case-sensitivity + wrong-category + missing pages |
**~870 of ~1,210 URLs (≈72%) are excluded from Google's index.** Only ~28% can rank. This is the single biggest problem and it dwarfs everything in Part A.
### The root-cause chain (fixing these clears most of the 870)
1. **Untranslated content** (Part A §2 C2) → 103 "duplicate" + a large share of the 587 "crawled not indexed". Google literally flags PT/FR pages as duplicates of the ES original because the body text *is* Spanish.
2. **Thin, templated content** (~400450 words, near-identical boilerplate) → the bulk of the 587 "crawled not indexed". Google's bar for indexing a 1,210-page programmatic site is "is each page uniquely valuable?" — currently no.
3. **Templated/near-duplicate meta descriptions** → reinforces the duplicate signal. Measured live: `/odoo/odoo-crm-…` and `/odoo/odoo-inventario-…` both use *"Guía completa sobre Odoo [X] con Odoo. Descubre las mejores prácticas y soluciones empresariales."* — only the keyword swapped. (Your hypothesis confirmed in pattern; titles are not identical but article `title` frequently equals the `H1`.)
4. **Weak internal linking / crawl depth** → 134 "discovered not indexed" (Google won't spend budget crawling pages the site itself barely links to).
5. **Sitemap hygiene** → sitemaps contain 404s, redirecting URLs, and non-canonical URLs, which lowers trust in the whole sitemap and wastes crawl budget.
## B1. Click depth & internal linking (measured live)
- Homepage exposes **only 9 internal links** (home, 3 category hubs, a few CTAs). The nav is **injected client-side via `document.write(createHeader())`** in `components/header.js` — it is NOT in the static HTML, so the entire crawlable link graph depends on JS rendering.
- Category hubs link **160 articles** total (`/odoo/` 28, `/odoo-hosting/` 78, `/odoo-ia/` 56).
- **37 of 193 Spanish articles are NOT reachable within 2 clicks** (orphaned — only in the sitemap). Extrapolated across 6 languages ≈ the 134 "discovered not indexed".
- **Best practice (your 3-click rule):** every indexable page ≤3 clicks from home. Today many article pages are reachable only via the sitemap (∞ clicks for a user). Article bodies have **zero in-body internal links** (Part A §2 H1) so link equity cannot flow.
## B2. The homepage is visually broken (verified — see `screenshots/www_odoo-expertos_com_desktop.png`)
Full-page capture shows: large **empty dark sections** where service cards / testimonials / "Funcionalidades" content should be; the hero "ecosystem" visualization renders as a few stray dots (D3 not rendering); broken copy ("Historia de Esto Comprobado"); and an **H1 word-spacing bug present on every homepage** — measured live: "Usan IA **ParaRobarte** Clientes", "Transform Your Business **withOdoo** ERP", "**mitOdoo** ERP", "Centro **deInteligencia Artificialpara** Odoo". Words are concatenated (spans rendered without spaces).
- Likely cause: content gated behind `opacity:0` + IntersectionObserver scroll reveals (Part A §5) that don't render server-side, plus a span-spacing bug in the headline builder. Either way: **content invisible to no-JS / partial-JS crawlers and to users who don't scroll**, and the page looks unfinished.
- **Visual score: 3/10.** Not shippable. Needs dev fix + human re-verify.
## B3. 404 patterns worth fixing at the source
- **Case-sensitivity:** `/odoo-Hosting/digitalocean-…` (capital H) 404s — Vercel paths are case-sensitive. Enforce lowercase URLs + add redirects for known capitalized variants.
- **Wrong category slug:** `/odoo-ai/odoo-18-ai-…` 404s because the site uses `/odoo-ia/`. Pick ONE (recommend `/odoo-ai/` for EN once localized) and 301 the other.
- **Linked-but-missing:** `/consultoria-erp`, `/de/odoo/consultoria-erp`, `/recursos/guia-aws-odoo.pdf`, `/mes` — internal links/old URLs point to pages that don't exist. Find the linking source and fix or 301.
## B4. 2026 SEO best-practice comparison
| 2026 best practice | This site | Gap |
|---|---|---|
| Every indexed page uniquely valuable (post-HCU / "crawled-not-indexed" era) | 587 crawled-not-indexed | **Critical** — consolidate/enrich, reduce page count |
| Real localization per market (not MT) | 400+ MT/untranslated pages | **Critical** |
| ≤3 clicks, strong internal links, server-rendered nav | JS `document.write` nav; 37+ orphans/lang | **High** |
| Unique title + meta per page | Templated metas, 260+ char titles | **High** |
| Server-rendered content (Googlebot-renders-but-budget-limited) | Hero/sections JS-reveal; nav JS-injected | **High** |
| Sitemaps = only 200, canonical, indexable URLs | Contains 404/redirect/non-canonical | **High** |
| E-E-A-T: real authors, entity, no fabricated claims | Fake author, "Apex AI Research Labs LLC", 280% ROI unsourced | **High** |
| Core Web Vitals (INP ≤200ms) | document.write + heavy inline JS | **Medium** |
| AI-search (GEO) | Strong crawler posture; weak content authority | **Medium** (strength to build on) |
| HTTPS/HSTS/canonical host | Correct | ✅ |
**Bottom line:** the site was built for *scale* (1,210 pages) before *quality per page*. 2026 Google rewards the opposite. The fix is partly **subtractive** (consolidate thin/duplicate pages, shrink the index to pages that deserve to rank) and partly **corrective** (translate, de-duplicate metas, fix linking, rebuild the homepage, clean sitemaps).