Skip to content

SEO: Add branded headers and cross-links to README and project description#49

Merged
jjroelofs merged 5 commits into
1.xfrom
seo/readme-desc-optimization
Apr 29, 2026
Merged

SEO: Add branded headers and cross-links to README and project description#49
jjroelofs merged 5 commits into
1.xfrom
seo/readme-desc-optimization

Conversation

@jjroelofs
Copy link
Copy Markdown
Contributor

Summary

  • Added branded DXPR CMS header with links to dxpr.com product pages at the top of README.md
  • Improved H1 title with descriptive, keyword-rich suffix for better search visibility
  • Added branded intro paragraph to the Drupal.org project description (desc.html)
  • Added "Related DXPR Modules" section at the bottom of both README.md and desc.html with cross-links to rl_sorting, analyze, and ai_content_strategy
  • Fixed pre-existing em-dashes in desc.html to pass pre-commit hook

SEO Impact

  • Branded header increases dxpr.com backlink presence across GitHub and Drupal.org
  • Keyword-rich H1 improves discoverability for "Drupal A/B testing" and "Thompson Sampling" queries
  • Cross-linking between related DXPR modules improves internal link equity and helps users discover the full ecosystem

Jurriaan Roelofs added 5 commits April 21, 2026 18:43
Why: rl.php used to swallow every rejected decide/turn/reward with a
`continue` and reply 200 `{"ok":true,"decisions":{}}`. The Drupal.rl
client then falls back to `armIds[0]` silently, so a site-wide
misconfiguration (e.g. a new entity-hook that never got its
implementations cache rebuilt, leaving experiments unregistered
despite the container being stamped with a valid-looking eid) is
indistinguishable from a healthy no-op request. The operator has
nothing to grep for in devtools or webserver logs; variants just
appear to never rotate.

handle_batch_request now:
- returns a structured array with `decisions`, `errors`, `requested`,
  `succeeded`
- tags each rejected entry with a machine-readable reason
  (unknown_experiment, invalid_id, missing_arms, invalid_arm_id,
  scoring_failed, manager_unavailable, malformed_entry)
- lets the caller pick the status code: 422 when a non-empty batch
  produced zero useful work, 200 for partial or full success

Partial failures stay 200 on purpose. A page rendering three healthy
containers plus one stale one should still get decisions for the
three, not reject the whole batch because one container is wrong
mid-deploy. The `errors` array surfaces the stale one to the client.

rl.js flushes the `errors` array to `console.warn` and forwards to an
optional `Drupal.rl.onErrors` listener so advanced consumers can wire
an alerting path without patching rl/api.
- Add branded DXPR header with links to dxpr.com product pages
- Improve H1 title with descriptive keyword-rich suffix
- Add Related DXPR Modules section for cross-linking
…desc.html

- README: GEO-optimized unique header with entity clarity and varied anchor text
- README: Add Pricing and Getting Started links
- README: Related Modules now includes non-DXPR community modules
- desc.html: Remove commercial branded header (community space)
- desc.html: Related Modules now includes non-DXPR community modules
 - Add bundled submodules RL Page Title and RL Menu Link to related modules
 - Replace AI Sorting reference with RL Sorting (correct project name)
 - Remove Google Tag and ECA which have no direct code integration
 - Remove duplicate Related Modules section mid-README
 - Add contextual dxpr.com/c/marketing-cms link in desc.html
 - Add RL Ecosystem section listing the full module family
Resolve conflict in rl.php: keep concise 1.x comment style for the
batch status code and handle_batch_request docblock, which also adds
manager_unavailable to the documented error reasons.
@jjroelofs jjroelofs merged commit 745bbff into 1.x Apr 29, 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