Skip to content

docs: SEO optimization for graphing / charts documentation#6703

Merged
carlosabadia merged 15 commits into
mainfrom
claude/plotly-charts-seo-o8sxyy
Jul 3, 2026
Merged

docs: SEO optimization for graphing / charts documentation#6703
carlosabadia merged 15 commits into
mainfrom
claude/plotly-charts-seo-o8sxyy

Conversation

@Alek99

@Alek99 Alek99 commented Jul 2, 2026

Copy link
Copy Markdown
Member

Summary

On-page SEO pass across the graphing docs, grounded in Ahrefs keyword/SERP data. These pages wrap Recharts (not Plotly, as sometimes assumed), and the winnable, high-volume terms are Recharts + general chart-type terms (mostly KD 0–15) where Reflex already ranked page 1 but with weak on-page signals. Two structural gaps affected every chart page — no meta descriptions and malformed titles ("Barchart") — plus near-zero internal linking and several thin/undocumented pages.

Type of change

  • This change requires a documentation update (it is a documentation update, plus small supporting code changes)

What changed

Framework/code (small, supporting):

  • Library docs now emit a page-specific meta description (derived from frontmatter/body) and honor an explicit frontmatter title: — previously every component doc inherited the generic site-wide description and a title-cased filename.
  • Sidebar labels now use the frontmatter title (e.g. "Area Chart" instead of "Areachart") while still deriving the URL from the filename.
  • reflex-docgen frontmatter parser: meta_description/description added to the known-keys set so they aren't misparsed as component-preview lambdas (with regression test).
  • Library index.md files render as normal docs (not components), enabling section overview pages.

Content:

  • Titles + keyword-rich meta descriptions on all chart pages; intros mention Reflex / Recharts / pure Python and high-value synonyms (scatter plot, donut, spider, gauge, combo, stacked/grouped/horizontal bar, bubble, multi-line).
  • New Stacked Bar Chart and Bubble Chart examples; expanded the thin composed / error-bar / radial-bar pages.
  • New Treemap page (the rx.recharts.treemap component shipped but was undocumented).
  • Plotly page built out with Plotly Express examples (bar, scatter, pie, heatmap, histogram, box plot) targeting the low-difficulty Plotly long-tail.
  • "Related Charts" cross-links added across all chart pages (internal linking was near-zero).
  • New graphing overview page at /library/graphing/general/ targeting category terms (python data visualization, python dashboard) and acting as an internal-linking hub.

