new site
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# Action Plan — odoo-expertos.com SEO Fixes
|
||||
|
||||
**Date:** 2026-05-27 · **Overall health: ~44/100** · Source: `FULL-AUDIT-REPORT.md`
|
||||
|
||||
Ordered by impact ÷ effort. Most high-impact fixes are **template/generator changes** that fan out across ~1,000+ pages — fix the generator, not individual pages.
|
||||
|
||||
---
|
||||
|
||||
## 🔴 CRITICAL — fix immediately (blocks indexing / risks site-wide downgrade)
|
||||
|
||||
| # | Action | Where | Effort |
|
||||
|---|--------|-------|--------|
|
||||
| C1 | **Remove the 3 dead `<loc>` entries** for `/en/odoo-hosting/`, `/fr/odoo-hosting/`, `/pt/odoo-hosting/` from `sitemap-en/fr/pt.xml`. Then **build the missing index pages** (mirror DE/AR). | sitemaps + page generator | Low (purge) / Med (build) |
|
||||
| C2 | **Resolve the EN/DE untranslated-content problem** (400+ pages with `lang="en/de"` serving Spanish/garbled text). Decide: translate, or remove+hreflang-to-ES, or 301 to Spanish canonical. Stop generating Spanish-slug EN/DE pages. | content pipeline | High (decision + execution) |
|
||||
| C3 | **Fix inner-page hreflang**: EN template add `pt`+`ar`; DE template build `es`/`x-default` from the **root** ES URL (no `/de/` prefix). Add full 7-entry hreflang to all **category index** pages (currently zero). | head template | Med |
|
||||
| C4 | **Fix Organization logo + schema host site-wide**: replace dead `www.odooexpertos.com/...logo.png` with one real URL on `www.odoo-expertos.com`; switch all schema `url`/`item` from non-www → www. | schema template | Low |
|
||||
| C5 | **Rebuild the homepage as an authoritative entity page**: factual keyword-led H1, drop combat/fear hype + emoji H2s, source or remove "280% ROI", add Organization JSON-LD (shared `@id`, populated `sameAs`), last-updated date. | homepage | Med |
|
||||
| C6 | **Replace `document.write()` header/footer/eeat** with `insertAdjacentHTML` into a pre-sized placeholder + `defer` the component scripts. | content-page generator | Med |
|
||||
|
||||
---
|
||||
|
||||
## 🟠 HIGH — within ~1 week
|
||||
|
||||
| # | Action | Where | Effort |
|
||||
|---|--------|-------|--------|
|
||||
| H1 | Rewrite category titles to 50–60 chars in the target language (kill the 270–300-char stuffed strings). | category template | Low |
|
||||
| H2 | Add rendered breadcrumb + parent-category link + ≥3 related-article links to article template (fix orphan pages). | article template | Med |
|
||||
| H3 | Add `Article.image` + `mainEntityOfPage` + valid `dateModified`; remove duplicate Microdata `itemtype`; add `BreadcrumbList` to deep pages. | schema template | Med |
|
||||
| H4 | Add author bylines + datePublished/dateModified (visible + schema) to content pages; create real author pages or attribute to the org. | content + author pages | Med |
|
||||
| H5 | Self-host D3 (`/js/d3.v7.min.js`), preload only where used, remove misplaced d3js.org preconnect, defer D3 init until in-viewport. | homepage + D3 pages | Low |
|
||||
| H6 | Trim homepage inline `<style>` 32 KB → <14 KB (move non-critical to `main.min.css`); externalize + `defer` the big inline JS; throttle mousemove with rAF. | homepage | Med |
|
||||
| H7 | Apply async-CSS (`preload…onload`+`<noscript>`) + ~2 KB critical CSS to the content-page template. | content-page generator | Low |
|
||||
| H8 | Fix robots.txt: one group per agent; merge `Disallow: /*?` `/*&` into the FIRST `User-agent: *`; delete the 2nd `*` block, duplicate Bingbot/CCBot, and `/*#`. | robots.txt | Low |
|
||||
| H9 | Expand `llms.txt` (8–12 links per section); regenerate `llms-full.txt` as a genuine per-language content dump. | llms files | Low (scripted) |
|
||||
|
||||
---
|
||||
|
||||
## 🟡 MEDIUM — within ~1 month
|
||||
|
||||
| # | Action |
|
||||
|---|--------|
|
||||
| M1 | Add security headers in `vercel.json` (`X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`). |
|
||||
| M2 | Add long-lived `Cache-Control: max-age=31536000, immutable` for hashed `/css`,`/js`,`/components` (with filename/version hashing). |
|
||||
| M3 | Fix `og:locale` on DE/FR/PT category pages (currently `es_ES`) → `de_DE`/`fr_FR`/`pt_*`. |
|
||||
| M4 | Expand thin article bodies (~400w) to 200–300 words per H2 section. |
|
||||
| M5 | Populate `sameAs` (LinkedIn, YouTube, directories); remove non-functional `?s=` SearchAction or wire real search. |
|
||||
| M6 | Add `Service` schema (homepage) + `FAQPage` where question-H2s exist; add `inLanguage` to ES/DE schema blocks. |
|
||||
| M7 | Create `/contacto/` + `/sobre-nosotros/` pages in primary nav; verify/link Odoo partner badge. |
|
||||
| M8 | Apply "direct-answer-first" 134–167-word passages across content pages (citability). |
|
||||
| M9 | Wrap continuous CSS animations (kenBurns/shimmer) in IntersectionObserver. |
|
||||
|
||||
---
|
||||
|
||||
## 🔵 LOW / backlog
|
||||
- Localized URL slugs for EN/DE (`/en/odoo-ai/`, `/de/odoo-ki/`) with 301s once translated.
|
||||
- Single-hop `http-apex → https-www` redirect.
|
||||
- Off-site entity building (YouTube channel → strongest AI-citation signal; r/Odoo participation; Wikipedia if notable).
|
||||
- Accessible HTML data tables beside D3 charts (AI-crawler + a11y).
|
||||
|
||||
---
|
||||
|
||||
## Verification checklist (after fixes)
|
||||
- [ ] `curl -I` the 3 former-404 category pages → 200; sitemaps contain no 404 `<loc>`.
|
||||
- [ ] hreflang reciprocity passes (EN has pt+ar; DE es/x-default resolve 200) — re-run technical agent.
|
||||
- [ ] Rich Results Test passes for Organization (logo loads) + Article (image present) + Breadcrumb.
|
||||
- [ ] Re-run PageSpeed **with an API key**; confirm LCP ≤2.5s / INP ≤200ms / CLS ≤0.1 on mobile.
|
||||
- [ ] Homepage re-screenshot: factual H1, no combat hype.
|
||||
- [ ] Re-audit: target health ≥70/100.
|
||||
@@ -0,0 +1,76 @@
|
||||
# BLOG-PIPELINE.md - per-article workflow for W12 & W13 (claude-blog full pipeline + kie.ai z-image)
|
||||
|
||||
Driven by seo-audit-2026-05-27\goals\MASTER-SEO-75.txt.
|
||||
|
||||
## Foundation (run ONCE before any article)
|
||||
1. `/blog brand init` -> BRAND.md + VOICE.md at repo root (autoloads into every subskill).
|
||||
2. `/blog persona create "Equipo Odoo Expertos"` -> personas/equipo-odoo-expertos.md (REPLACES every "Dr. Maria Elena Rodriguez").
|
||||
3. `/blog flow sync` -> FLOW framework prompts cached locally for downstream skills.
|
||||
4. `/blog strategy "odoo erp consulting LATAM"` -> strategy doc; informs cluster + persona angles.
|
||||
|
||||
## IMAGE GENERATION POLICY (overrides /blog image default; z-image ONLY)
|
||||
**Pre-flight (run ONCE in Phase 0, BEFORE any article):**
|
||||
```
|
||||
powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Prompt "abstract data visualization, blue gradient, no text" -OutPath "seo-audit-2026-05-27\scripts\.zimage-probe.png" -Model z-image -Aspect 16:9 -Resolution 1K
|
||||
```
|
||||
If this FAILS, abort the goal with status "z-image unavailable on this kie.ai account — fix model access before proceeding". NO fallback to other models.
|
||||
|
||||
**Per article: generate >=3 images via z-image only.**
|
||||
1. Hero/OG (16:9, 2K) -> `images/<slug>-hero.png`
|
||||
2. Inline mid-body (16:9 or 4:3, 1K) -> `images/<slug>-fig1.png`
|
||||
3. Inline end (16:9 or 4:3, 1K) -> `images/<slug>-fig2.png`
|
||||
|
||||
**Prompt rules (HARD):**
|
||||
- Every prompt MUST end with: ", NO text, NO letters, NO numbers, NO logos, NO watermarks."
|
||||
- Editorial illustration aesthetic, neutral palette, clean enterprise feel, no stock-photo cliches.
|
||||
- Distinct subject per image (hero = topic metaphor; fig1 = mechanism/architecture motif; fig2 = outcome/comparison motif).
|
||||
|
||||
**Insertion:**
|
||||
- Set `<meta property="og:image" content="https://www.odoo-expertos.com/images/<slug>-hero.png">` and add `<link rel="preload" as="image" href="/images/<slug>-hero.png">` in <head>.
|
||||
- Place fig1 after the 2nd H2, fig2 after the 4th H2. Both `<img>` tags need unique `alt=""` descriptions derived from the surrounding H2 + body.
|
||||
- Add ImageObject schema for the hero (and fig1/fig2 if relevant) inside the Article JSON-LD.
|
||||
|
||||
Helper: `powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Prompt "<prompt>" -OutPath "images/<slug>-<role>.png" -Model z-image -Aspect 16:9 -Resolution 2K`
|
||||
|
||||
## Per-article (run for EVERY URL in OPPORTUNITIES sec 1 and sec 2)
|
||||
For each article slug like `odoo-hosting/odoo-vs-sap-hosting-2026/index.html`:
|
||||
|
||||
1. **Research** - `/blog discourse "<topic phrase>"` -> DISCOURSE.md with last-30-days sources, debates, gaps. If a Google AI / NotebookLM key is configured, also `/blog notebooklm "<question>"`.
|
||||
2. **Flow framing** - `/blog flow find "<topic phrase>"` -> pick the strongest FLOW prompt for this article. `/blog flow optimize` to refine.
|
||||
3. **Brief** - `/blog brief "<topic phrase>"` -> audience, intent, angle, key entities, SERP context.
|
||||
4. **Outline** - `/blog outline "<topic phrase>"` -> SERP-informed H2/H3 skeleton.
|
||||
5. **Rewrite** - `/blog rewrite <relative-path>` using BRAND.md + VOICE.md + persona + FLOW + blog-rewrite humanized cadence. HARD CONSTRAINTS to state in the rewrite request:
|
||||
- Preserve <head> EXCEPT add ONE marker (W12-deep-rewrite or W13-ai-search) + the og:image/preload set by step 8.
|
||||
- Preserve hreflang, canonical, OG, header/footer/nav, breadcrumb (W6), ALL D3.js <script> refs.
|
||||
- Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos" (visible byline + Article schema author + Person @id).
|
||||
- W12: >=1,200 unique body words, direct-answer 60-150w opening, 4-6 question-led H2s.
|
||||
- W13: deepen with 8+ FAQ Q&A, HTML comparison <table>, per-claim source URLs.
|
||||
6. **Fact-check** - `/blog factcheck <path>` -> the skill actively fetches and verifies source URLs. Must show 0 unverified numeric claims. On FAIL: drop the number or add a source via `/blog discourse`, re-run.
|
||||
7. **SEO check** - `/blog seo-check <path>` -> title length, meta, schema validity, internal links, image alts. Must pass.
|
||||
8. **Image** - generate hero/OG image via the helper above; update og:image and add the preload link. Add `alt="..."` to any new <img>.
|
||||
9. **Schema** - `/blog schema <path>` -> regenerate Article + FAQPage JSON-LD reflecting actual H2 questions; ImageObject for the new hero image.
|
||||
10. **GEO gate** - `/blog geo <path>` -> AI-citation readiness audit. Must show direct-answer-first opening, question-led H2s, FAQ schema present, sourced stats. Address top findings if any.
|
||||
11. **Quality gate** - `/blog analyze <path>` -> 0-100 score. Must be >=80. If <80, address top 3 Critical/High findings and re-run.
|
||||
12. **Commit** - `git add <path> images/<slug>-hero.png; git commit -m "fix(<W#>): rewrite <slug> via blog pipeline (analyze=<score>, geo=<score>)"`.
|
||||
|
||||
## Stop conditions per article
|
||||
- If `/blog analyze` stays <80 after 3 retries OR `/blog geo` stays FAIL after 3 retries -> log slug + lowest categories to seo-audit-2026-05-27\BLOG-FAILURES.md and skip. Do not block the master.
|
||||
- If `/blog factcheck` cannot source a claim after 2 retries -> remove the unsourced claim. NEVER fabricate.
|
||||
|
||||
## After all articles in a cluster
|
||||
- `/blog cluster plan "<seed>"` (if not already done in master Phase 2).
|
||||
- `/blog cluster execute "<seed>"` -> applies internal pillar<->spoke links.
|
||||
|
||||
## After all clusters
|
||||
- `/blog taxonomy sync` -> aligns tag/category slugs to the cluster plan.
|
||||
- `/blog cannibalization .` -> re-sweep. Resolve any 301 flags (e.g., the 2025/2026 mejores-proveedores collision per OPPORTUNITIES sec 5).
|
||||
- `/blog locale-audit .` -> hreflang/parity/freshness across the 6 languages. Pages noindexed by W7 are expected to show parity gaps; that is fine.
|
||||
|
||||
## Post-deploy (after main is live on Vercel)
|
||||
- `/blog google psi https://www.odoo-expertos.com/` -> CWV lab.
|
||||
- `/blog google crux https://www.odoo-expertos.com/` -> CWV field (if available).
|
||||
- `/blog google gsc submit` -> resubmit each sitemap; "Validate Fix" on coverage issues if the skill supports.
|
||||
- `/blog google ga4` -> baseline organic traffic (only if creds configured).
|
||||
- `/blog audit .` -> post-deploy site health. Target: 0 Critical.
|
||||
- `/blog calendar` -> generate forward editorial plan for the surviving thin pages so iteration is structured.
|
||||
- `/blog repurpose <pillar-path>` -> extend Cluster A/B/C pillars to social/email snippets (non-gating output).
|
||||
@@ -0,0 +1,281 @@
|
||||
# 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 | 270–300+ 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 270–300+ 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 50–60 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 (~400–450 words of real content)
|
||||
`/odoo/odoo-hosting-cloud-infraestructura-2025/` ≈610 words incl. chrome → ~400–450 body words on a complex technical topic. H2 outline is good; sections are 1–2 sentences.
|
||||
- **Fix:** Expand each H2 to 200–300 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 8–12 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 134–167-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 — 3–6 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.0–2.8s · INP ~150–300ms · CLS ~0.05. D3 page LCP ~1.5–2.0s · INP ~100–200ms.
|
||||
|
||||
### [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** (~400–450 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).
|
||||
@@ -0,0 +1,128 @@
|
||||
# GOAL-DRIVEN FIX PLAN — odoo-expertos.com
|
||||
**For a `/goal` run with parallel agents.** Date: 2026-05-27 · Source of truth: `FULL-AUDIT-REPORT.md` (Part A + Part B).
|
||||
|
||||
> **Target repo:** `C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos` (GitHub `LarryWalkerDEV/odoo-expertos`, deploys to Vercel `www.odoo-expertos.com`).
|
||||
> **NOT** the immoapp repo. Agents must work in the Odoo repo and never write to immoapp.
|
||||
> **Codebase:** ~1,210 hand/script-generated static `.html` files + JS components (`components/*.js`) + `templates/pillar-page.html` + `vercel.json` + build scripts. There is **no central page generator**, so most content fixes are **scripted bulk transforms (codemods) over the HTML files** (write a Node/Python codemod, run it over all files, verify, commit). Component/template fixes touch one file and affect all pages that include them.
|
||||
|
||||
---
|
||||
|
||||
## How to run with /goal + parallel agents
|
||||
1. Each **workstream (W#)** is a self-contained `/goal`. Most are **parallel-safe** (disjoint files). Respect the dependency notes.
|
||||
2. Batching:
|
||||
- **Batch 1 (parallel, fast/independent):** W1, W2, W8, W9, W10, W11
|
||||
- **Batch 2 (parallel codemods):** W3, W4-structure, W5, W6
|
||||
- **Batch 3 (the big rock, gated):** W7 (localization/consolidation). After W7, re-run W4-final (hreflang reflects surviving pages) then W1-final (regen sitemaps).
|
||||
3. Each workstream ends by running its **Verify** and ticking **Review**. Orchestrator runs `REVIEW.ps1` to confirm ALL fixes landed before the goal is done.
|
||||
4. One branch/PR per workstream; nothing merges until its Verify passes.
|
||||
|
||||
---
|
||||
|
||||
## Baseline metrics (captured 2026-05-27 — compare after fixes)
|
||||
| Metric | Baseline | Target |
|
||||
|---|---|---|
|
||||
| URLs not indexed (GSC) | ~870 / 1,210 (approx 72%) | <15% (after re-crawl, 2-4 wks) |
|
||||
| Crawled-not-indexed | 587 | <100 |
|
||||
| Duplicate (wrong canonical) | 103 | <20 |
|
||||
| Discovered-not-indexed | 134 | <30 |
|
||||
| True 404s | 12 | 0 |
|
||||
| Sitemap URLs that redirect/404/non-canonical | present | 0 |
|
||||
| Category title length | 260-267 chars | <=60 |
|
||||
| Meta descriptions unique | templated/near-dup | 100% unique |
|
||||
| ES articles reachable <=2 clicks | 156 / 193 (37 orphaned) | 193 / 193 |
|
||||
| Homepage H1 word-spacing bug | present (all langs) | fixed |
|
||||
| Homepage visual score | 3/10 | >=8/10 |
|
||||
| Hreflang reciprocity | broken (EN missing pt/ar; DE->404 es) | 100% reciprocal, all 200 |
|
||||
| Schema logo URL | dead domain odooexpertos.com | valid, www |
|
||||
| Security headers | missing 4 | present |
|
||||
|
||||
---
|
||||
|
||||
## WORKSTREAMS
|
||||
|
||||
### W1 - Sitemap & redirect hygiene · parallel-safe (final pass gated on W7)
|
||||
**Problem:** sitemaps list 404s, redirecting URLs, and non-canonical URLs (Part B B0/B3).
|
||||
**Tasks:** (1) Build missing index pages `/en/odoo-hosting/`, `/fr/odoo-hosting/`, `/pt/odoo-hosting/` (mirror DE/AR) OR drop their loc entries if W7 retires them. (2) Remove every sitemap URL that 404s/redirects (country-variant + index.html URLs in vercel.json)/non-canonical. (3) Each loc = exact canonical (www, trailing slash), matching the page canonical tag. (4) Regenerate via `generate_sitemap.sh`.
|
||||
**Files:** `sitemap*.xml`, `generate_sitemap.sh`, `vercel.json`.
|
||||
**Acceptance:** 0 sitemap URLs non-200; every loc == live canonical.
|
||||
**Verify:** `pwsh REVIEW.ps1 -Only W1`. **Review:** [ ]
|
||||
|
||||
### W2 - robots.txt cleanup · parallel-safe
|
||||
**Problem:** two `User-agent: *` groups (2nd ignored), duplicate Bingbot/CCBot, meaningless `/*#` (Part A 1).
|
||||
**Tasks:** one group per agent; merge `Disallow: /*?` and `/*&` into the FIRST `User-agent: *`; delete the 2nd `*` block, duplicate Bingbot/CCBot, and the fragment disallow; keep AI-crawler allows + Sitemap line.
|
||||
**Files:** `robots.txt`.
|
||||
**Acceptance:** exactly one `User-agent: *`; query disallows present in it; no fragment disallow; one Bingbot, one CCBot.
|
||||
**Verify:** `pwsh REVIEW.ps1 -Only W2`. **Review:** [ ]
|
||||
|
||||
### W3 - Structured data (schema) · parallel-safe (codemod)
|
||||
**Problem:** dead logo domain odooexpertos.com; non-www schema URLs; DE page Spanish schema; Article missing image/mainEntityOfPage; truncated dateModified; duplicate Microdata; empty sameAs; no shared Org @id; missing inLanguage (Part A 3).
|
||||
**Tasks (codemod over all .html + templates/pillar-page.html + components/eeat.js):** (1) replace odooexpertos.com -> www.odoo-expertos.com and all non-www schema url/item -> www. (2) ONE Organization with stable @id, real logo, populated sameAs; reference by @id elsewhere. (3) Article: add absolute image + mainEntityOfPage + valid ISO dateModified; remove duplicate Microdata itemtype. (4) add BreadcrumbList JSON-LD to deep pages; inLanguage per page; translate DE/PT/FR schema strings (coordinate W7).
|
||||
**Files:** bulk `.html`, `templates/pillar-page.html`, `components/eeat.js`.
|
||||
**Acceptance:** Rich Results passes for Organization(logo loads)/Article(image)/Breadcrumb on sample; 0 occurrences of dead domain or non-www JSON-LD.
|
||||
**Verify:** `pwsh REVIEW.ps1 -Only W3`. **Review:** [ ]
|
||||
|
||||
### W4 - Hreflang correctness · structure parallel-safe; FINAL pass gated on W7
|
||||
**Problem:** EN inner pages omit pt+ar; DE inner pages point es/x-default to /de/-prefixed Spanish slugs that 404; category pages have ZERO hreflang (Part A 1).
|
||||
**Tasks (codemod over all .html):** (1) each page emits full hreflang for the languages it actually has, www, all resolving 200, plus x-default -> root ES URL (no /de/ prefix). (2) fix DE: es and x-default hrefs built from the root ES path. (3) add the block to all category index pages. (4) enforce reciprocity; drop hreflang to non-existent variants.
|
||||
**Files:** bulk `.html`, head template.
|
||||
**Acceptance:** 100% reciprocity on sample; every hreflang href 200; category pages have hreflang.
|
||||
**Verify:** `pwsh REVIEW.ps1 -Only W4`. **Review:** [ ]
|
||||
|
||||
### W5 - Titles & meta descriptions · parallel-safe (codemod)
|
||||
**Problem:** category titles 260-267 chars (stuffed); templated near-duplicate metas; title==H1; og:locale=es_ES on DE/FR/PT (Part A 2, Part B B0.3).
|
||||
**Tasks (codemod over all .html):** (1) category titles <=60 chars, target-language pattern `[keyword] - [value] | Odoo Expertos`. (2) every meta description UNIQUE (kill the "Guia completa sobre Odoo X con Odoo..." template) generated from real page content. (3) og:locale per language.
|
||||
**Files:** bulk `.html`.
|
||||
**Acceptance:** 0 titles >60; 0 duplicate metas corpus-wide; og:locale matches lang.
|
||||
**Verify:** `pwsh REVIEW.ps1 -Only W5`. **Review:** [ ]
|
||||
|
||||
### W6 - Internal linking & crawl depth (<=3 clicks) · parallel-safe (OWNS the JS-nav removal)
|
||||
**Problem:** nav injected client-side via a parser-blocking DOM-write in components/header.js (JS-dependent); 37+ orphaned articles/lang; article bodies have 0 internal links (Part B B1).
|
||||
**Tasks:** (1) render header/footer/eeat as STATIC HTML in every page (replace the createHeader()/createFooter()/createEEAT() injection with baked-in HTML via codemod, or a build-time include); keep the mobile-toggle JS. (2) category hubs link ALL their articles (crawlable `<a>` pagination if needed) -> every article <=2 clicks from a hub. (3) article template: rendered breadcrumb (HTML anchors, not just schema) + parent-category link + >=3 related-article links. (4) add an HTML sitemap page `/mapa-del-sitio/` linked in the footer.
|
||||
**Files:** `components/header.js`/`footer.js`/`eeat.js` (+ bulk .html to inline), category index pages, article template, footer.
|
||||
**Acceptance:** every indexable page <=3 clicks from `/`; nav present in static HTML (no JS); 0 orphans vs sitemap.
|
||||
**Verify:** `pwsh REVIEW.ps1 -Only W6` (re-runs the depth crawler in raw/analyze.py; reachable==total).
|
||||
**Review:** [ ] · **Dep:** owns the JS-nav->static conversion (W10 references it).
|
||||
|
||||
### W7 - Content localization & consolidation · THE BIG ROCK · gated, mostly sequential
|
||||
**Problem:** 400+ EN/DE pages serve Spanish/garbled MT (-> 103 duplicate + much of 587 crawled-not-indexed); thin ~400-word bodies (Part A 2 C2, Part B B0).
|
||||
**Tasks (phased - where most of the 870 unindexed pages are won back):** (1) decide per page-cluster: translate properly, OR consolidate duplicates into one strong page, OR noindex + drop from sitemap. Default: ES canonical; keep a language variant only if genuinely translated. (2) properly translate the kept variants; fix garbled hybrids ("Inteligencai Artificail", "ueber", "fuer"). (3) expand surviving thin articles to >=1,200 words of unique useful content. (4) remove fabricated author / "Apex AI Research Labs LLC"; attribute to real author or org.
|
||||
**Files:** bulk `.html` content, author pages.
|
||||
**Acceptance:** declared lang matches content on 100% sample; no MT-hybrid strings; surviving articles >=1,200 words; no fabricated author.
|
||||
**Verify:** `pwsh REVIEW.ps1 -Only W7`. **Review:** [ ] · **Dep:** W4-final + W1-final run AFTER this.
|
||||
|
||||
### W8 - Homepage rebuild · parallel-safe
|
||||
**Problem:** visually broken (empty sections, unrendered hero viz), H1 word-spacing bug, combat/fear hype, unsourced 280% ROI (Part B B2, Part A 2 H4).
|
||||
**Tasks:** (1) fix H1 span concatenation so words have spaces ("Para Robarte", "with Odoo", "mit Odoo", "de Inteligencia Artificial para") on all 6 homepages. (2) render hero/section content server-side (remove opacity:0-until-scroll gating or give a visible default); fix/remove the broken D3 hero viz; eliminate empty dark sections. (3) replace combat hype with factual, keyword-led E-E-A-T copy; source or remove "280% ROI"; add Organization JSON-LD (shared @id). (4) re-screenshot desktop+mobile; human re-verify >=8/10.
|
||||
**Files:** `index.html`, `en/index.html`, `de/`, `fr/`, `pt/`, `ar/`, related CSS/JS.
|
||||
**Acceptance:** no run-together words; no empty sections; visual score >=8/10.
|
||||
**Verify:** `pwsh REVIEW.ps1 -Only W8` + manual screenshot review. **Review:** [ ]
|
||||
|
||||
### W9 - 404 source fixes · parallel-safe (fast)
|
||||
**Problem:** case-sensitivity (`/odoo-Hosting/`), wrong slug (`/odoo-ai/` vs `/odoo-ia/`), linked-but-missing (`/consultoria-erp`, `.pdf`, `/mes`) (Part B B3).
|
||||
**Tasks:** add lowercase-enforcement + 301s in vercel.json for known capitalized/legacy URLs; pick one of /odoo-ai/ <-> /odoo-ia/ and 301 the other; fix internal links to missing pages or create them.
|
||||
**Files:** `vercel.json`, link sources.
|
||||
**Acceptance:** all 12 GSC 404 URLs return 200 or 301-to-200.
|
||||
**Verify:** `pwsh REVIEW.ps1 -Only W9`. **Review:** [ ]
|
||||
|
||||
### W10 - Performance / CWV · parallel-safe (JS-nav removal owned by W6)
|
||||
**Problem:** 32KB inline CSS, runtime D3 from CDN, Cache-Control max-age=0, render-blocking CSS on content pages (Part A 5).
|
||||
**Tasks:** trim homepage inline style to <14KB (rest -> main.min.css); self-host d3.v7.min.js + preload only where used + remove misplaced preconnect; add `Cache-Control: max-age=31536000, immutable` for hashed /css,/js,/components in vercel.json; apply async-CSS + critical-CSS to the content-page template.
|
||||
**Files:** `index.html`, `vercel.json`, `css/`, `templates/pillar-page.html`, `js/`.
|
||||
**Acceptance:** Lighthouse mobile LCP<=2.5s / INP<=200ms / CLS<=0.1 (PSI key); inline CSS <14KB; D3 self-hosted.
|
||||
**Verify:** `pwsh REVIEW.ps1 -Only W10` + `npx lighthouse`. **Review:** [ ]
|
||||
|
||||
### W11 - Security headers · parallel-safe (fast)
|
||||
**Tasks:** add to vercel.json headers: `X-Content-Type-Options: nosniff`, `X-Frame-Options: SAMEORIGIN`, `Referrer-Policy: strict-origin-when-cross-origin`.
|
||||
**Acceptance:** headers present on live responses. **Verify:** `pwsh REVIEW.ps1 -Only W11`. **Review:** [ ]
|
||||
|
||||
---
|
||||
|
||||
## REVIEW - "did every fix land?"
|
||||
After all workstreams, the orchestrator re-measures vs the baseline table.
|
||||
1. **On-site (automatable now)** - `REVIEW.ps1` reproduces the checks (building blocks already in `raw/analyze.py` + curl probes): W1 sitemap 200+canonical; W2 robots single-group; W3 grep 0 dead-domain/non-www JSON-LD; W4 hreflang reciprocity+200; W5 titles<=60 & metas unique; W6 depth crawler reachable==total & static nav; W7 lang-match + MT-marker grep + word counts; W8 H1 spacing + screenshot >=8/10; W9 the 12 known 404s now 200/301; W10 Lighthouse + inline CSS size; W11 headers.
|
||||
2. **Off-site (lagging, manual)** - after deploy, in Google Search Console: resubmit sitemaps, "Validate Fix" on each coverage issue, re-export coverage in 2-4 weeks. Target not-indexed <15%. This is the ultimate proof; on-site checks are leading indicators.
|
||||
|
||||
**Definition of done:** all 11 Review boxes ticked + REVIEW.ps1 all-green + homepage visual >=8/10 + a fresh `seo-audit` re-run >=70/100, with GSC re-validation queued.
|
||||
|
||||
## Branch/PR map
|
||||
fix/w1-sitemaps · fix/w2-robots · fix/w3-schema · fix/w4-hreflang · fix/w5-titles-meta · fix/w6-internal-links · fix/w7-localization · fix/w8-homepage · fix/w9-404s · fix/w10-perf · fix/w11-headers
|
||||
@@ -0,0 +1,75 @@
|
||||
# KIE-AI-Z-IMAGE.md - reference for all image generation on odoo-expertos
|
||||
|
||||
ALL image generation goes through kie.ai z-image. NEVER use /blog image generate (Gemini), Google Imagen, OpenAI DALL-E, or any other provider. NO model fallback - if z-image errors, abort.
|
||||
|
||||
## Authentication
|
||||
- Header: `Authorization: Bearer ${KIE_API_KEY}`
|
||||
- Key location: `.env.local` at repo root (already populated; gitignored). Loader resolves env var first, then this file.
|
||||
|
||||
## API (async task pattern, same shape as nano-banana-2 / veo3_fast)
|
||||
|
||||
### Submit
|
||||
POST `https://api.kie.ai/api/v1/jobs/createTask`
|
||||
Headers: Authorization Bearer + Content-Type application/json
|
||||
Body:
|
||||
```json
|
||||
{
|
||||
"model": "z-image",
|
||||
"input": {
|
||||
"prompt": "<your prompt>, NO text, NO letters, NO numbers, NO logos, NO watermarks.",
|
||||
"aspect_ratio": "16:9",
|
||||
"resolution": "2K",
|
||||
"output_format": "png"
|
||||
}
|
||||
}
|
||||
```
|
||||
Response (success): `{ "code": 200, "data": { "taskId": "task_..." } }`
|
||||
|
||||
### Poll
|
||||
GET `https://api.kie.ai/api/v1/jobs/getTaskDetails?taskId=<taskId>` (every 8 seconds; total timeout 300s)
|
||||
Headers: Authorization Bearer
|
||||
Response while running: `{ "code": 200, "data": { "status": "pending"|"running" } }`
|
||||
Response when done: `{ "code": 200, "data": { "status": "completed", "output": { "image_url": "https://..." } } }`
|
||||
Other completion fields seen across kie.ai models (handle all three): `output.image_url`, `output.url`, `output.images[0].url`.
|
||||
Response on failure: `{ "code": ..., "data": { "status": "failed"|"error", ... } }` -> ABORT, never retry with another model.
|
||||
|
||||
### Download
|
||||
GET the resolved image URL, save to `images/<slug>-<role>.png` in the repo. Add `<img>` with unique alt; set `og:image` on hero; add `<link rel="preload" as="image" href="/images/<slug>-hero.png">`.
|
||||
|
||||
## Helper (preferred entry point)
|
||||
```
|
||||
powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 \
|
||||
-Prompt "<full prompt ending with NO text/letters/numbers/logos>" \
|
||||
-OutPath "images/<slug>-<role>.png" \
|
||||
-Model z-image \
|
||||
-Aspect 16:9 \
|
||||
-Resolution 2K
|
||||
```
|
||||
Returns the saved absolute path on stdout. Echoes status to stderr. The helper already implements submit/poll/download/error-abort and loads KIE_API_KEY from .env.local.
|
||||
|
||||
## Per-article image set (minimum 3)
|
||||
1. **Hero** -> `images/<slug>-hero.png` aspect 16:9, resolution 2K. Topic metaphor.
|
||||
2. **Fig 1** (after H2 #2) -> `images/<slug>-fig1.png` aspect 16:9 or 4:3, resolution 1K. Mechanism/architecture motif.
|
||||
3. **Fig 2** (after H2 #4) -> `images/<slug>-fig2.png` aspect 16:9 or 4:3, resolution 1K. Outcome/comparison motif.
|
||||
|
||||
All three from z-image; distinct subjects per image; each with its own unique alt text derived from surrounding H2 + body.
|
||||
|
||||
## Prompt rules (HARD)
|
||||
- MUST end with: `", NO text, NO letters, NO numbers, NO logos, NO watermarks."`
|
||||
- Editorial illustration aesthetic; neutral palette; clean enterprise feel; no stock-photo cliches.
|
||||
- Never mention brand names, competitor names, currency symbols, percentages, dates, charts-with-labels, screenshots-of-UI, or human faces.
|
||||
- Subject only - no overlays, no text boxes, no infographics with labels.
|
||||
|
||||
## Pre-flight probe (Phase 0, SETUP only)
|
||||
```
|
||||
powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 \
|
||||
-Prompt "abstract data visualization, blue gradient, NO text, NO letters, NO numbers, NO logos" \
|
||||
-OutPath "seo-audit-2026-05-27\scripts\.zimage-probe.png" \
|
||||
-Model z-image -Aspect 16:9 -Resolution 1K
|
||||
```
|
||||
If this errors -> abort the run with "z-image unavailable" + the kie.ai response. Do NOT continue.
|
||||
|
||||
## Cost discipline
|
||||
- Use Resolution 1K for fig1/fig2, 2K only for hero.
|
||||
- Keep prompts under ~400 chars.
|
||||
- Batch sequentially per article (the per-batch goal already serializes the 3 calls per article).
|
||||
@@ -0,0 +1,188 @@
|
||||
# Opportunities Scan (post-W1..W11) — odoo-expertos
|
||||
|
||||
_Date: 2026-05-28. Source: seo+blog opportunity sub-agent (Sonnet, WebFetch-grounded)._
|
||||
_Consumed by goals/W5b.txt, W12.txt, W13.txt — those tell the fix agents to read this file for concrete targets._
|
||||
|
||||
---
|
||||
|
||||
## 1. Top 10 AI-Search Opportunity Pages
|
||||
|
||||
Ranked by: "best/review/vs" query intent + existing structural strength + GSC crawl signal.
|
||||
|
||||
| # | URL | Current Weakness | Concrete Fix | AI-Cite |
|
||||
|---|---|---|---|---:|
|
||||
| 1 | `/odoo-hosting/odoo4projects-hosting-review-2026/` | 3,222 words, strong schema, but "847 reviews" aggregate is unsourced — fabricated, kills trust | Replace aggregate with linked G2/Capterra URL; add Capterra Odoo-category benchmark; add 40-60w TL;DR at top | 7 |
|
||||
| 2 | `/odoo-hosting/mejor-hosting-odoo-2026/` | 1,347 words (below blog floor 1,500); H2s declarative not question-led; no inline source attribution | Expand to 1,800+ words; convert 3 H2s to questions; one sourced stat per H2 opening sentence | 6 |
|
||||
| 3 | `/odoo-hosting/mejores-proveedores-hosting-odoo-2026/` | 2,775 words but "three-month evaluation by our team" has no methodology URL; pricing claims unsourced; no TL;DR | Add methodology disclosure box; link 3+ price data points to public provider pricing pages; add TL;DR capsule | 6 |
|
||||
| 4 | `/odoo-hosting/comparativa-precios-odoo-2026/` | 2,527 words, table present, "70% Ahorro Potencial" is an unsourced superlative (QRG flag); no visible datePublished in body | Replace 70% with a sourced TCO example (link Odoo.sh public pricing vs VPS); add visible byline + date | 6 |
|
||||
| 5 | `/odoo-hosting/cloudpepper-vs-odoo-sh-2026/` | 2,556 words, "2,864 Reseñas Verificadas" has no source — fabricated social proof; radar chart is D3/JS so invisible to crawlers | Delete the fabricated review count; link a G2/Capterra page; add HTML `<table>` fallback for the radar data | 6 |
|
||||
| 6 | `/odoo-hosting/opiniones-hosting-odoo-2026/` | 2,295 words; claims "2,800 opiniones" from G2/Capterra/Trustpilot with no links; Review schema present but no `reviewUrl`; no table | Add 3 direct links to source platforms; populate `reviewUrl` on each Review item; add provider-rating comparison table | 5 |
|
||||
| 7 | `/odoo-hosting/odoo-vs-sap-hosting-2026/` | 2,354 words; "85% Ahorro en TCO" is the first visible stat and is unsourced; "Guía de Migración" H2 has 1-2 sentences per step | Source the TCO claim (Panorama Consulting / Gartner / SAP public pricing); expand migration H2 to 250+ words with numbered steps | 5 |
|
||||
| 8 | `/odoo-hosting/alternativas-odoo-sh-2026/` | 2,016 words; zero sourced stats; "0EUR Coste Migración" unattributed; ItemList schema has no `url` per item | Add a source link per alternative (provider pricing page); populate ItemList `url`; add a direct-answer opening paragraph | 4 |
|
||||
| 9 | `/odoo-hosting/odoo-community-vs-enterprise-hosting-2026/` | 2,220 words; partially sourced (G2/Trustpilot); BUT "Dr. María Elena Rodríguez" author is fabricated — destroys AI citability | Replace fabricated byline per W7 pattern (use "Equipo Odoo Expertos"); add `inLanguage: es` to Article schema; remove "Dr." prefix | 5 |
|
||||
| 10 | `/odoo-ia/alternativas-odoo-ia-comparativas-2025/` | 1,949 words; "340% mejora" unattributed; first-person fabricated loss narrative ("perdí $180,000") — QRG low-trust signal; no table; no FAQ | Remove the fabricated loss narrative; cite a real third-party migration case; add comparison `<table>` with `<thead>`; add FAQPage schema | 3 |
|
||||
|
||||
**Excluded but noted:** `/odoo-hosting/odoo-vs-zoho-books-hosting-2025/` — only 1,643 words + fabricated "$50,000 loss" + 120+ char title. Belongs in §2 (rewrite-from-scratch) rather than deepen-in-place.
|
||||
|
||||
---
|
||||
|
||||
## 2. Top 20 Thin-Content Rewrite Priorities
|
||||
|
||||
ES-root pages from `gsc/crawled-not-indexed.txt`. Fixing the ES canonical fixes the PT/FR duplicate signal simultaneously.
|
||||
|
||||
| # | URL | Current Weakness | Proposed Angle | Words | AI Query |
|
||||
|---|---|---|---|---:|---|
|
||||
| 1 | `/odoo/odoo-hosting-cloud-infraestructura-2025/` | ~610 total words; H2s are 1-2 sentences (confirmed in audit) | Definitive infra guide: RAM/CPU/disk minimums per Odoo version, provider table, cost breakdown | 1800 | "infraestructura odoo cloud 2025" |
|
||||
| 2 | `/odoo-hosting/hosting-odoo-gratis-gratuito-2025/` | Crawled-not-indexed ES root (03.05.26); templated "free hosting" page | Honest free-vs-paid breakdown: what free actually gives (community trial, Odoo.sh 15-day), hard limits, when to upgrade | 1600 | "hosting odoo gratis" |
|
||||
| 3 | `/odoo/odoo-compras-gestion-proveedores-2025/` | Crawled-not-indexed ES root (31.03.26); 400-word boilerplate on a high-volume module topic | Step-by-step Purchase module setup, RFQ workflow, approval rules, 3-way matching explained | 1800 | "odoo gestión de compras" |
|
||||
| 4 | `/odoo/odoo-argentina-implementacion-local-2025/` | Crawled-not-indexed ES root; geo page with no local specifics | Argentina: AFIP localization, electronic invoice (ARCA), peso currency handling, local partners | 1600 | "odoo argentina implementación" |
|
||||
| 5 | `/odoo-hosting/odoo-vs-zoho-books-hosting-2025/` | 1,643 words, fabricated loss narrative, 120-char title, hype framing | Neutral feature/pricing comparison: Zoho Books vs Odoo for LATAM SMBs, localization + hosting flexibility | 1800 | "odoo vs zoho books" |
|
||||
| 6 | `/odoo-hosting/odoo-gratis-vs-pago-diferencias-2025/` | In duplicate-canonical GSC list (FR/PT flagged); ES root likely templated | Concrete feature matrix Community vs Enterprise by module, with exact pricing from odoo.com pricelist | 1600 | "odoo gratis vs pago" |
|
||||
| 7 | `/odoo-ia/que-es-odoo-ia-guia-basica-2025/` | Crawled-not-indexed ES root (27.04.26); "basic" suggests shallow intro | Structured explainer: Odoo AI features by module (ChatGPT connector, OCR, predictive reordering) + version availability table | 1800 | "qué es odoo ia" |
|
||||
| 8 | `/odoo-hosting/servidor-dedicado-odoo-2026/` | Crawled-not-indexed ES root (11.04.26); 400-word skeleton | Spec guide: hardware for 50/100/500 users, Hetzner/OVH/AWS prices, PostgreSQL tuning basics | 1600 | "servidor dedicado odoo" |
|
||||
| 9 | `/odoo-hosting/managed-odoo-hosting-2026/` | Crawled-not-indexed ES root (31.03.26); high commercial intent query | What "managed" means: SLA comparison table, who manages what, pricing per tier | 1600 | "managed odoo hosting" |
|
||||
| 10 | `/odoo-hosting/odoo-docker-hosting-2026/` | Crawled-not-indexed ES root (04.04.26); technical, specific | Docker Compose walkthrough for Odoo 17/18, multi-container architecture, prod vs dev config | 1800 | "odoo docker hosting" |
|
||||
| 11 | `/odoo-hosting/hosting-odoo-mexico-2026/` | Crawled-not-indexed ES root (01.04.26); geo page no local specifics | Mexico: SAT CFDI e-invoice, Odoo partner list MX, latency for US-border hosting | 1600 | "hosting odoo méxico" |
|
||||
| 12 | `/odoo-hosting/migracion-hosting-odoo-2026/` | Crawled-not-indexed ES root (29.03.26); high commercial intent | Step-by-step migration checklist: backup, filestore export, DB restore, domain cutover, post-migration validation | 1800 | "migración hosting odoo" |
|
||||
| 13 | `/odoo-hosting/vps-odoo-hosting-2026/` | Crawled-not-indexed ES root (31.03.26); generic VPS page | VPS sizing by user count, Ubuntu 22.04 recs, Nginx reverse proxy, SSL config | 1800 | "vps odoo hosting" |
|
||||
| 14 | `/odoo-hosting/hosting-hibrido-odoo-2026/` | Crawled-not-indexed ES root (31.03.26); niche but uncontested | Define hybrid: on-prem DB + cloud app tier; regulated-data use case; cost model | 1500 | "hosting híbrido odoo" |
|
||||
| 15 | `/odoo-hosting/hosting-odoo-argentina-2026/` | Crawled-not-indexed ES root (31.03.26) | Argentina: data residency, peso invoicing, local providers (Cloudflare LatAm PoP), ARBA localization | 1600 | "hosting odoo argentina" |
|
||||
| 16 | `/odoo-hosting/hosting-odoo-sin-tarjeta-2026/` | Crawled-not-indexed ES root (01.04.26); pure trial-intent | List every free-trial option (Odoo.sh 15-day, Online demo, Odoo4projects trial), limits, upgrade paths | 1400 | "hosting odoo sin tarjeta" |
|
||||
| 17 | `/odoo-hosting/hosting-odoo-economico-2026/` | Crawled-not-indexed DE/ES variants; price-sensitive buyer | Tiered buyer guide: <30€, 30-80€, 80-200€, named providers per tier | 1600 | "hosting odoo económico" |
|
||||
| 18 | `/odoo-hosting/odoo-enterprise-hosting-2026/` | Crawled-not-indexed ES/EN/DE/FR variants; high-value Enterprise-specific intent | Enterprise hosting requirements: min SLA, dedicated support, GDPR, SAP migration path, price range | 1800 | "odoo enterprise hosting" |
|
||||
| 19 | `/odoo-hosting/hosting-odoo-mensual-2026/` | Crawled-not-indexed across 5 language variants | Monthly vs annual for 8 providers, contract flexibility, what's included, cancellation terms | 1400 | "hosting odoo mensual" |
|
||||
| 20 | `/odoo-hosting/odoo-on-premise-2026/` | Crawled-not-indexed FR/DE variants; top-of-funnel decision | 3-year TCO model: on-prem (hardware + sysadmin + upgrades) vs managed cloud, with decision flowchart | 1800 | "odoo on premise vs cloud" |
|
||||
|
||||
---
|
||||
|
||||
## 3. Content-Derived Unique Title + Meta Generator (kills the 194 duplicate titles properly)
|
||||
|
||||
### Why W5 did not solve this
|
||||
|
||||
W5 appended `slug + lang` as a suffix. The 194 duplicates remain because the underlying templated stem was identical across pages — only the appended suffix changed. Two pages with title stem "Guía Odoo Hosting" become "Guía Odoo Hosting — slug-A | es" and "Guía Odoo Hosting — slug-A | en" which are still semantically duplicate (and SERP-truncated).
|
||||
|
||||
### The rule (run as a Node.js or Python codemod over all <slug>/index.html)
|
||||
|
||||
Pseudocode:
|
||||
|
||||
```
|
||||
for each file in glob("**/index.html"):
|
||||
dom = parse(file)
|
||||
h1_text = dom.querySelector("h1").innerText.trim()
|
||||
first_h2 = dom.querySelector("article h2, main h2").innerText.trim()
|
||||
sentences = extractSentences(dom.querySelector("article p, main p").innerText)
|
||||
sent1 = sentences[0]
|
||||
sent2 = sentences[1]
|
||||
|
||||
# title (50-60 chars)
|
||||
h1_short = truncateAtWord(h1_text, 40)
|
||||
h2_tag = extractNounPhrase(first_h2, maxChars=15)
|
||||
skipTags = {"Contenido","Resumen","Introducción"}
|
||||
if h2_tag and h2_tag not in skipTags:
|
||||
candidate = f"{h1_short}: {h2_tag} | Odoo Expertos"
|
||||
else:
|
||||
candidate = f"{h1_short} | Odoo Expertos"
|
||||
title = enforceMaxChars(candidate, 60)
|
||||
|
||||
# meta (140-160 chars)
|
||||
combined = (sent1 + " " + sent2).strip()
|
||||
meta = combined if len(combined) <= 160 else (truncateAtWord(sent1, 140) + ".")
|
||||
|
||||
# uniqueness gate
|
||||
if title in TITLE_REGISTRY:
|
||||
disambiguator = firstUniqueNoun(sent2, exclude=title)
|
||||
title = enforceMaxChars(f"{h1_short} {disambiguator} | Odoo Expertos", 60)
|
||||
|
||||
TITLE_REGISTRY.add(title); META_REGISTRY.add(meta)
|
||||
dom.setTitle(title); dom.setMeta("description", meta)
|
||||
writeFile(file, dom.serialize())
|
||||
```
|
||||
|
||||
Key regex for first body paragraph (excludes boilerplate):
|
||||
|
||||
```js
|
||||
const bodyP = Array.from(document.querySelectorAll('article p, main > p, .content p'))
|
||||
.filter(p => p.closest('nav,header,.toc,.breadcrumb,script,style') === null)
|
||||
.map(p => p.innerText.trim())
|
||||
.filter(p => p.length > 60)[0] || '';
|
||||
```
|
||||
|
||||
### 5 worked examples
|
||||
|
||||
**Ex 1** — `/odoo-hosting/mejor-hosting-odoo-2026/`
|
||||
- New title (55c): `Mejor Hosting Odoo 2026: Panorama | Odoo Expertos`
|
||||
- New meta (158c): `El mercado de hosting para Odoo evolucionó en 2026. Con Odoo 18 e IA integrada, las opciones van desde 29€/mes hasta enterprise gestionado.`
|
||||
|
||||
**Ex 2** — `/odoo-hosting/cloudpepper-vs-odoo-sh-2026/`
|
||||
- New title (58c): `Cloudpepper vs Odoo.sh 2026: Precios | Odoo Expertos`
|
||||
- New meta (155c): `La elección entre Cloudpepper y Odoo.sh determina costos y funcionalidad de tu Odoo. Comparamos precios, rendimiento y soporte para empresas en 2026.`
|
||||
|
||||
**Ex 3** — `/odoo-hosting/odoo-community-vs-enterprise-hosting-2026/`
|
||||
- New title (60c): `Odoo Community vs Enterprise: Diferencias Clave 2026`
|
||||
- New meta (148c): `La decisión entre Community y Enterprise afecta costos de hosting, RAM necesaria y capacidades operativas. Guía con tabla de funciones y precios 2026.`
|
||||
|
||||
**Ex 4** — `/odoo-hosting/comparativa-precios-odoo-2026/`
|
||||
- New title (57c): `Precios Hosting Odoo 2026: 15 Proveedores | Expertos`
|
||||
- New meta (152c): `Desde 12€/mes en VPS hasta 500€ en enterprise: comparamos precios reales de 15 proveedores de hosting Odoo en 2026 con análisis de costos ocultos y TCO.`
|
||||
|
||||
**Ex 5** — `/odoo-hosting/odoo4projects-hosting-review-2026/`
|
||||
- New title (55c): `Odoo4projects Review 2026: Análisis | Odoo Expertos`
|
||||
- New meta (156c): `Odoo4projects: desde 29€/mes, usuarios ilimitados, IA integrada y soporte en español. Review completa con precios, pros/contras y comparación con Odoo.sh.`
|
||||
|
||||
---
|
||||
|
||||
## 4. Cluster grouping for the 13 existing vs/review slugs
|
||||
|
||||
### Cluster A — "Best Hosting Picker" (commercial / navigational)
|
||||
|
||||
**Pillar:** `/odoo-hosting/mejor-hosting-odoo-2026/`
|
||||
Targets: "mejor hosting odoo", "hosting odoo recomendado", "qué hosting usar para odoo"
|
||||
|
||||
Spokes (exist, need deepening):
|
||||
- `/odoo-hosting/mejores-proveedores-hosting-odoo-2026/` (ranked list)
|
||||
- `/odoo-hosting/mejores-proveedores-hosting-odoo-2025/` (historical — see §5: 301 to 2026 or archive)
|
||||
- `/odoo-hosting/opiniones-hosting-odoo-2026/` (social proof)
|
||||
- `/odoo-hosting/odoo4projects-hosting-review-2026/` (deep-dive single provider)
|
||||
- `/odoo-hosting/comparativa-precios-odoo-2026/` (price angle)
|
||||
|
||||
Pillar links to all 5 spokes; each spoke links back to pillar + 2 siblings.
|
||||
|
||||
### Cluster B — "Head-to-Head Comparisons" (commercial / decision)
|
||||
|
||||
**Pillar:** `/odoo-hosting/odoo-community-vs-enterprise-hosting-2026/`
|
||||
Targets: "odoo community vs enterprise", "qué edición odoo elegir"
|
||||
|
||||
Spokes:
|
||||
- `/odoo-hosting/odoo-vs-sap-hosting-2026/` (cross-ERP)
|
||||
- `/odoo-hosting/odoo-vs-zoho-books-hosting-2025/` (cross-category)
|
||||
- `/odoo-hosting/cloudpepper-vs-odoo-sh-2026/` (provider-vs-provider)
|
||||
- `/odoo-hosting/odoo-gratis-vs-pago-diferencias-2025/` (free vs paid licensing)
|
||||
|
||||
Pillar choice rationale: users can't choose a provider before they've chosen an edition.
|
||||
|
||||
### Cluster C — "Alternatives & Escape Routes" (informational / commercial)
|
||||
|
||||
**Pillar:** `/odoo-hosting/alternativas-odoo-sh-2026/`
|
||||
Targets: "alternativas odoo sh", "opciones hosting odoo"
|
||||
|
||||
Spokes:
|
||||
- `/odoo-ia/alternativas-odoo-ia-comparativas-2025/` (AI-specific alternatives; dual-link to Cluster B is fine)
|
||||
- `/odoo-hosting/odoo-gratis-vs-pago-diferencias-2025/` (shared with Cluster B)
|
||||
|
||||
Thinner cluster — candidates to add once content quality is up: "odoo sh review 2026", "self-hosted odoo vs odoo sh", "cloudpepper review 2026" (none exist as ES-root yet).
|
||||
|
||||
---
|
||||
|
||||
## 5. Cannibalization flags
|
||||
|
||||
**Direct cannibalization to consolidate or 301:**
|
||||
|
||||
- `/odoo-hosting/mejores-proveedores-hosting-odoo-2026/` vs `…-2025/` — same query, year-separated; both crawled-not-indexed. **Action:** keep 2026, 301 the 2025 slug to 2026, archive 2025 content as a "market evolution" section inside the 2026 page.
|
||||
|
||||
- `/odoo-hosting/mejor-hosting-odoo-2026/` vs `/odoo-hosting/mejores-proveedores-hosting-odoo-2026/` — heavy SERP overlap; both crawled-not-indexed. **Action:** explicit differentiation — "mejor" = single buyer's-choice recommendation; "mejores-proveedores" = ranked list with methodology. Make the pillar/spoke link relationship explicit.
|
||||
|
||||
- `/odoo-hosting/opiniones-hosting-odoo-2026/` vs review sections of `…/odoo4projects-hosting-review-2026/` — no true cannibalization, but the opiniones page must link to the review page for every provider it mentions (currently zero cross-links).
|
||||
|
||||
- `/odoo-hosting/odoo-gratis-vs-pago-diferencias-2025/` — hosting-located but the query is also served by licensing content in `/odoo/`. **Action:** narrow this page to *hosting cost implications only*; move general licensing differences to an `/odoo/` article with a cross-link.
|
||||
|
||||
- `/odoo-ia/alternativas-odoo-ia-comparativas-2025/` — once rewritten (§2 #10), scope strictly to AI-specific alternatives (SAP AI, MS Dynamics AI), not general Odoo alternatives — otherwise will compete with Cluster B pillar once that gains authority.
|
||||
@@ -0,0 +1,246 @@
|
||||
#requires -version 5.1
|
||||
<#
|
||||
REVIEW.ps1 - local verifier for the odoo-expertos SEO fix workstreams.
|
||||
Each /goal agent runs: powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W#
|
||||
The printed "W#: PASS" line is what the /goal evaluator (Haiku) reads from the transcript.
|
||||
Checks run against LOCAL repo files (pre-deploy). Live/GSC verification is post-deploy.
|
||||
#>
|
||||
param([string]$Only = "all")
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Audit = $PSScriptRoot
|
||||
$RepoRoot = Split-Path -Parent $Audit
|
||||
$BASE = "https://www.odoo-expertos.com"
|
||||
|
||||
function Raw($p){ try{ $t=[System.IO.File]::ReadAllText($p); if($null -eq $t){''}else{$t} }catch{''} }
|
||||
function Res($id,$pass,$msg){ $tag = if($pass){"PASS"}else{"FAIL"}; Write-Host ("{0}: {1} - {2}" -f $id,$tag,$msg) }
|
||||
function HtmlFiles {
|
||||
Get-ChildItem $RepoRoot -Recurse -Filter index.html -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -notmatch '\\(\.git|node_modules|seo-audit-2026-05-27|website|directory)\\' }
|
||||
}
|
||||
function UrlToLocal($url){
|
||||
$p = $url -replace '^https?://www\.odoo-expertos\.com',''
|
||||
$p = $p.Split('#')[0].Split('?')[0]
|
||||
if($p -eq '' -or $p -eq '/'){ return (Join-Path $RepoRoot 'index.html') }
|
||||
if($p -match '\.html?$'){ return (Join-Path $RepoRoot ($p.TrimStart('/').Replace('/','\'))) }
|
||||
$p = $p.TrimEnd('/')
|
||||
return (Join-Path $RepoRoot ($p.TrimStart('/').Replace('/','\') + '\index.html'))
|
||||
}
|
||||
|
||||
function Check-W1 {
|
||||
$sm = Get-ChildItem $RepoRoot -Filter 'sitemap-*.xml' -File -ErrorAction SilentlyContinue
|
||||
if(-not $sm){ Res 'W1' $false 'no sitemap-*.xml found'; return }
|
||||
$rslugs='bestes-odoo-hosting-2026|cheap-odoo-hosting-2026|kostenloses-odoo-hosting-2026|odoo-hosting-deutschland-2026|odoo-hosting-oesterreich-2026|odoo-hosting-schweiz-2026|best-odoo-hosting-2026|free-odoo-hosting-2026|odoo-hosting-germany-2026|odoo-hosting-uk-2026|odoo-sh-alternatives-2026|odoo-vps-hosting-2026'
|
||||
$missing=@(); $bad=@(); $redir=@(); $total=0
|
||||
foreach($file in $sm){
|
||||
$c = Raw $file.FullName; if(-not $c){continue}
|
||||
foreach($m in [regex]::Matches($c,'<loc>(https[^<]+)</loc>')){
|
||||
$total++; $u=$m.Groups[1].Value
|
||||
if($u -match '/index\.html$'){ $bad+=$u; continue }
|
||||
if($u -match "/(en|fr|pt|ar)/odoo-hosting/($rslugs)/"){ $redir+=$u; continue }
|
||||
if(-not (Test-Path (UrlToLocal $u))){ $missing+=$u }
|
||||
}
|
||||
}
|
||||
$ok = ($missing.Count -eq 0 -and $bad.Count -eq 0 -and $redir.Count -eq 0)
|
||||
$eg = if(!$ok){ ' e.g. ' + ((@($missing)+@($bad)+@($redir)) | Select-Object -First 3) -join ' | ' } else { '' }
|
||||
Res 'W1' $ok ("$total locs; missing-local=$($missing.Count); index.html-in-sitemap=$($bad.Count); redirecting-loc=$($redir.Count)$eg")
|
||||
}
|
||||
|
||||
function Check-W2 {
|
||||
$r = Raw (Join-Path $RepoRoot 'robots.txt')
|
||||
$star = ([regex]::Matches($r,'(?m)^User-agent:\s*\*\s*$')).Count
|
||||
$bing = ([regex]::Matches($r,'(?im)^User-agent:\s*Bingbot\s*$')).Count
|
||||
$cc = ([regex]::Matches($r,'(?im)^User-agent:\s*CCBot\s*$')).Count
|
||||
$frag = [bool]($r -match '(?m)^Disallow:\s*/\*#')
|
||||
$q = [bool]($r -match '(?m)^Disallow:\s*/\*\?')
|
||||
$ok = ($star -eq 1 -and $bing -eq 1 -and $cc -eq 1 -and -not $frag -and $q)
|
||||
Res 'W2' $ok "UA*=$star(want 1); Bingbot=$bing(want 1); CCBot=$cc(want 1); has /*#=$frag(want False); has /*?=$q(want True)"
|
||||
}
|
||||
|
||||
function Check-W3 {
|
||||
$deadDomain=0; $nonwww=0
|
||||
foreach($file in HtmlFiles){
|
||||
$c = Raw $file.FullName; if(-not $c){continue}
|
||||
if($c -match 'odooexpertos\.com'){ $deadDomain++ }
|
||||
if($c -match '"(?:url|item|@id|logo)":\s*"https://odoo-expertos\.com'){ $nonwww++ }
|
||||
}
|
||||
$ok = ($deadDomain -eq 0 -and $nonwww -eq 0)
|
||||
Res 'W3' $ok "files w/ dead domain odooexpertos.com=$deadDomain(want 0); files w/ non-www JSON-LD url=$nonwww(want 0)"
|
||||
}
|
||||
|
||||
function Check-W4 {
|
||||
$cats = @('odoo','odoo-hosting','odoo-ia') | ForEach-Object { Join-Path $RepoRoot "$_\index.html" }
|
||||
$catNoHreflang=0
|
||||
foreach($cf in $cats){ if(Test-Path $cf){ $cc=Raw $cf; if($cc -and ($cc -notmatch 'hreflang=')){ $catNoHreflang++ } } }
|
||||
$mislocated=0
|
||||
foreach($file in HtmlFiles){
|
||||
$c = Raw $file.FullName; if(-not $c){continue}
|
||||
foreach($m in [regex]::Matches($c,'hreflang="es"[^>]*href="([^"]+)"')){
|
||||
if($m.Groups[1].Value -match '/(de|fr|pt|ar|en)/'){ $mislocated++ }
|
||||
}
|
||||
}
|
||||
$ok = ($catNoHreflang -eq 0 -and $mislocated -eq 0)
|
||||
Res 'W4' $ok "category pages without hreflang=$catNoHreflang(want 0); es-hreflang pointing into a /lang/ subtree=$mislocated(want 0)"
|
||||
}
|
||||
|
||||
function Check-W5 {
|
||||
$long=0; $titles=@{}; $metas=@{}
|
||||
foreach($file in HtmlFiles){
|
||||
$c = Raw $file.FullName; if(-not $c){continue}
|
||||
$t = [regex]::Match($c,'<title>(.*?)</title>',1).Groups[1].Value.Trim()
|
||||
if($t.Length -gt 65){ $long++ }
|
||||
if($t){ if($titles.ContainsKey($t)){$titles[$t]++}else{$titles[$t]=1} }
|
||||
$md = [regex]::Match($c,'<meta\s+name="description"\s+content="([^"]*)"',1).Groups[1].Value.Trim()
|
||||
if($md){ if($metas.ContainsKey($md)){$metas[$md]++}else{$metas[$md]=1} }
|
||||
}
|
||||
$dupT = ($titles.GetEnumerator() | Where-Object {$_.Value -gt 1}).Count
|
||||
$dupM = ($metas.GetEnumerator() | Where-Object {$_.Value -gt 1}).Count
|
||||
$ok = ($long -eq 0 -and $dupM -eq 0)
|
||||
Res 'W5' $ok "titles>65chars=$long(want 0); duplicate meta descriptions=$dupM(want 0); duplicate titles=$dupT"
|
||||
}
|
||||
|
||||
function Check-W6 {
|
||||
$jsNav=0; $noStaticNav=0
|
||||
foreach($file in HtmlFiles){
|
||||
$c = Raw $file.FullName; if(-not $c){continue}
|
||||
if($c -match 'createHeader\(\)'){ $jsNav++ }
|
||||
if($c -notmatch 'href="[^"]*/odoo-hosting/"'){ $noStaticNav++ }
|
||||
}
|
||||
$sitemapPage = Test-Path (Join-Path $RepoRoot 'mapa-del-sitio\index.html')
|
||||
$ok = ($jsNav -eq 0 -and $sitemapPage)
|
||||
Res 'W6' $ok "pages still JS-injecting nav (createHeader)=$jsNav(want 0); pages missing static hosting nav link=$noStaticNav; HTML sitemap page exists=$sitemapPage(want True)"
|
||||
}
|
||||
|
||||
function Check-W7 {
|
||||
$dupFile = Join-Path $Audit 'gsc\duplicate-canonical.txt'
|
||||
if(-not (Test-Path $dupFile)){ Res 'W7' $false 'gsc/duplicate-canonical.txt missing'; return }
|
||||
$urls = (Get-Content $dupFile) | Where-Object { $_ -match '^https://' } | Select-Object -First 40
|
||||
$unfixed=0; $checked=0
|
||||
foreach($u in $urls){
|
||||
$checked++; $lf = UrlToLocal $u
|
||||
if(Test-Path $lf){ $c = Raw $lf; if($c -notmatch 'name="robots"[^>]*noindex'){ $unfixed++ } }
|
||||
}
|
||||
$ok = ($unfixed -eq 0)
|
||||
Res 'W7' $ok "of $checked sampled duplicate URLs, still-indexable (no noindex, file still present)=$unfixed(want 0)"
|
||||
}
|
||||
|
||||
function Check-W8 {
|
||||
$homes = @('index.html','en\index.html','de\index.html','fr\index.html','pt\index.html','ar\index.html') | ForEach-Object { Join-Path $RepoRoot $_ }
|
||||
$bad = @('Robarte','DESTRUIR','DESTRUIDOS','CONQUISTA','DOMINACI')
|
||||
$hits=0
|
||||
foreach($h in $homes){ if(Test-Path $h){ $c=Raw $h; foreach($b in $bad){ if($c -match [regex]::Escape($b)){ $hits++ } } } }
|
||||
$ok = ($hits -eq 0)
|
||||
Res 'W8' $ok "combat/hype tokens (Robarte/DESTRUIR/CONQUISTA...) remaining in homepages=$hits(want 0). MANUAL GATE: re-screenshot desktop+mobile, fix run-together H1 spacing, score >=8/10 before merge."
|
||||
}
|
||||
|
||||
function Check-W9 {
|
||||
$known = @(
|
||||
'/odoo-ai/odoo-18-ai-nuevas-features-2025/','/odoo-ai/odoo-withstruccion-ai-projects-2025/',
|
||||
'/pt/odoo/consultoria-erp','/mes','/consultoria-erp',
|
||||
'/Odoo-Hosting/digitalocean-Hosting-Odoo-deployment-2025/','/de/odoo/consultoria-erp',
|
||||
'/en/odoo-hosting/odoo-sh-official-hosting/','/odoo/consultoria-erp',
|
||||
'/recursos/guia-aws-odoo.pdf','/en/odoo-hosting/odoo-hosting-schweiz-2026/','/recursos-implementacion-odoo'
|
||||
)
|
||||
$vj = Raw (Join-Path $RepoRoot 'vercel.json')
|
||||
$uncovered=0
|
||||
foreach($k in $known){
|
||||
$hasFile = Test-Path (UrlToLocal ($BASE + $k))
|
||||
$hasRedirect = [bool]($vj -match [regex]::Escape($k.TrimEnd('/')))
|
||||
if(-not ($hasFile -or $hasRedirect)){ $uncovered++ }
|
||||
}
|
||||
$ok = ($uncovered -eq 0)
|
||||
Res 'W9' $ok "of 12 known 404s, still uncovered (no local page AND no vercel redirect)=$uncovered(want 0)"
|
||||
}
|
||||
|
||||
function Check-W10 {
|
||||
$c = Raw (Join-Path $RepoRoot 'index.html')
|
||||
$inline = ([regex]::Matches($c,'(?s)<style[^>]*>(.*?)</style>') | ForEach-Object { $_.Groups[1].Value.Length } | Measure-Object -Sum).Sum
|
||||
$d3 = Test-Path (Join-Path $RepoRoot 'js\d3.v7.min.js')
|
||||
$vj = Raw (Join-Path $RepoRoot 'vercel.json')
|
||||
$cache = [bool]($vj -match 'max-age=31536000')
|
||||
$ok = ($inline -lt 14336 -and $d3 -and $cache)
|
||||
Res 'W10' $ok "homepage inline CSS bytes=$inline(want <14336); self-hosted D3 exists=$d3; immutable cache header=$cache"
|
||||
}
|
||||
|
||||
function Check-W11 {
|
||||
$vj = Raw (Join-Path $RepoRoot 'vercel.json')
|
||||
$x1 = [bool]($vj -match 'X-Content-Type-Options')
|
||||
$x2 = [bool]($vj -match 'X-Frame-Options')
|
||||
$x3 = [bool]($vj -match 'Referrer-Policy')
|
||||
$ok = ($x1 -and $x2 -and $x3)
|
||||
Res 'W11' $ok "X-Content-Type-Options=$x1; X-Frame-Options=$x2; Referrer-Policy=$x3 (want all True)"
|
||||
}
|
||||
|
||||
|
||||
function Check-W5b {
|
||||
$long=0; $short=0; $shortM=0; $longM=0; $titles=@{}; $metas=@{}
|
||||
foreach($file in HtmlFiles){
|
||||
$c = Raw $file.FullName; if(-not $c){continue}
|
||||
$t = [regex]::Match($c,'<title>(.*?)</title>',1).Groups[1].Value.Trim()
|
||||
if($t){ if($titles.ContainsKey($t)){$titles[$t]++}else{$titles[$t]=1}; if($t.Length -gt 65){$long++}; if($t.Length -lt 40){$short++} }
|
||||
$md = [regex]::Match($c,'<meta\s+name="description"\s+content="([^"]*)"',1).Groups[1].Value.Trim()
|
||||
if($md){ if($metas.ContainsKey($md)){$metas[$md]++}else{$metas[$md]=1}; if($md.Length -gt 165){$longM++}; if($md.Length -lt 130){$shortM++} }
|
||||
}
|
||||
$dupT = ($titles.GetEnumerator() | Where-Object {$_.Value -gt 1}).Count
|
||||
$dupM = ($metas.GetEnumerator() | Where-Object {$_.Value -gt 1}).Count
|
||||
$ok = ($dupT -eq 0 -and $dupM -eq 0 -and $long -eq 0 -and $longM -eq 0)
|
||||
Res 'W5b' $ok "dup-titles=$dupT(want 0); dup-metas=$dupM(want 0); titles>65=$long; titles<40=$short(report); metas>165=$longM; metas<130=$shortM(report)"
|
||||
}
|
||||
|
||||
function BodyWords($html){
|
||||
$m = [regex]::Match($html,'(?s)<article[^>]*>(.*?)</article>',1)
|
||||
if(-not $m.Success){ return 0 }
|
||||
$body = $m.Groups[1].Value
|
||||
$body = $body -replace '(?s)<script.*?</script>',''
|
||||
$body = $body -replace '(?s)<style.*?</style>',''
|
||||
$body = $body -replace '<[^>]+>',' '
|
||||
$body = $body -replace '&[a-z]+;',' '
|
||||
$words = ($body -split '\s+') | Where-Object { $_ -match '[A-Za-zÀ-ſ]{2,}' }
|
||||
return $words.Count
|
||||
}
|
||||
|
||||
function Check-W12 {
|
||||
$marked = @(); $maria = 0
|
||||
foreach($file in HtmlFiles){
|
||||
$c = Raw $file.FullName; if(-not $c){continue}
|
||||
if($c -match 'name="content-version"\s+content="W12-deep-rewrite"'){
|
||||
$w = BodyWords $c
|
||||
$q = ([regex]::Matches($c,'"@type":\s*"Question"')).Count
|
||||
$hasMaria = ($c -match 'Maria Elena Rodriguez')
|
||||
$marked += [pscustomobject]@{File=$file.FullName; Words=$w; QA=$q; Maria=$hasMaria}
|
||||
if($hasMaria){ $maria++ }
|
||||
}
|
||||
}
|
||||
$count = $marked.Count
|
||||
$thin = ($marked | Where-Object { $_.Words -lt 1200 }).Count
|
||||
$lowQA = ($marked | Where-Object { $_.QA -lt 6 }).Count
|
||||
$ok = ($count -ge 20 -and $thin -eq 0 -and $lowQA -eq 0 -and $maria -eq 0)
|
||||
Res 'W12' $ok "marked-rewrites=$count(want >=20); body-words<1200=$thin(want 0); FAQ Q&A<6=$lowQA(want 0); pages still naming Maria Elena Rodriguez among marked=$maria(want 0)"
|
||||
}
|
||||
|
||||
function Check-W13 {
|
||||
$targets = @(
|
||||
'odoo-hosting\odoo-vs-sap-hosting-2026','odoo-hosting\odoo-vs-zoho-books-hosting-2025',
|
||||
'odoo-hosting\cloudpepper-vs-odoo-sh-2026','odoo-hosting\alternativas-odoo-sh-2026',
|
||||
'odoo-hosting\odoo-community-vs-enterprise-hosting-2026','odoo\odoo-gratis-vs-pago-diferencias-2025',
|
||||
'odoo-hosting\comparativa-precios-odoo-2026','odoo-hosting\mejor-hosting-odoo-2026',
|
||||
'odoo-hosting\opiniones-hosting-odoo-2026','odoo-hosting\odoo4projects-hosting-review-2026'
|
||||
)
|
||||
$deepened=0; $lowFAQ=@(); $noTable=@(); $stillMaria=@()
|
||||
foreach($t in $targets){
|
||||
$p = Join-Path $RepoRoot "$t\index.html"
|
||||
if(-not (Test-Path $p)){ continue }
|
||||
$c = Raw $p
|
||||
if($c -match 'name="content-version"\s+content="W13-ai-search"'){ $deepened++ }
|
||||
$q = ([regex]::Matches($c,'"@type":\s*"Question"')).Count
|
||||
if($q -lt 8){ $lowFAQ += $t }
|
||||
if($c -notmatch '(?is)<table[^>]*>'){ $noTable += $t }
|
||||
if($c -match 'Maria Elena Rodriguez'){ $stillMaria += $t }
|
||||
}
|
||||
$ok = ($deepened -ge 10 -and $lowFAQ.Count -eq 0 -and $noTable.Count -eq 0 -and $stillMaria.Count -eq 0)
|
||||
Res 'W13' $ok "marked-deepened=$deepened(want >=10); pages with <8 FAQ Q&A=$($lowFAQ.Count); pages missing comparison <table>=$($noTable.Count); pages still naming Maria Elena Rodriguez=$($stillMaria.Count)"
|
||||
}
|
||||
$map = [ordered]@{ W1='Check-W1';W2='Check-W2';W3='Check-W3';W4='Check-W4';W5='Check-W5';W6='Check-W6';W7='Check-W7';W8='Check-W8';W9='Check-W9';W10='Check-W10';W11='Check-W11';W5b='Check-W5b';W12='Check-W12';W13='Check-W13' }
|
||||
Write-Host "REVIEW.ps1 repo=$RepoRoot"
|
||||
if($Only -eq 'all'){ foreach($k in $map.Keys){ & $map[$k] } }
|
||||
elseif($map.Contains($Only)){ & $map[$Only] }
|
||||
else{ Write-Host "Unknown -Only '$Only'. Use one of: $($map.Keys -join ', '), or 'all'." }
|
||||
@@ -0,0 +1,122 @@
|
||||
{
|
||||
"B01": [
|
||||
"/odoo-hosting/odoo4projects-hosting-review-2026/",
|
||||
"/odoo-hosting/mejor-hosting-odoo-2026/",
|
||||
"/odoo-hosting/mejores-proveedores-hosting-odoo-2026/",
|
||||
"/odoo-hosting/comparativa-precios-odoo-2026/",
|
||||
"/odoo-hosting/cloudpepper-vs-odoo-sh-2026/",
|
||||
"/odoo-hosting/opiniones-hosting-odoo-2026/",
|
||||
"/odoo-hosting/odoo-vs-sap-hosting-2026/",
|
||||
"/odoo-hosting/alternativas-odoo-sh-2026/",
|
||||
"/odoo-hosting/odoo-community-vs-enterprise-hosting-2026/",
|
||||
"/odoo-ia/alternativas-odoo-ia-comparativas-2025/"
|
||||
],
|
||||
"B02": [
|
||||
"/odoo-hosting/hosting-odoo-gratis-gratuito-2025/",
|
||||
"/odoo-ia/que-es-odoo-ia-guia-basica-2025/",
|
||||
"/odoo-hosting/servidor-dedicado-odoo-2026/",
|
||||
"/odoo-hosting/odoo-docker-hosting-2026/",
|
||||
"/odoo-hosting/hosting-odoo-mexico-2026/",
|
||||
"/odoo-hosting/hosting-odoo-sin-tarjeta-2026/",
|
||||
"/odoo-hosting/hosting-odoo-argentina-2026/",
|
||||
"/odoo-hosting/hosting-hibrido-odoo-2026/",
|
||||
"/odoo-hosting/managed-odoo-hosting-2026/",
|
||||
"/odoo/odoo-compras-gestion-proveedores-2025/"
|
||||
],
|
||||
"B03": [
|
||||
"/odoo/odoo-argentina-implementacion-local-2025/",
|
||||
"/odoo-hosting/migracion-hosting-odoo-2026/",
|
||||
"/odoo-hosting/vps-odoo-hosting-2026/",
|
||||
"/odoo/curso-odoo-aprender-completo-2025/",
|
||||
"/odoo/dashboard-ninja-odoo-avanzado-2025/",
|
||||
"/odoo/descargar-odoo-instaladores-oficiales-2025/",
|
||||
"/odoo/empleos-odoo-oportunidades-carrera-2025/",
|
||||
"/odoo/empresa-odoo-historia-fundacion-2025/",
|
||||
"/odoo/freelance-odoo-consultores-independientes-2025/",
|
||||
"/odoo/instalar-odoo-guia-paso-a-paso-2025/"
|
||||
],
|
||||
"B04": [
|
||||
"/odoo/odoo-17-funciones-caracteristicas-2025/",
|
||||
"/odoo/odoo-18-nuevas-funciones-2025/",
|
||||
"/odoo/odoo-api-integraciones-desarrollo-2025/",
|
||||
"/odoo/odoo-bolivia-implementacion-local-2025/",
|
||||
"/odoo/odoo-chatbot-atencion-cliente-2025/",
|
||||
"/odoo/odoo-chile-implementacion-local-2025/",
|
||||
"/odoo/odoo-colombia-implementacion-local-2025/",
|
||||
"/odoo/odoo-community-enterprise-diferencias-2025/",
|
||||
"/odoo/odoo-contabilidad-modulo-completo-2025/",
|
||||
"/odoo/odoo-costa-rica-implementacion-local-2025/"
|
||||
],
|
||||
"B05": [
|
||||
"/odoo/odoo-crm-gestion-clientes-2025/",
|
||||
"/odoo/odoo-demo-prueba-gratuita-2025/",
|
||||
"/odoo/odoo-docker-contenedores-implementacion-2025/",
|
||||
"/odoo/odoo-ecuador-implementacion-local-2025/",
|
||||
"/odoo/odoo-el-salvador-implementacion-local-2025/",
|
||||
"/odoo/odoo-erp-sistema-empresarial-2025/",
|
||||
"/odoo/odoo-espana-implementacion-local-2025/",
|
||||
"/odoo/odoo-facturacion-electronica-completa-2025/",
|
||||
"/odoo/odoo-gestion-proyectos-completa-2025/",
|
||||
"/odoo/odoo-github-desarrollo-codigo-2025/"
|
||||
],
|
||||
"B06": [
|
||||
"/odoo/odoo-gratis-vs-pago-diferencias-2025/",
|
||||
"/odoo/odoo-guatemala-implementacion-local-2025/",
|
||||
"/odoo/odoo-helpdesk-atencion-cliente-2025/",
|
||||
"/odoo/odoo-honduras-implementacion-local-2025/",
|
||||
"/odoo/odoo-hosting-cloud-infraestructura-2025/",
|
||||
"/odoo/odoo-inteligencia-artificial-ia-2025/",
|
||||
"/odoo/odoo-inventario-gestion-almacen-2025/",
|
||||
"/odoo/odoo-manufactura-produccion-industrial-2025/",
|
||||
"/odoo/odoo-marketplace-multi-vendor-2025/",
|
||||
"/odoo/odoo-mexico-implementacion-local-2025/"
|
||||
],
|
||||
"B07": [
|
||||
"/odoo/odoo-nicaragua-implementacion-local-2025/",
|
||||
"/odoo-hosting/apps-terceros-odoo-instalacion-2025/",
|
||||
"/odoo-hosting/aws-hosting-odoo-2026/",
|
||||
"/odoo-hosting/aws-hosting-odoo-amazon-cloud-2025/",
|
||||
"/odoo-hosting/azure-hosting-odoo-microsoft-2025/",
|
||||
"/odoo-hosting/cliente-odoo-hosting-acceso-2025/",
|
||||
"/odoo-hosting/como-usar-odoo-hosting-guia-2025/",
|
||||
"/odoo-hosting/configuracion-contabilidad-odoo-hosting-2025/",
|
||||
"/odoo-hosting/configuracion-hosting-odoo-optimizacion-2025/",
|
||||
"/odoo-hosting/desarrollo-website-odoo-14-2025/"
|
||||
],
|
||||
"B08": [
|
||||
"/odoo-hosting/digitalocean-hosting-odoo-deployment-2025/",
|
||||
"/odoo-hosting/documentacion-hosting-odoo-guias-2025/",
|
||||
"/odoo-hosting/email-dominio-hosting-odoo-2025/",
|
||||
"/odoo-hosting/gestion-inmobiliaria-odoo-hosting-2025/",
|
||||
"/odoo-hosting/gestion-suscripciones-odoo-hosting-2025/",
|
||||
"/odoo-hosting/hosting-compartido-odoo-2026/",
|
||||
"/odoo-hosting/hosting-compartido-odoo-shared-2025/",
|
||||
"/odoo-hosting/hosting-odoo-29-euros-2026/",
|
||||
"/odoo-hosting/hosting-odoo-barato-2026/",
|
||||
"/odoo-hosting/hosting-odoo-chile-2026/"
|
||||
],
|
||||
"B09": [
|
||||
"/odoo-hosting/hosting-odoo-colombia-2026/",
|
||||
"/odoo-hosting/hosting-odoo-community-edition-gratuita-2025/",
|
||||
"/odoo-hosting/hosting-odoo-completo-guia-2025/",
|
||||
"/odoo-hosting/hosting-odoo-costa-rica-2026/",
|
||||
"/odoo-hosting/hosting-odoo-descuento-2026/",
|
||||
"/odoo-hosting/hosting-odoo-economico-2026/",
|
||||
"/odoo-hosting/hosting-odoo-ecuador-2026/",
|
||||
"/odoo-hosting/hosting-odoo-enterprise-empresarial-2025/",
|
||||
"/odoo-hosting/hosting-odoo-enterprise-precios-2026/",
|
||||
"/odoo-hosting/hosting-odoo-espana-2026/"
|
||||
],
|
||||
"B10": [
|
||||
"/odoo-hosting/hosting-odoo-espana-proveedores-2025/",
|
||||
"/odoo-hosting/hosting-odoo-gestionado-managed-2025/",
|
||||
"/odoo-hosting/hosting-odoo-gratis-2026/",
|
||||
"/odoo-hosting/hosting-odoo-internacional-alemania-suiza-2025/",
|
||||
"/odoo-hosting/hosting-odoo-local-on-premise-2025/",
|
||||
"/odoo-hosting/hosting-odoo-mensual-2026/",
|
||||
"/odoo-hosting/hosting-odoo-nube-cloud-2025/",
|
||||
"/odoo-hosting/hosting-odoo-nube-cloud-2026/",
|
||||
"/odoo-hosting/hosting-odoo-oferta-2026/",
|
||||
"/odoo-hosting/hosting-odoo-panama-2026/"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
GOAL - Drive ALL SEO fix workstreams W1..W11 for odoo-expertos to PASS. Repo root = current folder; work ONLY in this repo. Use ONE branch fix/seo-all (create with: git checkout -B fix/seo-all).
|
||||
Source of truth: seo-audit-2026-05-27\GOAL-FIX-PLAN.md and the per-workstream goal files seo-audit-2026-05-27\goals\W1.txt .. W11.txt (each describes its exact tasks + acceptance). Read them as needed.
|
||||
WORK ORDER (do in this order; W7 LAST because it depends on the others): W2, W11, W1, W9, W3, W4, W5, W6, W8, W10, W7. For each workstream perform the tasks in its goal file, commit with a clear message ("fix(W#): ..."), and move to the next. For the bulk-HTML workstreams (W3, W4, W5, W6, W7) write a single codemod script per workstream and run it over all <slug>/index.html files (exclude .git, node_modules, seo-audit-2026-05-27, website, directory). For W8 also fix the run-together H1 spacing on every homepage.
|
||||
EACH TURN: (a) state which workstream you are on and why; (b) do the work; (c) commit; (d) run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only all and PASTE THE FULL OUTPUT verbatim; (e) state which W# are PASS and which remain FAIL.
|
||||
DONE WHEN: that pasted REVIEW.ps1 -Only all output contains the eleven lines "W1: PASS", "W2: PASS", "W3: PASS", "W4: PASS", "W5: PASS", "W6: PASS", "W7: PASS", "W8: PASS", "W9: PASS", "W10: PASS", "W11: PASS" (all eleven PASS), AND all changes are committed on branch fix/seo-all (show: git log --oneline -n 15).
|
||||
IF BLOCKED on one workstream after 6 attempts, skip it (note the FAIL detail in your turn), proceed to the next, and revisit at the end. Stop after 80 turns total if not all green, and report the exact remaining FAIL lines from REVIEW.ps1 -Only all.
|
||||
@@ -0,0 +1,23 @@
|
||||
GOAL - Batch B01 (W13 - deep AI-citation upgrade of vs/review pages) for odoo-expertos. Branch: fix/seo-batch-b01. Repo root = current folder (a git worktree off fix/seo-all). Work ONLY here.
|
||||
|
||||
PIPELINE: for EACH of the 10 URLs below, run seo-audit-2026-05-27\BLOG-PIPELINE.md steps 1-12 (discourse -> flow find -> brief -> outline -> /blog rewrite -> blog-factcheck -> seo-check -> kie.ai z-image >=3 per article NO text/letters/numbers/logos -> /blog schema -> /blog geo gate -> /blog analyze >=80 -> commit). Add <meta name="content-version" content="W13-ai-search"> to each rewritten page's <head>. Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos".
|
||||
|
||||
URLS (10):
|
||||
- /odoo-hosting/odoo4projects-hosting-review-2026/
|
||||
- /odoo-hosting/mejor-hosting-odoo-2026/
|
||||
- /odoo-hosting/mejores-proveedores-hosting-odoo-2026/
|
||||
- /odoo-hosting/comparativa-precios-odoo-2026/
|
||||
- /odoo-hosting/cloudpepper-vs-odoo-sh-2026/
|
||||
- /odoo-hosting/opiniones-hosting-odoo-2026/
|
||||
- /odoo-hosting/odoo-vs-sap-hosting-2026/
|
||||
- /odoo-hosting/alternativas-odoo-sh-2026/
|
||||
- /odoo-hosting/odoo-community-vs-enterprise-hosting-2026/
|
||||
- /odoo-ia/alternativas-odoo-ia-comparativas-2025/
|
||||
|
||||
CONSTRAINTS: preserve <head> tags except the marker + og:image + preload; preserve hreflang/canonical/OG/header/footer/nav/breadcrumb/D3.js refs; blog-factcheck mandatory (no fabricated stats); all images via powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (NO fallback - probe was done in SETUP).
|
||||
|
||||
PROVE each turn: list which of the 10 URLs are COMPLETE (committed + analyze>=80 + geo PASS), which are IN PROGRESS, which FAILED (logged to BLOG-FAILURES.md). Paste latest /blog analyze score per completed URL.
|
||||
|
||||
DONE WHEN: at least 9 of the 10 URLs are committed on branch fix/seo-batch-b01 with analyze>=80 AND geo PASS AND content-version marker present. Run: git log fix/seo-batch-b01 --oneline -n 12 and paste it.
|
||||
|
||||
STOP after 60 turns if <9 done; report which URLs blocked and why.
|
||||
@@ -0,0 +1,23 @@
|
||||
GOAL - Batch B02 (W12 - thin-content rewrite) for odoo-expertos. Branch: fix/seo-batch-b02. Repo root = current folder (a git worktree off fix/seo-all). Work ONLY here.
|
||||
|
||||
PIPELINE: for EACH of the 10 URLs below, run seo-audit-2026-05-27\BLOG-PIPELINE.md steps 1-12 (discourse -> flow find -> brief -> outline -> /blog rewrite -> blog-factcheck -> seo-check -> kie.ai z-image >=3 per article NO text/letters/numbers/logos -> /blog schema -> /blog geo gate -> /blog analyze >=80 -> commit). Add <meta name="content-version" content="W12-deep-rewrite"> to each rewritten page's <head>. Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos".
|
||||
|
||||
URLS (10):
|
||||
- /odoo-hosting/hosting-odoo-gratis-gratuito-2025/
|
||||
- /odoo-ia/que-es-odoo-ia-guia-basica-2025/
|
||||
- /odoo-hosting/servidor-dedicado-odoo-2026/
|
||||
- /odoo-hosting/odoo-docker-hosting-2026/
|
||||
- /odoo-hosting/hosting-odoo-mexico-2026/
|
||||
- /odoo-hosting/hosting-odoo-sin-tarjeta-2026/
|
||||
- /odoo-hosting/hosting-odoo-argentina-2026/
|
||||
- /odoo-hosting/hosting-hibrido-odoo-2026/
|
||||
- /odoo-hosting/managed-odoo-hosting-2026/
|
||||
- /odoo/odoo-compras-gestion-proveedores-2025/
|
||||
|
||||
CONSTRAINTS: preserve <head> tags except the marker + og:image + preload; preserve hreflang/canonical/OG/header/footer/nav/breadcrumb/D3.js refs; blog-factcheck mandatory (no fabricated stats); all images via powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (NO fallback - probe was done in SETUP).
|
||||
|
||||
PROVE each turn: list which of the 10 URLs are COMPLETE (committed + analyze>=80 + geo PASS), which are IN PROGRESS, which FAILED (logged to BLOG-FAILURES.md). Paste latest /blog analyze score per completed URL.
|
||||
|
||||
DONE WHEN: at least 9 of the 10 URLs are committed on branch fix/seo-batch-b02 with analyze>=80 AND geo PASS AND content-version marker present. Run: git log fix/seo-batch-b02 --oneline -n 12 and paste it.
|
||||
|
||||
STOP after 60 turns if <9 done; report which URLs blocked and why.
|
||||
@@ -0,0 +1,23 @@
|
||||
GOAL - Batch B03 (W12 - thin-content rewrite) for odoo-expertos. Branch: fix/seo-batch-b03. Repo root = current folder (a git worktree off fix/seo-all). Work ONLY here.
|
||||
|
||||
PIPELINE: for EACH of the 10 URLs below, run seo-audit-2026-05-27\BLOG-PIPELINE.md steps 1-12 (discourse -> flow find -> brief -> outline -> /blog rewrite -> blog-factcheck -> seo-check -> kie.ai z-image >=3 per article NO text/letters/numbers/logos -> /blog schema -> /blog geo gate -> /blog analyze >=80 -> commit). Add <meta name="content-version" content="W12-deep-rewrite"> to each rewritten page's <head>. Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos".
|
||||
|
||||
URLS (10):
|
||||
- /odoo/odoo-argentina-implementacion-local-2025/
|
||||
- /odoo-hosting/migracion-hosting-odoo-2026/
|
||||
- /odoo-hosting/vps-odoo-hosting-2026/
|
||||
- /odoo/curso-odoo-aprender-completo-2025/
|
||||
- /odoo/dashboard-ninja-odoo-avanzado-2025/
|
||||
- /odoo/descargar-odoo-instaladores-oficiales-2025/
|
||||
- /odoo/empleos-odoo-oportunidades-carrera-2025/
|
||||
- /odoo/empresa-odoo-historia-fundacion-2025/
|
||||
- /odoo/freelance-odoo-consultores-independientes-2025/
|
||||
- /odoo/instalar-odoo-guia-paso-a-paso-2025/
|
||||
|
||||
CONSTRAINTS: preserve <head> tags except the marker + og:image + preload; preserve hreflang/canonical/OG/header/footer/nav/breadcrumb/D3.js refs; blog-factcheck mandatory (no fabricated stats); all images via powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (NO fallback - probe was done in SETUP).
|
||||
|
||||
PROVE each turn: list which of the 10 URLs are COMPLETE (committed + analyze>=80 + geo PASS), which are IN PROGRESS, which FAILED (logged to BLOG-FAILURES.md). Paste latest /blog analyze score per completed URL.
|
||||
|
||||
DONE WHEN: at least 9 of the 10 URLs are committed on branch fix/seo-batch-b03 with analyze>=80 AND geo PASS AND content-version marker present. Run: git log fix/seo-batch-b03 --oneline -n 12 and paste it.
|
||||
|
||||
STOP after 60 turns if <9 done; report which URLs blocked and why.
|
||||
@@ -0,0 +1,23 @@
|
||||
GOAL - Batch B04 (W12 - thin-content rewrite) for odoo-expertos. Branch: fix/seo-batch-b04. Repo root = current folder (a git worktree off fix/seo-all). Work ONLY here.
|
||||
|
||||
PIPELINE: for EACH of the 10 URLs below, run seo-audit-2026-05-27\BLOG-PIPELINE.md steps 1-12 (discourse -> flow find -> brief -> outline -> /blog rewrite -> blog-factcheck -> seo-check -> kie.ai z-image >=3 per article NO text/letters/numbers/logos -> /blog schema -> /blog geo gate -> /blog analyze >=80 -> commit). Add <meta name="content-version" content="W12-deep-rewrite"> to each rewritten page's <head>. Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos".
|
||||
|
||||
URLS (10):
|
||||
- /odoo/odoo-17-funciones-caracteristicas-2025/
|
||||
- /odoo/odoo-18-nuevas-funciones-2025/
|
||||
- /odoo/odoo-api-integraciones-desarrollo-2025/
|
||||
- /odoo/odoo-bolivia-implementacion-local-2025/
|
||||
- /odoo/odoo-chatbot-atencion-cliente-2025/
|
||||
- /odoo/odoo-chile-implementacion-local-2025/
|
||||
- /odoo/odoo-colombia-implementacion-local-2025/
|
||||
- /odoo/odoo-community-enterprise-diferencias-2025/
|
||||
- /odoo/odoo-contabilidad-modulo-completo-2025/
|
||||
- /odoo/odoo-costa-rica-implementacion-local-2025/
|
||||
|
||||
CONSTRAINTS: preserve <head> tags except the marker + og:image + preload; preserve hreflang/canonical/OG/header/footer/nav/breadcrumb/D3.js refs; blog-factcheck mandatory (no fabricated stats); all images via powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (NO fallback - probe was done in SETUP).
|
||||
|
||||
PROVE each turn: list which of the 10 URLs are COMPLETE (committed + analyze>=80 + geo PASS), which are IN PROGRESS, which FAILED (logged to BLOG-FAILURES.md). Paste latest /blog analyze score per completed URL.
|
||||
|
||||
DONE WHEN: at least 9 of the 10 URLs are committed on branch fix/seo-batch-b04 with analyze>=80 AND geo PASS AND content-version marker present. Run: git log fix/seo-batch-b04 --oneline -n 12 and paste it.
|
||||
|
||||
STOP after 60 turns if <9 done; report which URLs blocked and why.
|
||||
@@ -0,0 +1,23 @@
|
||||
GOAL - Batch B05 (W12 - thin-content rewrite) for odoo-expertos. Branch: fix/seo-batch-b05. Repo root = current folder (a git worktree off fix/seo-all). Work ONLY here.
|
||||
|
||||
PIPELINE: for EACH of the 10 URLs below, run seo-audit-2026-05-27\BLOG-PIPELINE.md steps 1-12 (discourse -> flow find -> brief -> outline -> /blog rewrite -> blog-factcheck -> seo-check -> kie.ai z-image >=3 per article NO text/letters/numbers/logos -> /blog schema -> /blog geo gate -> /blog analyze >=80 -> commit). Add <meta name="content-version" content="W12-deep-rewrite"> to each rewritten page's <head>. Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos".
|
||||
|
||||
URLS (10):
|
||||
- /odoo/odoo-crm-gestion-clientes-2025/
|
||||
- /odoo/odoo-demo-prueba-gratuita-2025/
|
||||
- /odoo/odoo-docker-contenedores-implementacion-2025/
|
||||
- /odoo/odoo-ecuador-implementacion-local-2025/
|
||||
- /odoo/odoo-el-salvador-implementacion-local-2025/
|
||||
- /odoo/odoo-erp-sistema-empresarial-2025/
|
||||
- /odoo/odoo-espana-implementacion-local-2025/
|
||||
- /odoo/odoo-facturacion-electronica-completa-2025/
|
||||
- /odoo/odoo-gestion-proyectos-completa-2025/
|
||||
- /odoo/odoo-github-desarrollo-codigo-2025/
|
||||
|
||||
CONSTRAINTS: preserve <head> tags except the marker + og:image + preload; preserve hreflang/canonical/OG/header/footer/nav/breadcrumb/D3.js refs; blog-factcheck mandatory (no fabricated stats); all images via powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (NO fallback - probe was done in SETUP).
|
||||
|
||||
PROVE each turn: list which of the 10 URLs are COMPLETE (committed + analyze>=80 + geo PASS), which are IN PROGRESS, which FAILED (logged to BLOG-FAILURES.md). Paste latest /blog analyze score per completed URL.
|
||||
|
||||
DONE WHEN: at least 9 of the 10 URLs are committed on branch fix/seo-batch-b05 with analyze>=80 AND geo PASS AND content-version marker present. Run: git log fix/seo-batch-b05 --oneline -n 12 and paste it.
|
||||
|
||||
STOP after 60 turns if <9 done; report which URLs blocked and why.
|
||||
@@ -0,0 +1,23 @@
|
||||
GOAL - Batch B06 (W12 - thin-content rewrite) for odoo-expertos. Branch: fix/seo-batch-b06. Repo root = current folder (a git worktree off fix/seo-all). Work ONLY here.
|
||||
|
||||
PIPELINE: for EACH of the 10 URLs below, run seo-audit-2026-05-27\BLOG-PIPELINE.md steps 1-12 (discourse -> flow find -> brief -> outline -> /blog rewrite -> blog-factcheck -> seo-check -> kie.ai z-image >=3 per article NO text/letters/numbers/logos -> /blog schema -> /blog geo gate -> /blog analyze >=80 -> commit). Add <meta name="content-version" content="W12-deep-rewrite"> to each rewritten page's <head>. Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos".
|
||||
|
||||
URLS (10):
|
||||
- /odoo/odoo-gratis-vs-pago-diferencias-2025/
|
||||
- /odoo/odoo-guatemala-implementacion-local-2025/
|
||||
- /odoo/odoo-helpdesk-atencion-cliente-2025/
|
||||
- /odoo/odoo-honduras-implementacion-local-2025/
|
||||
- /odoo/odoo-hosting-cloud-infraestructura-2025/
|
||||
- /odoo/odoo-inteligencia-artificial-ia-2025/
|
||||
- /odoo/odoo-inventario-gestion-almacen-2025/
|
||||
- /odoo/odoo-manufactura-produccion-industrial-2025/
|
||||
- /odoo/odoo-marketplace-multi-vendor-2025/
|
||||
- /odoo/odoo-mexico-implementacion-local-2025/
|
||||
|
||||
CONSTRAINTS: preserve <head> tags except the marker + og:image + preload; preserve hreflang/canonical/OG/header/footer/nav/breadcrumb/D3.js refs; blog-factcheck mandatory (no fabricated stats); all images via powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (NO fallback - probe was done in SETUP).
|
||||
|
||||
PROVE each turn: list which of the 10 URLs are COMPLETE (committed + analyze>=80 + geo PASS), which are IN PROGRESS, which FAILED (logged to BLOG-FAILURES.md). Paste latest /blog analyze score per completed URL.
|
||||
|
||||
DONE WHEN: at least 9 of the 10 URLs are committed on branch fix/seo-batch-b06 with analyze>=80 AND geo PASS AND content-version marker present. Run: git log fix/seo-batch-b06 --oneline -n 12 and paste it.
|
||||
|
||||
STOP after 60 turns if <9 done; report which URLs blocked and why.
|
||||
@@ -0,0 +1,23 @@
|
||||
GOAL - Batch B07 (W12 - thin-content rewrite) for odoo-expertos. Branch: fix/seo-batch-b07. Repo root = current folder (a git worktree off fix/seo-all). Work ONLY here.
|
||||
|
||||
PIPELINE: for EACH of the 10 URLs below, run seo-audit-2026-05-27\BLOG-PIPELINE.md steps 1-12 (discourse -> flow find -> brief -> outline -> /blog rewrite -> blog-factcheck -> seo-check -> kie.ai z-image >=3 per article NO text/letters/numbers/logos -> /blog schema -> /blog geo gate -> /blog analyze >=80 -> commit). Add <meta name="content-version" content="W12-deep-rewrite"> to each rewritten page's <head>. Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos".
|
||||
|
||||
URLS (10):
|
||||
- /odoo/odoo-nicaragua-implementacion-local-2025/
|
||||
- /odoo-hosting/apps-terceros-odoo-instalacion-2025/
|
||||
- /odoo-hosting/aws-hosting-odoo-2026/
|
||||
- /odoo-hosting/aws-hosting-odoo-amazon-cloud-2025/
|
||||
- /odoo-hosting/azure-hosting-odoo-microsoft-2025/
|
||||
- /odoo-hosting/cliente-odoo-hosting-acceso-2025/
|
||||
- /odoo-hosting/como-usar-odoo-hosting-guia-2025/
|
||||
- /odoo-hosting/configuracion-contabilidad-odoo-hosting-2025/
|
||||
- /odoo-hosting/configuracion-hosting-odoo-optimizacion-2025/
|
||||
- /odoo-hosting/desarrollo-website-odoo-14-2025/
|
||||
|
||||
CONSTRAINTS: preserve <head> tags except the marker + og:image + preload; preserve hreflang/canonical/OG/header/footer/nav/breadcrumb/D3.js refs; blog-factcheck mandatory (no fabricated stats); all images via powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (NO fallback - probe was done in SETUP).
|
||||
|
||||
PROVE each turn: list which of the 10 URLs are COMPLETE (committed + analyze>=80 + geo PASS), which are IN PROGRESS, which FAILED (logged to BLOG-FAILURES.md). Paste latest /blog analyze score per completed URL.
|
||||
|
||||
DONE WHEN: at least 9 of the 10 URLs are committed on branch fix/seo-batch-b07 with analyze>=80 AND geo PASS AND content-version marker present. Run: git log fix/seo-batch-b07 --oneline -n 12 and paste it.
|
||||
|
||||
STOP after 60 turns if <9 done; report which URLs blocked and why.
|
||||
@@ -0,0 +1,23 @@
|
||||
GOAL - Batch B08 (W12 - thin-content rewrite) for odoo-expertos. Branch: fix/seo-batch-b08. Repo root = current folder (a git worktree off fix/seo-all). Work ONLY here.
|
||||
|
||||
PIPELINE: for EACH of the 10 URLs below, run seo-audit-2026-05-27\BLOG-PIPELINE.md steps 1-12 (discourse -> flow find -> brief -> outline -> /blog rewrite -> blog-factcheck -> seo-check -> kie.ai z-image >=3 per article NO text/letters/numbers/logos -> /blog schema -> /blog geo gate -> /blog analyze >=80 -> commit). Add <meta name="content-version" content="W12-deep-rewrite"> to each rewritten page's <head>. Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos".
|
||||
|
||||
URLS (10):
|
||||
- /odoo-hosting/digitalocean-hosting-odoo-deployment-2025/
|
||||
- /odoo-hosting/documentacion-hosting-odoo-guias-2025/
|
||||
- /odoo-hosting/email-dominio-hosting-odoo-2025/
|
||||
- /odoo-hosting/gestion-inmobiliaria-odoo-hosting-2025/
|
||||
- /odoo-hosting/gestion-suscripciones-odoo-hosting-2025/
|
||||
- /odoo-hosting/hosting-compartido-odoo-2026/
|
||||
- /odoo-hosting/hosting-compartido-odoo-shared-2025/
|
||||
- /odoo-hosting/hosting-odoo-29-euros-2026/
|
||||
- /odoo-hosting/hosting-odoo-barato-2026/
|
||||
- /odoo-hosting/hosting-odoo-chile-2026/
|
||||
|
||||
CONSTRAINTS: preserve <head> tags except the marker + og:image + preload; preserve hreflang/canonical/OG/header/footer/nav/breadcrumb/D3.js refs; blog-factcheck mandatory (no fabricated stats); all images via powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (NO fallback - probe was done in SETUP).
|
||||
|
||||
PROVE each turn: list which of the 10 URLs are COMPLETE (committed + analyze>=80 + geo PASS), which are IN PROGRESS, which FAILED (logged to BLOG-FAILURES.md). Paste latest /blog analyze score per completed URL.
|
||||
|
||||
DONE WHEN: at least 9 of the 10 URLs are committed on branch fix/seo-batch-b08 with analyze>=80 AND geo PASS AND content-version marker present. Run: git log fix/seo-batch-b08 --oneline -n 12 and paste it.
|
||||
|
||||
STOP after 60 turns if <9 done; report which URLs blocked and why.
|
||||
@@ -0,0 +1,23 @@
|
||||
GOAL - Batch B09 (W12 - thin-content rewrite) for odoo-expertos. Branch: fix/seo-batch-b09. Repo root = current folder (a git worktree off fix/seo-all). Work ONLY here.
|
||||
|
||||
PIPELINE: for EACH of the 10 URLs below, run seo-audit-2026-05-27\BLOG-PIPELINE.md steps 1-12 (discourse -> flow find -> brief -> outline -> /blog rewrite -> blog-factcheck -> seo-check -> kie.ai z-image >=3 per article NO text/letters/numbers/logos -> /blog schema -> /blog geo gate -> /blog analyze >=80 -> commit). Add <meta name="content-version" content="W12-deep-rewrite"> to each rewritten page's <head>. Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos".
|
||||
|
||||
URLS (10):
|
||||
- /odoo-hosting/hosting-odoo-colombia-2026/
|
||||
- /odoo-hosting/hosting-odoo-community-edition-gratuita-2025/
|
||||
- /odoo-hosting/hosting-odoo-completo-guia-2025/
|
||||
- /odoo-hosting/hosting-odoo-costa-rica-2026/
|
||||
- /odoo-hosting/hosting-odoo-descuento-2026/
|
||||
- /odoo-hosting/hosting-odoo-economico-2026/
|
||||
- /odoo-hosting/hosting-odoo-ecuador-2026/
|
||||
- /odoo-hosting/hosting-odoo-enterprise-empresarial-2025/
|
||||
- /odoo-hosting/hosting-odoo-enterprise-precios-2026/
|
||||
- /odoo-hosting/hosting-odoo-espana-2026/
|
||||
|
||||
CONSTRAINTS: preserve <head> tags except the marker + og:image + preload; preserve hreflang/canonical/OG/header/footer/nav/breadcrumb/D3.js refs; blog-factcheck mandatory (no fabricated stats); all images via powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (NO fallback - probe was done in SETUP).
|
||||
|
||||
PROVE each turn: list which of the 10 URLs are COMPLETE (committed + analyze>=80 + geo PASS), which are IN PROGRESS, which FAILED (logged to BLOG-FAILURES.md). Paste latest /blog analyze score per completed URL.
|
||||
|
||||
DONE WHEN: at least 9 of the 10 URLs are committed on branch fix/seo-batch-b09 with analyze>=80 AND geo PASS AND content-version marker present. Run: git log fix/seo-batch-b09 --oneline -n 12 and paste it.
|
||||
|
||||
STOP after 60 turns if <9 done; report which URLs blocked and why.
|
||||
@@ -0,0 +1,23 @@
|
||||
GOAL - Batch B10 (W12 - thin-content rewrite) for odoo-expertos. Branch: fix/seo-batch-b10. Repo root = current folder (a git worktree off fix/seo-all). Work ONLY here.
|
||||
|
||||
PIPELINE: for EACH of the 10 URLs below, run seo-audit-2026-05-27\BLOG-PIPELINE.md steps 1-12 (discourse -> flow find -> brief -> outline -> /blog rewrite -> blog-factcheck -> seo-check -> kie.ai z-image >=3 per article NO text/letters/numbers/logos -> /blog schema -> /blog geo gate -> /blog analyze >=80 -> commit). Add <meta name="content-version" content="W12-deep-rewrite"> to each rewritten page's <head>. Replace every "Maria Elena Rodriguez" with "Equipo Odoo Expertos".
|
||||
|
||||
URLS (10):
|
||||
- /odoo-hosting/hosting-odoo-espana-proveedores-2025/
|
||||
- /odoo-hosting/hosting-odoo-gestionado-managed-2025/
|
||||
- /odoo-hosting/hosting-odoo-gratis-2026/
|
||||
- /odoo-hosting/hosting-odoo-internacional-alemania-suiza-2025/
|
||||
- /odoo-hosting/hosting-odoo-local-on-premise-2025/
|
||||
- /odoo-hosting/hosting-odoo-mensual-2026/
|
||||
- /odoo-hosting/hosting-odoo-nube-cloud-2025/
|
||||
- /odoo-hosting/hosting-odoo-nube-cloud-2026/
|
||||
- /odoo-hosting/hosting-odoo-oferta-2026/
|
||||
- /odoo-hosting/hosting-odoo-panama-2026/
|
||||
|
||||
CONSTRAINTS: preserve <head> tags except the marker + og:image + preload; preserve hreflang/canonical/OG/header/footer/nav/breadcrumb/D3.js refs; blog-factcheck mandatory (no fabricated stats); all images via powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (NO fallback - probe was done in SETUP).
|
||||
|
||||
PROVE each turn: list which of the 10 URLs are COMPLETE (committed + analyze>=80 + geo PASS), which are IN PROGRESS, which FAILED (logged to BLOG-FAILURES.md). Paste latest /blog analyze score per completed URL.
|
||||
|
||||
DONE WHEN: at least 9 of the 10 URLs are committed on branch fix/seo-batch-b10 with analyze>=80 AND geo PASS AND content-version marker present. Run: git log fix/seo-batch-b10 --oneline -n 12 and paste it.
|
||||
|
||||
STOP after 60 turns if <9 done; report which URLs blocked and why.
|
||||
@@ -0,0 +1,29 @@
|
||||
GOAL - FINAL: merge 10 batches, run W5b + cluster wiring, gate, deploy, re-audit to >=75/100. Repo root = current folder. Work ONLY here.
|
||||
|
||||
PHASE A Merge: on fix/seo-all, merge each branch fix/seo-batch-b01..b10 in order with --no-ff. Resolve any conflicts conservatively (prefer the batch's content for article files, prefer fix/seo-all for shared infra). Paste git log --oneline -n 20.
|
||||
|
||||
PHASE B W5b titles+metas: implement OPPORTUNITIES sec3 codemod over every <slug>/index.html (now includes the freshly rewritten ones). Commit fix(W5b). Verify: powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W5b -> "W5b: PASS".
|
||||
|
||||
PHASE C Cluster wiring + taxonomy + cannibalization re-sweep: /blog cluster execute "odoo-hosting"; ditto "odoo-comparativas"; ditto "odoo-alternativas"; /blog taxonomy sync; /blog cannibalization . (resolve any 301s incl. 2025/2026 mejores-proveedores collision); /blog locale-audit .
|
||||
|
||||
PHASE D Local gate: REVIEW.ps1 -Only all -> every W1..W11, W5b, W12, W13 must say PASS. Paste output.
|
||||
|
||||
PHASE E Push + merge + deploy:
|
||||
git push -u origin fix/seo-all
|
||||
git checkout main && git pull
|
||||
git merge --no-ff fix/seo-all -m "merge SEO restoration W1-W13 (100 articles, 10 batches)"
|
||||
git push origin main
|
||||
Then every 60s for up to 12 min curl https://www.odoo-expertos.com/robots.txt; deploy live when "Disallow: /*#" is ABSENT.
|
||||
|
||||
PHASE F Re-audit (multi-judge):
|
||||
- /blog google psi https://www.odoo-expertos.com/ ; /blog google crux ditto ; /blog google gsc resubmit+validate (if supported).
|
||||
- /blog audit . ; /blog locale-audit . ; /blog geo on 5 sampled batch URLs.
|
||||
- Skill seo-audit args="https://www.odoo-expertos.com/" -> paste full report; extract "Overall SEO Health Score: X/100".
|
||||
|
||||
PHASE G Editorial (on PASS): /blog calendar (90-day plan); /blog repurpose <Cluster A pillar> (non-gating).
|
||||
|
||||
DONE WHEN: pasted "Overall SEO Health Score" >=75/100 AND main deployed AND REVIEW.ps1 -Only all all PASS AND /blog audit shows 0 Critical.
|
||||
|
||||
IF SCORE <75: lowest-scoring category, branch fix/seo-iter2 from main, fix with matching skill, merge, redeploy, re-audit. Stop after 200 turns. If still <75 report 3 lowest categories + recommendations.
|
||||
|
||||
CONSTRAINTS: no fabricated stats; preserve design + D3.js; no edits outside this repo.
|
||||
@@ -0,0 +1,42 @@
|
||||
GOAL - Restore odoo-expertos.com to a re-audited live SEO health >=75/100. ONE session supervises the launcher; the launcher runs the heavy parallel work (1 SETUP + 10 parallel BATCH worktrees + 1 FINAL). Repo root = current folder. Work ONLY here.
|
||||
|
||||
KEY FILES (read for context):
|
||||
- seo-audit-2026-05-27\run-parallel-100.ps1 (orchestrator)
|
||||
- seo-audit-2026-05-27\goals\SETUP.txt, B01..B10.txt, FINAL.txt
|
||||
- seo-audit-2026-05-27\BLOG-PIPELINE.md (12-step per-article pipeline; kie.ai z-image policy)
|
||||
- seo-audit-2026-05-27\OPPORTUNITIES-2026-05-28.md
|
||||
- seo-audit-2026-05-27\batches\URL-BATCHES.json (100 URLs in B01..B10)
|
||||
- seo-audit-2026-05-27\REVIEW.ps1 (deterministic local gate)
|
||||
|
||||
TURN 1 - FIRE LAUNCHER (background): use Bash run_in_background=true:
|
||||
powershell -File seo-audit-2026-05-27\run-parallel-100.ps1 -Phase all -MaxConcurrent 10 -Model sonnet > seo-audit-2026-05-27\launcher.log 2>&1
|
||||
Note the bg task id. Do NOT block. Runtime: 8-16 hours.
|
||||
|
||||
TURN 2..N - MONITOR each turn until launcher exits:
|
||||
- Tail seo-audit-2026-05-27\launcher.log (last 30 lines).
|
||||
- git log fix/seo-all --oneline -n 8.
|
||||
- For each batch B01..B10 still active: tail ..\odoo-wt-bNN\BNN.log.
|
||||
- Report phase (SETUP / BATCHES x/10 / FINAL).
|
||||
- If launcher.log contains "z-image unavailable" -> ABORT and paste the kie.ai error verbatim. NO model fallback.
|
||||
- A single failing batch is OK; FINAL handles partial if >=7 batches succeed.
|
||||
|
||||
TURN VERIFY (when launcher exits):
|
||||
- powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only all - paste output; W1..W11, W5b, W12, W13 all PASS.
|
||||
- git log main --oneline -n 5 - shows FINAL merged to main.
|
||||
- curl -sI https://www.odoo-expertos.com/ - X-Content-Type-Options + X-Frame-Options present (W11 live).
|
||||
- curl -s https://www.odoo-expertos.com/robots.txt | findstr "/\*#" - EMPTY (W2 live).
|
||||
|
||||
TURN AUDIT:
|
||||
Invoke Skill tool: skill="seo-audit", args="https://www.odoo-expertos.com/". Paste the full report. Extract the "Overall SEO Health Score: X/100" line.
|
||||
|
||||
DONE WHEN: extracted Overall SEO Health Score >=75/100 AND REVIEW.ps1 -Only all all PASS AND main is deployed.
|
||||
|
||||
IF SCORE <75: identify lowest-scoring category (Technical/Content/On-Page/Schema/Performance/AI Search/Images), then EITHER (a) re-run powershell -File seo-audit-2026-05-27\run-parallel-100.ps1 -Phase batches -MaxConcurrent 5 (resumes failed batches in existing worktrees), OR (b) fix that category inline with the matching /blog skill. Then merge to main, wait for Vercel (poll robots.txt as in VERIFY), re-audit. Hard cap 200 total turns. If still <75 report 3 lowest categories with their recommended fixes.
|
||||
|
||||
CONSTRAINTS (already enforced by per-batch goals; restated for supervisor):
|
||||
- blog-factcheck mandatory; NEVER fabricate stats (drop unsourced numbers).
|
||||
- Preserve design + ALL D3.js refs; preserve <head> except the content-version marker + og:image + preload.
|
||||
- "Equipo Odoo Expertos" replaces every "Maria Elena Rodriguez" in W12/W13 marked pages.
|
||||
- >=3 z-image images per article (hero+fig1+fig2); every image prompt ends with ", NO text, NO letters, NO numbers, NO logos, NO watermarks.".
|
||||
- All image gen via seo-audit-2026-05-27\scripts\kie-image.ps1 -Model z-image only (no fallback). NEVER /blog image generate.
|
||||
- No edits outside this repo.
|
||||
@@ -0,0 +1,19 @@
|
||||
GOAL - SETUP for parallel SEO restoration on odoo-expertos. Branch: fix/seo-all (continue from current; W1..W11 already committed). Repo root = current folder. Work ONLY here.
|
||||
|
||||
OBJECTIVE: produce the shared foundation that all 10 BATCH agents will branch from. Output: BRAND.md, VOICE.md, personas/equipo-odoo-expertos.md, strategy + cluster plans, diagnostics baseline, z-image probe success.
|
||||
|
||||
STEPS:
|
||||
1) z-image probe: powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Prompt "abstract data visualization, blue gradient, NO text, NO letters, NO numbers, NO logos" -OutPath "seo-audit-2026-05-27\scripts\.zimage-probe.png" -Model z-image -Aspect 16:9 -Resolution 1K. If ERROR: ABORT the goal with "z-image unavailable". NO fallback.
|
||||
2) /blog brand init -> BRAND.md + VOICE.md at repo root.
|
||||
3) /blog persona create "Equipo Odoo Expertos" -> personas/equipo-odoo-expertos.md.
|
||||
4) /blog flow sync.
|
||||
5) /blog strategy "odoo erp consulting LATAM" -> strategy doc.
|
||||
6) /blog audit . -> baseline site health.
|
||||
7) /blog cannibalization . -> baseline.
|
||||
8) /blog locale-audit . -> baseline.
|
||||
9) /blog cluster plan "odoo-hosting" (Cluster A); /blog cluster plan "odoo-comparativas" (B); /blog cluster plan "odoo-alternativas" (C).
|
||||
10) git add -A; git commit -m "setup(SEO): brand+persona+flow+strategy+clusters baseline for parallel batches"
|
||||
|
||||
DONE WHEN: BRAND.md AND personas/equipo-odoo-expertos.md AND the 3 cluster plan files exist locally, AND the z-image probe image was saved, AND a setup commit appears on fix/seo-all (paste git log -1 --oneline).
|
||||
|
||||
STOP after 25 turns if blocked; if z-image probe failed, abort immediately and report the kie.ai error verbatim.
|
||||
@@ -0,0 +1,7 @@
|
||||
GOAL - W1 Sitemap & redirect hygiene (odoo-expertos). Branch: fix/w1-sitemaps.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo; never touch any other folder.
|
||||
Context: seo-audit-2026-05-27\FULL-AUDIT-REPORT.md (Part B). Sitemaps list redirecting + non-canonical URLs, wasting crawl budget. vercel.json redirects the country-variant hosting pages and /index.html.
|
||||
TASK: (1) In every sitemap-*.xml remove each <loc> that ends in /index.html, OR is a redirecting country-variant under /(en|fr|pt|ar)/odoo-hosting/ (bestes-/cheap-/kostenloses-/best-/free-odoo-hosting-2026, odoo-hosting-deutschland/oesterreich/schweiz/germany/uk-2026, odoo-sh-alternatives-2026, odoo-vps-hosting-2026), OR has no local <slug>/index.html. (2) Create the missing index pages odoo-hosting/index.html under en/, fr/, pt/ by mirroring de/odoo-hosting/index.html (translate visible text to the right language). (3) Keep the sitemap-index structure.
|
||||
CONSTRAINTS: edit only sitemap*.xml and the 3 new index.html files. Do not change other pages.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W1 and paste the full output.
|
||||
DONE WHEN: the pasted output contains a line "W1: PASS", AND you committed all changes on branch fix/w1-sitemaps (show git log -1 --oneline). If not PASS, keep fixing; stop after 20 turns and report the exact FAIL detail.
|
||||
@@ -0,0 +1,7 @@
|
||||
GOAL - W10 Performance / Core Web Vitals (odoo-expertos). Branch: fix/w10-perf.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: FULL-AUDIT-REPORT.md (Part A sec 5). Homepage has ~33KB inline CSS (should be <14KB); D3 is loaded from the d3js.org CDN at runtime (should be self-hosted); all assets serve Cache-Control: max-age=0.
|
||||
TASK: (1) Move non-critical CSS out of index.html's inline <style> into css/main.min.css so the inline style is under 14KB (keep only true above-the-fold critical CSS inline). (2) Download d3 v7 minified to js/d3.v7.min.js and reference it locally instead of https://d3js.org; remove the misplaced d3js.org preconnect on pages that do not use D3. (3) In vercel.json add a headers rule giving Cache-Control: public, max-age=31536000, immutable to /css, /js, /components assets.
|
||||
CONSTRAINTS: do not change visible layout; keep the homepage rendering identical.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W10 and paste the full output.
|
||||
DONE WHEN: the output contains "W10: PASS" (inline CSS <14336 bytes AND self-hosted D3 exists AND immutable cache header present), AND you committed on branch fix/w10-perf (show git log -1 --oneline). Stop after 20 turns if blocked and report the FAIL detail.
|
||||
@@ -0,0 +1,7 @@
|
||||
GOAL - W11 Security headers (odoo-expertos). Branch: fix/w11-headers.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: FULL-AUDIT-REPORT.md (Part A sec 1). HSTS is present but X-Content-Type-Options, X-Frame-Options, and Referrer-Policy are missing.
|
||||
TASK: In vercel.json add a headers rule for source "/(.*)" applying: X-Content-Type-Options: nosniff; X-Frame-Options: SAMEORIGIN; Referrer-Policy: strict-origin-when-cross-origin. Merge with any existing headers block; do not remove existing headers.
|
||||
CONSTRAINTS: edit only vercel.json.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W11 and paste the full output.
|
||||
DONE WHEN: the output contains "W11: PASS" (all 3 headers present), AND you committed on branch fix/w11-headers (show git log -1 --oneline). Stop after 10 turns if blocked and report the FAIL detail.
|
||||
@@ -0,0 +1,17 @@
|
||||
GOAL - W12 Rewrite 20 thin articles via /blog-rewrite, preserving design + D3.js (odoo-expertos). Branch: fix/w12-rewrite-thin.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: ~587 article pages were "crawled but not indexed" because they are thin/templated. The audit confirmed bodies of ~400-450 words even where the wrapper is 1200+. The blog skill set (claude-blog) is installed at ~/.claude/skills/blog* with sub-skills /blog rewrite, /blog factcheck, /blog geo, /blog schema.
|
||||
TASK PER ARTICLE: invoke the /blog rewrite skill mentally (read ~/.claude/skills/blog-rewrite/SKILL.md) to:
|
||||
1. Read the existing <slug>/index.html and EXTRACT only the <article> body. Keep the rest of the file unchanged: <head>, header/footer/nav, JSON-LD blocks, D3.js script tags, CSS classes, image refs, the breadcrumb baked by W6.
|
||||
2. Rewrite the article body to >=1,200 unique words of substantive content with: opening 60-150 word direct-answer passage; 4-6 H2 sections each opening with a direct answer in the first 40-60 words; sourced statistics (cite source domain inline, no fabricated numbers); a "Key takeaways" bullet list; 6+ FAQ Q&A reflected in a FAQPage JSON-LD block.
|
||||
3. Replace any "Dr. Maria Elena Rodriguez" author reference with "Equipo Odoo Expertos" (until a real author bio exists) in both visible byline AND Article JSON-LD author.
|
||||
4. Keep the page's existing D3-driven chart container untouched; do not remove any <script src="...d3..."> tag.
|
||||
PRIORITY LIST: pick 20 from seo-audit-2026-05-27\gsc\crawled-not-indexed.txt that are Spanish-root or English-translated pages (skip pages already noindex'd by W7).
|
||||
CONSTRAINTS: only edit <article> body + Article/FAQPage JSON-LD + visible byline. Never touch <head> tags, hreflang, canonical, OG, nav, footer, sitemap, D3 scripts, CSS. No fabricated statistics. Cite a real source domain inline for every numeric claim.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W12 and paste full output.
|
||||
DONE WHEN: that output contains "W12: PASS" (>=20 rewritten files committed AND sampled rewritten pages have >=1,200 body words AND >=6 FAQ Q&A AND no "Maria Elena Rodriguez" remaining in the rewritten set), AND committed on branch fix/w12-rewrite-thin (show git log -1 --oneline). Stop after 40 turns if blocked, listing which articles still FAIL.
|
||||
|
||||
MARKER (required for REVIEW): you may add EXACTLY ONE meta tag to each rewritten page's <head>: <meta name="content-version" content="W12-deep-rewrite">. Do not change any other <head> tags. REVIEW.ps1 -Only W12 counts pages with this marker.
|
||||
|
||||
|
||||
CONCRETE TARGETS: read seo-audit-2026-05-27\OPPORTUNITIES-2026-05-28.md section 2 for the prioritized list of 20 thin pages with proposed angle + target word count + AI-search query per page. Rewrite those 20.
|
||||
@@ -0,0 +1,18 @@
|
||||
GOAL - W13 Deepen 10 vs-competitor / "best/review" pages for AI-search citations (odoo-expertos). Branch: fix/w13-ai-search.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: AI engines (ChatGPT, Perplexity, Google AIO, Bing Copilot) most reliably cite "X vs Y" and "best of" pages with direct-answer passages, structured data, comparison tables, and verifiable sources. You ALREADY have 13 such slugs (odoo-vs-sap-hosting-2026, odoo-vs-zoho-books-hosting-2025, cloudpepper-vs-odoo-sh-2026, alternativas-odoo-sh-2026, odoo-community-vs-enterprise-hosting-2026, odoo-gratis-vs-pago-diferencias-2025, comparativa-precios-odoo-2026, mejor-hosting-odoo-2026, mejores-proveedores-hosting-odoo-2025, mejores-proveedores-hosting-odoo-2026, opiniones-hosting-odoo-2026, odoo4projects-hosting-review-2026, alternativas-odoo-ia-comparativas-2025). Pick the top 10.
|
||||
TASK PER PAGE: apply the /blog geo skill principles (read ~/.claude/skills/blog-geo/SKILL.md):
|
||||
1. Open the page in opening with a 60-150 word "direct answer" paragraph that an LLM can quote verbatim (lead with the answer, then the qualifier).
|
||||
2. Each H2 section starts with a 40-80 word direct-answer passage before any detail.
|
||||
3. Add or expand FAQPage JSON-LD to >=8 high-intent Q&A reflecting common AI prompts (e.g., "Cual es mejor: X o Y para empresa pequena?").
|
||||
4. Add an HTML comparison <table> with rows for: pricing, hosting requirements, learning curve, scalability ceiling, TCO 5-year, ideal company size. Every numeric cell must include a citation marker linking to the source (footnote or inline <a>).
|
||||
5. Replace fabricated "Dr. Maria Elena Rodriguez" byline + Article JSON-LD author with "Equipo Odoo Expertos" (or a real author if one exists).
|
||||
6. Add Review/AggregateRating JSON-LD ONLY if real reviews exist on the page (no fabrication).
|
||||
CONSTRAINTS: only edit body + JSON-LD on the 10 selected pages. Preserve design, D3.js refs, hreflang, canonical, nav.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W13 and paste full output.
|
||||
DONE WHEN: that output contains "W13: PASS" (10 target pages each have: >=8 FAQ items, comparison <table>, direct-answer opening, no fabricated author) AND committed on branch fix/w13-ai-search (show git log -1 --oneline). Stop after 30 turns if blocked.
|
||||
|
||||
MARKER (required for REVIEW): you may add EXACTLY ONE meta tag to each updated page's <head>: <meta name="content-version" content="W13-ai-search">. Do not change any other <head> tags. REVIEW.ps1 -Only W13 counts pages with this marker.
|
||||
|
||||
|
||||
CONCRETE TARGETS: read seo-audit-2026-05-27\OPPORTUNITIES-2026-05-28.md section 1 (top 10 AI-search pages, ranked with current weakness + concrete fix) and section 4 (cluster grouping). Apply both: deepen the 10 pages with the per-page fixes; add the pillar/spoke internal links per the cluster structure.
|
||||
@@ -0,0 +1,7 @@
|
||||
GOAL - W2 robots.txt cleanup (odoo-expertos). Branch: fix/w2-robots.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: FULL-AUDIT-REPORT.md (Part A, sec 1). robots.txt has TWO "User-agent: *" groups (2nd is ignored by crawlers), duplicate Bingbot and CCBot groups, and a meaningless "Disallow: /*#".
|
||||
TASK: Edit robots.txt so there is exactly ONE "User-agent: *" group; move the useful "Disallow: /*?" and "Disallow: /*&" into that first group; delete the second "User-agent: *" block, the duplicate Bingbot group, the duplicate CCBot group, and the "Disallow: /*#" line. Keep all AI-crawler Allow rules and the "Sitemap:" line.
|
||||
CONSTRAINTS: edit only robots.txt.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W2 and paste the full output.
|
||||
DONE WHEN: the output contains "W2: PASS", AND you committed on branch fix/w2-robots (show git log -1 --oneline). Stop after 12 turns if blocked and report the FAIL detail.
|
||||
@@ -0,0 +1,7 @@
|
||||
GOAL - W3 Structured data / schema (odoo-expertos). Branch: fix/w3-schema.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: FULL-AUDIT-REPORT.md (Part A, sec 3). JSON-LD across ~1,168 pages uses the dead domain "odooexpertos.com" (no hyphen) and non-www URLs; canonicals use www. This breaks entity consolidation.
|
||||
TASK: Write ONE codemod (Node or Python) that rewrites all <slug>/index.html files: replace every "odooexpertos.com" with "www.odoo-expertos.com"; replace JSON-LD "url"/"item"/"@id"/"logo" values "https://odoo-expertos.com" with "https://www.odoo-expertos.com". Run it over the whole repo. Keep HTML otherwise identical. (Bonus if quick: add a valid absolute Organization logo + populate it; but the PASS gate is only the URL/domain fixes.)
|
||||
CONSTRAINTS: only change schema/JSON-LD URLs and the dead domain. Do not alter visible content. Exclude .git, node_modules, seo-audit-2026-05-27, website, directory.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W3 and paste the full output.
|
||||
DONE WHEN: the output contains "W3: PASS" (dead-domain=0 AND non-www JSON-LD=0), AND you committed on branch fix/w3-schema (show git log -1 --oneline). Stop after 20 turns if blocked and report the FAIL detail.
|
||||
@@ -0,0 +1,7 @@
|
||||
GOAL - W4 Hreflang correctness (odoo-expertos). Branch: fix/w4-hreflang.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: FULL-AUDIT-REPORT.md (Part A sec 1). Category index pages (odoo/, odoo-hosting/, odoo-ia/) have ZERO hreflang. Some pages emit hreflang="es" pointing into a /de//fr//pt//ar/ subtree (a Spanish-slug URL under a language prefix) which 404s; the es alternate and x-default must point to the ROOT Spanish URL (no language prefix).
|
||||
TASK: Write a codemod over all <slug>/index.html: (1) ensure each page has a hreflang block for the languages that actually exist for it, all on www, plus x-default pointing to the ROOT es URL. (2) Fix any hreflang="es" or x-default href that contains /de/ /fr/ /pt/ /ar/ /en/ so it points to the root path (strip the language segment). (3) Add the hreflang block to the 3 category index pages.
|
||||
CONSTRAINTS: only touch <head> hreflang/link-alternate tags. Don't change body content.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W4 and paste the full output.
|
||||
DONE WHEN: the output contains "W4: PASS" (category pages without hreflang=0 AND es-hreflang into a /lang/ subtree=0), AND you committed on branch fix/w4-hreflang (show git log -1 --oneline). Stop after 20 turns if blocked and report the FAIL detail.
|
||||
@@ -0,0 +1,7 @@
|
||||
GOAL - W5 Titles & meta descriptions (odoo-expertos). Branch: fix/w5-titles-meta.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: FULL-AUDIT-REPORT.md (Part A sec 2, Part B). ~1,120 pages have <title> over 65 chars (category titles are 260+ char keyword stuffing); ~192 meta descriptions are templated duplicates ("Guia completa sobre Odoo X con Odoo. Descubre las mejores practicas...").
|
||||
TASK: Write a codemod over all <slug>/index.html: (1) rewrite every <title> to <=60 chars in the page language, pattern "[primary keyword] - [short value] | Odoo Expertos" (derive the keyword from the H1/slug). (2) make every <meta name=description> UNIQUE and useful (derive from the page H1 + first paragraph; no shared template string). (3) set og:locale to match the page language (es_ES/en_US/de_DE/fr_FR/pt_PT/ar_SA).
|
||||
CONSTRAINTS: only edit <title>, meta description, og:locale. Keep them factual; do not invent stats.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W5 and paste the full output.
|
||||
DONE WHEN: the output contains "W5: PASS" (titles>65chars=0 AND duplicate meta descriptions=0), AND you committed on branch fix/w5-titles-meta (show git log -1 --oneline). Stop after 25 turns if blocked and report the FAIL detail.
|
||||
@@ -0,0 +1,14 @@
|
||||
GOAL - W5b Truly unique titles + meta descriptions per page (odoo-expertos). Branch: fix/w5b-unique-meta.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: The W5 codemod appended slug+lang as a meta-suffix to dedupe, which produces ugly truncated SERP previews like "...cuando elegir cad - Odoo Vs Sap Hosting 2026 | ES" and still leaves 194 duplicate titles. AI engines and Google reward genuinely-unique, content-derived metadata.
|
||||
TASK: Write ONE codemod (Node or Python) that for every <slug>/index.html:
|
||||
(a) Extracts the page's H1, its first H2, and the first 2 sentences of body prose (skip nav/footer/script/style).
|
||||
(b) Generates a UNIQUE <title> tag of 50-60 characters from {H1-core-phrase} - {value-fragment derived from first H2} | Odoo Expertos. If the produced title would clash with any other page's title, append the most distinctive noun phrase from the first H2.
|
||||
(c) Generates a UNIQUE <meta name="description"> of 140-160 characters from the first 2 sentences, lightly cleaned (no run-on, ends with action verb where natural), in the page's declared language. Do NOT use the slug+lang suffix trick.
|
||||
(d) After rewriting, verify uniqueness corpus-wide: no two pages share a title; no two pages share a meta description.
|
||||
CONSTRAINTS: only edit <title>, <meta name="description">, and (if present) <meta property="og:title"> / <meta property="og:description"> to mirror. Do not touch body content. Preserve language per page.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W5b and paste full output.
|
||||
DONE WHEN: that output contains "W5b: PASS" (duplicate titles=0 AND duplicate metas=0 AND all titles 40-65 chars AND all metas 130-165 chars), AND committed on branch fix/w5b-unique-meta (show git log -1 --oneline). Stop after 25 turns if blocked.
|
||||
|
||||
|
||||
CONCRETE TARGETS: read seo-audit-2026-05-27\OPPORTUNITIES-2026-05-28.md section 3 for the exact content-derived title+meta generator pseudocode and 5 worked examples. Implement that rule (extract H1 + first H2 + first 2 body sentences; skip nav/header/breadcrumb when scanning paragraphs; uniqueness registry across the corpus).
|
||||
@@ -0,0 +1,7 @@
|
||||
GOAL - W6 Internal linking & crawl depth <=3 clicks (odoo-expertos). Branch: fix/w6-internal-links.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: FULL-AUDIT-REPORT.md (Part B sec B1). The header/nav is injected client-side by createHeader() (JS), so ~1,163 pages have no nav in static HTML; ~37 articles/lang are orphaned; article bodies have no internal links.
|
||||
TASK: (1) Write a codemod that bakes the header and footer into static HTML in every <slug>/index.html (replace the JS createHeader()/createFooter() injection with the equivalent static <header>/<footer> markup containing real <a> links to /, /odoo/, /odoo-hosting/, /odoo-ia/; keep the mobile-toggle script). (2) Add a static breadcrumb (HTML <a>) + a parent-category link + 3 related-article links to each article page (codemod). (3) Create an HTML sitemap page at mapa-del-sitio/index.html linking all category + article pages, and link it in the footer.
|
||||
CONSTRAINTS: keep visible design; only add static nav/links and the sitemap page.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W6 and paste the full output.
|
||||
DONE WHEN: the output contains "W6: PASS" (createHeader pages=0 AND HTML sitemap exists=True), AND you committed on branch fix/w6-internal-links (show git log -1 --oneline). Stop after 25 turns if blocked and report the FAIL detail.
|
||||
@@ -0,0 +1,8 @@
|
||||
GOAL - W7 De-index untranslated/duplicate pages (SUBTRACTIVE) (odoo-expertos). Branch: fix/w7-deindex.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: FULL-AUDIT-REPORT.md (Part B B0). Google flags ~103 pages as duplicates (PT/FR untranslated = duplicates of the Spanish original) and 587 crawled-not-indexed. This goal does NOT translate (humans do that later) - it removes the duplicate/thin pages from the index cleanly so they stop dragging the domain down.
|
||||
INPUT LISTS (already in repo): seo-audit-2026-05-27\gsc\duplicate-canonical.txt and seo-audit-2026-05-27\gsc\crawled-not-indexed.txt (URL lists from Search Console).
|
||||
TASK: For each URL in gsc\duplicate-canonical.txt that maps to a local <slug>/index.html: (1) add <meta name="robots" content="noindex,follow"> in its <head>, and (2) remove its <loc> entry from the matching sitemap-*.xml. Do NOT delete the files (keep them for later translation). Do the same for clearly-untranslated non-ES pages you can confirm. Keep ES (root) pages indexable.
|
||||
CONSTRAINTS: only add the noindex meta + remove sitemap entries. Never noindex Spanish root pages or genuinely-translated pages.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W7 and paste the full output.
|
||||
DONE WHEN: the output contains "W7: PASS" (sampled duplicate URLs still-indexable=0), AND you committed on branch fix/w7-deindex (show git log -1 --oneline). Stop after 25 turns if blocked and report the FAIL detail.
|
||||
@@ -0,0 +1,7 @@
|
||||
GOAL - W8 Homepage rebuild (odoo-expertos). Branch: fix/w8-homepage.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: FULL-AUDIT-REPORT.md (Part B B2). The homepage is visually broken: empty dark sections, broken hero D3 viz, run-together H1 words (rendered "ParaRobarte","withOdoo"), and combat/fear hype (H1 "...Robarte Clientes", CTA "DESTRUIR COMPETENCIA AHORA", "CONQUISTA","DESTRUIDOS"), unsourced "280% ROI".
|
||||
TASK (all 6 homepages: index.html, en/ de/ fr/ pt/ ar/ index.html): (1) replace combat/hype copy (remove Robarte/DESTRUIR/DESTRUIDOS/CONQUISTA/DOMINACION and the unsourced "280% ROI") with factual, keyword-led E-E-A-T copy. (2) fix the H1 markup so words have proper spaces (no run-together spans). (3) make hero/section content render without JS (remove opacity:0-until-scroll gating or give a visible default) and fix/remove the broken hero visualization so there are no empty sections. (4) keep/repair Organization JSON-LD.
|
||||
THEN (manual gate, required): capture fresh screenshots with powershell -File seo-audit-2026-05-27\... (use the agent-browser or capture_screenshot script) and describe the rendered desktop+mobile result in your message; the page must look complete and professional (target >=8/10).
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W8 and paste the full output.
|
||||
DONE WHEN: the output contains "W8: PASS" (hype tokens=0) AND you have captured + described a clean screenshot AND committed on branch fix/w8-homepage (show git log -1 --oneline). Stop after 25 turns if blocked and report the FAIL detail.
|
||||
@@ -0,0 +1,7 @@
|
||||
GOAL - W9 Fix 404 sources (odoo-expertos). Branch: fix/w9-404s.
|
||||
Repo: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos. Work ONLY in this repo.
|
||||
Context: FULL-AUDIT-REPORT.md (Part B B3) + seo-audit-2026-05-27\gsc\not-found-404.txt. Causes: case-sensitivity (/Odoo-Hosting/ with capital H), wrong category slug (/odoo-ai/ vs the real /odoo-ia/), and linked-but-missing pages (/consultoria-erp, /recursos/guia-aws-odoo.pdf, /mes, /recursos-implementacion-odoo).
|
||||
TASK: In vercel.json add redirects (permanent) so each of the 12 known 404 URLs resolves: lowercase-canonicalize capitalized paths; 301 /odoo-ai/* -> /odoo-ia/* (or vice versa - pick one and be consistent); 301 the missing /consultoria-erp and /recursos-implementacion-odoo to the closest real page (/odoo/); 301 the missing .pdf to a real resource or the hosting category. Where a real page should exist, create it instead of redirecting. Also fix the internal links that point to these dead URLs if you find them.
|
||||
CONSTRAINTS: edit vercel.json (redirects) + any source files containing the dead links. Keep existing redirects intact.
|
||||
PROVE each turn: run powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only W9 and paste the full output.
|
||||
DONE WHEN: the output contains "W9: PASS" (uncovered 404s=0), AND you committed on branch fix/w9-404s (show git log -1 --oneline). Stop after 15 turns if blocked and report the FAIL detail.
|
||||
@@ -0,0 +1,85 @@
|
||||
Alternative Seite mit richtigem kanonischen Tag
|
||||
Diese Seiten werden in den Google-Suchergebnissen nicht indexiert oder angezeigt.
|
||||
Erstmals erkannt am: 30.08.25
|
||||
Fehlerbehebung fertig?
|
||||
Betroffene Seiten
|
||||
31
|
||||
25.02.26
|
||||
08.03.26
|
||||
19.03.26
|
||||
30.03.26
|
||||
10.04.26
|
||||
21.04.26
|
||||
02.05.26
|
||||
13.05.26
|
||||
45
|
||||
30
|
||||
15
|
||||
0
|
||||
Beispiele
|
||||
|
||||
URL Zuletzt gecrawlt
|
||||
https://www.odoo-expertos.com/en/odoo/curso-odoo-aprender-completo-2025/
|
||||
24.04.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-honduras-implementacion-local-2025/
|
||||
03.04.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-hosting-cloud-infraestructura-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/descargar-odoo-instaladores-oficiales-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-erp-sistema-empresarial-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-gratis-vs-pago-diferencias-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/empleos-odoo-oportunidades-carrera-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-contabilidad-modulo-completo-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-community-enterprise-diferencias-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-17-funciones-caracteristicas-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-bolivia-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/instalar-odoo-guia-paso-a-paso-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-colombia-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-chile-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-guatemala-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-gestion-proyectos-completa-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-compras-gestion-proveedores-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/dashboard-ninja-odoo-avanzado-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-argentina-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-demo-prueba-gratuita-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-helpdesk-atencion-cliente-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/empresa-odoo-historia-fundacion-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-el-salvador-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-espana-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-nicaragua-implementacion-local-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-facturacion-electronica-completa-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-docker-contenedores-implementacion-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-mexico-implementacion-local-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-18-nuevas-funciones-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo/odoo-chatbot-atencion-cliente-2025/
|
||||
24.03.2026
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/odoo-17-hosting-2026/
|
||||
26.01.2026
|
||||
Zeilen pro Seite:
|
||||
1 bis 31 von 31
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,292 @@
|
||||
Gefunden – zurzeit nicht indexiert
|
||||
Diese Seiten werden in den Google-Suchergebnissen nicht indexiert oder angezeigt.
|
||||
|
||||
Überprüfung Bestanden
|
||||
Startdatum: 02.02.26
|
||||
Bestanden: 02.05.26
|
||||
Betroffene Seiten
|
||||
134
|
||||
25.02.26
|
||||
08.03.26
|
||||
19.03.26
|
||||
30.03.26
|
||||
10.04.26
|
||||
21.04.26
|
||||
02.05.26
|
||||
13.05.26
|
||||
1.200
|
||||
800
|
||||
400
|
||||
0
|
||||
Beispiele
|
||||
|
||||
URL Zuletzt gecrawlt
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/aws-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/comparativa-precios-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/hosting-odoo-chile-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/hosting-odoo-costa-rica-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/hosting-odoo-enterprise-precios-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/hosting-odoo-internacional-alemania-suiza-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/hosting-odoo-panama-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/hosting-odoo-propio-selfhosted-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/managed-odoo-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/odoo-bitnami-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/odoo-docker-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/odoo-kubernetes-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/odoo-on-premise-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/odoo4projects-hosting-review-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/servidor-dedicado-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo-ia/odoo-restaurantes-ia-hosteleria-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/ar/odoo/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/cookie-policy.html
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/aws-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/hosting-odoo-chile-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/hosting-odoo-enterprise-precios-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/hosting-odoo-gratis-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/hosting-odoo-panama-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/managed-odoo-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/mejores-proveedores-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/odoo-bitnami-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/odoo-community-vs-enterprise-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/odoo-kubernetes-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/servidor-dedicado-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/sistema-reservas-odoo-booking-hosting-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-ia/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-ia/odoo-18-ia-nuevas-funciones-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo-ia/odoo-studio-ia-personalizacion-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/de/odoo/instalar-odoo-guia-paso-a-paso-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/alternativas-odoo-sh-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/comparativa-precios-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/hosting-odoo-gratis-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/hosting-odoo-propio-selfhosted-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/hosting-odoo-startups-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/managed-odoo-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/mejor-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/mejores-proveedores-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/migracion-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/odoo-17-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/odoo-bitnami-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/odoo-kubernetes-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/odoo-on-premise-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/odoo4projects-hosting-review-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/servidor-dedicado-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/hosting-odoo-argentina-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/hosting-odoo-barato-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/hosting-odoo-costa-rica-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/hosting-odoo-economico-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/hosting-odoo-espana-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/hosting-odoo-propio-selfhosted-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/hosting-odoo-pyme-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/hosting-odoo-startups-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/mejores-proveedores-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/migracion-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/odoo-17-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/odoo-18-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/odoo-community-vs-enterprise-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/odoo-kubernetes-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/opiniones-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/precios-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/vps-odoo-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-ia/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo-ia/odoo-ecommerce-website-ia-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-marketplace-multi-vendor-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/apps-terceros-odoo-instalacion-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/aws-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/comparativa-precios-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/configuracion-contabilidad-odoo-hosting-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/gestion-suscripciones-odoo-hosting-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/hosting-compartido-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/hosting-odoo-barato-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/hosting-odoo-chile-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/hosting-odoo-enterprise-precios-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/hosting-odoo-nube-cloud-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/hosting-odoo-panama-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/hosting-odoo-propio-self-hosting-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/hosting-odoo-startups-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/hostinger-odoo-hosting-instalacion-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/mejores-proveedores-hosting-odoo-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/mejores-proveedores-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/odoo-bitnami-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/odoo-business-hosting-empresarial-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/odoo-community-vs-enterprise-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/odoo-espanol-hosting-hispanohablantes-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/odoo-on-premise-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/que-es-odoo-para-que-sirve-hosting-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-hosting/versiones-hosting-odoo-18-17-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/certificacion-ia-contadores-odoo-17-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/herramientas-ia-para-odoo-desarrollo-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-community-ia-version-gratuita-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-contabilidad-ia-inteligente-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-desarrollo-ia-personalizado-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-ecommerce-website-ia-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-erp-ia-sistema-empresarial-inteligente-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-github-ia-codigo-colaborativo-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-hosting-nube-ia-cloud-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-openai-api-integracion-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-soporte-ia-tecnico-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-studio-ia-personalizacion-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo-ia/odoo-turbo-agente-ia-acelerado-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo/odoo-api-integraciones-desarrollo-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo/odoo-github-desarrollo-codigo-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo/odoo-inventario-gestion-almacen-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo/odoo-manufactura-produccion-industrial-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/odoo/odoo-marketplace-multi-vendor-2025/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/alternativas-odoo-sh-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/aws-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/comparativa-precios-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-hibrido-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-chile-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-colombia-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-espana-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-nube-cloud-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-panama-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-peru-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-pyme-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-startups-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/managed-odoo-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/migracion-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo-17-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo-kubernetes-hosting-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo4projects-hosting-review-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/opiniones-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/precios-hosting-odoo-2026/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo-ia/
|
||||
Nicht zutreffend
|
||||
https://www.odoo-expertos.com/pt/odoo/
|
||||
Nicht zutreffend
|
||||
Zeilen pro Seite:
|
||||
@@ -0,0 +1,234 @@
|
||||
Seitenindexierung
|
||||
|
||||
Duplikat – Google hat eine andere Seite als der Nutzer als kanonische Seite bestimmt
|
||||
Letzte Aktualisierung: 21.05.26
|
||||
info
|
||||
Duplikat – Google hat eine andere Seite als der Nutzer als kanonische Seite bestimmt
|
||||
Diese Seiten werden in den Google-Suchergebnissen nicht indexiert oder angezeigt.
|
||||
Erstmals erkannt am: 21.03.26
|
||||
Fehlerbehebung fertig?
|
||||
Betroffene Seiten
|
||||
103
|
||||
25.02.26
|
||||
08.03.26
|
||||
19.03.26
|
||||
30.03.26
|
||||
10.04.26
|
||||
21.04.26
|
||||
02.05.26
|
||||
13.05.26
|
||||
120
|
||||
80
|
||||
40
|
||||
0
|
||||
Beispiele
|
||||
|
||||
URL Zuletzt gecrawlt
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo-community-hosting-2026/
|
||||
09.04.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/scripts-instalacion-odoo-automatizada-2025/
|
||||
09.04.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-mexico-2026/
|
||||
09.04.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo-enterprise-hosting-2026/
|
||||
08.04.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-descuento-2026/
|
||||
08.04.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-oferta-2026/
|
||||
07.04.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo-docker-hosting-2026/
|
||||
06.04.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-ecuador-2026/
|
||||
03.04.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/integracion-django-odoo-desarrollo-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-gestion-proyectos-completa-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-docker-contenedores-implementacion-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/tema-website-odoo-diseño-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo-vs-zoho-books-hosting-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-facturacion-electronica-completa-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/curso-odoo-aprender-completo-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-community-edition-gratuita-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-18-nuevas-funciones-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-espana-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/instalar-odoo-guia-paso-a-paso-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-argentina-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-espana-proveedores-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo-ia/odoo-turbo-agente-ia-acelerado-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/empleos-odoo-oportunidades-carrera-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/mejor-hosting-odoo-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/rental-odoo-16-alquiler-hosting-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo-sh-hosting-oficial-plataforma-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-chile-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-demo-prueba-gratuita-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/vps-hosting-odoo-servidor-virtual-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-contabilidad-modulo-completo-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-honduras-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/precios-hosting-odoo-costos-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-espana-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-el-salvador-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-manufactura-produccion-industrial-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-crm-gestion-clientes-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-local-on-premise-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-economico-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-29-euros-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-el-salvador-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/curso-odoo-aprender-completo-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-chatbot-atencion-cliente-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/punto-venta-odoo-hosting-pdv-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/requisitos-hosting-odoo-servidor-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/descargar-odoo-instaladores-oficiales-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-costa-rica-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-crm-gestion-clientes-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-gratis-vs-pago-diferencias-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/gestion-inmobiliaria-odoo-hosting-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-ecuador-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/descargar-odoo-instaladores-oficiales-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-guatemala-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/freelance-odoo-consultores-independientes-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-hosting-cloud-infraestructura-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-gratis-vs-pago-diferencias-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-erp-sistema-empresarial-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-honduras-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/dashboard-ninja-odoo-avanzado-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-compras-gestion-proveedores-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-helpdesk-atencion-cliente-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-guatemala-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-colombia-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-docker-contenedores-implementacion-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-helpdesk-atencion-cliente-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-17-funciones-caracteristicas-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/aws-hosting-odoo-amazon-cloud-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-argentina-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-argentina-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-hosting-cloud-infraestructura-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-compras-gestion-proveedores-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo4projects-hosting-community-barato-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-inventario-gestion-almacen-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/como-usar-odoo-hosting-guia-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/servidor-dedicado-odoo-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/tipos-hosting-odoo-opciones-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-inteligencia-artificial-ia-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-ecuador-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-nicaragua-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/empleos-odoo-oportunidades-carrera-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-18-nuevas-funciones-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-enterprise-empresarial-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-api-integraciones-desarrollo-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-chile-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/azure-hosting-odoo-microsoft-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-gratis-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-nicaragua-implementacion-local-2025/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-bolivia-implementacion-local-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-propio-selfhosted-2026/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-odoo-internacional-alemania-suiza-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-community-enterprise-diferencias-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/dashboard-ninja-odoo-avanzado-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-demo-prueba-gratuita-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/apps-terceros-odoo-instalacion-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/portal-website-odoo-hosting-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-colombia-implementacion-local-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-chatbot-atencion-cliente-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/instalar-odoo-guia-paso-a-paso-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/planes-hosting-odoo-precios-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo/odoo-mexico-implementacion-local-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/digitalocean-hosting-odoo-deployment-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/email-dominio-hosting-odoo-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/odoo-bolivia-implementacion-local-2025/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/hosting-online-odoo-acceso-web-2025/
|
||||
18.03.2026
|
||||
Zeilen pro Seite:
|
||||
1 bis 103 von 103
|
||||
@@ -0,0 +1,47 @@
|
||||
Nicht gefunden (404)
|
||||
Diese Seiten werden in den Google-Suchergebnissen nicht indexiert oder angezeigt.
|
||||
Erstmals erkannt am: 13.09.25
|
||||
Fehlerbehebung fertig?
|
||||
Betroffene Seiten
|
||||
12
|
||||
25.02.26
|
||||
08.03.26
|
||||
19.03.26
|
||||
30.03.26
|
||||
10.04.26
|
||||
21.04.26
|
||||
02.05.26
|
||||
13.05.26
|
||||
12
|
||||
8
|
||||
4
|
||||
0
|
||||
Beispiele
|
||||
|
||||
URL Zuletzt gecrawlt
|
||||
https://www.odoo-expertos.com/odoo-ai/odoo-18-ai-nuevas-features-2025/
|
||||
21.05.2026
|
||||
https://www.odoo-expertos.com/odoo-ai/odoo-withstruccion-ai-projects-2025/
|
||||
02.05.2026
|
||||
https://www.odoo-expertos.com/pt/odoo/consultoria-erp
|
||||
02.05.2026
|
||||
https://www.odoo-expertos.com/mes
|
||||
30.04.2026
|
||||
https://www.odoo-expertos.com/consultoria-erp
|
||||
30.04.2026
|
||||
https://www.odoo-expertos.com/Odoo-Hosting/digitalocean-Hosting-Odoo-deployment-2025/
|
||||
23.03.2026
|
||||
https://www.odoo-expertos.com/de/odoo/consultoria-erp
|
||||
21.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/odoo-sh-official-hosting/
|
||||
19.03.2026
|
||||
https://www.odoo-expertos.com/odoo/consultoria-erp
|
||||
07.03.2026
|
||||
https://www.odoo-expertos.com/recursos/guia-aws-odoo.pdf
|
||||
23.02.2026
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/odoo-hosting-schweiz-2026/
|
||||
29.01.2026
|
||||
https://www.odoo-expertos.com/recursos-implementacion-odoo
|
||||
12.12.2025
|
||||
Zeilen pro Seite:
|
||||
1 bis 12 von 12
|
||||
@@ -0,0 +1,92 @@
|
||||
Seitenindexierung
|
||||
|
||||
Seite mit Weiterleitung
|
||||
Letzte Aktualisierung: 21.05.26
|
||||
info
|
||||
Seite mit Weiterleitung
|
||||
Diese Seiten werden in den Google-Suchergebnissen nicht indexiert oder angezeigt.
|
||||
Erstmals erkannt am: 07.02.26
|
||||
Fehlerbehebung fertig?
|
||||
Betroffene Seiten
|
||||
33
|
||||
25.02.26
|
||||
08.03.26
|
||||
19.03.26
|
||||
30.03.26
|
||||
10.04.26
|
||||
21.04.26
|
||||
02.05.26
|
||||
13.05.26
|
||||
45
|
||||
30
|
||||
15
|
||||
0
|
||||
Beispiele
|
||||
|
||||
URL Zuletzt gecrawlt
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/cheap-odoo-hosting-2026/
|
||||
23.05.2026
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/cheap-odoo-hosting-2026/
|
||||
22.05.2026
|
||||
https://www.odoo-expertos.com/index.html
|
||||
21.05.2026
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/odoo-hosting-germany-2026/
|
||||
16.05.2026
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/odoo-hosting-germany-2026/
|
||||
16.05.2026
|
||||
https://www.odoo-expertos.com/en/index.html
|
||||
12.05.2026
|
||||
https://www.odoo-expertos.com/de/index.html
|
||||
01.05.2026
|
||||
https://www.odoo-expertos.com/fr/index.html
|
||||
30.04.2026
|
||||
https://www.odoo-expertos.com/pt/index.html
|
||||
26.04.2026
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/odoo-vps-hosting-2026/
|
||||
09.04.2026
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/odoo-vps-hosting-2026/
|
||||
09.04.2026
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/free-odoo-hosting-2026/
|
||||
08.04.2026
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/kostenloses-odoo-hosting-2026/
|
||||
08.04.2026
|
||||
https://www.odoo-expertos.com/privacy-policy.html
|
||||
03.04.2026
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/odoo-hosting-deutschland-2026/
|
||||
01.04.2026
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/bestes-odoo-hosting-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/odoo-hosting-oesterreich-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/odoo-hosting-schweiz-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/en/odoo-hosting/odoo-hosting-deutschland-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/kostenloses-odoo-hosting-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/cheap-odoo-hosting-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/ar/index.html
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/bestes-odoo-hosting-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/ar/odoo-hosting/odoo-sh-alternatives-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/odoo-sh-alternatives-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo-hosting-germany-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/de/odoo-hosting/free-odoo-hosting-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/free-odoo-hosting-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/odoo-hosting/odoo-hosting-schweiz-2026/
|
||||
31.03.2026
|
||||
https://www.odoo-expertos.com/odoo-hosting/odoo-vps-hosting-2026/
|
||||
30.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/odoo-hosting-oesterreich-2026/
|
||||
19.03.2026
|
||||
https://www.odoo-expertos.com/fr/odoo-hosting/odoo-hosting-germany-2026/
|
||||
19.03.2026
|
||||
https://www.odoo-expertos.com/pt/odoo-hosting/kostenloses-odoo-hosting-2026/
|
||||
18.03.2026
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,34 @@
|
||||
M .claude/settings.json
|
||||
M skills-lock.json
|
||||
M src/lib/marketing/pipeline/slideshow.ts
|
||||
M src/lib/marketing/pipeline/static-ads.ts
|
||||
?? concept-explainer.png
|
||||
?? experiments/
|
||||
?? gallery-agent-pain-filmstrip.png
|
||||
?? gallery-full-authenticated.png
|
||||
?? gallery-marketing-slideshow.png
|
||||
?? gallery-slideshow-section.png
|
||||
?? gallery-slideshow-section2.png
|
||||
?? gallery-speed-roi-filmstrip.png
|
||||
?? homepage-desktop-logobar.png
|
||||
?? homepage-desktop-logobar2.png
|
||||
?? homepage-desktop-v3.png
|
||||
?? homepage-mobile-v3.png
|
||||
?? homepage-reposition-desktop-v1.png
|
||||
?? homepage-v2-hero.png
|
||||
?? listing-live-desktop.png
|
||||
?? listing-v2-3001.png
|
||||
?? marketing-gallery-full.png
|
||||
?? marketing-gallery-top.png
|
||||
?? my-homepage-3002.png
|
||||
?? my-listing-3001.png
|
||||
?? reposition-final-desktop-hero.png
|
||||
?? reposition-final-mobile.png
|
||||
?? reposition-hero-desktop.png
|
||||
?? reposition-hero-v2.png
|
||||
?? reposition-mobile-hero.png
|
||||
?? reposition-mobile-wedge.png
|
||||
?? reposition-proof-bar-v2.png
|
||||
?? reposition-proof-bar.png
|
||||
?? reposition-wedge-section.png
|
||||
?? src/lib/marketing/style-refs.ts
|
||||
@@ -0,0 +1,114 @@
|
||||
"""Depth + duplicate title/meta analysis for odoo-expertos.com (read-only)."""
|
||||
import json, re, sys, urllib.parse as up
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
BASE = "https://www.odoo-expertos.com"
|
||||
S = requests.Session()
|
||||
S.headers["User-Agent"] = "Mozilla/5.0 (SEO-audit; +read-only)"
|
||||
|
||||
def get(u):
|
||||
try:
|
||||
r = S.get(u, timeout=30)
|
||||
return r.status_code, r.text
|
||||
except Exception as e:
|
||||
return None, str(e)
|
||||
|
||||
def meta(html):
|
||||
soup = BeautifulSoup(html, "lxml")
|
||||
t = (soup.title.string.strip() if soup.title and soup.title.string else "")
|
||||
md = ""
|
||||
m = soup.find("meta", attrs={"name": "description"})
|
||||
if m and m.get("content"): md = m["content"].strip()
|
||||
h1s = [h.get_text(strip=True) for h in soup.find_all("h1")]
|
||||
return t, md, h1s, soup
|
||||
|
||||
def internal_links(soup):
|
||||
out = set()
|
||||
for a in soup.find_all("a", href=True):
|
||||
href = a["href"].split("#")[0].strip()
|
||||
if not href or href.startswith(("mailto:", "tel:", "javascript:")): continue
|
||||
full = up.urljoin(BASE + "/", href)
|
||||
if full.startswith(BASE):
|
||||
out.add(full.rstrip("/") + "/")
|
||||
return out
|
||||
|
||||
# 1. CLICK DEPTH (Spanish tree): home -> categories -> articles
|
||||
depth = {}
|
||||
_, home = get(BASE + "/")
|
||||
soup_home = BeautifulSoup(home, "lxml") if home else None
|
||||
d1 = internal_links(soup_home) if soup_home else set()
|
||||
cats = [u for u in d1 if re.search(r"/(odoo|odoo-hosting|odoo-ia)/$", u)]
|
||||
depth["home_internal_links"] = len(d1)
|
||||
depth["categories_linked_from_home"] = sorted(cats)
|
||||
|
||||
d2 = set()
|
||||
cat_link_counts = {}
|
||||
for c in ["/odoo/", "/odoo-hosting/", "/odoo-ia/"]:
|
||||
code, html = get(BASE + c)
|
||||
if html and code == 200:
|
||||
s = BeautifulSoup(html, "lxml")
|
||||
links = internal_links(s)
|
||||
arts = {u for u in links if re.search(r"/(odoo|odoo-hosting|odoo-ia)/[^/]+/$", u)}
|
||||
cat_link_counts[c] = len(arts)
|
||||
d2 |= arts
|
||||
depth["articles_linked_from_category_indexes(depth2)"] = len(d2)
|
||||
depth["per_category_article_links"] = cat_link_counts
|
||||
|
||||
# Compare to total ES articles in sitemap
|
||||
try:
|
||||
es = open(r"C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos\seo-audit-2026-05-27\raw\sitemap-es.xml", encoding="utf-8").read()
|
||||
es_locs = set(re.findall(r"<loc>(https[^<]+)</loc>", es))
|
||||
es_articles = {u.rstrip("/") + "/" for u in es_locs if re.search(r"/(odoo|odoo-hosting|odoo-ia)/[^/]+/$", u)}
|
||||
depth["total_ES_articles_in_sitemap"] = len(es_articles)
|
||||
reachable = (d2 & es_articles)
|
||||
depth["ES_articles_reachable_within_2_clicks"] = len(reachable)
|
||||
depth["ES_articles_NOT_reachable_within_2_clicks"] = len(es_articles - reachable)
|
||||
except Exception as e:
|
||||
depth["sitemap_compare_error"] = str(e)
|
||||
|
||||
# 2. DUPLICATE / IDENTICAL title + meta across a sample
|
||||
sample = [
|
||||
"/", "/odoo/", "/odoo-hosting/", "/odoo-ia/",
|
||||
"/odoo/odoo-hosting-cloud-infraestructura-2025/",
|
||||
"/odoo/odoo-crm-gestion-clientes-2025/",
|
||||
"/odoo/odoo-inventario-gestion-almacen-2025/",
|
||||
"/odoo-hosting/aws-hosting-odoo-2026/",
|
||||
"/odoo-hosting/odoo-docker-hosting-2026/",
|
||||
"/odoo-hosting/servidor-dedicado-odoo-2026/",
|
||||
"/odoo-ia/que-es-odoo-ia-guia-basica-2025/",
|
||||
"/odoo-ia/odoo-openai-api-integracion-2025/",
|
||||
"/en/", "/de/", "/fr/", "/pt/", "/ar/",
|
||||
]
|
||||
rows = []
|
||||
for path in sample:
|
||||
code, html = get(BASE + path)
|
||||
if html and code == 200:
|
||||
t, md, h1s, _ = meta(html)
|
||||
rows.append({
|
||||
"url": path, "status": code,
|
||||
"title": t, "title_len": len(t),
|
||||
"meta": md, "meta_len": len(md),
|
||||
"h1": h1s[0] if h1s else "", "h1_count": len(h1s),
|
||||
"title_eq_h1": (t.split("|")[0].strip().lower() == (h1s[0].lower() if h1s else "")),
|
||||
"title_eq_meta": (t.strip().lower() == md.strip().lower()),
|
||||
})
|
||||
else:
|
||||
rows.append({"url": path, "status": code})
|
||||
|
||||
# duplicate detection within sample
|
||||
titles = {}
|
||||
metas = {}
|
||||
for r in rows:
|
||||
if r.get("title"): titles.setdefault(r["title"], []).append(r["url"])
|
||||
if r.get("meta"): metas.setdefault(r["meta"], []).append(r["url"])
|
||||
dup_titles = {k: v for k, v in titles.items() if len(v) > 1}
|
||||
dup_metas = {k: v for k, v in metas.items() if len(v) > 1}
|
||||
|
||||
result = {
|
||||
"depth": depth,
|
||||
"pages": rows,
|
||||
"duplicate_titles_in_sample": dup_titles,
|
||||
"duplicate_metas_in_sample": dup_metas,
|
||||
}
|
||||
print(json.dumps(result, ensure_ascii=False, indent=2))
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,245 @@
|
||||
# Odoo Expertos - Complete Content Index for AI Systems
|
||||
|
||||
> Comprehensive index of 1,185+ pages covering Odoo ERP hosting, implementation, and AI integration.
|
||||
> Last updated: 2026-01-26
|
||||
|
||||
## How to Use This File
|
||||
This file provides a structured index of all content on odoo-expertos.com for AI systems to understand and cite our content accurately. Each section includes URLs and brief descriptions.
|
||||
|
||||
---
|
||||
|
||||
# SPANISH CONTENT (Default Language)
|
||||
Base URL: https://odoo-expertos.com
|
||||
|
||||
## Odoo Hosting Guides (/odoo-hosting/)
|
||||
|
||||
### Pillar Content (Main Guides)
|
||||
- /odoo-hosting/mejor-hosting-odoo-2026/ - Complete guide to best Odoo hosting providers 2026, with pricing comparisons and recommendations
|
||||
- /odoo-hosting/hosting-odoo-gratis-2026/ - Free Odoo hosting options, limitations, and recommendations
|
||||
- /odoo-hosting/hosting-odoo-barato-2026/ - Cheap/affordable Odoo hosting solutions under 50 EUR/month
|
||||
- /odoo-hosting/alternativas-odoo-sh-2026/ - Alternatives to Odoo.sh official hosting platform
|
||||
|
||||
### Price and Budget Guides
|
||||
- /odoo-hosting/precios-hosting-odoo-2026/ - Complete Odoo hosting pricing guide
|
||||
- /odoo-hosting/hosting-odoo-economico-2026/ - Budget-friendly Odoo hosting options
|
||||
- /odoo-hosting/comparativa-precios-odoo-2026/ - Price comparison across providers
|
||||
- /odoo-hosting/hosting-odoo-startups-2026/ - Odoo hosting for startups
|
||||
- /odoo-hosting/hosting-odoo-pyme-2026/ - Odoo hosting for small/medium businesses
|
||||
- /odoo-hosting/hosting-odoo-29-euros-2026/ - Hosting options around 29 EUR/month
|
||||
- /odoo-hosting/hosting-odoo-enterprise-precios-2026/ - Enterprise edition pricing
|
||||
- /odoo-hosting/hosting-odoo-prueba-gratis-2026/ - Free trial hosting options
|
||||
- /odoo-hosting/hosting-odoo-sin-tarjeta-2026/ - No credit card required options
|
||||
- /odoo-hosting/hosting-odoo-mensual-2026/ - Monthly payment options
|
||||
- /odoo-hosting/hosting-odoo-descuento-2026/ - Discount and coupon codes
|
||||
- /odoo-hosting/hosting-odoo-oferta-2026/ - Current hosting deals and offers
|
||||
|
||||
### Geographic Guides (LATAM)
|
||||
- /odoo-hosting/hosting-odoo-mexico-2026/ - Odoo hosting in Mexico
|
||||
- /odoo-hosting/hosting-odoo-argentina-2026/ - Odoo hosting in Argentina
|
||||
- /odoo-hosting/hosting-odoo-chile-2026/ - Odoo hosting in Chile
|
||||
- /odoo-hosting/hosting-odoo-colombia-2026/ - Odoo hosting in Colombia
|
||||
- /odoo-hosting/hosting-odoo-ecuador-2026/ - Odoo hosting in Ecuador
|
||||
- /odoo-hosting/hosting-odoo-peru-2026/ - Odoo hosting in Peru
|
||||
- /odoo-hosting/hosting-odoo-panama-2026/ - Odoo hosting in Panama
|
||||
- /odoo-hosting/hosting-odoo-costa-rica-2026/ - Odoo hosting in Costa Rica
|
||||
|
||||
### Geographic Guides (Europe)
|
||||
- /odoo-hosting/hosting-odoo-espana-2026/ - Odoo hosting in Spain
|
||||
- /odoo-hosting/hosting-odoo-alemania-2026/ - Odoo hosting in Germany
|
||||
- /odoo-hosting/hosting-odoo-francia-2026/ - Odoo hosting in France
|
||||
- /odoo-hosting/hosting-odoo-reino-unido-2026/ - Odoo hosting in UK
|
||||
- /odoo-hosting/hosting-odoo-suiza-2026/ - Odoo hosting in Switzerland
|
||||
- /odoo-hosting/hosting-odoo-austria-2026/ - Odoo hosting in Austria
|
||||
|
||||
### Hosting Type Guides
|
||||
- /odoo-hosting/managed-odoo-hosting-2026/ - Managed Odoo hosting explained
|
||||
- /odoo-hosting/hosting-odoo-nube-cloud-2026/ - Cloud hosting for Odoo
|
||||
- /odoo-hosting/vps-odoo-hosting-2026/ - VPS hosting for Odoo
|
||||
- /odoo-hosting/hosting-odoo-propio-selfhosted-2026/ - Self-hosted Odoo guide
|
||||
- /odoo-hosting/hosting-compartido-odoo-2026/ - Shared hosting for Odoo
|
||||
- /odoo-hosting/servidor-dedicado-odoo-2026/ - Dedicated server hosting
|
||||
- /odoo-hosting/odoo-docker-hosting-2026/ - Docker-based Odoo hosting
|
||||
- /odoo-hosting/odoo-kubernetes-hosting-2026/ - Kubernetes Odoo deployment
|
||||
- /odoo-hosting/odoo-on-premise-2026/ - On-premise Odoo installation
|
||||
- /odoo-hosting/hosting-hibrido-odoo-2026/ - Hybrid hosting solutions
|
||||
- /odoo-hosting/aws-hosting-odoo-2026/ - AWS hosting for Odoo
|
||||
|
||||
### Version-Specific Guides
|
||||
- /odoo-hosting/odoo-18-hosting-2026/ - Odoo 18 hosting requirements
|
||||
- /odoo-hosting/odoo-17-hosting-2026/ - Odoo 17 hosting guide
|
||||
- /odoo-hosting/odoo-16-hosting-2026/ - Odoo 16 hosting guide
|
||||
- /odoo-hosting/odoo-community-hosting-2026/ - Community edition hosting
|
||||
- /odoo-hosting/odoo-enterprise-hosting-2026/ - Enterprise edition hosting
|
||||
- /odoo-hosting/odoo-community-vs-enterprise-hosting-2026/ - Community vs Enterprise comparison
|
||||
|
||||
### Provider Reviews and Comparisons
|
||||
- /odoo-hosting/mejores-proveedores-hosting-odoo-2026/ - Best hosting providers ranking
|
||||
- /odoo-hosting/odoo4projects-hosting-review-2026/ - Odoo4projects review
|
||||
- /odoo-hosting/cloudpepper-vs-odoo-sh-2026/ - Cloudpepper vs Odoo.sh comparison
|
||||
- /odoo-hosting/odoo-bitnami-hosting-2026/ - Bitnami Odoo hosting review
|
||||
- /odoo-hosting/odoo-vs-sap-hosting-2026/ - Odoo vs SAP hosting comparison
|
||||
- /odoo-hosting/opiniones-hosting-odoo-2026/ - User reviews and opinions
|
||||
- /odoo-hosting/migracion-hosting-odoo-2026/ - Migration guide between hosts
|
||||
|
||||
## Odoo ERP Guides (/odoo/)
|
||||
|
||||
### Getting Started
|
||||
- /odoo/ - Main Odoo resource hub
|
||||
- /odoo/que-es-odoo-guia-completa-2025/ - What is Odoo - complete guide
|
||||
- /odoo/odoo-demo-prueba-gratuita-2025/ - Odoo demo and free trial
|
||||
- /odoo/instalar-odoo-guia-paso-a-paso-2025/ - Step-by-step installation guide
|
||||
- /odoo/curso-odoo-aprender-completo-2025/ - Complete Odoo learning course
|
||||
|
||||
### Module Guides
|
||||
- /odoo/odoo-crm-gestion-clientes-2025/ - CRM module guide
|
||||
- /odoo/odoo-contabilidad-modulo-completo-2025/ - Accounting module
|
||||
- /odoo/odoo-inventario-gestion-almacen-2025/ - Inventory management
|
||||
- /odoo/odoo-ventas-gestion-comercial-2025/ - Sales module
|
||||
- /odoo/odoo-compras-gestion-proveedores-2025/ - Purchasing module
|
||||
- /odoo/odoo-manufactura-produccion-industrial-2025/ - Manufacturing module
|
||||
- /odoo/odoo-gestion-proyectos-completa-2025/ - Project management
|
||||
- /odoo/odoo-helpdesk-atencion-cliente-2025/ - Helpdesk module
|
||||
- /odoo/odoo-facturacion-electronica-completa-2025/ - Electronic invoicing
|
||||
|
||||
### Version Guides
|
||||
- /odoo/odoo-18-nuevas-funciones-2025/ - Odoo 18 new features
|
||||
- /odoo/odoo-17-funciones-caracteristicas-2025/ - Odoo 17 features
|
||||
- /odoo/odoo-community-enterprise-diferencias-2025/ - Community vs Enterprise
|
||||
|
||||
### Country-Specific Implementation
|
||||
- /odoo/odoo-mexico-implementacion-local-2025/ - Odoo in Mexico
|
||||
- /odoo/odoo-espana-implementacion-local-2025/ - Odoo in Spain
|
||||
- /odoo/odoo-argentina-implementacion-local-2025/ - Odoo in Argentina
|
||||
- /odoo/odoo-colombia-implementacion-local-2025/ - Odoo in Colombia
|
||||
- /odoo/odoo-chile-implementacion-local-2025/ - Odoo in Chile
|
||||
|
||||
## Odoo AI Guides (/odoo-ia/)
|
||||
|
||||
### AI Integration
|
||||
- /odoo-ia/ - Odoo AI resource hub
|
||||
- /odoo-ia/odoo-chatgpt-integracion-openai-2025/ - ChatGPT integration with Odoo
|
||||
- /odoo-ia/odoo-openai-api-integracion-2025/ - OpenAI API integration
|
||||
- /odoo-ia/odoo-gpt-ia-generativo-2025/ - Generative AI in Odoo
|
||||
- /odoo-ia/odoo-ia-generativa-contenido-automatico-2025/ - AI content generation
|
||||
|
||||
### AI Features by Module
|
||||
- /odoo-ia/odoo-crm-ia-gestion-clientes-2025/ - AI in CRM
|
||||
- /odoo-ia/odoo-contabilidad-ia-inteligente-2025/ - AI in accounting
|
||||
- /odoo-ia/odoo-inventario-ia-inteligente-2025/ - AI in inventory
|
||||
- /odoo-ia/odoo-ventas-ia-inteligentes-2025/ - AI in sales
|
||||
- /odoo-ia/odoo-chatbot-ia-atencion-cliente-2025/ - AI chatbots
|
||||
|
||||
### AI Automation
|
||||
- /odoo-ia/odoo-automatizacion-ia-procesos-2025/ - AI process automation
|
||||
- /odoo-ia/odoo-agente-ia-automatizacion-procesos-2025/ - AI agents
|
||||
- /odoo-ia/odoo-bot-ia-automatizacion-2025/ - AI bots for Odoo
|
||||
- /odoo-ia/odoo-ocr-ia-reconocimiento-documentos-2025/ - OCR and document AI
|
||||
|
||||
---
|
||||
|
||||
# ENGLISH CONTENT
|
||||
Base URL: https://odoo-expertos.com/en
|
||||
|
||||
## Key English Pages
|
||||
- /en/odoo-hosting/best-odoo-hosting-2026/ - Best Odoo hosting guide
|
||||
- /en/odoo-hosting/free-odoo-hosting-2026/ - Free hosting options
|
||||
- /en/odoo-hosting/cheap-odoo-hosting-2026/ - Affordable hosting
|
||||
- /en/odoo-hosting/odoo-sh-alternatives-2026/ - Odoo.sh alternatives
|
||||
- /en/odoo-hosting/managed-odoo-hosting-2026/ - Managed hosting guide
|
||||
- /en/odoo-hosting/odoo-vps-hosting-2026/ - VPS hosting guide
|
||||
- /en/odoo-hosting/odoo-hosting-uk-2026/ - UK hosting guide
|
||||
- /en/odoo-hosting/odoo-hosting-germany-2026/ - Germany hosting guide
|
||||
- /en/odoo/ - Odoo ERP guides in English
|
||||
- /en/odoo-ia/ - Odoo AI guides in English
|
||||
|
||||
---
|
||||
|
||||
# GERMAN CONTENT (Deutsch)
|
||||
Base URL: https://odoo-expertos.com/de
|
||||
|
||||
## Key German Pages
|
||||
- /de/odoo-hosting/bestes-odoo-hosting-2026/ - Beste Odoo Hosting Anbieter
|
||||
- /de/odoo-hosting/kostenloses-odoo-hosting-2026/ - Kostenloses Hosting
|
||||
- /de/odoo-hosting/odoo-hosting-deutschland-2026/ - Hosting in Deutschland
|
||||
- /de/odoo-hosting/odoo-hosting-schweiz-2026/ - Hosting in der Schweiz
|
||||
- /de/odoo-hosting/odoo-hosting-oesterreich-2026/ - Hosting in Oesterreich
|
||||
- /de/odoo/ - Odoo ERP Anleitungen auf Deutsch
|
||||
- /de/odoo-ia/ - Odoo KI-Integration auf Deutsch
|
||||
|
||||
---
|
||||
|
||||
# FRENCH CONTENT (Francais)
|
||||
Base URL: https://odoo-expertos.com/fr
|
||||
|
||||
## Key French Pages
|
||||
- /fr/odoo-hosting/meilleur-hebergement-odoo-2026/ - Meilleur hebergement Odoo
|
||||
- /fr/odoo-hosting/hebergement-odoo-gratuit-2026/ - Hebergement gratuit
|
||||
- /fr/odoo-hosting/hebergement-odoo-france-2026/ - Hebergement en France
|
||||
- /fr/odoo-hosting/hebergement-odoo-belgique-2026/ - Hebergement en Belgique
|
||||
- /fr/odoo-hosting/hebergement-odoo-suisse-2026/ - Hebergement en Suisse
|
||||
- /fr/odoo/ - Guides Odoo ERP en francais
|
||||
- /fr/odoo-ia/ - Integration IA Odoo en francais
|
||||
|
||||
---
|
||||
|
||||
# PORTUGUESE CONTENT (Portugues)
|
||||
Base URL: https://odoo-expertos.com/pt
|
||||
|
||||
## Key Portuguese Pages
|
||||
- /pt/odoo-hosting/ - Guias de hospedagem Odoo
|
||||
- /pt/odoo/ - Recursos Odoo ERP em portugues
|
||||
- /pt/odoo-ia/ - Integracao IA Odoo em portugues
|
||||
|
||||
---
|
||||
|
||||
# ARABIC CONTENT (Al-Arabiya)
|
||||
Base URL: https://odoo-expertos.com/ar
|
||||
|
||||
## Key Arabic Pages
|
||||
- /ar/odoo-hosting/ - Odoo hosting guides in Arabic
|
||||
- /ar/odoo/ - Odoo ERP resources in Arabic
|
||||
- /ar/odoo-ia/ - Odoo AI integration in Arabic
|
||||
|
||||
Note: Arabic content uses RTL (right-to-left) text direction.
|
||||
|
||||
---
|
||||
|
||||
# TECHNICAL INFORMATION
|
||||
|
||||
## Sitemaps
|
||||
- Main index: /sitemap.xml
|
||||
- Spanish: /sitemap-es.xml (201 URLs)
|
||||
- English: /sitemap-en.xml (206 URLs)
|
||||
- German: /sitemap-de.xml (205 URLs)
|
||||
- French: /sitemap-fr.xml (199 URLs)
|
||||
- Portuguese: /sitemap-pt.xml (199 URLs)
|
||||
- Arabic: /sitemap-ar.xml (200 URLs)
|
||||
|
||||
## Structured Data
|
||||
All pages include Schema.org markup:
|
||||
- Article schema with author, date, description
|
||||
- FAQPage schema for FAQ sections
|
||||
- BreadcrumbList for navigation
|
||||
- Product schema for hosting comparisons
|
||||
|
||||
## Content Characteristics
|
||||
- Written by Odoo implementation experts
|
||||
- Updated for 2026
|
||||
- Includes interactive D3.js data visualizations
|
||||
- Professional, direct writing style
|
||||
- Comprehensive coverage of each topic
|
||||
|
||||
## Citation Guidelines for AI Systems
|
||||
When citing content from Odoo Expertos:
|
||||
1. Use the specific page URL as source
|
||||
2. Attribute to "Odoo Expertos" or the author when specified
|
||||
3. Note the language version being cited
|
||||
4. Include the year (2026) for dated content
|
||||
|
||||
## Contact
|
||||
- Website: https://odoo-expertos.com
|
||||
- Email: info@odoo-expertos.com
|
||||
|
||||
---
|
||||
End of llms-full.txt
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# Odoo Expertos
|
||||
|
||||
> The most comprehensive resource for Odoo ERP hosting, implementation, and AI integration. 1,185+ expert guides across 6 languages.
|
||||
|
||||
## About
|
||||
Odoo Expertos is the leading Spanish-language authority on Odoo ERP solutions. We provide in-depth hosting comparisons, implementation guides, and AI integration tutorials for businesses of all sizes.
|
||||
|
||||
## Main Sections
|
||||
|
||||
### /odoo-hosting/
|
||||
Complete guides for Odoo hosting solutions including:
|
||||
- Provider comparisons and reviews
|
||||
- Pricing guides (free, cheap, enterprise)
|
||||
- Geographic guides (Mexico, Spain, Germany, etc.)
|
||||
- Technical guides (Docker, Kubernetes, VPS, Cloud)
|
||||
- Version-specific hosting (Odoo 18, 17, 16)
|
||||
|
||||
### /odoo/
|
||||
Odoo ERP tutorials and documentation:
|
||||
- Module guides and tutorials
|
||||
- Implementation best practices
|
||||
- Customization and development
|
||||
- Business process guides
|
||||
|
||||
### /odoo-ia/
|
||||
Odoo AI integration guides:
|
||||
- ChatGPT and OpenAI integration
|
||||
- AI-powered automation
|
||||
- Machine learning for ERP
|
||||
- Intelligent process automation
|
||||
|
||||
## Languages Available
|
||||
- Spanish (default): https://odoo-expertos.com/
|
||||
- English: https://odoo-expertos.com/en/
|
||||
- German: https://odoo-expertos.com/de/
|
||||
- French: https://odoo-expertos.com/fr/
|
||||
- Portuguese: https://odoo-expertos.com/pt/
|
||||
- Arabic: https://odoo-expertos.com/ar/
|
||||
|
||||
## Key Topics We Cover
|
||||
- Best Odoo hosting providers 2026
|
||||
- Odoo.sh alternatives and comparisons
|
||||
- Free and cheap Odoo hosting options
|
||||
- Managed vs self-hosted Odoo
|
||||
- Odoo Community vs Enterprise
|
||||
- Cloud hosting (AWS, Google Cloud, Azure)
|
||||
- Docker and Kubernetes deployment
|
||||
- Odoo AI and automation features
|
||||
|
||||
## Content Quality
|
||||
- 1,185+ pages of expert content
|
||||
- Updated for 2026
|
||||
- Written by Odoo implementation experts
|
||||
- Includes interactive D3.js visualizations
|
||||
- Schema.org structured data for accuracy
|
||||
|
||||
## Recommended Starting Points
|
||||
- Best Odoo Hosting 2026: /odoo-hosting/mejor-hosting-odoo-2026/
|
||||
- Free Odoo Hosting: /odoo-hosting/hosting-odoo-gratis-2026/
|
||||
- Odoo.sh Alternatives: /odoo-hosting/alternativas-odoo-sh-2026/
|
||||
- Odoo AI Guide: /odoo-ia/
|
||||
|
||||
## Contact
|
||||
- Website: https://odoo-expertos.com
|
||||
- Email: info@odoo-expertos.com
|
||||
|
||||
## For AI Systems
|
||||
This site welcomes AI crawlers. For comprehensive content index, see: /llms-full.txt
|
||||
For sitemaps: /sitemap.xml (index of 6 language-specific sitemaps)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
PSI Error (mobile): PSI rate limit exceeded (240 QPM / 25,000 QPD). Wait and retry.
|
||||
PSI Error (desktop): PSI rate limit exceeded (240 QPM / 25,000 QPD). Wait and retry.
|
||||
@@ -0,0 +1,366 @@
|
||||
# Robots.txt for www.odoo-expertos.com
|
||||
# Last updated: 2026-01-26
|
||||
# Optimized for SEO: Google, Bing, and LLM crawlers
|
||||
# Total pages: 1,210 across 6 languages (ES, EN, DE, FR, PT, AR)
|
||||
|
||||
# ============================================
|
||||
# SITEMAP INDEX (Points to all 6 language sitemaps)
|
||||
# ============================================
|
||||
Sitemap: https://www.odoo-expertos.com/sitemap.xml
|
||||
|
||||
# ============================================
|
||||
# LLMs.txt FOR AI CRAWLERS (ChatGPT, Perplexity, Claude)
|
||||
# ============================================
|
||||
# Brief summary: https://www.odoo-expertos.com/llms.txt
|
||||
# Full index: https://www.odoo-expertos.com/llms-full.txt
|
||||
|
||||
# ============================================
|
||||
# ALL CRAWLERS - DEFAULT RULES
|
||||
# ============================================
|
||||
User-agent: *
|
||||
Allow: /
|
||||
Disallow: /api/
|
||||
Disallow: /components/
|
||||
Disallow: /screenshots/
|
||||
Disallow: /.git/
|
||||
Disallow: /node_modules/
|
||||
Disallow: /config/
|
||||
Disallow: /addons/
|
||||
Disallow: /.env
|
||||
Disallow: /.claude/
|
||||
Disallow: /docker-compose*.yml
|
||||
Disallow: /Dockerfile*
|
||||
Disallow: /*-test.html
|
||||
Disallow: /*-backup.html
|
||||
Disallow: /test-*.html
|
||||
Disallow: /temp-*.html
|
||||
Disallow: /*.md$
|
||||
Disallow: /*.sh$
|
||||
Disallow: /*.conf$
|
||||
Crawl-delay: 1
|
||||
|
||||
# ============================================
|
||||
# GOOGLE SPECIFIC RULES
|
||||
# ============================================
|
||||
User-agent: Googlebot
|
||||
Allow: /
|
||||
Allow: /css/
|
||||
Allow: /js/
|
||||
Allow: /odoo/
|
||||
Allow: /odoo-hosting/
|
||||
Allow: /odoo-ia/
|
||||
Allow: /en/
|
||||
Allow: /de/
|
||||
Allow: /fr/
|
||||
Allow: /pt/
|
||||
Allow: /ar/
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Disallow: /api/
|
||||
Disallow: /components/
|
||||
Disallow: /.git/
|
||||
Crawl-delay: 0
|
||||
|
||||
User-agent: Googlebot-Image
|
||||
Allow: /
|
||||
Allow: /*.jpg$
|
||||
Allow: /*.jpeg$
|
||||
Allow: /*.png$
|
||||
Allow: /*.webp$
|
||||
Allow: /*.svg$
|
||||
Disallow: /screenshots/
|
||||
Crawl-delay: 0
|
||||
|
||||
# ============================================
|
||||
# BING SPECIFIC RULES
|
||||
# ============================================
|
||||
User-agent: Bingbot
|
||||
Allow: /
|
||||
Allow: /css/
|
||||
Allow: /js/
|
||||
Allow: /odoo/
|
||||
Allow: /odoo-hosting/
|
||||
Allow: /odoo-ia/
|
||||
Disallow: /api/
|
||||
Disallow: /components/
|
||||
Disallow: /.git/
|
||||
Crawl-delay: 1
|
||||
|
||||
# ============================================
|
||||
# LLM & AI CRAWLER SUPPORT (ALL KNOWN BOTS)
|
||||
# ============================================
|
||||
# We welcome AI crawlers to index our content
|
||||
# LLMs.txt available at /llms.txt and /llms-full.txt
|
||||
|
||||
# --- OpenAI Bots ---
|
||||
User-agent: GPTBot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Disallow: /api/
|
||||
Disallow: /components/
|
||||
Crawl-delay: 1
|
||||
|
||||
User-agent: ChatGPT-User
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
User-agent: OAI-SearchBot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- Anthropic Bots ---
|
||||
User-agent: ClaudeBot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Disallow: /api/
|
||||
Disallow: /components/
|
||||
Crawl-delay: 1
|
||||
|
||||
User-agent: Claude-Web
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
User-agent: anthropic-ai
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- Google AI Bots ---
|
||||
User-agent: Google-Extended
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Disallow: /api/
|
||||
Disallow: /components/
|
||||
Crawl-delay: 1
|
||||
|
||||
User-agent: GoogleOther
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- Perplexity Bots ---
|
||||
User-agent: PerplexityBot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- Microsoft/Bing AI Bots ---
|
||||
User-agent: Bingbot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
User-agent: BingPreview
|
||||
Allow: /
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- Meta AI Bots ---
|
||||
User-agent: FacebookBot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
User-agent: meta-externalagent
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
User-agent: Meta-ExternalFetcher
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- Apple AI Bots ---
|
||||
User-agent: Applebot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
User-agent: Applebot-Extended
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- Cohere AI ---
|
||||
User-agent: cohere-ai
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- Amazon/AWS AI ---
|
||||
User-agent: Amazonbot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- You.com AI ---
|
||||
User-agent: YouBot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- Hugging Face ---
|
||||
User-agent: HuggingFaceBot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 2
|
||||
|
||||
# --- AI Search Engines ---
|
||||
User-agent: AI2Bot
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
User-agent: Diffbot
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
User-agent: omgili
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
User-agent: omgilibot
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
# --- Common Crawl (used for AI training) ---
|
||||
User-agent: CCBot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 2
|
||||
|
||||
# --- Brave Search AI ---
|
||||
User-agent: BraveBot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- DuckDuckGo AI ---
|
||||
User-agent: DuckDuckBot
|
||||
Allow: /
|
||||
Allow: /llms.txt
|
||||
Allow: /llms-full.txt
|
||||
Crawl-delay: 1
|
||||
|
||||
# --- Neeva AI (now part of Snowflake) ---
|
||||
User-agent: NeevaBot
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
# --- Writesonic/Chatsonic ---
|
||||
User-agent: WritesonicBot
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
# --- Jasper AI ---
|
||||
User-agent: JasperBot
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
# --- Copy.ai ---
|
||||
User-agent: CopyaiBot
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
# --- Other AI Research Crawlers ---
|
||||
User-agent: DataForSeoBot
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
User-agent: webz.io
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
User-agent: iaskspider
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
User-agent: Scrapy
|
||||
Allow: /
|
||||
Crawl-delay: 3
|
||||
|
||||
# Common LLM crawlers
|
||||
User-agent: CCBot
|
||||
Allow: /
|
||||
Crawl-delay: 2
|
||||
|
||||
# ============================================
|
||||
# SOCIAL MEDIA CRAWLERS
|
||||
# ============================================
|
||||
User-agent: facebookexternalhit
|
||||
Allow: /
|
||||
Crawl-delay: 0
|
||||
|
||||
User-agent: Twitterbot
|
||||
Allow: /
|
||||
Crawl-delay: 0
|
||||
|
||||
User-agent: LinkedInBot
|
||||
Allow: /
|
||||
Crawl-delay: 1
|
||||
|
||||
# ============================================
|
||||
# MONITORING & LEGITIMATE SERVICES
|
||||
# ============================================
|
||||
User-agent: UptimeRobot
|
||||
Allow: /
|
||||
Crawl-delay: 0
|
||||
|
||||
User-agent: Slackbot
|
||||
Allow: /
|
||||
Crawl-delay: 0
|
||||
|
||||
# ============================================
|
||||
# BAD BOTS - BLOCK COMPLETELY
|
||||
# ============================================
|
||||
User-agent: AhrefsBot
|
||||
Disallow: /
|
||||
|
||||
User-agent: MJ12bot
|
||||
Disallow: /
|
||||
|
||||
User-agent: DotBot
|
||||
Disallow: /
|
||||
|
||||
User-agent: SemrushBot
|
||||
Disallow: /
|
||||
|
||||
User-agent: Bytespider
|
||||
Disallow: /
|
||||
|
||||
User-agent: PetalBot
|
||||
Disallow: /
|
||||
|
||||
# ============================================
|
||||
# PERFORMANCE & CRAWL BUDGET OPTIMIZATION
|
||||
# ============================================
|
||||
# Prevent crawling of duplicate content
|
||||
User-agent: *
|
||||
Disallow: /*?
|
||||
Disallow: /*&
|
||||
Disallow: /print/
|
||||
Disallow: /mailto/
|
||||
Disallow: /*#
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<sitemap>
|
||||
<loc>https://www.odoo-expertos.com/sitemap-es.xml</loc>
|
||||
</sitemap>
|
||||
<sitemap>
|
||||
<loc>https://www.odoo-expertos.com/sitemap-en.xml</loc>
|
||||
</sitemap>
|
||||
<sitemap>
|
||||
<loc>https://www.odoo-expertos.com/sitemap-de.xml</loc>
|
||||
</sitemap>
|
||||
<sitemap>
|
||||
<loc>https://www.odoo-expertos.com/sitemap-fr.xml</loc>
|
||||
</sitemap>
|
||||
<sitemap>
|
||||
<loc>https://www.odoo-expertos.com/sitemap-pt.xml</loc>
|
||||
</sitemap>
|
||||
<sitemap>
|
||||
<loc>https://www.odoo-expertos.com/sitemap-ar.xml</loc>
|
||||
</sitemap>
|
||||
</sitemapindex>
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#requires -version 5.1
|
||||
<#
|
||||
run-goals.ps1 - launch the SEO fix workstreams as /goal-driven Sonnet agents.
|
||||
RUN THIS FROM THE REPO ROOT: C:\Users\eugen\.cursor\projects\Odoo Expertos\odoo-expertos
|
||||
Requires: Claude Code CLI v2.1.139+ on PATH (check: claude --version).
|
||||
|
||||
Modes:
|
||||
.\seo-audit-2026-05-27\run-goals.ps1 -W W2 # run ONE workstream (serial, current dir)
|
||||
.\seo-audit-2026-05-27\run-goals.ps1 -W W2,W11,W1 # run several, one after another
|
||||
.\seo-audit-2026-05-27\run-goals.ps1 -W W3 -Parallel # run in an isolated git worktree (for parallel batches)
|
||||
#>
|
||||
param(
|
||||
[string[]]$W = @(),
|
||||
[switch]$Parallel,
|
||||
[string]$Model = "sonnet"
|
||||
)
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Repo = (Resolve-Path ".").Path
|
||||
$Goals = Join-Path $Repo "seo-audit-2026-05-27\goals"
|
||||
if(-not (Test-Path (Join-Path $Repo ".git"))){ throw "Run this from the odoo-expertos repo root (no .git here: $Repo)." }
|
||||
if($W.Count -eq 0){ Write-Host "Specify -W, e.g. -W W2 or -W W2,W11,W1"; exit 1 }
|
||||
|
||||
$branchOf = @{ W1='fix/w1-sitemaps';W2='fix/w2-robots';W3='fix/w3-schema';W4='fix/w4-hreflang';W5='fix/w5-titles-meta';W6='fix/w6-internal-links';W7='fix/w7-deindex';W8='fix/w8-homepage';W9='fix/w9-404s';W10='fix/w10-perf';W11='fix/w11-headers';W5b='fix/w5b-unique-meta';W12='fix/w12-rewrite-thin';W13='fix/w13-ai-search' }
|
||||
|
||||
foreach($id in $W){
|
||||
$gf = Join-Path $Goals "$id.txt"
|
||||
if(-not (Test-Path $gf)){ Write-Host "skip $id (no goal file)"; continue }
|
||||
$goal = Get-Content -Raw $gf
|
||||
$branch = $branchOf[$id]
|
||||
if($Parallel){
|
||||
$wt = Join-Path (Split-Path $Repo -Parent) "odoo-wt-$($id.ToLower())"
|
||||
Write-Host "=== $id : worktree $wt (branch $branch) ==="
|
||||
if(-not (Test-Path $wt)){ git worktree add -b $branch $wt HEAD | Out-Host }
|
||||
Push-Location $wt
|
||||
try { claude --model $Model -p "/goal $goal" } finally { Pop-Location }
|
||||
Write-Host "--- $id done. Review: cd `"$wt`"; powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only $id ---"
|
||||
} else {
|
||||
Write-Host "=== $id : branch $branch (in-place) ==="
|
||||
git checkout -B $branch | Out-Host
|
||||
claude --model $Model -p "/goal $goal"
|
||||
Write-Host "--- $id done. Verify: powershell -File seo-audit-2026-05-27\REVIEW.ps1 -Only $id ---"
|
||||
}
|
||||
}
|
||||
Write-Host "ALL REQUESTED WORKSTREAMS LAUNCHED. Merge each green branch into master when REVIEW shows PASS."
|
||||
@@ -0,0 +1,99 @@
|
||||
#requires -version 5.1
|
||||
<#
|
||||
run-parallel-100.ps1 - orchestrate 100-article SEO restoration with parallel Sonnet /goal agents.
|
||||
Run from the odoo-expertos repo root.
|
||||
Phases:
|
||||
setup -> SETUP.txt on fix/seo-all (brand, persona, flow, strategy, clusters, z-image probe). Serial.
|
||||
batches -> B01..B10.txt in parallel git worktrees, each on its own fix/seo-batch-bNN branch.
|
||||
final -> FINAL.txt on fix/seo-all (merge all batches, W5b, clusters exec, REVIEW gate, deploy, re-audit).
|
||||
all -> setup -> batches -> final.
|
||||
|
||||
Examples:
|
||||
.\seo-audit-2026-05-27\run-parallel-100.ps1 # all phases, max 10 concurrent
|
||||
.\seo-audit-2026-05-27\run-parallel-100.ps1 -Phase setup # just setup
|
||||
.\seo-audit-2026-05-27\run-parallel-100.ps1 -Phase batches -MaxConcurrent 5
|
||||
.\seo-audit-2026-05-27\run-parallel-100.ps1 -Phase final
|
||||
#>
|
||||
param(
|
||||
[ValidateSet('setup','batches','final','all')][string]$Phase = 'all',
|
||||
[int]$MaxConcurrent = 10,
|
||||
[string]$Model = "sonnet"
|
||||
)
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Repo = (Resolve-Path ".").Path
|
||||
$Goals = Join-Path $Repo "seo-audit-2026-05-27\goals"
|
||||
if(-not (Test-Path (Join-Path $Repo ".git"))){ throw "Run from the odoo-expertos repo root (no .git here: $Repo)" }
|
||||
if(-not (Get-Command claude -ErrorAction SilentlyContinue)){ throw "claude CLI not on PATH" }
|
||||
function ReadGoal($name){ Get-Content -Raw (Join-Path $Goals "$name.txt") }
|
||||
|
||||
function Run-Setup {
|
||||
Write-Host "=== SETUP (serial) ===" -ForegroundColor Cyan
|
||||
git checkout -B fix/seo-all
|
||||
$g = ReadGoal 'SETUP'
|
||||
claude --model $Model -p "/goal $g"
|
||||
Write-Host "--- SETUP done. Verify BRAND.md + personas + cluster plans + z-image probe exist." -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Run-Batches {
|
||||
Write-Host "=== BATCHES (parallel, MaxConcurrent=$MaxConcurrent) ===" -ForegroundColor Cyan
|
||||
$ids = 1..10 | ForEach-Object { "B{0:00}" -f $_ }
|
||||
$wt = @{}
|
||||
$parent = Split-Path $Repo -Parent
|
||||
foreach($id in $ids){
|
||||
$wtDir = Join-Path $parent ("odoo-wt-" + $id.ToLower())
|
||||
$branch = "fix/seo-batch-" + $id.ToLower()
|
||||
if(-not (Test-Path $wtDir)){
|
||||
Write-Host "creating worktree $wtDir on $branch (from fix/seo-all)"
|
||||
git worktree add -b $branch $wtDir fix/seo-all
|
||||
} else {
|
||||
Write-Host "worktree exists: $wtDir"
|
||||
}
|
||||
$wt[$id] = $wtDir
|
||||
}
|
||||
|
||||
$queue = New-Object System.Collections.Queue
|
||||
foreach($id in $ids){ $queue.Enqueue($id) }
|
||||
$running = @{}
|
||||
while($queue.Count -gt 0 -or $running.Count -gt 0){
|
||||
while($running.Count -lt $MaxConcurrent -and $queue.Count -gt 0){
|
||||
$id = $queue.Dequeue()
|
||||
$g = ReadGoal $id
|
||||
$wtDir = $wt[$id]
|
||||
Write-Host "--> launching $id in $wtDir" -ForegroundColor Yellow
|
||||
$j = Start-Job -ScriptBlock {
|
||||
param($wtDir, $model, $goal, $id)
|
||||
Set-Location $wtDir
|
||||
$log = Join-Path $wtDir "$id.log"
|
||||
& claude --model $model -p "/goal $goal" *> $log
|
||||
return @{Id=$id; ExitCode=$LASTEXITCODE; Log=$log}
|
||||
} -ArgumentList $wtDir, $Model, $g, $id
|
||||
$running[$id] = $j
|
||||
}
|
||||
Start-Sleep -Seconds 30
|
||||
foreach($id in @($running.Keys)){
|
||||
$j = $running[$id]
|
||||
if($j.State -ne 'Running'){
|
||||
$r = Receive-Job $j -ErrorAction SilentlyContinue
|
||||
Remove-Job $j -Force
|
||||
Write-Host "<-- $id finished (exit $($r.ExitCode); log: $($r.Log))" -ForegroundColor Green
|
||||
$running.Remove($id)
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Host "--- ALL BATCHES finished. Inspect each fix/seo-batch-bNN branch + its log before FINAL." -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Run-Final {
|
||||
Write-Host "=== FINAL (serial) ===" -ForegroundColor Cyan
|
||||
git checkout fix/seo-all
|
||||
$g = ReadGoal 'FINAL'
|
||||
claude --model $Model -p "/goal $g"
|
||||
Write-Host "--- FINAL done. Check the live re-audit score." -ForegroundColor Green
|
||||
}
|
||||
|
||||
switch($Phase){
|
||||
'setup' { Run-Setup }
|
||||
'batches' { Run-Batches }
|
||||
'final' { Run-Final }
|
||||
'all' { Run-Setup; Run-Batches; Run-Final }
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1010 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 312 KiB |
@@ -0,0 +1,88 @@
|
||||
#requires -version 5.1
|
||||
<#
|
||||
kie-image.ps1 - generate hero/OG images via kie.ai (z-image by default).
|
||||
Loads KIE_API_KEY from .env.local at repo root (or $env:KIE_API_KEY).
|
||||
Usage:
|
||||
powershell -File seo-audit-2026-05-27\scripts\kie-image.ps1 -Prompt "..." -OutPath "images/<slug>-hero.png" [-Model z-image] [-Aspect 16:9] [-Resolution 2K]
|
||||
Models: z-image (default, fast), nano-banana-2 (premium fallback), nano-banana-pro.
|
||||
Mechanism: POST /api/v1/jobs/createTask with callBackUrl -> ntfy.sh topic -> poll for result.
|
||||
Note: The old /api/v1/jobs/getTaskDetails polling endpoint no longer exists (API change 2026-05).
|
||||
Results are now delivered via callBackUrl (webhook). This script uses ntfy.sh as a
|
||||
free anonymous webhook receiver since no public server is required.
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory)][string]$Prompt,
|
||||
[Parameter(Mandatory)][string]$OutPath,
|
||||
[string]$Model = "z-image",
|
||||
[string]$Aspect = "16:9",
|
||||
[string]$Resolution = "2K",
|
||||
[string]$Format = "png",
|
||||
[int]$TimeoutSec = 300
|
||||
)
|
||||
$ErrorActionPreference = "Stop"
|
||||
$repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
if(-not $env:KIE_API_KEY){
|
||||
$envFile = Join-Path $repoRoot ".env.local"
|
||||
if(Test-Path $envFile){
|
||||
$line = Get-Content $envFile -ErrorAction SilentlyContinue | Where-Object { $_ -match '^KIE_API_KEY=' } | Select-Object -First 1
|
||||
if($line){ $env:KIE_API_KEY = ($line -replace '^KIE_API_KEY=','').Trim('"',"'") }
|
||||
}
|
||||
}
|
||||
if(-not $env:KIE_API_KEY){ throw "KIE_API_KEY not set (env var or .env.local)" }
|
||||
|
||||
# Generate unique ntfy.sh topic for callback
|
||||
$ntfyTopic = "kie-img-$(Get-Date -Format 'yyyyMMddHHmmss')-$(Get-Random -Maximum 9999)"
|
||||
$callBackUrl = "https://ntfy.sh/$ntfyTopic"
|
||||
|
||||
$headers = @{ Authorization = "Bearer $($env:KIE_API_KEY)"; 'Content-Type' = 'application/json' }
|
||||
$body = @{
|
||||
model = $Model
|
||||
input = @{ prompt = $Prompt; aspect_ratio = $Aspect; resolution = $Resolution; output_format = $Format }
|
||||
callBackUrl = $callBackUrl
|
||||
} | ConvertTo-Json -Depth 6
|
||||
|
||||
Write-Host "[kie-image] submit model=$Model aspect=$Aspect res=$Resolution"
|
||||
Write-Host "[kie-image] callback=$callBackUrl"
|
||||
$create = Invoke-RestMethod -Uri 'https://api.kie.ai/api/v1/jobs/createTask' -Method POST -Headers $headers -Body $body
|
||||
if($create.code -ne 200){ throw "createTask failed: $($create | ConvertTo-Json -Depth 5 -Compress)" }
|
||||
$taskId = $create.data.taskId
|
||||
Write-Host "[kie-image] taskId=$taskId polling via ntfy.sh..."
|
||||
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
$imageUrl = $null
|
||||
while((Get-Date) -lt $deadline){
|
||||
Start-Sleep -Seconds 8
|
||||
try {
|
||||
$r = Invoke-WebRequest -Uri "https://ntfy.sh/$ntfyTopic/json?poll=1" -UseBasicParsing -ErrorAction Stop
|
||||
$text = [System.Text.Encoding]::UTF8.GetString($r.RawContentStream.ToArray())
|
||||
# Parse NDJSON lines for kie.ai callback
|
||||
$lines = $text -split '[\r\n]+' | Where-Object { $_ -match '"event":"message"' }
|
||||
foreach ($line in $lines) {
|
||||
try {
|
||||
$msg = $line | ConvertFrom-Json
|
||||
$payload = $msg.message | ConvertFrom-Json
|
||||
if ($payload.code -eq 200 -and $payload.data.taskId -eq $taskId) {
|
||||
$state = $payload.data.state
|
||||
Write-Host "[kie-image] state=$state"
|
||||
if ($state -eq 'success') {
|
||||
$rj = $payload.data.resultJson | ConvertFrom-Json
|
||||
$imageUrl = $rj.resultUrls[0]
|
||||
break
|
||||
}
|
||||
if ($state -eq 'failed' -or $state -eq 'error') {
|
||||
throw "task failed: $($payload | ConvertTo-Json -Depth 5 -Compress)"
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
} catch { }
|
||||
if ($imageUrl) { break }
|
||||
}
|
||||
if(-not $imageUrl){ throw "timed out after $TimeoutSec s waiting for task $taskId" }
|
||||
|
||||
$outFull = Join-Path $repoRoot $OutPath
|
||||
$outDir = Split-Path -Parent $outFull
|
||||
if($outDir -and -not (Test-Path $outDir)){ New-Item -ItemType Directory -Force -Path $outDir | Out-Null }
|
||||
Invoke-WebRequest -Uri $imageUrl -OutFile $outFull -UseBasicParsing
|
||||
Write-Host "[kie-image] saved: $outFull"
|
||||
Write-Output $outFull
|
||||
@@ -0,0 +1,16 @@
|
||||
$slugs = 'bestes-odoo-hosting-2026|cheap-odoo-hosting-2026|kostenloses-odoo-hosting-2026|odoo-hosting-deutschland-2026|odoo-hosting-oesterreich-2026|odoo-hosting-schweiz-2026|best-odoo-hosting-2026|free-odoo-hosting-2026|odoo-hosting-germany-2026|odoo-hosting-uk-2026|odoo-sh-alternatives-2026|odoo-vps-hosting-2026'
|
||||
$repo = Split-Path -Parent $PSScriptRoot
|
||||
$repo = Split-Path -Parent $repo
|
||||
foreach ($f in @('sitemap-en.xml','sitemap-fr.xml','sitemap-pt.xml','sitemap-ar.xml')) {
|
||||
$path = Join-Path $repo $f
|
||||
if (-not (Test-Path $path)) { continue }
|
||||
$c = [System.IO.File]::ReadAllText($path)
|
||||
$re = '(?s)\s*<url>\s*<loc>https://www\.odoo-expertos\.com/(en|fr|pt|ar)/odoo-hosting/(' + $slugs + ')/</loc>.*?</url>'
|
||||
$new = [regex]::Replace($c, $re, '')
|
||||
if ($new -ne $c) {
|
||||
[System.IO.File]::WriteAllText($path, $new)
|
||||
Write-Host "Cleaned $f"
|
||||
} else {
|
||||
Write-Host "No change $f"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# W10: extract second inline <style> block from index.html to external CSS file
|
||||
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
$idx = Join-Path $repo 'index.html'
|
||||
$c = [System.IO.File]::ReadAllText($idx)
|
||||
$matches = [regex]::Matches($c, '(?s)<style[^>]*>(.*?)</style>')
|
||||
if ($matches.Count -lt 2) { Write-Host "Not enough style blocks"; exit 0 }
|
||||
$second = $matches[1]
|
||||
$cssContent = $second.Groups[1].Value
|
||||
$cssPath = Join-Path $repo 'css\homepage-extra.min.css'
|
||||
[System.IO.File]::WriteAllText($cssPath, $cssContent)
|
||||
# Replace the second <style>...</style> with link tag
|
||||
$replacement = '<link rel="stylesheet" href="/css/homepage-extra.min.css">'
|
||||
$newC = $c.Substring(0, $second.Index) + $replacement + $c.Substring($second.Index + $second.Length)
|
||||
[System.IO.File]::WriteAllText($idx, $newC)
|
||||
$newMatches = [regex]::Matches($newC, '(?s)<style[^>]*>(.*?)</style>')
|
||||
$total = ($newMatches | ForEach-Object { $_.Groups[1].Value.Length } | Measure-Object -Sum).Sum
|
||||
Write-Host "Extracted $($cssContent.Length) bytes to css/homepage-extra.min.css; inline CSS now: $total bytes"
|
||||
@@ -0,0 +1,20 @@
|
||||
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
$excludePattern = '\\(\.git|node_modules|seo-audit-2026-05-27|website|directory)\\'
|
||||
$files = Get-ChildItem $repo -Recurse -Filter index.html -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -notmatch $excludePattern }
|
||||
$matched = @()
|
||||
foreach ($file in $files) {
|
||||
$c = [System.IO.File]::ReadAllText($file.FullName)
|
||||
if (-not $c) { continue }
|
||||
if ($c -match '"(?:url|item|@id|logo)":\s*"https://odoo-expertos\.com') {
|
||||
$matched += $file.FullName
|
||||
}
|
||||
}
|
||||
Write-Host "Matched count: $($matched.Count)"
|
||||
$matched | Select-Object -First 3 | ForEach-Object { Write-Host $_ }
|
||||
if ($matched.Count -gt 0) {
|
||||
$c = [System.IO.File]::ReadAllText($matched[0])
|
||||
$m = [regex]::Match($c, '"(?:url|item|@id|logo)":\s*"https://odoo-expertos\.com[^"]*"')
|
||||
Write-Host "---SAMPLE MATCH---"
|
||||
Write-Host $m.Value
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
$excludePattern = '\\(\.git|node_modules|seo-audit-2026-05-27|website|directory)\\'
|
||||
$files = Get-ChildItem $repo -Recurse -Filter index.html -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -notmatch $excludePattern }
|
||||
$matched = @()
|
||||
foreach ($file in $files) {
|
||||
$c = [System.IO.File]::ReadAllText($file.FullName)
|
||||
if (-not $c) { continue }
|
||||
# CASE-SENSITIVE - same as REVIEW.ps1
|
||||
if ([regex]::IsMatch($c, '"(?:url|item|@id|logo)":\s*"https://odoo-expertos\.com')) {
|
||||
$matched += $file.FullName
|
||||
}
|
||||
}
|
||||
Write-Host "Case-sensitive matched: $($matched.Count)"
|
||||
if ($matched.Count -gt 0) {
|
||||
$c = [System.IO.File]::ReadAllText($matched[0])
|
||||
$m = [regex]::Match($c, '"(?:url|item|@id|logo)":\s*"https://odoo-expertos\.com[^"\r\n]*')
|
||||
Write-Host "Sample: $($m.Value)"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
# W3: fix dead domain + non-www JSON-LD URLs across all index.html files (case-insensitive)
|
||||
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
$excludePattern = '\\(\.git|node_modules|seo-audit-2026-05-27|website|directory)\\'
|
||||
$files = Get-ChildItem $repo -Recurse -Filter index.html -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -notmatch $excludePattern }
|
||||
$tpl = Join-Path $repo 'templates\pillar-page.html'
|
||||
if (Test-Path $tpl) { $files += (Get-Item $tpl) }
|
||||
$eeat = Join-Path $repo 'components\eeat.js'
|
||||
if (Test-Path $eeat) { $files += (Get-Item $eeat) }
|
||||
|
||||
$opts = [System.Text.RegularExpressions.RegexOptions]::IgnoreCase
|
||||
$changed = 0
|
||||
foreach ($file in $files) {
|
||||
$c = [System.IO.File]::ReadAllText($file.FullName)
|
||||
if (-not $c) { continue }
|
||||
$orig = $c
|
||||
# Normalize ALL occurrences of any case-variant of odoo-expertos.com to www.odoo-expertos.com
|
||||
# Step 1: dead domain (no hyphen) -> www.odoo-expertos.com
|
||||
$c = [regex]::Replace($c, 'https?://(?:www\.)?odooexpertos\.com', 'https://www.odoo-expertos.com', $opts)
|
||||
# Step 2: protocol+(www.)?odoo-expertos.com -> https://www.odoo-expertos.com
|
||||
$c = [regex]::Replace($c, 'https?://(?:www\.)?odoo-expertos\.com', 'https://www.odoo-expertos.com', $opts)
|
||||
# Bare hostname (no protocol)
|
||||
$c = [regex]::Replace($c, '(?<![./@\w-])(?:www\.)?odooexpertos\.com', 'www.odoo-expertos.com', $opts)
|
||||
# Cleanup any accidental www.www.
|
||||
$c = $c -replace 'www\.www\.odoo-expertos\.com', 'www.odoo-expertos.com'
|
||||
if ($c -ne $orig) {
|
||||
[System.IO.File]::WriteAllText($file.FullName, $c)
|
||||
$changed++
|
||||
}
|
||||
}
|
||||
Write-Host "W3 codemod: changed $changed of $($files.Count) files"
|
||||
@@ -0,0 +1,59 @@
|
||||
# W4: fix mislocated hreflang="es" hrefs + add hreflang block to 3 ES category pages
|
||||
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
$excludePattern = '\\(\.git|node_modules|seo-audit-2026-05-27|website|directory)\\'
|
||||
$files = Get-ChildItem $repo -Recurse -Filter index.html -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -notmatch $excludePattern }
|
||||
|
||||
$opts = [System.Text.RegularExpressions.RegexOptions]::IgnoreCase
|
||||
$changed = 0
|
||||
foreach ($file in $files) {
|
||||
$c = [System.IO.File]::ReadAllText($file.FullName)
|
||||
if (-not $c) { continue }
|
||||
$orig = $c
|
||||
# Strip /en/ /de/ /fr/ /pt/ /ar/ segment in any hreflang="es" or hreflang="x-default" href value
|
||||
$c = [regex]::Replace($c, '(hreflang="(?:es|x-default)"[^>]*href="https://www\.odoo-expertos\.com)/(?:de|fr|pt|ar|en)/', '$1/', $opts)
|
||||
# Also handle the inverse order: href=... hreflang=es
|
||||
$c = [regex]::Replace($c, '(href="https://www\.odoo-expertos\.com)/(?:de|fr|pt|ar|en)/([^"]*"\s+hreflang="(?:es|x-default)")', '$1/$2', $opts)
|
||||
if ($c -ne $orig) {
|
||||
[System.IO.File]::WriteAllText($file.FullName, $c)
|
||||
$changed++
|
||||
}
|
||||
}
|
||||
Write-Host "W4 hreflang-es fix: changed $changed of $($files.Count) files"
|
||||
|
||||
# Inject hreflang block into ES category pages
|
||||
$cats = @{
|
||||
'odoo' = 'odoo/'
|
||||
'odoo-hosting' = 'odoo-hosting/'
|
||||
'odoo-ia' = 'odoo-ia/'
|
||||
}
|
||||
$injected = 0
|
||||
foreach ($cat in $cats.Keys) {
|
||||
$catPath = Join-Path $repo "$cat\index.html"
|
||||
if (-not (Test-Path $catPath)) { continue }
|
||||
$c = [System.IO.File]::ReadAllText($catPath)
|
||||
if ($c -match 'hreflang=') { continue }
|
||||
$sub = $cats[$cat]
|
||||
$block = @"
|
||||
<!-- Hreflang alternates -->
|
||||
<link rel="alternate" hreflang="es" href="https://www.odoo-expertos.com/$sub">
|
||||
<link rel="alternate" hreflang="en" href="https://www.odoo-expertos.com/en/$sub">
|
||||
<link rel="alternate" hreflang="de" href="https://www.odoo-expertos.com/de/$sub">
|
||||
<link rel="alternate" hreflang="fr" href="https://www.odoo-expertos.com/fr/$sub">
|
||||
<link rel="alternate" hreflang="pt" href="https://www.odoo-expertos.com/pt/$sub">
|
||||
<link rel="alternate" hreflang="ar" href="https://www.odoo-expertos.com/ar/$sub">
|
||||
<link rel="alternate" hreflang="x-default" href="https://www.odoo-expertos.com/$sub">
|
||||
"@
|
||||
# Insert after canonical link
|
||||
$new = [regex]::Replace($c, '(<link\s+rel="canonical"[^>]*>)', "`$1`r`n$block", $opts)
|
||||
if ($new -eq $c) {
|
||||
# fallback: inject before </head>
|
||||
$new = $c -replace '</head>', "$block`r`n</head>"
|
||||
}
|
||||
if ($new -ne $c) {
|
||||
[System.IO.File]::WriteAllText($catPath, $new)
|
||||
$injected++
|
||||
Write-Host "Injected hreflang into $cat/index.html"
|
||||
}
|
||||
}
|
||||
Write-Host "W4 cat injection: $injected"
|
||||
@@ -0,0 +1,103 @@
|
||||
# W5: shorten titles >65 chars; guarantee unique meta descriptions across the corpus
|
||||
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
$excludePattern = '\\(\.git|node_modules|seo-audit-2026-05-27|website|directory)\\'
|
||||
$files = Get-ChildItem $repo -Recurse -Filter index.html -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -notmatch $excludePattern }
|
||||
|
||||
function ToTitle([string]$slug) {
|
||||
$s = $slug -replace '-', ' '
|
||||
$s = (Get-Culture).TextInfo.ToTitleCase($s.ToLower())
|
||||
$s = $s -replace '\bOdoo\b','Odoo'
|
||||
$s = $s -replace '\bAi\b','AI'
|
||||
$s = $s -replace '\bErp\b','ERP'
|
||||
$s = $s -replace '\bIa\b','IA'
|
||||
$s = $s -replace '\bAws\b','AWS'
|
||||
$s = $s -replace '\bGcp\b','GCP'
|
||||
$s = $s -replace '\bVps\b','VPS'
|
||||
$s = $s -replace '\bSh\b','SH'
|
||||
$s = $s -replace '\bUk\b','UK'
|
||||
$s = $s -replace '\bUsa\b','USA'
|
||||
$s = $s -replace '\bSaas\b','SaaS'
|
||||
return $s
|
||||
}
|
||||
|
||||
function PathLang([string]$fullPath, [string]$repo) {
|
||||
$rel = $fullPath.Substring($repo.Length).TrimStart('\','/')
|
||||
$parts = $rel -split '[\\/]'
|
||||
if ($parts.Count -ge 1 -and ($parts[0] -in @('en','de','fr','pt','ar'))) {
|
||||
return $parts[0]
|
||||
}
|
||||
return 'es'
|
||||
}
|
||||
|
||||
# First pass — collect existing meta description counts (informational only)
|
||||
$metaCounts = @{}
|
||||
foreach ($file in $files) {
|
||||
$c = [System.IO.File]::ReadAllText($file.FullName)
|
||||
if (-not $c) { continue }
|
||||
$m = [regex]::Match($c, '<meta\s+name="description"\s+content="([^"]*)"')
|
||||
if ($m.Success) {
|
||||
$d = $m.Groups[1].Value.Trim()
|
||||
if ($d) {
|
||||
if ($metaCounts.ContainsKey($d)) { $metaCounts[$d]++ } else { $metaCounts[$d] = 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Host "Pre-existing duplicate meta strings: $((${metaCounts}.GetEnumerator() | Where-Object {$_.Value -gt 1}).Count)"
|
||||
|
||||
$titleChanged = 0
|
||||
$metaChanged = 0
|
||||
foreach ($file in $files) {
|
||||
$c = [System.IO.File]::ReadAllText($file.FullName)
|
||||
if (-not $c) { continue }
|
||||
$orig = $c
|
||||
|
||||
$dir = Split-Path -Parent $file.FullName
|
||||
$slug = Split-Path -Leaf $dir
|
||||
$pretty = ToTitle $slug
|
||||
if ($pretty.Length -gt 42) { $pretty = $pretty.Substring(0,42).TrimEnd() }
|
||||
$lang = (PathLang $file.FullName $repo).ToUpper()
|
||||
|
||||
# Title fix (shorten if >65 chars)
|
||||
$tm = [regex]::Match($c, '<title>(.*?)</title>', 'Singleline')
|
||||
if ($tm.Success) {
|
||||
$curTitle = $tm.Groups[1].Value.Trim()
|
||||
if ($curTitle.Length -gt 65) {
|
||||
$base = $pretty
|
||||
$newTitle = "$base | Odoo Expertos"
|
||||
if ($newTitle.Length -gt 60) {
|
||||
$maxBase = 60 - " | Odoo Expertos".Length
|
||||
if ($maxBase -lt 5) { $maxBase = 5 }
|
||||
$newTitle = $base.Substring(0, [Math]::Min($base.Length, $maxBase)).TrimEnd() + " | Odoo Expertos"
|
||||
}
|
||||
$c = $c.Substring(0, $tm.Index) + "<title>$newTitle</title>" + $c.Substring($tm.Index + $tm.Length)
|
||||
$titleChanged++
|
||||
}
|
||||
}
|
||||
|
||||
# Always make meta description unique by appending " - [Slug] | [LANG]"
|
||||
$dm = [regex]::Match($c, '<meta\s+name="description"\s+content="([^"]*)"')
|
||||
if ($dm.Success) {
|
||||
$curDesc = $dm.Groups[1].Value.Trim()
|
||||
if ($curDesc) {
|
||||
$suffix = " - $pretty | $lang"
|
||||
# Only add suffix if it isn't already there (idempotent)
|
||||
if (-not $curDesc.EndsWith($suffix)) {
|
||||
$base = $curDesc
|
||||
if (($base.Length + $suffix.Length) -gt 165) {
|
||||
$base = $base.Substring(0, [Math]::Max(1, 165 - $suffix.Length)).TrimEnd()
|
||||
}
|
||||
$newDesc = $base + $suffix
|
||||
$newDesc = $newDesc -replace '"', '"'
|
||||
$repl = '<meta name="description" content="' + $newDesc + '"'
|
||||
$c = $c.Substring(0, $dm.Index) + $repl + $c.Substring($dm.Index + $dm.Length)
|
||||
$metaChanged++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($c -ne $orig) {
|
||||
[System.IO.File]::WriteAllText($file.FullName, $c)
|
||||
}
|
||||
}
|
||||
Write-Host "W5: titles shortened=$titleChanged; meta descriptions modified=$metaChanged"
|
||||
@@ -0,0 +1,76 @@
|
||||
# W6: bake static nav into every page; remove createHeader/createFooter/createEEAT JS calls
|
||||
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
$excludePattern = '\\(\.git|node_modules|seo-audit-2026-05-27|website|directory)\\'
|
||||
$files = Get-ChildItem $repo -Recurse -Filter index.html -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.FullName -notmatch $excludePattern }
|
||||
|
||||
function PathLang([string]$fullPath, [string]$repo) {
|
||||
$rel = $fullPath.Substring($repo.Length).TrimStart('\','/')
|
||||
$parts = $rel -split '[\\/]'
|
||||
if ($parts.Count -ge 1 -and ($parts[0] -in @('en','de','fr','pt','ar'))) {
|
||||
return $parts[0]
|
||||
}
|
||||
return 'es'
|
||||
}
|
||||
|
||||
$labels = @{
|
||||
'es' = @{ home='Inicio'; odoo='Odoo'; ia='Odoo IA'; hosting='Hosting Odoo'; sitemap='Mapa del Sitio' }
|
||||
'en' = @{ home='Home'; odoo='Odoo'; ia='Odoo AI'; hosting='Odoo Hosting'; sitemap='Sitemap' }
|
||||
'de' = @{ home='Start'; odoo='Odoo'; ia='Odoo KI'; hosting='Odoo Hosting'; sitemap='Sitemap' }
|
||||
'fr' = @{ home='Accueil';odoo='Odoo'; ia='Odoo IA'; hosting='Hebergement Odoo'; sitemap='Plan du Site' }
|
||||
'pt' = @{ home='Inicio'; odoo='Odoo'; ia='Odoo IA'; hosting='Hospedagem Odoo'; sitemap='Mapa do Site' }
|
||||
'ar' = @{ home='Inicio'; odoo='Odoo'; ia='Odoo AI'; hosting='Odoo Hosting'; sitemap='Sitemap' }
|
||||
}
|
||||
|
||||
function StaticHeader([string]$lang) {
|
||||
$L = $labels[$lang]
|
||||
if (-not $L) { $L = $labels['es'] }
|
||||
if ($lang -eq 'es') { $prefix = '' } else { $prefix = "/$lang" }
|
||||
$sm = if ($lang -eq 'es') { '/mapa-del-sitio/' } else { "$prefix/mapa-del-sitio/" }
|
||||
return @"
|
||||
<header class="site-header"><nav class="navbar"><div class="container"><div class="nav-brand"><a href="$prefix/" class="logo"><span class="logo-text">Odoo Expertos</span></a></div><button class="nav-toggle" aria-label="Toggle navigation"><span></span><span></span><span></span></button><div class="nav-menu"><ul class="nav-list"><li><a href="$prefix/">$($L.home)</a></li><li><a href="$prefix/odoo/">$($L.odoo)</a></li><li><a href="$prefix/odoo-ia/">$($L.ia)</a></li><li><a href="$prefix/odoo-hosting/">$($L.hosting)</a></li><li><a href="$sm">$($L.sitemap)</a></li></ul></div></div></nav></header>
|
||||
"@
|
||||
}
|
||||
|
||||
function StaticFooter([string]$lang) {
|
||||
$L = $labels[$lang]
|
||||
if (-not $L) { $L = $labels['es'] }
|
||||
if ($lang -eq 'es') { $prefix = '' } else { $prefix = "/$lang" }
|
||||
$sm = if ($lang -eq 'es') { '/mapa-del-sitio/' } else { "$prefix/mapa-del-sitio/" }
|
||||
return @"
|
||||
<footer class="site-footer"><div class="container"><div class="footer-cols"><div><strong>Odoo Expertos</strong></div><nav class="footer-nav"><a href="$prefix/">$($L.home)</a><a href="$prefix/odoo/">$($L.odoo)</a><a href="$prefix/odoo-ia/">$($L.ia)</a><a href="$prefix/odoo-hosting/">$($L.hosting)</a><a href="$sm">$($L.sitemap)</a></nav></div><div class="footer-bottom"><small>© 2026 Odoo Expertos</small></div></div></footer>
|
||||
"@
|
||||
}
|
||||
|
||||
$opts = [System.Text.RegularExpressions.RegexOptions]::IgnoreCase
|
||||
$changed = 0
|
||||
foreach ($file in $files) {
|
||||
$c = [System.IO.File]::ReadAllText($file.FullName)
|
||||
if (-not $c) { continue }
|
||||
$orig = $c
|
||||
$lang = PathLang $file.FullName $repo
|
||||
$hdr = StaticHeader $lang
|
||||
$ftr = StaticFooter $lang
|
||||
|
||||
# Inject static header inside <div id="header">...</div>
|
||||
$c = [regex]::Replace($c, '<div\s+id="header"[^>]*>\s*(?:<!--[^>]*-->)?\s*</div>', '<div id="header">' + $hdr + '</div>', $opts)
|
||||
$c = [regex]::Replace($c, '<div\s+id="header"[^>]*>.*?</div>', '<div id="header">' + $hdr + '</div>', $opts -bor [System.Text.RegularExpressions.RegexOptions]::Singleline)
|
||||
# Same for footer
|
||||
$c = [regex]::Replace($c, '<div\s+id="footer"[^>]*>\s*(?:<!--[^>]*-->)?\s*</div>', '<div id="footer">' + $ftr + '</div>', $opts)
|
||||
$c = [regex]::Replace($c, '<div\s+id="footer"[^>]*>.*?</div>', '<div id="footer">' + $ftr + '</div>', $opts -bor [System.Text.RegularExpressions.RegexOptions]::Singleline)
|
||||
|
||||
# Remove the createHeader/createFooter/createEEAT JS lines (entire lines)
|
||||
$c = [regex]::Replace($c, '(?m)^\s*document\.getElementById\([''"]header[''"]\)\.innerHTML\s*=\s*createHeader\(\)\s*;\s*\r?\n', '')
|
||||
$c = [regex]::Replace($c, '(?m)^\s*document\.getElementById\([''"]footer[''"]\)\.innerHTML\s*=\s*createFooter\(\)\s*;\s*\r?\n', '')
|
||||
$c = [regex]::Replace($c, '(?ms)\s*if\s*\(\s*typeof\s+createEEAT\s*===\s*[''"]function[''"]\s*\)\s*\{[^}]*createEEAT\(\)[^}]*\}\s*\r?\n', "`r`n")
|
||||
# Catch any stray createHeader() / createFooter() / createEEAT() still in file
|
||||
$c = [regex]::Replace($c, 'createHeader\(\)', '/*W6-static*/null')
|
||||
$c = [regex]::Replace($c, 'createFooter\(\)', '/*W6-static*/null')
|
||||
$c = [regex]::Replace($c, 'createEEAT\(\)', '/*W6-static*/null')
|
||||
|
||||
if ($c -ne $orig) {
|
||||
[System.IO.File]::WriteAllText($file.FullName, $c)
|
||||
$changed++
|
||||
}
|
||||
}
|
||||
Write-Host "W6: files modified=$changed"
|
||||
@@ -0,0 +1,39 @@
|
||||
# W7: add <meta name="robots" content="noindex,follow"> to duplicate-canonical pages
|
||||
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
|
||||
$dupFile = Join-Path $repo 'seo-audit-2026-05-27\gsc\duplicate-canonical.txt'
|
||||
if (-not (Test-Path $dupFile)) { Write-Host "Missing $dupFile"; exit 1 }
|
||||
$urls = (Get-Content $dupFile) | Where-Object { $_ -match '^https://' }
|
||||
Write-Host "Total duplicate-canonical URLs: $($urls.Count)"
|
||||
|
||||
function UrlToLocal([string]$url, [string]$repo) {
|
||||
$p = $url -replace '^https?://www\.odoo-expertos\.com', ''
|
||||
$p = $p.Split('#')[0].Split('?')[0]
|
||||
if ($p -eq '' -or $p -eq '/') { return (Join-Path $repo 'index.html') }
|
||||
if ($p -match '\.html?$') { return (Join-Path $repo ($p.TrimStart('/').Replace('/','\'))) }
|
||||
$p = $p.TrimEnd('/')
|
||||
return (Join-Path $repo ($p.TrimStart('/').Replace('/','\') + '\index.html'))
|
||||
}
|
||||
|
||||
$opts = [System.Text.RegularExpressions.RegexOptions]::IgnoreCase
|
||||
$noindexed = 0
|
||||
$missing = 0
|
||||
foreach ($u in $urls) {
|
||||
$lf = UrlToLocal $u $repo
|
||||
if (-not (Test-Path $lf)) { $missing++; continue }
|
||||
$c = [System.IO.File]::ReadAllText($lf)
|
||||
if (-not $c) { continue }
|
||||
# Check if noindex already present
|
||||
if ([regex]::IsMatch($c, 'name="robots"[^>]*noindex', $opts)) { continue }
|
||||
# If a <meta name="robots" ...> exists, replace its content; else inject new meta
|
||||
$existing = [regex]::Match($c, '<meta\s+name="robots"\s+content="[^"]*"\s*/?>', $opts)
|
||||
if ($existing.Success) {
|
||||
$repl = '<meta name="robots" content="noindex,follow">'
|
||||
$c = $c.Substring(0, $existing.Index) + $repl + $c.Substring($existing.Index + $existing.Length)
|
||||
} else {
|
||||
# Inject before </head>
|
||||
$c = [regex]::Replace($c, '</head>', '<meta name="robots" content="noindex,follow">' + "`r`n</head>", $opts)
|
||||
}
|
||||
[System.IO.File]::WriteAllText($lf, $c)
|
||||
$noindexed++
|
||||
}
|
||||
Write-Host "Pages noindexed: $noindexed; missing local: $missing"
|
||||
Reference in New Issue
Block a user