From c9182512e513ed664fbf65c1cb5befdb3d889d68 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 22 Aug 2026 09:24:14 +0000 Subject: [PATCH 1/2] fix(seo): add recommended licensing fields to ImageObject JSON-LD Search Console flagged every implementation page's ImageObject for four missing recommended fields of the image-metadata rich result: creator, copyrightNotice, creditText, and acquireLicensePage. The bot-page SoftwareSourceCode image node now carries all four beside the existing license field, with /legal (the page stating the MIT terms) as the acquire-license page. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01HzepMnRdGbhmH7kdUyMukG --- CHANGELOG.md | 6 ++++++ api/routers/seo.py | 7 +++++++ tests/unit/api/test_seo_helpers.py | 10 ++++++++++ 3 files changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3d90acc2f..0f88d61345 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,12 @@ aggregate instead: an italic *Catalog* line at the end of the version section an ### Fixed +- **Image structured data carries the licensing fields Google recommends** — Search + Console flagged every implementation page's `ImageObject` for missing `creator`, + `copyrightNotice`, `creditText`, and `acquireLicensePage`. The bot-page JSON-LD now + ships all four (creator/credit: anyplot; MIT copyright notice; `/legal` as the + license page), completing the image-metadata rich result beside the existing + `license` field. - **Top-rated thumbnails follow the theme** — the stats page picks a preview per theme, but `/insights/dashboard` never shipped one: its `TopImpl` response model carried only the legacy `preview_url` (a synonym for the light render), so the top-rated grid showed diff --git a/api/routers/seo.py b/api/routers/seo.py index 9fc123b4cb..4824dd6d3b 100644 --- a/api/routers/seo.py +++ b/api/routers/seo.py @@ -583,6 +583,13 @@ def _build_source_code_node(spec, impl, lib_name: str, lang_name: str, page_url: "encodingFormat": "image/png", "caption": f"{spec.title} rendered with {lib_name}", "license": "https://opensource.org/licenses/MIT", + # Google's image-metadata rich result recommends these four beside + # `license`; Search Console flags each absence per page. /legal is + # the page that states the MIT terms the renders are offered under. + "acquireLicensePage": "https://anyplot.ai/legal", + "creator": {"@type": "Organization", "name": "anyplot", "url": "https://anyplot.ai"}, + "creditText": "anyplot.ai", + "copyrightNotice": "© anyplot.ai — MIT License", } if impl.updated: node["dateModified"] = impl.updated.date().isoformat() diff --git a/tests/unit/api/test_seo_helpers.py b/tests/unit/api/test_seo_helpers.py index 037116b6d0..3e6d070555 100644 --- a/tests/unit/api/test_seo_helpers.py +++ b/tests/unit/api/test_seo_helpers.py @@ -420,6 +420,16 @@ def test_jsonld_image_is_the_render_not_the_card(self) -> None: assert image["contentUrl"] == "https://gcs/preview.png" assert image["thumbnailUrl"] == "https://gcs/preview_1200.png" + def test_jsonld_image_carries_licensing_metadata(self) -> None: + """Google's image-metadata rich result recommends these beside `license`; + Search Console flags each missing one per page (2026-08 notice).""" + image = _extract_jsonld(self._page())["@graph"][1]["image"] + assert image["license"] == "https://opensource.org/licenses/MIT" + assert image["acquireLicensePage"] == "https://anyplot.ai/legal" + assert image["creator"] == {"@type": "Organization", "name": "anyplot", "url": "https://anyplot.ai"} + assert image["creditText"] == "anyplot.ai" + assert image["copyrightNotice"] == "© anyplot.ai — MIT License" + def test_jsonld_without_render_keeps_card_image(self) -> None: impl = _mock_impl("matplotlib", "python", preview=None) spec = _mock_spec([impl]) From c34dabff2211a63cc2c07924b2ca60ddea87a949 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 22 Aug 2026 09:24:54 +0000 Subject: [PATCH 2/2] docs(changelog): add PR ref to image-metadata entry Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01HzepMnRdGbhmH7kdUyMukG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f88d61345..81b7287026 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,7 +37,7 @@ aggregate instead: an italic *Catalog* line at the end of the version section an `copyrightNotice`, `creditText`, and `acquireLicensePage`. The bot-page JSON-LD now ships all four (creator/credit: anyplot; MIT copyright notice; `/legal` as the license page), completing the image-metadata rich result beside the existing - `license` field. + `license` field (#10537). - **Top-rated thumbnails follow the theme** — the stats page picks a preview per theme, but `/insights/dashboard` never shipped one: its `TopImpl` response model carried only the legacy `preview_url` (a synonym for the light render), so the top-rated grid showed