Testing

  • ruff check and ruff format --check pass on all changed Python files.
  • Added regression tests: tests/units/docgen/test_markdown.py and docs/app/tests/test_doc_description.py.
  • Every added demo/demo exec code block AST-parses; all new component APIs (z_axis, Treemap, ErrorBar on Line, dual y_axis_id) verified against the component source; all internal links verified to resolve; all frontmatter validated as YAML.
  • ⚠️ I could not run the full pytest suite or a reflex compile in the sandbox (the pinned Python toolchain wasn't installable there). Please run the docs build + unit tests in CI before merging.

Notes

Two remaining levers are outside on-page docs: the /library/graphing/charts/ index is still a thin shell (could get the same overview treatment), and backlinks (every subpage has URL Rating 0). Rankings will move only after deploy + re-crawl (~1–4 weeks); the target keywords aren't yet in the Ahrefs Rank Tracker, so adding them would make the impact measurable.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR


Generated by Claude Code

claude added 10 commits July 2, 2026 21:10
The graphing chart docs (Recharts-based) target high-value, low-difficulty
terms — "recharts" (8.4K US/mo, KD 5), "recharts bar/line/area/pie chart"
(KD ~0), where the pages already ranked page 1 but with weak on-page signals.

Two structural gaps hurt every chart page:

- Library docs render via `multi_docs`, which never passed a `description`,
  so every chart (and every other component doc) inherited the generic
  site-wide meta description. `handle_library_doc` now derives a page-specific
  meta description from the doc's frontmatter/body via `extract_doc_description`
  and threads it through `multi_docs` -> `docpage`.
- Titles came from the title-cased filename, rendering "Barchart" instead of
  "Bar Chart". Docs now honor an explicit frontmatter `title:` for a clean,
  keyword-rich page title (and sidebar label).

Each chart page gains a `title:` and a keyword-rich `meta_description:`
(Recharts + Python + chart type), and the intro prose mentions Reflex,
Recharts, and pure Python naturally. The Plotly and Pyplot pages get the same
treatment (pyplot targets "pyplot", 1.5K/mo).

Adds `meta_description`/`description` to the docgen frontmatter known-keys so
they aren't misparsed as component-preview lambdas, with regression tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
…docs

Broaden the chart docs beyond "recharts X chart" to the general graphing
terms people actually search, and fix term mismatches surfaced by keyword
data:

- Scatter page now leads with "scatter plot" (31K/mo) alongside "scatter
  chart" — the page was titled for the less-searched phrasing.
- Pie page calls out "donut chart" (1.9K/mo, KD 3) in the intro.
- Radar page calls out its "spider chart" synonym (radar chart's parent
  topic in Ahrefs).
- Plotly meta description now names the winnable Plotly long-tail
  (Plotly Express, heatmaps, histograms) rather than the KD 47-57 head.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
The Plotly page ranked for essentially nothing (only "reflex charts", vol 10)
despite a cluster of low-difficulty Plotly Express terms — plotly express
(450, KD 12), plotly heatmap (250, KD 2), plotly scatter plot (200, KD 8),
plotly bar chart (150, KD 4), plotly pie chart (90, KD 2). The page only
demonstrated a line chart, a 3D surface, and state usage, so it had no on-page
content matching those queries.

Add a "Plotly Express Chart Types" section with runnable bar, scatter, pie,
and heatmap examples (offline px.data datasets), giving the page keyword-aligned
headings and code for the terms above.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
Research surfaced two more winnable, Plotly-native terms with no matching
on-page content: histogram python (1.1K/mo, KD 11, traffic potential 11K)
and box plot python (KD 22). Add px.histogram and px.box examples to the
Plotly Express section.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
Per-page SEO audit found 6 of 10 chart docs had no internal links and the
rest had only one, so the sibling pages passed no anchor-text signal or link
authority to each other. Add a keyword-anchored "Related Charts" section
(3 related chart types each) to every chart page that lacked cross-links.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
The per-page SEO audit flagged three pages as too thin to rank well
(94/122/175 words of prose). Deepen each with explanation and, where useful,
a second worked example:

- Composed Chart: add "When to Use" guidance and a dual-axis bar+line example
  (y_axis_id), plus a Related Charts section.
- Error Bar: explain symmetric vs asymmetric [low, high] errors and the
  direction prop, and add an error-bars-on-a-line-chart example.
- Radial Bar Chart: de-duplicate the definition and add a "When to Use"
  section covering inner/outer radius, start/end angle, min_angle, background.

All added demo blocks use valid Recharts APIs (Line accepts ErrorBar; Bar/Line
support y_axis_id) and parse cleanly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
The sidebar labelled chart pages from the filename key via get_display_name,
so single-word filenames rendered as "Areachart", "Composedchart", etc. —
the frontmatter title fix only reached the page <title>, not the nav, because
the sidebar reads clist[0] (also used to build the URL).

Record each doc's frontmatter title in a filename-keyed map and have the
sidebar prefer it for the label while still deriving the link from the
filename. Sidebar now shows "Area Chart", "Composed Chart", etc., with URLs
unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
…bo, react)

Keyword research surfaced high-volume, low-difficulty terms that map to
existing Recharts features but had no on-page content:

- Bar chart: add a Stacked Bar Chart example (stack_id) targeting "stacked
  bar chart" (5.4K/mo, KD 0) plus "segmented"/"100 stacked"; note grouped/
  clustered on the multiple-bars section and horizontal on the vertical-layout
  section ("grouped bar chart" 1.1K, "clustered" 1.3K, "horizontal" 1.2K).
- Radial bar: frame the half-circle example as a gauge chart ("gauge chart"
  2.8K/mo, KD 6).
