You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(routing): restructure URLs to /{specId}/{language}/{library} (#5289)
Move language from a top-level URL prefix (`/python/...`) to a middle
segment so the spec slug becomes the canonical SEO entity:
/{specId} cross-language hub
/{specId}/{language} language overview
/{specId}/{language}/{library} implementation detail
Interactive view collapses into the detail page as an in-place toggle
(`?view=interactive`). Legacy `/python/*` and `/python/interactive/*`
paths fall through to NotFoundPage with no redirects.
Backend: `Library.language` column (default "python"), threaded
through `ImplementationResponse`, `LibraryInfo`, `PlotImage`, `TopImpl`,
`RelatedSpecItem`, `PlotOfTheDayResponse`. Sitemap now emits all three
URL tiers; SEO proxy and OG image routes restructured accordingly.
Frontend: `specPath(specId, language?, library?)` builds the dynamic
path; `RESERVED_TOP_LEVEL` blocks slug collisions. `MastheadRule` and
`useAnalytics` parse path segments instead of hard-coding `/python`.
`InteractivePage` removed; iframe logic merged into `SpecDetailView`.
Subdomain: `python.anyplot.ai` server block added with an internal
nginx rewrite for the SEO bot path (canonical points back to
anyplot.ai). Human SPA path still needs hostname-aware route resolution
before flipping DNS.
Workflow: `spec-create.yml` rejects spec IDs that collide with reserved
top-level routes.
https://claude.ai/code/session_01Sd9QoGJfcNU8yEhsQixDCV
---------
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: .github/workflows/spec-create.yml
+11Lines changed: 11 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -286,6 +286,17 @@ jobs:
286
286
exit 1
287
287
fi
288
288
289
+
# Reserved spec slugs collide with top-level frontend routes.
290
+
# Keep this list in sync with `RESERVED_TOP_LEVEL` in app/src/utils/paths.ts.
291
+
RESERVED_SLUGS=(plots specs libraries palette about legal mcp stats debug api og sitemap.xml robots.txt)
292
+
for reserved in "${RESERVED_SLUGS[@]}"; do
293
+
if [[ "$SPEC_ID" == "$reserved" ]]; then
294
+
echo "::error::Spec ID '$SPEC_ID' collides with reserved top-level route. Choose a different slug."
295
+
gh issue comment ${{ github.event.issue.number }} --body "**Error:** Generated spec ID \`${SPEC_ID}\` collides with a reserved top-level route. Please rename the issue with a more specific title and re-trigger."
0 commit comments