Add 12-month growth plan, baseline, weekly log and measurement loop
Week-by-week plan grounded in current GSC data (4,745 impressions, 9 clicks, CTR 0.19%, hosting cluster at position 27.5, 1,090 impressions on page-1 zero-click queries). One bounded change per week, measured the following week. Snapshot script: ~/.hermes/scripts/growth_week.py.
This commit is contained in:
1 parent
21b274f91f
commit
8df260b90d
5 files changed
+248
No files matched your search
@@ -0,0 +1,55 @@
|
|||||||
|
# Baseline — 2026-10-24
|
||||||
|
|
||||||
|
Captured from the n8n stats webhook before any CRO work. Every later week is compared to
|
||||||
|
this. Range: 2026-01-01 → 2026-10-24.
|
||||||
|
|
||||||
|
## Search Console (10 months)
|
||||||
|
|
||||||
|
| metric | value |
|
||||||
|
|---|---|
|
||||||
|
| queries | 447 |
|
||||||
|
| impressions | 4,745 |
|
||||||
|
| clicks | 9 |
|
||||||
|
| CTR | 0.19% |
|
||||||
|
| average position | 24.7 |
|
||||||
|
| queries with ≥10 impressions | 105 |
|
||||||
|
| of those, on page 1 (pos ≤ 10) | 31 |
|
||||||
|
| page-1 queries with **zero** clicks | 17, holding 1,090 impressions |
|
||||||
|
|
||||||
|
Clusters:
|
||||||
|
|
||||||
|
| cluster | queries | impressions | clicks | avg position |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| hosting (money) | 33 | 538 | 1 | 27.5 |
|
||||||
|
| consulting | 11 | 402 | 0 | 50.4 |
|
||||||
|
| AI | 22 | 555 | 0 | 9.6 |
|
||||||
|
|
||||||
|
Head terms: `odoo hosting` 298 impr / pos 31.5 · `hosting odoo` 85 / 28.5 ·
|
||||||
|
`odoo beratung` 155 / 51.5 · `odo ia` 279 / 6.8 (0 clicks) ·
|
||||||
|
`odoo de donde es` 154 / 5.3 (0 clicks).
|
||||||
|
|
||||||
|
## Plausible
|
||||||
|
|
||||||
|
| metric | value |
|
||||||
|
|---|---|
|
||||||
|
| visitors | 2 (both test/owner traffic, week of 2026-10-19) |
|
||||||
|
| pageviews | 3 |
|
||||||
|
| goals configured | 1 — page goal `Visit /` |
|
||||||
|
| affiliate clicks (goal) | not measured yet — custom-event goals not created |
|
||||||
|
|
||||||
|
## Site
|
||||||
|
|
||||||
|
- 1,208 HTML pages across 6 locales (es root, en, de, fr, pt, ar).
|
||||||
|
- 479 outbound links to odoo4projects.com, all bearing `utm_source=odoo-expertos.com`.
|
||||||
|
- 12 pages carry the hosting CTA block (6 homepages, 6 hosting hubs).
|
||||||
|
- 40 near-duplicate `/odoo-hosting/*` pages per locale.
|
||||||
|
- Known defects: 3 fabricated testimonials, unverifiable ISO 27001 / SOC 2 / "200+ proyectos"
|
||||||
|
badges, placeholder phone on 8 pages, one 0-byte page in the PT sitemap.
|
||||||
|
|
||||||
|
## How to refresh
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 ~/.hermes/skills/marketing/odoo-expertos-site/scripts/website_stats.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Snapshots are appended to `growth/metrics.jsonl` by `~/.hermes/scripts/growth_week.py`.
|
||||||
+161
@@ -0,0 +1,161 @@
|
|||||||
|
# odoo-expertos.com — 12-month improvement plan
|
||||||
|
|
||||||
|
One change per week. Measure the previous week before starting the next.
|
||||||
|
North-star metric: **affiliate clicks** (Plausible goal `Affiliate Click`).
|
||||||
|
Supporting metrics: GSC clicks, money-keyword position, outbound CTR.
|
||||||
|
|
||||||
|
Guiding rules:
|
||||||
|
|
||||||
|
- A week ships **one** bounded change, deployed and verified live, logged in `WEEKLY-LOG.md`.
|
||||||
|
- Every change states a hypothesis and the metric it should move, **before** it ships.
|
||||||
|
- Next week starts by reading the result of last week. Keep, revert, or adjust — then move on.
|
||||||
|
- Impressions are the guardrail: if GSC impressions drop more than 10% week over week, stop
|
||||||
|
new work and diagnose before continuing.
|
||||||
|
- No invented proof. No fake testimonials, certifications or client names, ever.
|
||||||
|
|
||||||
|
Baseline (2026-10-24, see `BASELINE.md`): 4,745 impressions, 9 clicks, CTR 0.19%, avg
|
||||||
|
position 24.7, money cluster at position 27.5, affiliate clicks ≈ 0.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 0 — Instrumentation (week 0)
|
||||||
|
|
||||||
|
Done before the loop starts: Plausible tag on 1,206 pages, `Affiliate Click` /
|
||||||
|
`Outbound Click` events, UTM on all 479 outbound links, weekly snapshot script, this plan.
|
||||||
|
|
||||||
|
**Week 1 — Product marketing context.**
|
||||||
|
Write `.agents/product-marketing.md`: ICP, pains, objections, proof, positioning. Every
|
||||||
|
later copy decision reads from this file.
|
||||||
|
*Metric:* none (enabler). *Done when:* file exists and is committed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 1 — Remove what disqualifies us (weeks 2–7)
|
||||||
|
|
||||||
|
**Week 2 — Strip the fabricated proof.**
|
||||||
|
Remove the three invented testimonials, the ISO 27001 / SOC 2 / "200+ proyectos" badges, and
|
||||||
|
the placeholder phone number (8 pages). Replace with the real customer list.
|
||||||
|
*Hypothesis:* E-E-A-T and trust signals improve; removes legal exposure.
|
||||||
|
*Metric:* no ranking loss (guardrail week), Plausible outbound CTR on those pages.
|
||||||
|
|
||||||
|
**Weeks 3–6 — CTR rescue on page-1 zero-click queries.**
|
||||||
|
17 queries sit on page 1 with 0 clicks and hold 1,090 impressions (23% of all impressions).
|
||||||
|
Rewrite title + meta description for 4 landing pages per week, ordered by impressions:
|
||||||
|
`odo ia` (279), `odoo de donde es` (154), `de donde es odoo` (115), `odoo honduras` (81),
|
||||||
|
`.odo ia` (66), `odoo origen` (60), `odoobot que es` (56), `docker odoo 20` (32 ×2),
|
||||||
|
`odoo 20 docker`, `odoo de que pais es` (32), `hosting economicos` (30), `odoo inmobiliaria`
|
||||||
|
(27), `odoo bot` (25), `odoo de donde es originario` (25).
|
||||||
|
*Hypothesis:* these positions already earn the impression; the snippet is what fails.
|
||||||
|
*Metric:* CTR on those queries (target 0.19% → 1.5% site-wide by week 8).
|
||||||
|
|
||||||
|
**Week 7 — Kill the empty page.**
|
||||||
|
`pt/odoo-ia/odoo-sistema-reservas-booking-ia-2025/` is a 0-byte file in the sitemap that
|
||||||
|
returns an empty 200. Fill it with the translated ES content or remove it and regenerate the
|
||||||
|
sitemap.
|
||||||
|
*Metric:* index coverage.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2 — Make the money pages worth ranking (weeks 8–19)
|
||||||
|
|
||||||
|
Context: `odoo hosting` = 298 impressions at position 31.5. `hosting odoo` = 85 at 28.5.
|
||||||
|
The affiliate funnel is correct but nothing reaches it.
|
||||||
|
|
||||||
|
**Weeks 8–10 — Consolidate the thin hosting pages (ES first).**
|
||||||
|
40 near-duplicate `/odoo-hosting/*` pages per language cannibalize each other. Keep one hub,
|
||||||
|
keep the 6 genuine country pages, 301 the rest into the closest survivor, regenerate the
|
||||||
|
sitemap. Do not delete pages that have impressions without checking GSC per URL first.
|
||||||
|
*Hypothesis:* consolidating authority lifts the hub for `hosting odoo`.
|
||||||
|
*Metric:* position of `hosting odoo` / `odoo hosting`, hub impressions.
|
||||||
|
|
||||||
|
**Weeks 11–13 — Rebuild the ES hosting hub as a real comparison.**
|
||||||
|
Actual prices ($214/$395/$595/$950+), what each plan includes, backups, regions, migration
|
||||||
|
path, who it is wrong for. Comparison table above the fold. `Service` + `FAQPage` schema.
|
||||||
|
One primary CTA with our UTM.
|
||||||
|
*Hypothesis:* a page that answers "which plan and why" earns links and converts.
|
||||||
|
*Metric:* affiliate clicks from `/odoo-hosting/`, position for `odoo hosting`.
|
||||||
|
|
||||||
|
**Weeks 14–16 — Same rewrite for EN, then DE.**
|
||||||
|
DE matters: `odoo beratung` has 155 impressions at position 51.5 — the German section is
|
||||||
|
underperforming relative to its size.
|
||||||
|
*Metric:* per-language affiliate clicks.
|
||||||
|
|
||||||
|
**Weeks 17–19 — Internal links into the money pages.**
|
||||||
|
Add contextual links from the 50 highest-impression articles to the hosting hub, in the
|
||||||
|
article's own language. Anchor text describes the destination, not "click here".
|
||||||
|
*Metric:* hub entry pages, affiliate clicks.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3 — Content that deserves to rank (weeks 20–30)
|
||||||
|
|
||||||
|
**Weeks 20–23 — Upgrade the top 20 impression pages.**
|
||||||
|
Add what competitors don't have: screenshots from a real instance, benchmark numbers,
|
||||||
|
version-specific detail (19 vs 20), "what this costs" sections.
|
||||||
|
*Metric:* average position and CTR on those 20 URLs.
|
||||||
|
|
||||||
|
**Weeks 24–27 — Article-level CRO.**
|
||||||
|
Contextual CTA blocks inside articles at natural stopping points, matching the article's
|
||||||
|
topic (hosting article → hosting CTA; module article → module CTA). No popups.
|
||||||
|
*Metric:* affiliate clicks per 1,000 sessions; scroll-to-CTA rate.
|
||||||
|
|
||||||
|
**Weeks 28–30 — Contact path.**
|
||||||
|
The only conversion today is `mailto:`. Replace with a short form (name, email, what they
|
||||||
|
need) posting to the existing webhook, with a real success state.
|
||||||
|
*Metric:* form submissions (new goal), goal conversion rate.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4 — Locale quality (weeks 31–36)
|
||||||
|
|
||||||
|
**Weeks 31–33 — Audit ar/pt/fr.**
|
||||||
|
Find pages whose main content is untranslated boilerplate. Either translate the body or
|
||||||
|
`noindex` them. Never cross-locale canonical, never hreflang a page you don't want indexed.
|
||||||
|
*Metric:* index coverage ratio per locale, locale impressions.
|
||||||
|
|
||||||
|
**Weeks 34–36 — Localise the money pages properly.**
|
||||||
|
Currency, payment methods, local hosting expectations, local phone/hours where real.
|
||||||
|
*Metric:* affiliate clicks from non-ES locales.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 5 — Authority (weeks 37–46)
|
||||||
|
|
||||||
|
**Weeks 37–40 — Original data asset.**
|
||||||
|
Publish "Odoo hosting prices compared" with a method, a date, and a table others can cite.
|
||||||
|
This is the link magnet; everything else is maintenance.
|
||||||
|
*Metric:* referring domains, positions for comparison queries.
|
||||||
|
|
||||||
|
**Weeks 41–43 — Directory + OCA presence.**
|
||||||
|
Submit to relevant directories; get the OCA module tracker listed where Odoo users look.
|
||||||
|
*Metric:* referring domains, referral sessions.
|
||||||
|
|
||||||
|
**Weeks 44–46 — Outreach round.**
|
||||||
|
20 personalised pitches to Odoo blogs/communities pointing at the data asset. No bought links.
|
||||||
|
*Metric:* links earned, referral traffic.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 6 — Scale what works (weeks 47–52)
|
||||||
|
|
||||||
|
**Weeks 47–49 — Template the winner.**
|
||||||
|
Take the best-converting page structure and apply it to the 6 country pages.
|
||||||
|
*Metric:* affiliate clicks per country page.
|
||||||
|
|
||||||
|
**Weeks 50–51 — Decay sweep.**
|
||||||
|
Refresh the 20 posts with falling impressions (update prices, versions, dates).
|
||||||
|
*Metric:* recovered impressions.
|
||||||
|
|
||||||
|
**Week 52 — Year review.**
|
||||||
|
Compare every phase against its metric. Kill what didn't work, codify what did into the
|
||||||
|
templates and into the `odoo-expertos-site` skill.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Weekly loop (what the cron job does)
|
||||||
|
|
||||||
|
1. Snapshot metrics, diff against last week, print the delta.
|
||||||
|
2. Read last week's log entry: what shipped, what it was supposed to move.
|
||||||
|
3. Record the verdict: keep / revert / adjust.
|
||||||
|
4. Take the next week's action from this file, implement it, deploy, verify live.
|
||||||
|
5. Write the log entry with hypothesis + metric before moving on.
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Weekly log
|
||||||
|
|
||||||
|
One entry per week. The hypothesis and the metric are written **before** the change ships;
|
||||||
|
the measurement is filled in by the following week's run. A week without a measurement is
|
||||||
|
an unfinished week.
|
||||||
|
|
||||||
|
| Week | Date | Change | Hypothesis | Metric watched | Expected | Measured | Verdict |
|
||||||
|
|---|---|---|---|---|---|---|---|
|
||||||
|
| 0 | 2026-10-24 | Instrumentation: Plausible tag on 1,206 pages, `Affiliate Click` / `Outbound Click` custom events, UTM on 479 outbound links, CTA blocks on 6 homepages + 6 hosting hubs, weekly loop installed | Without measurement every change is a guess | all | baseline established | n/a (setup) | keep |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entry template
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
### Week N — YYYY-MM-DD
|
||||||
|
|
||||||
|
**Shipped:** <what changed, with commit hash>
|
||||||
|
**Hypothesis:** <why this should move a number>
|
||||||
|
**Metric:** <the one number that decides>
|
||||||
|
**Expected:** <direction and rough size>
|
||||||
|
|
||||||
|
**Measured (week N+1):** <actual, from growth_week.py>
|
||||||
|
**Verdict:** keep / revert / adjust — and why
|
||||||
|
|
||||||
|
**Next:** <carried into the following week>
|
||||||
|
```
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"ts": "2026-10-24T19:00:18+00:00", "clicks": 9, "impressions": 4745, "ctr": 0.18967334035827188, "position": 24.75, "queries": 447, "page1_zero_queries": 17, "page1_zero_impressions": 1090, "money_impressions": 538, "money_position": 27.5, "visitors": 2, "pageviews": 3, "goals": {"Visit /": 1}}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"current_week": 1,
|
||||||
|
"started": "2026-10-24"
|
||||||
|
}
|
||||||
Reference in new issue
Block a user