- Area: rename the stacking section to "Stacked Area Chart" ("stacked area
  chart" 1K, KD 5).
- Composed: note the "combo chart" synonym (600/mo).
- Line: note "multi-line chart".
- All chart pages: describe Recharts as "a React charting library" so the
  pages also match react bar/line/pie chart intent (Reflex compiles to React).

Bar and radial-bar meta descriptions updated with the new terms. All demo
blocks parse and frontmatter is valid YAML.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
Two more high-traffic, on-Recharts opportunities with no existing content:

- Bubble chart (5.5K/mo, KD 14): a scatter chart with a z_axis controlling
  point size. Add a "Bubble Chart" example to the scatter page and mention it
  in the meta description.
- Treemap (rx.recharts.treemap ships in Reflex but had no doc page): new
  treemap.md targeting "treemap chart" (1K/mo, KD 28) / "python treemap",
  with a simple example and an aspect_ratio example.

Verified rx.recharts.z_axis (data_key + range) and ScatterChart's valid
children include ZAxis; Treemap exposes data/data_key/name_key/aspect_ratio.
All demo blocks parse and frontmatter is valid YAML.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
The /library/graphing/general/ URL had no backing content — the sidebar's
"Overview" link pointed at an unbacked route. Add a real overview page there,
targeting category terms (python data visualization, python charts, python
dashboard, recharts) and acting as an internal-linking hub to every chart
type, the general customization components, and the Plotly/Pyplot pages.

Library section index.md files are now excluded from handle_library_doc (they
were being mis-registered as components, which would add a stray sidebar item
with a broken link) and render as normal docs instead, matching how the
enterprise section index pages already work. A manual title gives the page a
keyword-rich <title>.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
@codspeed-hq

codspeed-hq Bot commented Jul 2, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing claude/plotly-charts-seo-o8sxyy (397887a) with main (a73404a)

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.

@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR performs an SEO pass across the Recharts-based graphing documentation: adding keyword-rich title and meta_description frontmatter to every chart page, new examples (stacked bar, bubble/scatter, treemap, Plotly Express chart types), "Related Charts" cross-links, and a new Treemap page for the previously undocumented rx.recharts.Treemap component.

  • Framework changes: handle_library_doc now reads frontmatter to emit page-specific meta descriptions and human-friendly titles (e.g. "Bar Chart" instead of "Barchart"); a new library_display_titles module-level dict is populated during doc processing and used by the sidebar builder via the same deferred-import pattern already in place. meta_description/description were added to _KNOWN_KEYS in the reflex_docgen frontmatter parser so they are not misparsed as component-preview lambdas.
  • Content: Frontmatter titles and meta descriptions added to all chart pages; new stacked bar, bubble chart, dual-axis composed chart, error-bar-on-line, and Plotly Express examples; "Related Charts" sections across all pages; new treemap.md page. All APIs verified against component source.

Confidence Score: 5/5

Safe to merge — all Python changes are additive and narrowly scoped to doc metadata extraction and sidebar label rendering.

The Python changes are small: a new module-level dict populated during startup, a deferred import following the existing pattern in the sidebar, and a one-line addition to _KNOWN_KEYS in the docgen parser. All component API usages in the new examples were verified against the component source. Tests cover both the parser fix and the description extraction fallback. No existing paths are altered.

No files require special attention.

Important Files Changed

Filename Overview
docs/app/reflex_docs/pages/docs/init.py Adds library_display_titles dict and populates it from frontmatter title: in handle_library_doc; correctly threaded into multi_docs call. Logic and ordering look correct.
docs/app/reflex_docs/templates/docpage/sidebar/sidebar_items/component_lib.py Uses a deferred from reflex_docs.pages.docs import library_display_titles inside get_category_children, consistent with the existing pattern for component_list and graphing_components. Lookup with fallback to get_display_name is correct.
docs/library/graphing/charts/treemap.md New page documenting rx.recharts.Treemap. Props (data_key, name_key, aspect_ratio) verified against component source. rx.color() inside data dicts matches the established pattern used in piechart.md and radialbarchart.md.
docs/library/graphing/other-charts/plotly.md Added six Plotly Express examples (bar, scatter, pie, heatmap, histogram, box plot) using px.data built-in datasets; all use demo exec code blocks and rx.plotly(data=fig) correctly.
docs/library/graphing/charts/composedchart.md New dual-axis composed chart example; y_axis_id on bar/line and orientation=right on the second y_axis are valid props verified against component source.
docs/library/graphing/charts/scatterchart.md New bubble chart section using rx.recharts.z_axis(); data_key, range, and name props verified against ZAxis component source.
tests/units/docgen/test_markdown.py Added test_meta_description_not_treated_as_preview confirming meta_description/description stay in frontmatter.metadata and don't become component-preview lambdas; correct and covers the newly added _KNOWN_KEYS entries.
docs/app/tests/test_doc_description.py New test validates the regex fallback path of extract_doc_description handles the components: list + meta_description: pattern without treating component names as description content.
docs/app/reflex_docs/pages/library_previews.py Updated three graphing section descriptions to be more keyword-rich and accurate; purely cosmetic/copy change.

Reviews (5): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

Comment thread docs/app/reflex_docs/pages/docs/__init__.py
claude added 3 commits July 2, 2026 22:38
- Duplicate route: the section root /library/graphing/general/ is already
  served by the create_previews gallery page, so the new index.md collided
  (test_unique_routes). Remove index.md and its routing bypass; instead give
  the existing preview pages real meta descriptions by passing `description`
  into their docpage, clean up their <title>, and make the charts/general/
  other-charts descriptions keyword-rich (python charts, data visualization,
  recharts, plotly, matplotlib).
- changelog: add a news fragment for the reflex-docgen parser fix.

Also addresses two review comments (same as #6704): low-level docpages no
longer emit a duplicate meta description, and multi_docs reuses the source
already read in handle_library_doc instead of re-reading the file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
fm.metadata is typed Mapping[str, object]; coerce the value to str before
calling .startswith so pyright (pre-commit) passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
The test extracts meta_description from the frontmatter block, not the body;
rename from _from_body to _from_frontmatter to match (review nit).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
#6702 (an earlier Plotly-only SEO PR) overlaps this PR on plotly.md and is a
subset of it, except for a stronger, keyword-rich H1 and a richer intro.
Adopt those here so this PR fully supersedes #6702:

- H1: "Plotly" -> "Plotly in Python: Interactive Charts with Reflex"
- Intro rewritten to lead with the Plotly link, name the figure types, and
  note the no-JavaScript / live-state angle.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR
@adhami3310 adhami3310 added the documentation Improvements or additions to documentation label Jul 3, 2026
carlosabadia pushed a commit that referenced this pull request Jul 3, 2026
* docs: SEO optimization for tables and data grids

Optimize the tables & data grids docs, grounded in Ahrefs keyword data:

- Data Table: target "data table" (16K/mo), "python table" (KD 0), "react
  data table", "pandas table"; keyword-rich intro + meta description.
- Data Editor: target "datagrid"/"react data grid", "glide data grid" (exact
  match, KD 1), "editable table", "spreadsheet"; intro + meta description.
- Table: target "react table"/"react table component", "table component".
- New overview page at /library/tables-and-data-grids/ (the section root had
  no content) targeting "data table"/"python table"/"data grid" and linking
  to all three components.
- "Related" cross-links between the three pages.

Supporting docs-infra (shared with the graphing SEO PR #6703): thread a
page-specific meta description through multi_docs (library docs previously
inherited the generic site-wide description); add meta_description/description
to the docgen frontmatter known-keys so they aren't parsed as component
previews; render library index.md as a normal doc so section overview pages
work.

Note: I could not run the full pytest suite / reflex compile in the sandbox
(pinned Python toolchain unavailable); validated ruff, YAML, and links.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR

* fix: resolve CI failures on tables/data-grids SEO

- Duplicate route: the section root /library/tables-and-data-grids/ is already
  served by the create_previews gallery page, so the new index.md collided
  (test_unique_routes). Remove index.md and its routing bypass; instead give
  the existing preview page a real meta description by passing `description`
  into its docpage (it was only used as visible body text before), clean up
  its <title>, and make the tables description keyword-rich.
- changelog: add a news fragment for the reflex-docgen parser fix.

Also addresses two review comments:
- Low-level docpages no longer emit a duplicate meta description (a
  "(low-level API reference)" qualifier differentiates them).
- multi_docs reuses the source already read in handle_library_doc instead of
  re-reading the markdown file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez43BK9AhhMPMdRcFmMEPR

---------

Co-authored-by: Claude <noreply@anthropic.com>
…seo-o8sxyy

# Conflicts:
#	docs/app/reflex_docs/pages/docs/__init__.py
@carlosabadia carlosabadia marked this pull request as ready for review July 3, 2026 08:29
@carlosabadia carlosabadia requested a review from a team as a code owner July 3, 2026 08:29
@carlosabadia carlosabadia merged commit 3280121 into main Jul 3, 2026
108 checks passed
@carlosabadia carlosabadia deleted the claude/plotly-charts-seo-o8sxyy branch July 3, 2026 08:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants