Skip to content

SEO audit fixes: docs meta/titles/H1/alt + shared redirect & structured-data#6686

Draft
Alek99 wants to merge 8 commits into
mainfrom
seo-fixes
Draft

SEO audit fixes: docs meta/titles/H1/alt + shared redirect & structured-data#6686
Alek99 wants to merge 8 commits into
mainfrom
seo-fixes

Conversation

@Alek99

@Alek99 Alek99 commented Jun 26, 2026

Copy link
Copy Markdown
Member

Fixes a large batch of issues from the Ahrefs site audit. Verified by importing the docs app and reflex-site-shared consumers and inspecting the emitted <head> / sitemap (not yet re-crawled β€” that requires a deploy).

Three groups (see commits)

1. Shared site package (packages/reflex-site-shared/) β€” also consumed by marketing + blog

  • Footer/navbar now link /blog/ and /docs/ (were /blog, /docs, which 301) and FORUM_URL β†’ GitHub Discussions β†’ clears ~1,400 "page has links to redirect" rows sitewide
  • pricing_jsonld drops the price-less Enterprise Offer; blog_index_jsonld drops invalid ListItem.datePublished β†’ fixes structured-data validation errors

2. Docs renderer (docs/app/reflex_docs/)

  • Per-page meta (description + full OG + Twitter card + canonical), no duplicates β†’ Twitter card missing (~770), OG incomplete (~691), meta description missing (~770), duplicate-without-canonical (~765)
  • Longer/unique titles + descriptions auto-extracted from each page's first paragraph β†’ title too short (~549)
  • Sitemap loc = /docs/-prefixed canonical β†’ non-canonical / 3XX in sitemap

