Skip to content

SEO and GEO for Czechia: landing pages, use cases, auto annotation (#2) - #5

Merged
ahmmmh merged 11 commits into
masterfrom
feat/seo-geo-use-cases
Nov 10, 2026
Merged

ahmmmh merged 11 commits into
masterfrom
feat/seo-geo-use-cases

Conversation

@ahmmmh

@ahmmmh ahmmmh commented Nov 10, 2026

Copy link
Copy Markdown
Collaborator

Refs #2. Draft: do not merge before Filip approves the copy in seed-assets/copy/seo-geo/.

What changes

  • Root /: the stored language choice wins (only the footer switcher and the locale suggestion write NEXT_LOCALE). Without it, Accept-Language decides: cs and sk go to /cs, others to /en. next-intl no longer writes the cookie on every visit.
  • Metadata: one buildMeta() gives every page a self canonical, hreflang with x-default and Open Graph. The doubled og:image URL (https://robopipe.iohttps//storage…) is fixed on all pages, blog included.
  • JSON-LD: Organization, WebSite, Product (offers read from the pricing table in Payload), BlogPosting, FAQPage, BreadcrumbList.
  • Use cases: detail pages at /{locale}/case-studies/{slug} with problem, solution, result, technique and FAQ. The listing URLs stay. Cards link to the detail page.
  • Sitemap and /llms.txt read one list of indexable documents. /llms.txt answers 200 now. /foo.txt answers 404 instead of 500.
  • Memberships: Česká inovační platforma logo in the footer and in a "Jsme součástí" band on the home page, plus Organization.memberOf.
  • Content script pnpm seed:seo-geo: drafts by default, idempotent, refuses a remote database without --production. Nothing runs on production from this PR.
  • Old shop URLs go to /en/case-studies/ai-product-tagging instead of a 404.
  • Migration seo_geo: adds case study sections and FAQ relation, memberships, logoCloud.source. Drops the empty content column of case studies (checked empty in production on 10 Nov).

For Filip to review

  • Copy: seed-assets/copy/seo-geo/ (landing pages, auto annotation page, case study sections, FAQs, home blocks, navigation, blog draft).
  • Open points: docs/specs/2-seo-geo/implementation.md, chapters 7 and 8. One [ověřit] is in the copy: where auto annotation sends images.
  • Conflict: the pricing page lists AI image annotation only on Pro and Enterprise, but the decision says all customers have it.

Verification (local, seeded database)

  • Integration tests 33/33, e2e 43/43, lint 0 errors, typecheck 0 errors, build OK.
  • Lighthouse SEO 100 on /cs and /cs/kamerova-kontrola-kvality (mobile and desktop).
  • JSON-LD: 39 blocks on 10 pages, structural check 0 errors.
  • Production rollout steps: implementation.md, chapter 6.

- Root `/` follows Accept-Language only (localeCookie off).
- One place for canonical, hreflang with x-default and Open Graph (buildMeta, alternatesFor). Fix og:image URLs from GCS.
- JSON-LD: Organization, WebSite, Product, BlogPosting, FAQPage, BreadcrumbList.
- Case study detail pages at /{locale}/case-studies/{slug} with problem, solution, result, technique and FAQ sections. Cards link to them.
- Sitemap and /llms.txt read one list of indexable documents.
- Memberships in site settings, shown in the footer and in logo bands.
- Content script `pnpm seed:seo-geo` (draft by default, refuses a remote database without --production). Copy in seed-assets/copy/seo-geo.
- Migration seo_geo, tests (int and e2e), shop redirects to the tagging use case.
The home page metadata queried Payload with the locale "foo.txt", which is
not a value of the locale enum. Check the locale first. With that check the
locale layout's notFound() answers 404, so experimental.globalNotFound
(architecture 5.3) is not needed.
- Keep the language cookie: only an explicit choice (footer switcher, locale
  suggestion) writes NEXT_LOCALE, and the root `/` reads it before
  Accept-Language. next-intl no longer writes it on every visit.
- Product JSON-LD gets offers from the pricing table in Payload.
- Auto annotation copy: all Studio customers have it, it is not in the
  open-source edition.
- Seed and copy fixes keep the new home claim.
- Footer grid has one track per link column.
- docs: decisions in product.md, implementation.md.
# Conflicts:
#	playwright.config.ts
#	tests/e2e/admin.e2e.spec.ts
#	tests/e2e/frontend.e2e.spec.ts
#	tests/helpers/login.ts
…riteria J (#2)

- Auto annotation is in the Pro and Enterprise plans only, as the pricing
  says (decision G, replaces A2).
- Landing page, post and FAQ say a person reviews, edits and approves the
  proposed boxes (H).
- Drop the [ověřit] sentence about the cloud and the model provider. Offer
  an offline model or an on-premise deployment instead (I).
- Acceptance criteria for og:image, shop redirect, offers, claim and blog
  hreflang in product.md, with tests (J).
- docs/specs/2-seo-geo/test-report.md: every acceptance criterion with
  evidence, 12 defects with steps and severity, content notes for Filip.
- tests/int/testerFindings.int.spec.ts: parsePrice thousands separators,
  database guard with ?host=, no [ověřit] markers in the copy.
- tests/e2e/testerFindings.e2e.spec.ts: Slovak browser header to /cs,
  nested path under a dotted segment answers 404.

These tests fail until the defects are fixed.
…ation heading (#2)

- T1: the root picks the first served language by q value, so a Slovak
  browser with an English fallback lands on /cs.
- T3: parsePrice reads comma and dot thousands separators.
- T4: nested routes answer 404 for an unknown locale before querying Payload.
- T6: the database guard also checks the host query parameter.
- Hero heading says the person reviews and approves the boxes (H).
@ahmmmh
ahmmmh marked this pull request as ready for review November 10, 2026 20:50
@ahmmmh
ahmmmh merged commit 3cf0640 into master Nov 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant