fix(docs): SEO improvements - #1858
Conversation
Four of the errors in the September Ahrefs Site Audit of langfuse.com land on python.reference.langfuse.com, and all four come from how pdoc's output is generated rather than from the SDK. pdoc writes an `index.html` that is only a `<meta http-equiv="refresh">` stub, because a single root module makes `langfuse.html` the entry point. That stub has no title, no links and no canonical URL, so `/` and `/index.html` read as duplicate, soft-redirecting pages. Worse, the host serves that same stub with a `200` for *any* unmatched path when the output contains no `404.html`, so every stale or mistyped URL becomes another indexable copy of it -- which is how two nonexistent `…/concepts/models.md` paths ended up in the crawl. Separately, pdoc inlines the full source of every symbol, which put `langfuse.html` at 2.7 MB, over the crawler's 2 MB limit and slow for readers. - `pdoc-templates/index.html.jinja2` sets `root_module_name` to false, the escape hatch pdoc's own template documents, and fills the main column, so `/` is a real landing page: title, description, canonical, and links to `langfuse`, `langfuse.experiment` and `langfuse.api`. - `pdoc-templates/module.html.jinja2` adds a self-referencing canonical to every module page, without the `.html` suffix -- the site is served with clean URLs, so `/langfuse.html` 308-redirects to `/langfuse` and a canonical pointing there would point at a redirect. - `pdoc-templates/404.html` is copied into the output so unmatched paths get a real 404 instead of a 200. - `--no-show-source` takes `langfuse.html` from 2.7 MB to 484 KB. `--edit-url` replaces the inline source with a link to the module on GitHub. `scripts/build_reference_docs.sh` wraps all of this, so the published site cannot be built correctly by accident; CONTRIBUTING.md and AGENTS.md now point at the script instead of the raw pdoc command. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@claude review |
There was a problem hiding this comment.
Claude Code Review
No review was started: this request came from a bot account. Manual reviews can only be requested by someone with write access to this repository. Ask a maintainer to comment @claude review, or have your automation post the comment from a user account with write access.
Tip: disable this comment in your organization's Code Review settings.
…ailing slash Review follow-ups on the reference-site build: - `PDOC_CANONICAL_BASE_URL` was concatenated straight onto the module path, so an origin given without a trailing slash (`https://staging.example.com`, a perfectly valid form) produced `https://staging.example.comlangfuse` on every module page -- the same class of broken canonical this change exists to fix. The base URL is now normalized to exactly one trailing slash. - `OUT_DIR` was captured before the script cd'd to the repo root, so a relative output path resolved against the repo instead of the caller's directory. Relative paths are now made absolute first. - Recorded why the landing-page links keep their `.html` suffix, so the next reader does not mistake it for an oversight. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Addressed the review in aa1ba78 — two of the three suggestions taken, one declined with reasoning. Fixed: canonical base URL could merge into the path. Both reviewers flagged this and they were right. Before the fix the last two would have been Fixed: relative Declined: landing-page links keeping the
A 308 is cached and passes full signal, so one hop on an internal link is cheap; a canonical pointing at a redirect is not, which is why the canonicals do drop the suffix. Added a comment in the template recording that distinction so it does not read as an oversight. Re-verified after the changes: 50/50 pages have a title and a clean-URL canonical, |
Four of the errors in the September Ahrefs Site Audit of langfuse.com land on
python.reference.langfuse.com(the crawl runs in subdomains mode). None of them come from the SDK — all four come from how pdoc's output is generated and served.Important
This PR alone does not change the live site. The published build command lives outside this repo —
docs/is gitignored, and no workflow here references pdoc. Whoever owns the Cloudflare Pages project needs to point its build command atbash scripts/build_reference_docs.sh(output directorydocs). Details in "Deploying this" below.What's wrong
1.
/is a stub with no title, no links and no canonical. With a single root module, pdoc makeslangfuse.htmlthe entry point and writes anindex.htmlthat is nothing but a redirect:That accounts for three audit errors at once:
Title tag missing or empty,Page has no outgoing links, andDuplicate pages without canonical(/and/index.htmlare byte-identical with nothing marking either canonical).2. Every unmatched path returns that stub with HTTP 200. The host has no
404.htmlin the output, so it falls back to the landing page for anything it cannot match:Every stale or mistyped URL is therefore an indexable duplicate. That is how two paths that have never existed —
…/langfuse/concepts/models.mdand…/langfuse/api/concepts/models.md— ended up in the crawl as real pages. For comparison,js.reference.langfuse.comreturns a proper404for the same request.3.
/langfuseis 2.7 MB. pdoc inlines the full source of every symbol. That is over Ahrefs' 2 MB crawl limit, so the single most important page on the reference site is not crawled at all — and it is slow for readers regardless of crawlers.The fix
pdoc-templates/index.html.jinja2setsroot_module_nameto false — the escape hatch pdoc's own template documents — and fills the main column, which pdoc's version leaves empty/becomes a real landing page: title, meta description, canonical, and links tolangfuse,langfuse.experiment,langfuse.apiplus the docs, GitHub and PyPIpdoc-templates/module.html.jinja2adds a self-referencing canonical to every module pagepdoc-templates/404.htmlis copied into the output--no-show-source, with--edit-urladding a GitHub source link per module in its placelangfuse.html2.7 MB → 484 KBscripts/build_reference_docs.shwraps all of the aboveOn (2): the
.htmlsuffix is deliberately dropped from the canonical. The site is served with clean URLs, and/langfuse.html308-redirects to/langfuse— so a canonical pointing at the.htmlpath would point at a redirect, which is its own audit error:On (4): losing the inline source is a real trade, which is why
--edit-urlis added alongside it — every module page now links to its source on GitHub (verified:/langfuse/__init__.pyand/langfuse/experiment.pyboth 200). 2.7 MB of HTML on one page is worse for readers than one click through to GitHub.PDOC_CANONICAL_BASE_URLoverrides the canonical origin for local or preview builds.Verification
bash scripts/build_reference_docs.sh <tmpdir>with pdoc 15.0.4, then served locally and driven in a browser.Every page now has a title and a clean-URL canonical:
Page sizes — nothing over 2 MB any more (was 2669 KB):
Search still works, and pdoc's restore-on-clear behaviour keeps the new landing content intact — the
contentblock writes intomain.pdoc, which is exactly what pdoc's search captures asoriginalContent:Rendered the landing page, a module page and the 404 page in a browser; all three look correct, logo and styling intact. Every link on the landing page checked: the three module targets exist in the output, and the three external links return 200.
uv run --frozen ruff check .passes,bash -n scripts/build_reference_docs.shclean. Nothing here is touched by the pre-commit hooks or CI (they cover Python underlangfuse/only).Deploying this
docs/is gitignored and no workflow in this repo builds it, so the published site is built from outside — the host is Cloudflare Pages (it strips.html, 308-redirects trailing slashes, and falls back to the landing page when no404.htmlexists;js.referenceby contrast is on Vercel).To make this PR take effect, the Pages project's build command needs to become:
with output directory
docs. If the site is instead deployed by hand, run that script beforewrangler pages deploy docs.Fix (3) — the
404.html— is the highest-value item, since it stops every stale URL from being indexed, not just the two the crawl happened to find.🤖 Generated with Claude Code
Greptile Summary
This PR adds a standardized pdoc reference-site build that generates an indexable landing page, clean canonical metadata, a static 404 response, smaller module pages, and GitHub source links. It also updates contributor guidance to require the new build script.
Confidence Score: 4/5
The PR should not merge until alternate canonical origins are normalized, because the documented override can generate incorrect metadata across every module page.
The default production origin works, but supplying the documented override without a trailing slash concatenates the hostname and module name, breaking all generated module canonicals for that build.
Files Needing Attention: pdoc-templates/module.html.jinja2
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR Script["build_reference_docs.sh"] --> Pdoc["pdoc 15.0.4"] Templates["pdoc-templates"] --> Pdoc Pdoc --> Index["docs/index.html"] Pdoc --> Modules["docs/module pages"] ErrorPage["pdoc-templates/404.html"] --> Copy["Copy step"] Copy --> NotFound["docs/404.html"] Index --> Pages["Cloudflare Pages output"] Modules --> Pages NotFound --> PagesPrompt To Fix All With AI
Reviews (1): Last reviewed commit: "fix(docs): make the generated reference ..." | Re-trigger Greptile