3. Docs content (docs/*.md, packages/integrations-docs/)

  • Added missing # H1 to 10 docs pages β†’ H1 missing
  • Descriptive alt= on ~97 rx.image() calls + integrations screenshots β†’ missing alt text
  • Fixed dead build.reflex.dev/tokens link in hosting/databricks.md

Not included (documented, needs a judgment call)

  • apiref/cloud-CLI title too short (~30–40 pages) β€” the title doubles as the docs sidebar namespace key, so it needs a sidebar-aware change
  • Multiple-H1 from in-page demos (rx.heading defaults to <h1>) β€” would alter many teaching examples
  • Out of scope: third-party subdomains (status./build./learn./enterprise.), Cloudflare /cdn-cgi/ email obfuscation, www robots.txt

πŸ€– Generated with Claude Code

Alek and others added 3 commits June 26, 2026 15:54
…ckage

Footer/navbar link to /blog/ and /docs/ (was /blog, /docs which 301) and FORUM_URL -> GitHub Discussions, clearing ~1400 'links to redirect' rows sitewide. pricing_jsonld drops the price-less Enterprise offer and blog_index_jsonld drops the invalid ListItem datePublished (Google rich-results / schema.org errors).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Docs pages now emit description + full Open Graph + Twitter card + canonical (previously only a title), with page-specific OG values and a /docs-prefixed trailing-slash canonical that also drives the sitemap loc. Titles lengthened and de-duplicated; descriptions auto-extracted from each page's first paragraph. Fixes Twitter-card-missing (~770), OG-incomplete (~691), meta-description-missing (~770), duplicate-without-canonical (~765), title-too-short (~549), and non-canonical/3XX-in-sitemap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a top-level H1 to 10 docs pages that had none; add descriptive alt text to ~97 rx.image() calls across docs and to integrations-docs screenshots; repoint the dead build.reflex.dev/tokens link to /docs/hosting/tokens.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codspeed-hq

codspeed-hq Bot commented Jun 26, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

βœ… 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing seo-fixes (be90818) with main (f86f86c)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a large batch of Ahrefs site-audit issues across the docs and shared site package, addressing ~3,000+ flagged rows from redirect links, missing meta/OG/Twitter tags, invalid structured-data, missing alt text, and non-canonical sitemap entries.

  • Shared package (reflex-site-shared): Footer and navbar links updated to trailing-slash form, FORUM_URL pointed directly to GitHub Discussions (eliminating the 301 hop), pricing_jsonld drops the price-less Enterprise Offer, and blog_index_jsonld removes the invalid ListItem.datePublished field.
  • Docs renderer (reflex_docs): Introduces per-page meta descriptions extracted from each doc's first prose paragraph (with frontmatter-priority logic), per-page Open Graph / Twitter card / canonical tags via create_meta_tags, a revised title-length strategy that includes the section segment when the result stays under 60 chars, and sitemap <loc> values pointing at the canonical trailing-slash URL.
  • Docs content: Adds missing # H1 headings to 10 pages, descriptive alt= attributes to ~97 rx.image() calls, and fixes the dead build.reflex.dev/tokens link in databricks.md.

Confidence Score: 5/5

Safe to merge β€” all changes are SEO metadata, link fixes, and alt text additions with no logic that affects runtime app behavior.

The renderer changes (meta tag construction, title logic, description extraction) operate entirely at build time and fall back gracefully on any parsing failure. The shared-package link/JSONLD fixes are straightforward constant and data-structure changes. No data paths, state handlers, or auth flows are touched.

No files require special attention; the core reflex_docs.py meta-construction logic is the most complex change but is well-commented and handles edge cases (dynamic routes, missing descriptions, og:image deduplication) correctly.

Important Files Changed

Filename Overview
docs/app/reflex_docs/pages/docs/init.py Adds extract_doc_description for all markdown docs and threads description through make_docpage to docpage; logic is sound and all edge cases (frontmatter leakage, code-block stripping, ordered lists) are handled.
docs/app/reflex_docs/reflex_docs.py Replaces per-route meta construction with create_meta_tags, deduplicates against route-declared tags, filters og:image to avoid compiler double-emit, and sets trailing-slash canonical as the sitemap loc; strategy is consistent and author-verified.
docs/app/reflex_docs/templates/docpage/docpage.py Title logic refactored to include section segment when it fits within 60 chars, adds description parameter that flows to Route, and deduplicate-title guard prevents repeated section titles.
packages/reflex-site-shared/src/reflex_site_shared/meta/meta.py Removes invalid ListItem.datePublished from blog_index_jsonld and drops the price-less Enterprise Offer from pricing_jsonld; both are valid structured-data fixes.
packages/reflex-site-shared/src/reflex_site_shared/constants.py Points FORUM_URL directly to GITHUB_DISCUSSIONS_URL to eliminate the forum.reflex.dev 301 redirect hop site-wide.
packages/reflex-site-shared/src/reflex_site_shared/views/footer.py Adds trailing slash to /blog and /docs footer links to avoid 301 redirects.
packages/reflex-site-shared/src/reflex_site_shared/views/marketing_navbar.py Adds trailing slash to the Read All in Blog navbar link to avoid the 301 redirect.
docs/app/reflex_docs/pages/docs_landing/init.py Updates the docs landing page to pass image= separately and filters og:image from the meta list to match the reflex_docs.py pattern; canonical URL updated to trailing-slash form.
docs/app/reflex_docs/pages/library_previews.py Library preview page titles now include Reflex Docs suffix, making them longer and more descriptive for search engines.
docs/hosting/databricks.md Replaces dead external link build.reflex.dev/tokens with internal /docs/hosting/tokens link, which maps to a confirmed existing page.
packages/reflex-site-shared/src/reflex_site_shared/gallery/common.py Adds descriptive alt text to gallery item images.
packages/reflex-site-shared/src/reflex_site_shared/components/blocks/headings.py Adds generic alt=Documentation image to img_comp_xd; acceptable but non-descriptive since actual image content varies per call site.

Reviews (3): Last reviewed commit: "SEO: stop frontmatter leaking into docs ..." | Re-trigger Greptile

Comment thread docs/app/reflex_docs/pages/docs/__init__.py Outdated
Comment thread docs/app/reflex_docs/templates/docpage/docpage.py
Comment thread docs/app/reflex_docs/reflex_docs.py
@Alek99 Alek99 requested a review from carlosabadia June 26, 2026 23:12
extract_doc_description now skips ordered-list items 1.-9. (was 1.-3.) so later numbered items aren't pulled into descriptions; the bare-title fallback is now length-checked, dropping to the unsuffixed title when even that would exceed ~60 chars.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread docs/app/reflex_docs/pages/docs/__init__.py
Alek and others added 3 commits June 26, 2026 16:28
Reflex's compiler always renders one og:image from add_page's image kwarg (defaulting to favicon.ico). Pass the real preview image to add_page and strip og:image from the create_meta_tags meta list, so each page has exactly one og:image (the preview) plus one twitter:image, instead of favicon + preview. Applies to the docs renderer (reflex_docs.py) and docs landing page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
extract_doc_description now prefers a frontmatter description field and otherwise strips the whole --- block before scanning, so lines like 'title: Aligned Grids' or 'tags: DevTools' no longer become the meta description. Also add alt text to docs-landing and shared gallery/markdown images.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Multiple H1: demote demo rx.heading() to as_=h2 across 57 docs (164 calls), demote section-level markdown '# ' headings to '##' in 18 docs, and render the component 'API Reference' heading as h2 β€” each docs page now has a single H1. Redirect links: make all top-level internal links in the shared footer/navbar/sidebar trailing-slash (/docs/, /blog/, /pricing/, ...) so they no longer hit 301s. Alt text: add descriptive alt to ui.avatar.image logos/avatars in docs-landing, integration gallery, and shared gallery.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Too many files changed for review. (139 files found, 100 file limit)

@Alek99

Alek99 commented Jun 27, 2026

Copy link
Copy Markdown
Member Author

Round 3 review addressed (commit be90818)

  • Redirect links (comprehensive): every top-level internal link in the shared footer/navbar/sidebar is now trailing-slash (/docs/, /blog/, /pricing/, …). Verified 0 redirect-prone /docs//blog links remain. (FORUM_URL β†’ GitHub Discussions was already in.)
  • Multiple H1 β€” eliminated at the source: demo rx.heading() β†’ as_="h2" across 57 docs / 164 calls (incl. the /docs/getting-started/introduction/ counter "0"); 18 docs with section-level # headings demoted to ##; the component "API Reference" heading β†’ h2. Each docs page now has a single H1.
  • P1 frontmatter leak: extract_doc_description now uses a frontmatter description: when present, else strips the whole --- block before scanning. Verified on connect_to_github.md and aligned-grids.md.
  • og:image: single tag per page (real preview via add_page, og:image dropped from the meta list).
  • Alt text: added alt to the ui.avatar.image integration logos/avatars the earlier rx.image/rx.el.img sweep didn't cover.

Decorative images (connector/squares/pattern SVGs) intentionally keep alt="" per WCAG β€” they're presentational, and descriptive alt would add noise for screen-reader users. If Ahrefs flags empty alt on these, it's a known decorative-image false positive.

πŸ€– via Claude Code

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