Skip to content

feat: new docs design#2505

Open
wassimoo wants to merge 238 commits intomasterfrom
una-redesign-imp2
Open

feat: new docs design#2505
wassimoo wants to merge 238 commits intomasterfrom
una-redesign-imp2

Conversation

@wassimoo
Copy link
Copy Markdown
Contributor

@wassimoo wassimoo commented Apr 10, 2026

Preview link: https://docs-rfbjzxqwi-ory.vercel.app/docs

Summary

This PR delivers a significant redesign of the Ory documentation site, introducing a new Homepage navigation experience, a new Quick Start page, restructured content architecture, and visual design improvements. It also establishes the foundational framework for separating documentation by deployment model: Ory Network, Ory OEL, and Ory OSS.

Changes

Homepage navigation

Replaced the previous homepage with a guided navigation experience that helps technical evaluators and developers orient quickly and find the right entry point for their use case. (Aligns better with our marketing site.)

Quick Start page

Added a new Quick Start page as a dedicated onboarding path for developers getting started with Ory for the first time.

Content restructuring

Reorganized existing documentation to support clearer content hierarchy. This restructuring is a prerequisite for the deployment-model separation work.

Product overview

Added new high-level product explanations with visual elements to demonstrate how each product fits within the context of an IAM system.

Visual design enhancements

Updated layout, typography, and component styling throughout the portal for improved readability and consistency. Introduced product color association.

Deployment model framework

Introduced the structural scaffolding to separate documentation by deployment context — Ory Network, Ory OEL, and Ory OSS — enabling product-specific content targeting in follow-on PRs.

What's not included

Full content separation by deployment model is out of scope for this PR. This change puts the framework in place; content migration and product-specific pages will follow.
Complete alignment on product names is out of the scope of this PR.

TESTING

New feature documentation (last few months)

Verify your new content appears in the redesigned navigation (docs/sidebar.ts). If it doesn't appear, add it to the /docs/sidebar.ts.

NOTE: There are several new sidebar files located within the /docs folder; if your content was added to the previous sidebar.ts file located in /src that file is no longer in use.

Content is complete

Verify that your product area contains the expected full set of content. The restructure may have affected navigation visibility for some pages.

Broken links

Spot-check links in your product area. Internal navigation files were significantly changed in this redesign.

Checklist

  • [ X] I have read the contributing guidelines and signed the CLA.
  • I have referenced an issue containing the design document if my change introduces a new feature.
  • [X ] I have read the security policy.
  • [X ] I confirm that this pull request does not address a security vulnerability.
    If this pull request addresses a security vulnerability,
    I confirm that I got approval (please contact security@ory.com) from the maintainers to push the changes.
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added the necessary documentation within the code base (if appropriate).

Summary by CodeRabbit

  • New Features

    • Added interactive product architecture diagram and solution design questionnaire.
    • Added comprehensive quickstarts section with deployment and language filtering.
    • Added new welcome landing page with guided learning paths and framework selection.
    • Added OSS product documentation hub with reorganized sidebar structure.
  • Documentation

    • Updated documentation links and paths for consistency across guides.
    • Added product architecture reference guide.
  • Chores

    • Updated GitHub Actions to version 6 and Node.js runtime to version 24.
    • Added new React Flow library dependency for diagram components.
    • Updated navbar with new Quickstarts and Solutions sections.

sidebar_label: Scalability
---

import MyPartial from "@site/src/components/Shared/kratos/10_scalability.mdx"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Kratos Courier content is not applicable to Hydra.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is existing content that has a high level 'scalability' section that mentions Hydra. Apart from the Mail Courier sub-section, does the high level scalability sections still apply to Hydra?

@alnr
Copy link
Copy Markdown
Contributor

alnr commented Apr 13, 2026

This redesign mentions Polis in the context of SCIM and Enterprise SSO many times.

Polis only does SAML, nothing else.

REPLY: Please refer to Deepak, I'm 99.999999999% sure Polis support our SCIM functionality. See https://www.ory.com/polis

@alnr
Copy link
Copy Markdown
Contributor

alnr commented Apr 13, 2026

It is still very confusing for me to find concrete pages. Like for example Hydra Guides.

If I start on the OEL page (https://docs-7qgoc8ot0-ory.vercel.app/docs/oel/getting-started) and click Hydra in the sidebar, I have an option "Guides".

When I click that, I get a selection of "Running Hydra in Docker" and a couple others, but few details.

Whereas when I start on the Ory Network page (https://docs-7qgoc8ot0-ory.vercel.app/docs/network/getting-started) and click on Hydra in the Sidebar, I also see an option Guides. But that link leads me to a completely different set of Hydra Guides which actually explain how to use the product.

REPLY: The focus of this round is to create a separate framework for the different deployments. That is why Network has far more content. We have yet to write stuff for OEL. We reorganized the content and will start creating (or reusing/sharing) content where appropriate.

@hperl
Copy link
Copy Markdown
Collaborator

hperl commented Apr 13, 2026

Method: I (with Claude) diffed every kratos/* and identities/* doc id referenced by the old src/sidebar.ts on master against the new sidebar files (sidebars-network.ts, sidebars-oel.ts, sidebars-oss.ts, etc.). I also scanned all 200 pages under docs/kratos/ and docs/identities/ for broken internal file links.

Pages dropped from navigation

Doc ids present in the old src/sidebar.ts on master, absent from every new sidebar file in this PR:

# Doc id File Notes
1 console/single-sign-on docs/console/single-sign-on.mdx Ory Console SSO + break-glass recovery (#2471, #2491). No replacement. Clear regression. REPLY: Added feature /docs/console/single-sign-on
2 kratos/self-service/flows/CAPTCHA docs/kratos/self-service/flows/captcha.mdx Recently moved by the team in commit 4b3aa00c ("docs: moved and updated CAPTCHA challenge doc"). File still exists — just orphaned. Regression. REPLY: Added it back to Network sidebar nav /docs/kratos/self-service/flows/CAPTCHA
3 kratos/guides/e2e-integration-tests docs/kratos/guides/e2e-integration-tests.mdx E2E/integration test guide. No replacement found. Regression. REPLY: It is replaced and redirects to /docs/oss/guidelines/e2e-integration-tests
4 identities/index docs/identities/index.mdx "Introduction to Ory Kratos Identities" landing page. No replacement found. Regression. REPLY: It is replaced and redirects to /docs/network/kratos/intro
5 identities/get-started/index docs/identities/get-started/index.mdx "Identity management guide — Day 1 essentials". Was a category link in old sidebar; new sidebar uses identities/get-started/setup as first item and drops this. Regression. REPLY: Intentionally removed. Provided no concrete instructions.
6 kratos/mfa/overview docs/kratos/mfa/01_overview.mdx Likely intentionally superseded by network/kratos/mfa-overview (referenced as category link at sidebars-network.ts:302). Old file is now orphaned content — delete or redirect. REPLY: Correct, will delete later to avoid too many redirects at once.
7 kratos/manage-identities/overview docs/kratos/manage-identities/01_overview.mdx Likely intentionally superseded by network/kratos/identity_model (referenced at sidebars-network.ts:148). Old file is orphaned — delete or redirect. REPLY: Correct, will delete later to avoid too many redirects at once.

Pages correctly present in sidebars-network.ts

All of these were in the old sidebar and are still wired up:

  • Social sign-in providers: generic, ory, google, facebook, microsoft, github, apple, gitlab, auth0, salesforce, slack, spotify, discord, twitch, netid, yandex, vk, dingtalk, lark, patreon, linkedin, x-twitter, line, amazon, uaepass
  • Social sign-in concepts: data-mapping, account-linking, get-tokens, native-apps, oidc-pkce, fedcm, redirect-url
  • Flows: registration, login, logout, recovery, verification, settings, two-step-registration, identifier-first-authentication, code-submission-limit, login-hint
  • MFA: lookup-secrets, totp, webauthn-fido-yubikey, mfa-via-sms, step-up-authentication
  • Identity management: create/import/export, invite-users, account-recovery, identity-state, external-id, customize-identity-schema, managing-users-identities-metadata, identity-schema-selection
  • SCIM: ms-entra, okta, google-workspace
  • Passwordless: one-time-code, passkeys, passkeys-mobile, passwordless
  • Bring-your-own UI: custom-ui-overview, configure-ory-to-use-your-ui, custom-vs-built-in-ui, custom-ui-basic-integration, custom-ui-advanced-integration
  • Other: organizations, emails-sms, hooks, actions, concepts/redirects, session-management, personal-access-token

Other findings

Broken internal links

I ran a full resolver over every kratos/* and identities/* file: zero broken relative file links.

Two remaining cross-references target orphaned pages (they still resolve at build time, but land on pages with no navigation context):

  • docs/hydra/self-hosted/deploy-hydra-example.mdx:480../../identities/index.mdx REPLY: Now links to /docs/oel/kratos/intro
  • docs/kratos/organizations/organizations.mdx:421/docs/console/single-sign-on#break-glass-account-recovery REPLY: Link works now once 'console/single-sign-on' was added

Both self-resolve once regressions 1 and 4 are fixed.

Incoming references to superseded pages (#6, #7)

No .mdx file in the repo links to kratos/mfa/overview or kratos/manage-identities/overview. If the supersession is intentional, the old files should be removed and redirects added to avoid dead URLs for existing inbound links.
REPLY: Correct, will delete later to avoid too many redirects at once

Accidental files

sidebars-oel copy.ts and sidebars-oss copy.ts were added in commit cce4f15a and are not imported anywhere — they look like macOS Finder-style duplicates committed by accident. Safe to delete before merge. REPLY: Agreed, these were temporary backups and are deleted now.

@unatasha8
Copy link
Copy Markdown
Contributor

unatasha8 commented Apr 14, 2026

We have several hard failures for missing redirects, hard 404s, or potentially broken redirects because the H1 title changed of the redirected-to page.

url,expected_title,vercel_status,vercel_title
https://www.ory.com/docs/actions/live-events,Live event streams | Ory,404,
https://www.ory.com/docs/category/operations-reference,Operations | Ory,200,Scalability | Ory
https://www.ory.com/docs/console/change-owner,Change a project or workspace owner | Ory,404,
https://www.ory.com/docs/console/roles-and-permissions,Roles and permissions in the Ory Console | Ory,404,
https://www.ory.com/docs/console/usage-billing,Usage-based billing | Ory,404,
https://www.ory.com/docs/ecosystem/projects,Introduction | Ory,200,Introduction to Ory Open Source | Ory
https://www.ory.com/docs/ecosystem/sqa,Software quality assurance | Ory,200,Product telemetry and privacy | Ory
https://www.ory.com/docs/getting-started/ory-network-oauth2,Perform OAuth2 Authorization Code Grant and Client Credentials Grant | Ory,200,OAuth2 authorization code and client credentials grants | Ory
https://www.ory.com/docs/getting-started/overview,Quickstarts & Tutorials | Ory,200,Ory Documentation | Ory
https://www.ory.com/docs/guides/custom-domains,Set up custom domains | Ory,404,
https://www.ory.com/docs/guides/gitops,Manage Ory Network configuration in git | Ory,404,
https://www.ory.com/docs/guides/manage-project-via-api,Manage Ory Network projects through the API | Ory,404,
https://www.ory.com/docs/guides/oauth2-oidc,OAuth2 and OpenID Connect | Ory,404,
https://www.ory.com/docs/guides/operations,Operations | Ory,200,Scalability | Ory
https://www.ory.com/docs/guides/permissions/overview,Get started with Permissions in the Ory Network | Ory,200,Get started with Ory Keto | Ory
https://www.ory.com/docs/guides/workspaces,"Ory Network Workspaces, Projects, and Environments | Ory",404,
https://www.ory.com/docs/hydra/reference/configuration,Configuration | Ory,200,Configuration file | Ory
https://www.ory.com/docs/hydra/self-hosted/quickstart,Quickstart | Ory,200,Ory Hydra (OAuth2) Quickstart | Ory
https://www.ory.com/docs/identities,Introduction to Ory Kratos Identities | Ory,200,Introduction to Ory Kratos | Ory
https://www.ory.com/docs/intro,Ory Overview | Ory,200,Introduction to Ory Network | Ory
https://www.ory.com/docs/keto,Introduction to Ory Keto Permissions | Ory,200,Introduction to Ory Keto—Fine-grained Permissions | Ory
https://www.ory.com/docs/keto/examples/olymp-file-sharing,Basic: Olymp library | Ory,200,File sharing example | Ory
https://www.ory.com/docs/keto/quickstart,Quickstart: Cat Videos Example | Ory,200,Ory Keto Quickstart | Ory
https://www.ory.com/docs/keto/reference/configuration,Configuration | Ory,200,Configuration file | Ory
https://www.ory.com/docs/kratos/quickstart,Quickstart | Ory,200,Ory Kratos Quickstart | Ory
https://www.ory.com/docs/oathkeeper/guides/upgrade,Upgrade Ory Oathkeeper OSS | Ory,200,Upgrade Ory Oathkeeper OEL to a newer version | Ory
https://www.ory.com/docs/oathkeeper/reference/configuration,Configuration | Ory,200,Configuration file | Ory
https://www.ory.com/docs/oauth2-oidc,Introduction to Ory Hydra OAuth2 | Ory,200,Introduction to Ory Hydra—Delegated AuthZ & Federated AuthN | Ory
https://www.ory.com/docs/polis,Introduction to Ory Polis | Ory,200,Introduction to Ory Polis—Enterprise SSO AuthZ | Ory
https://www.ory.com/docs/polis/quickstart,Quickstart | Ory,200,Ory Polis Quickstart | Ory
https://www.ory.com/docs/security-compliance/compliance-and-certifications,Compliance and certifications | Ory,200,Security and compliance | Ory
https://www.ory.com/docs/self-hosted/oel/keto/configuration,OEL Configuration | Ory,200,Configuration file | Ory
https://www.ory.com/docs/self-hosted/oel/kratos/configuration,OEL Configuration | Ory,200,Configuration file | Ory
https://www.ory.com/docs/self-hosted/oel/oathkeeper/configuration,OEL Configuration | Ory,200,Configuration file | Ory
https://www.ory.com/docs/self-hosted/oel/oauth2/configuration,OEL Configuration | Ory,200,Configuration file | Ory
https://www.ory.com/docs/welcome,Welcome to Ory! | Ory,200,Ory Documentation | Ory

All of these have redirects in the vercel.json file. What are you doing to generate these as errors/404s etc?

@wassimoo
Copy link
Copy Markdown
Contributor Author

wassimoo commented Apr 14, 2026

@coderabbitai review again

@ory ory deleted a comment from coderabbitai bot Apr 14, 2026
@ory ory deleted a comment from coderabbitai bot Apr 14, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 14, 2026

@wassimoo Sure, I'll review the PR again now!

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 14, 2026

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{"name":"HttpError","status":404,"request":{"method":"PATCH","url":"https://api.github.com/repos/ory/docs/issues/comments/4243856473","headers":{"accept":"application/vnd.github.v3+json","user-agent":"octokit.js/0.0.0-development octokit-core.js/7.0.6 Node.js/24","authorization":"token [REDACTED]","content-type":"application/json; charset=utf-8"},"body":{"body":"<!-- This is an auto-generated comment: summarize by coderabbit.ai -->\n<!-- walkthrough_start -->\n\n<details>\n<summary>📝 Walkthrough</summary>\n\n## Walkthrough\n\nComprehensive restructuring of documentation from \"self-hosted\" to \"oss\" path structure with introduction of deployment-specific sidebars (Network, OEL, OSS). Adds interactive UI components for architecture diagrams, quickstart filtering, and solution design workflow. Updates theme styling, GitHub Actions versions, and Docusaurus configuration to support multiple deployment modes.\n\n## Changes\n\n|Cohort / File(s)|Summary|\n|---|---|\n|**GitHub Actions Updates** <br> `.github/workflows/closed_references.yml`, `.github/workflows/conventional_commits.yml`, `.github/workflows/labels.yml`|Updated GitHub Actions to use v6 versions for `checkout` and `setup-node`; bumped Node.js runtime from v14 to v24.|\n|**Documentation Path Restructuring** <br> `docs/hydra/self-hosted/*`, `docs/keto/guides/production.md`, `docs/kratos/*`|Updated documentation links from `self-hosted/deployment` or `ecosystem/configuring` paths to `oss/deployment` or `oss/configuring` equivalents across multiple product guides.|\n|**Documentation Files** <br> `docs/oss/index.md`, `docs/products/product-arch`, `docs/self-hosted/deployment.md`|Added new OSS index page and product architecture guide; removed (emptied) legacy self-hosted deployment doc. Introduced interactive Mermaid flowchart for product selection.|\n|**Sidebar Configuration** <br> `sidebars.ts`, `sidebars-*.ts` (OSS, OEL, Network, Quickstarts, etc.)|Restructured sidebar system with deployment-specific sidebars and new solution-based sidebars (CIAM, B2B, Agentic, Workforce). Created centralized sidebars.ts aggregating all configurations.|\n|**Docusaurus Core Config** <br> `docusaurus.config.ts`, `index.js`|Softened build link validation (throw → warn); updated Prism magic comments; adjusted footer UI and branding; replaced inline plugin config with structured setup; added Webpack polyfill plugin for Node.js compatibility.|\n|**Architecture Diagram Components** <br> `src/components/OryArchitectureDiagram.tsx`, `src/components/oryArchitectureDiagramModel.ts`, `src/components/solutionDesignDiagram/...`|Added interactive XYFlow-based architecture diagram with node/edge builders, layout modes (compact row), SCIM/identity logic, and product selection responsiveness. Includes custom edge and node renderers.|\n|**Quickstarts UI System** <br> `src/components/QuickStarts/*`, `src/contexts/QuickstartsDeploymentContext.tsx`|Introduced comprehensive quickstarts filtering UI with category, language, and deployment mode selectors; deployment-aware routing; example filtering; and React context for cross-component state.|\n|**Welcome Page Components** <br> `src/components/welcomePage/*`, `src/pages/welcome.tsx`|Created modular welcome page sections: hero demo, framework selector, solution stepper, deployment selector, content sections, guides, and footer with persistent session storage for solution design progress.|\n|**Styling and Theme** <br> `src/css/theme.css`, `src/components/Examples/example-list.module.css`, `src/components/OryNetworkCta/...`, `src/components/WelcomeCard/welcome-card.module.css`|Comprehensive theme overrides with Ory design tokens (colors, spacing, radius), typography/button/tag component classes, dark mode support, navbar/sidebar customization, responsive behavior, and CSS module updates for examples and cards.|\n|**Navigation and Plugin System** <br> `src/navbar.ts`, `src/plugins/productLinePlugin.ts`, `src/scripts/config.js`|Restructured navbar with dropdown menus for Products/Solutions/Reference, replaced \"Start\" with \"Home\" and \"Quickstarts\", added solution categories; introduced Remark plugin for product-line-conditional content; updated config script paths.|\n|**Content and Configuration** <br> `package.json`, `src/pages/_assets/examples-content.tsx`, `src/pages/_assets/welcome-content.tsx`, `.coderabbit.yaml`|Added `@xyflow/react` dependency; updated example docs links to relative paths; adjusted deployment cards (added Network card, updated paths); configured CodeRabbit to skip MDX reviews.|\n|**CSS Styling Assets** <br> `src/pages/_assets/product-selector-graph.module.css`, `src/pages/_assets/product-selector-stepper.module.css`|Added styled modules for interactive product selector components with Mermaid customization, dark mode overrides, and responsive grid/stepper layouts.|\n|**Component Utilities and Types** <br> `src/components/Shared/...`, `src/components/welcomePage/solutionDesignStepper/...`|Added shared product-specific components (AuthOverview, E2EIntegrationTests, DeploymentDatabase) and solution stepper support utilities (types, constants, storage helpers, product computation logic).|\n|**Demo and Refactored Components** <br> `src/components/OryHeroDemo.jsx`, `src/components/SidebarDeploymentModel/index.tsx`, `src/components/Welcome/welcome.tsx`, `src/components/ConfigMarkdown/index.tsx`|Added interactive terminal-style demo component; created sidebar deployment mode selector; refactored welcome page to use modular OverviewCard; updated internal documentation links.|\n\n## Estimated code review effort\n\n🎯 5 (Critical) | ⏱️ ~120 minutes\n\n## Poem\n\n> 🐰 *Hop, hop, hooray!* The docs now gleam with paths anew,\n> OSS sidebars bloom, and quickstarts dance through deployment's hue,\n> Architecture diagrams sparkle with interactive delight,\n> While welcome pages welcome warmly—oh, what a joyful sight! 🎉\n\n</details>\n\n<!-- walkthrough_end -->\n\n\n<!-- pre_merge_checks_walkthrough_start -->\n\n<details>\n<summary>🚥 Pre-merge checks | ✅ 2 | ❌ 1</summary>\n\n### ❌ Failed checks (1 warning)\n\n|     Check name     | Status     | Explanation                                                                           | Resolution                                                                         |\n| :----------------: | :--------- | :------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------- |\n| Docstring Coverage | ⚠️ Warning | Docstring coverage is 21.74% which is insufficient. The required threshold is 80.00%. | Write docstrings for the functions missing them to satisfy the coverage threshold. |\n\n<details>\n<summary>✅ Passed checks (2 passed)</summary>\n\n|     Check name    | Status   | Explanation                                                                                                                                                                     |\n| :---------------: | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n|    Title check    | ✅ Passed | The title 'feat: new docs design' clearly summarizes the main change—a comprehensive redesign of the documentation site—and is concise and descriptive.                         |\n| Description check | ✅ Passed | The PR description is comprehensive and well-structured, covering summary, changes (with section headers), testing guidance, checklist completion, and design document context. |\n\n</details>\n\n<sub>✏️ Tip: You can configure your own custom pre-merge checks in the settings.</sub>\n\n</details>\n\n<!-- pre_merge_checks_walkthrough_end -->\n\n<!-- finishing_touch_checkbox_start -->\n\n<details>\n<summary>✨ Finishing Touches</summary>\n\n<details>\n<summary>📝 Generate docstrings</summary>\n\n- [ ] <!-- {\"checkboxId\": \"7962f53c-55bc-4827-bfbf-6a18da830691\"} --> Create stacked PR\n- [ ] <!-- {\"checkboxId\": \"3e1879ae-f29b-4d0d-8e06-d12b7ba33d98\"} --> Commit on current branch\n\n</details>\n<details>\n<summary>🧪 Generate unit tests (beta)</summary>\n\n- [ ] <!-- {\"checkboxId\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Create PR with unit tests\n- [ ] <!-- {\"checkboxId\": \"6ba7b810-9dad-11d1-80b4-00c04fd430c8\", \"radioGroupId\": \"utg-output-choice-group-unknown_comment_id\"} -->   Commit unit tests in branch `una-redesign-imp2`\n\n</details>\n\n</details>\n\n<!-- finishing_touch_checkbox_end -->\n\n<!-- tips_start -->\n\n---\n\n\n\n<sub>Comment `@coderabbitai help` to get the list of available commands and usage tips.</sub>\n\n<!-- tips_end -->\n\n<!-- internal state start -->\n\n\n<!-- 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= -->\n\n<!-- internal state end -->"},"request":{"signal":{}}},"response":{"url":"https://api.github.com/repos/ory/docs/issues/comments/4243856473","status":404,"headers":{"access-control-allow-origin":"*","access-control-expose-headers":"ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset","content-encoding":"gzip","content-security-policy":"default-src 'none'","content-type":"application/json; charset=utf-8","date":"Tue, 14 Apr 2026 13:39:42 GMT","referrer-policy":"origin-when-cross-origin, strict-origin-when-cross-origin","server":"github.com","strict-transport-security":"max-age=31536000; includeSubdomains; preload","transfer-encoding":"chunked","vary":"Accept-Encoding, Accept, X-Requested-With","x-accepted-github-permissions":"issues=write; pull_requests=write","x-content-type-options":"nosniff","x-frame-options":"deny","x-github-api-version-selected":"2022-11-28","x-github-media-type":"github.v3; format=json","x-github-request-id":"82A0:284504:7C25E:1FC363:69DE439E","x-ratelimit-limit":"12500","x-ratelimit-remaining":"12438","x-ratelimit-reset":"1776177341","x-ratelimit-resource":"core","x-ratelimit-used":"62","x-xss-protection":"0"},"data":{"message":"Not Found","documentation_url":"https://docs.github.com/rest/issues/comments#update-an-issue-comment","status":"404"}}}

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

♻️ Duplicate comments (1)
docusaurus.config.ts (1)

19-20: ⚠️ Potential issue | 🟠 Major

Keep broken-link failures enabled in CI.

Line 19 and Line 20 remove the one automated check most likely to catch the navigation regressions this redesign is introducing. If CI uses the same config, broken links will ship silently. Gate this on process.env.CI instead of relaxing it globally.

Suggested change
-  onBrokenLinks: "warn",
-  onBrokenMarkdownLinks: "warn",
+  onBrokenLinks: process.env.CI ? "throw" : "warn",
+  onBrokenMarkdownLinks: process.env.CI ? "throw" : "warn",

Verify whether CI shares this config without an override. Expected result: CI builds should still fail on broken links even if local rebuilds only warn.

#!/bin/bash
set -euo pipefail

echo "Current broken-link policy in docusaurus.config.ts:"
sed -n '17,22p' docusaurus.config.ts

echo
echo "Any env-specific override already present?"
rg -n -C2 'onBrokenLinks|onBrokenMarkdownLinks|process\.env\.CI|CI' docusaurus.config.ts || true

echo
echo "Build commands in package scripts:"
if [ -f package.json ]; then
  rg -n -C2 'docusaurus build|npm run build|pnpm build|yarn build' package.json || true
fi

echo
echo "Build commands in GitHub workflows:"
if [ -d .github ]; then
  rg -n -C2 'docusaurus build|npm run build|pnpm build|yarn build' .github || true
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docusaurus.config.ts` around lines 19 - 20, The config currently sets
onBrokenLinks and onBrokenMarkdownLinks to "warn" globally; change this so CI
still fails: update the values for onBrokenLinks and onBrokenMarkdownLinks in
docusaurus.config.ts to use a conditional based on process.env.CI (e.g., use
"error" when process.env.CI is truthy, otherwise "warn") so local builds warn
but CI builds fail; locate the properties named onBrokenLinks and
onBrokenMarkdownLinks in the exported config object and replace the static
"warn" strings with the CI-gated expression.
🟠 Major comments (19)
.coderabbit.yaml-4-5 (1)

4-5: ⚠️ Potential issue | 🟠 Major

Global MDX exclusion removes review coverage from the docs surface.

Lines 4–5 exclude every *.mdx file, which suppresses review on the main docs content in a docs-focused repo/PR. This can hide navigation and link regressions.

Suggested adjustment
 reviews:
   review_status: false
-  # Temporarily exclude MDX files from review processing.
+  # Keep MDX in scope; only exclude generated/vendor artifacts if needed.
   path_filters:
-    - "!**/*.mdx"
+    - "!**/node_modules/**"
+    - "!**/build/**"
+    - "!**/.docusaurus/**"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.coderabbit.yaml around lines 4 - 5, The global path_filters entry currently
negates all MDX files via the pattern "!**/*.mdx", which removes review coverage
for docs; update the .coderabbit.yaml by removing or narrowing that exclusion
(e.g., delete the "!**/*.mdx" pattern or replace it with more specific
exclusions such as "!public/**.mdx" or an allow-list for your docs directory) so
that documentation MDX files are included in reviews; look for the path_filters
key and the pattern "!**/*.mdx" to make the change.
src/pages/_assets/product-selector-graph.module.css-25-25 (1)

25-25: ⚠️ Potential issue | 🟠 Major

Configure stylelint to allow CSS Modules :global() pseudo-class.

The file uses :global() selectors extensively (lines 25, 34, 41, 46–252) to style global Mermaid classes within the CSS Module. The stylelint configuration does not currently ignore the global pseudo-class, causing selector-pseudo-class-no-unknown to treat it as invalid and block CI.

Add the following to .stylelintrc.json:

"selector-pseudo-class-no-unknown": [
  true,
  {
    "ignorePseudoClasses": ["global"]
  }
]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/_assets/product-selector-graph.module.css` at line 25, The
Stylelint rule is flagging the CSS Modules :global() pseudo-class used in
selectors like ".graphContainer :global(.mermaid) :global(.cluster)"; update the
Stylelint config (in .stylelintrc.json) to allow the "global" pseudo-class by
adding "global" to the selector-pseudo-class-no-unknown ignorePseudoClasses
array so stylelint no longer treats :global as unknown.
src/pages/_assets/product-selector-graph.module.css-142-145 (1)

142-145: ⚠️ Potential issue | 🟠 Major

Remove redundant background shorthand declarations that conflict with background-color longhand.

The declaration-block-no-shorthand-property-overrides rule (enabled via stylelint-config-standard-scss) flags when a shorthand property overrides a longhand property in the same declaration block. The redundant background: transparent !important; should be removed from all four affected locations, keeping only background-color for clarity.

🩹 Proposed fix
 .graphContainer :global(.mermaid) :global(.edgeLabel) {
   background-color: transparent !important;
-  background: transparent !important;
   color: var(--ifm-color-emphasis-800) !important;
   font-size: 11px !important;
   font-weight: 600 !important;
@@
 .graphContainer
   :global(.mermaid)
   :global(.edgeLabel)
   :global(foreignObject)
   :global(div) {
   background-color: transparent !important;
-  background: transparent !important;
 }
@@
 :global([data-theme="dark"])
   .graphContainer
   :global(.mermaid)
   :global(.edgeLabel) {
   background-color: transparent !important;
-  background: transparent !important;
   color: var(--ifm-color-emphasis-100) !important;
   border: none !important;
 }
@@
 :global([data-theme="dark"])
   .graphContainer
   :global(.mermaid)
   :global(.edgeLabel)
   :global(foreignObject)
   :global(div) {
   background-color: transparent !important;
-  background: transparent !important;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/_assets/product-selector-graph.module.css` around lines 142 - 145,
Remove the redundant background shorthand that overrides the longhand
background-color in the CSS rule for .graphContainer :global(.mermaid)
:global(.edgeLabel) (and the three other similar selectors flagged in this
file); keep only background-color: transparent !important; and color as-is so
the declaration-block-no-shorthand-property-overrides lint rule is satisfied and
the longhand value is not shadowed by a subsequent background shorthand.
docs/products/product-arch-28-57 (1)

28-57: ⚠️ Potential issue | 🟠 Major

Mermaid diagram won’t render without a fenced block.

Line 28 starts Mermaid syntax directly, but it must be wrapped in a ```mermaid code fence to render.

Proposed fix
-flowchart TD
+```mermaid
+flowchart TD
     Start([What are you building?]) --> Q1{Need to manage<br>user identities?}
     
     Q1 -->|Yes| Kratos[✓ Kratos]
@@
     Q5 -->|Yes| Oathkeeper[✓ Add Oathkeeper]
     Q5 -->|No| Done([Your stack is ready])
     Oathkeeper --> Done
+```
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/products/product-arch` around lines 28 - 57, The Mermaid diagram
starting with "flowchart TD" (nodes like Start, Q1, Kratos, Polis, Hydra, Keto,
Oathkeeper, Done) must be wrapped in a fenced Mermaid code block; update the doc
so the entire diagram is enclosed between a starting ```mermaid line and a
closing ``` line (no other changes to node names or arrows), ensuring the exact
sequence from "flowchart TD" through "Oathkeeper --> Done" sits inside that
fence so the renderer can parse it.
docs/oss/index.md-1-4 (1)

1-4: ⚠️ Potential issue | 🟠 Major

Avoid shipping an empty OSS landing page.

With hide_title: true on Line 3 and no body content, this route renders as a blank page. Add at least a short intro (or remove hide_title) so /docs/oss is navigable.

Proposed fix
 ---
 title: Ory Open Source
 hide_title: true
 ---
+
+Welcome to Ory Open Source docs. Start with deployment, configuration, and product guides tailored for OSS users.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/oss/index.md` around lines 1 - 4, The OSS docs page currently contains
only frontmatter with hide_title: true which results in a blank route; either
add a short introductory paragraph below the YAML frontmatter in
docs/oss/index.md (e.g., a one- or two-sentence intro about the Ory open source
offering) or remove the hide_title: true key so the title is shown—update the
file so /docs/oss renders non-empty content.
src/components/Shared/kratos/e2e-integration-tests.tsx-18-41 (1)

18-41: ⚠️ Potential issue | 🟠 Major

Don't render a self-hosted setup example for the network product.

Lines 18–41 set commandPrefix to "ory" for Ory Network and "kratos" for self-hosted deployments. However, the surrounding text (lines 35–36) describes booting Ory Kratos locally with DSN=memory and a config file—a self-hosted setup that is incorrect for Ory Network, which is a managed service. Line 40 will produce ory serve -c ./path/to/config/kratos.yml --dev for the network branch, which is not a valid command pattern.

Additionally, line 76 contains a hardcoded hydra serve command (should be kratos serve or use the commandPrefix variable like line 40 does).

Either restrict this entire section to oel | oss products, or provide separate Network-specific instructions that don't assume self-hosted operation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/Shared/kratos/e2e-integration-tests.tsx` around lines 18 - 41,
The text and example command incorrectly present a self-hosted Kratos startup
for the "network" product by using commandPrefix (set to "ory" for network) and
a hardcoded "hydra serve" elsewhere; update the component so this section only
renders for self-hosted products (check product values "oel" | "oss") or split
into two branches: for self-hosted use the existing DSN=memory ${commandPrefix}
serve example (with commandPrefix set to "kratos") and for Network render an
explicit note and Network-specific instructions (no local serve command). Also
replace the hardcoded "hydra serve" occurrence to use the commandPrefix variable
or the correct "kratos serve" in the self-hosted branch and ensure the UI text
never suggests running a local Kratos server when product === "network".
src/components/QuickStarts/hooks/useClickOutside.ts-3-6 (1)

3-6: ⚠️ Potential issue | 🟠 Major

Accept nullable refs from callers.

Line 4 is typed as RefObject<HTMLElement>, but actual callers in DeploymentModeSelector.tsx and LanguageFilter.tsx use useRef<HTMLDivElement | null>(null), which yields RefObject<HTMLDivElement | null>. This causes a type mismatch. The hook implementation already safely handles null refs via the guard clause if (ref.current && ...) on line 14, but the signature should reflect this. Make the hook generic to accept nullable refs.

🛠️ Proposed fix
-export function useClickOutside(
-  ref: RefObject<HTMLElement>,
+export function useClickOutside<T extends HTMLElement>(
+  ref: RefObject<T | null>,
   isOpen: boolean,
   onClose: () => void,
 ) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/QuickStarts/hooks/useClickOutside.ts` around lines 3 - 6, The
hook signature for useClickOutside currently requires RefObject<HTMLElement> but
callers pass nullable refs; update the signature to accept nullable refs by
making the hook generic (e.g., useClickOutside<T extends HTMLElement | null>)
and change the ref parameter type to RefObject<T> (or RefObject<T | null>) so
callers using useRef<HTMLDivElement | null>(null) match; keep the existing
null-guard logic inside the function and ensure the generic is used in the
function definition and any exported typing to preserve callers' inferred
element type.
src/components/Shared/kratos/e2e-integration-tests.tsx-66-77 (1)

66-77: ⚠️ Potential issue | 🟠 Major

Fix the command snippet and update prose for environment variable value.

The code block has multiple issues:

  • Uses hydra serve instead of kratos serve
  • Stray ) at end of command
  • Indentation breaks shell syntax
  • Prose contradicts code by stating DEV_DISABLE_API_FLOW_ENFORCEMENT=1, but per Ory documentation, boolean environment variables require =true (or =false), not =1

Update both the prose and code block:

🛠️ Proposed fix
       <p>
         If you want to test React Native (rendered as a web application) in
         Cypress, you need to disable security features preventing browser from
         executing self-service API flows. To do this, set the environment
-        variable <code>DEV_DISABLE_API_FLOW_ENFORCEMENT=1</code>:
+        variable <code>DEV_DISABLE_API_FLOW_ENFORCEMENT=true</code>:
       </p>

       <CodeBlock language="sh">
         {`DSN=memory \\
-    DEV_DISABLE_API_FLOW_ENFORCEMENT=true
-    hydra serve -c ./path/to/config/kratos.yml --dev  > "kratos.e2e.log" 2>&1 &)`}
+DEV_DISABLE_API_FLOW_ENFORCEMENT=true \\
+kratos serve -c ./path/to/config/kratos.yml --dev > "kratos.e2e.log" 2>&1 &`}
       </CodeBlock>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/Shared/kratos/e2e-integration-tests.tsx` around lines 66 - 77,
Update the prose to say DEV_DISABLE_API_FLOW_ENFORCEMENT=true (not =1) and fix
the shell snippet inside the CodeBlock: replace the incorrect "hydra serve" with
"kratos serve", remove the stray trailing ")" and correct line
breaks/indentation so environment variables (DSN=memory and
DEV_DISABLE_API_FLOW_ENFORCEMENT=true) are exported/set before invoking kratos,
and ensure the kratos serve command uses the correct flags and
backgrounding/redirect syntax (e.g., proper use of & and redirections) so the
snippet is a valid shell command; locate and edit the CodeBlock component and
surrounding explanatory paragraph in kratos/e2e-integration-tests.tsx.
src/components/OryNetworkCta/ory-network-cta.tsx-17-21 (1)

17-21: ⚠️ Potential issue | 🟠 Major

Don't call useBaseUrl() conditionally.

Lines 17-21 invoke useBaseUrl() only when the imported asset is not a string. Since useBaseUrl is a React hook, this violates the Rules of Hooks—hooks must always be called unconditionally at the top level of a component. Move the useBaseUrl() call outside the conditional and reuse the result.

🛠️ Proposed fix
 export const OryNetworkCta = () => {
   const { title, description, ctaLabel, href } = CTA_CONFIG
+  const fallbackImageSrc = useBaseUrl("/img/network-cta/network.png")
   const imageSrc =
     typeof networkImg === "string"
       ? networkImg
-      : (networkImg as { default?: string }).default ??
-        useBaseUrl("/img/network-cta/network.png")
+      : (networkImg as { default?: string }).default ?? fallbackImageSrc
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/OryNetworkCta/ory-network-cta.tsx` around lines 17 - 21, The
component currently calls useBaseUrl() conditionally inside the imageSrc
expression which breaks the Rules of Hooks; call useBaseUrl once at the top of
the component (e.g., const baseNetworkImg =
useBaseUrl("/img/network-cta/network.png")) and then compute imageSrc using
networkImg and baseNetworkImg (use typeof networkImg === "string" ? networkImg :
(networkImg as { default?: string }).default ?? baseNetworkImg) so useBaseUrl is
invoked unconditionally and imageSrc logic is unchanged.
src/components/Shared/self-hosted/deployment.tsx-172-179 (1)

172-179: ⚠️ Potential issue | 🟠 Major

This shared section hard-codes OEL-only navigation into every deployment page.

DeploymentDatabase is shared across network, oel, and oss, but this block always renders OEL-specific copy. ./oel/high-performance-pooling resolves relative to the current page, and the #high-performance-pooling jump on Line 200 has no matching id on Line 172. Gate this section by product (or compute a deployment-aware destination) and add an explicit heading id.

Also applies to: 195-204

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/Shared/self-hosted/deployment.tsx` around lines 172 - 179, The
shared DeploymentDatabase component currently renders OEL-specific content
unconditionally and uses a relative ./oel/high-performance-pooling link plus a
mismatched anchor; update DeploymentDatabase to only render the
"High-performance pooling" block when product === "oel" (or compute a
deployment-aware destination based on the current page context), change the link
to an explicit deployment-aware path rather than a relative "./oel/..." URL, and
add a matching id attribute (e.g., id="high-performance-pooling") to the <h5>
heading so the `#high-performance-pooling` anchor works; ensure the same gating
and id fix is applied to the other repeated block around lines 195-204.
sidebars-quickstarts.ts-52-58 (1)

52-58: ⚠️ Potential issue | 🟠 Major

Don't send the Network sidebar into OEL docs.

This Ory Network Polis section mixes a Network landing page with an OEL quickstart. Following that second item switches deployment model from inside the Network sidebar and undermines the split-navigation structure this PR introduces. Keep this section network-only, or drop the second entry until a Network-specific quickstart exists.

🧭 Suggested fix
         items: [
           "network/polis/quickstarts/index",
-          "oel/polis/quickstarts/quickstart",
         ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sidebars-quickstarts.ts` around lines 52 - 58, The "Enterprise SSO AuthZ"
Network sidebar currently mixes Network and OEL content by including
"oel/polis/quickstarts/quickstart"; remove that entry from the items array
(leave only "network/polis/quickstarts/index") so the Network sidebar remains
network-only, or alternatively move the "oel/polis/quickstarts/quickstart" entry
into the appropriate OEL sidebar instead; update the items list in
sidebars-quickstarts.ts for the "Enterprise SSO AuthZ" category accordingly.
src/components/welcomePage/ContentSection.tsx-10-15 (1)

10-15: ⚠️ Potential issue | 🟠 Major

Use a stable Console signup URL here.

The flow= UUID is transient state. Baking it into a homepage CTA means this card will eventually send users to an expired registration flow instead of starting signup. Point this at a stable Console entry URL and let Console mint a fresh flow.

🔗 Suggested fix
-      to: "https://console.ory.sh/registration?flow=e27eca2b-ca8a-4722-8a4e-9c52a20aa0d4",
+      to: "https://console.ory.sh/registration",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/welcomePage/ContentSection.tsx` around lines 10 - 15, The "Ory
Console" card uses a transient registration flow URL (the `to` property
containing `flow=<UUID>`), which will expire; update the `to` value in the
object with label "Ory Console" inside ContentSection (the card definition) to a
stable Console entry URL (e.g., remove the `flow=` query and point to a
persistent entry like https://console.ory.sh/registration or
https://console.ory.sh/) so Console can mint a fresh flow when users click the
CTA.
sidebars.ts-7-10 (1)

7-10: ⚠️ Potential issue | 🟠 Major

Avoid importing Docusaurus internal src types.

Line 7 imports from @docusaurus/plugin-content-docs/src/sidebars/types, which is an internal module and not supported for public use. This can break on dependency updates. Use the public SidebarsConfig API instead.

🔧 Proposed refactor (public API only)
 import type { SidebarsConfig } from "@docusaurus/plugin-content-docs"
-
-import { SidebarItemConfig } from "@docusaurus/plugin-content-docs/src/sidebars/types"
-
-type SidebarItemsConfig = SidebarItemConfig[]
+type SidebarItemsConfig = SidebarsConfig[string]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sidebars.ts` around lines 7 - 10, Replace the internal import of
SidebarItemConfig with the public SidebarsConfig API: remove the import from
"@docusaurus/plugin-content-docs/src/sidebars/types" and instead import
SidebarsConfig from the public package (e.g.,
"@docusaurus/plugin-content-docs"), then update the type alias
SidebarItemsConfig to use the public SidebarsConfig type (or derive the specific
item type from SidebarsConfig if you need a narrower shape) so the file no
longer depends on internal src types.
sidebars-oss.ts-55-60 (1)

55-60: ⚠️ Potential issue | 🟠 Major

Keep the OSS sidebar inside OSS/shared docs.

These entries live under “Ory Open Source” but send users to oel/... and self-hosted/oel/... pages. That makes the new deployment split feel broken as soon as someone clicks into a product from the OSS nav.

Also applies to: 134-142, 205-211, 251-255, 427-430

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sidebars-oss.ts` around lines 55 - 60, The OSS sidebar currently contains
entries that reference OEL pages ("oel/kratos/intro", "kratos/install",
"self-hosted/oel/kratos/upgrade", "self-hosted/oel/kratos/changelog",
"oel/kratos/quickstart") which breaks the OSS/shared split; move or replace
these entries so the OSS sidebar only links to OSS/shared docs — either remove
them from the OSS sidebar array and add equivalent links to the OEL/self-hosted
sidebar, or update the ids to the correct OSS/shared ids, and apply the same fix
for the other occurrences noted (the other blocks that reference "oel/..." or
"self-hosted/oel/..."). Ensure the references in the sidebar data structure (the
items with type: "ref" and string IDs) point to the proper namespace
(OSS/shared) or are relocated to the OEL sidebar.
src/navbar.ts-30-31 (1)

30-31: ⚠️ Potential issue | 🟠 Major

Make the Products dropdown target absolute.

Unlike the other top-level dropdowns, this to value is relative. From a nested docs page it will resolve against the current URL instead of /docs/products/products-overview.

Suggested fix
-      to: "products/products-overview",
+      to: "/docs/products/products-overview",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/navbar.ts` around lines 30 - 31, The Products dropdown entry currently
uses a relative `to` value ("products/products-overview") which can resolve
incorrectly from nested docs pages; update the dropdown item (the object with
type: "dropdown" and its `to` property in src/navbar.ts) to use the absolute
docs path (e.g. "/docs/products/products-overview") consistent with the other
top-level dropdowns so it always targets the correct top-level products overview
page.
src/components/QuickStarts/quickstart-filter.tsx-107-124 (1)

107-124: ⚠️ Potential issue | 🟠 Major

Clamp language to the current category.

The effect mirrors any ?language= value into state without checking availableLanguages. After a category/deployment change, a stale language can blank out filteredByLanguage, and if the new category only has one language the picker disappears so the user can't recover from the empty state.

Also applies to: 137-141

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/QuickStarts/quickstart-filter.tsx` around lines 107 - 124, The
effect handling URL params sets activeLanguage directly from getSearchParams
without validating it against the selected category's availableLanguages, which
can leave activeLanguage stale/invalid after category changes; update the
useEffect (the hook that reads location.search) to clamp the urlLanguage to the
current category by checking visibleCategories / the chosen category's
availableLanguages (or a derived availableLanguages array) before calling
setActiveLanguage, and if the urlLanguage is not in that list fall back to a
valid language (e.g., the category default or "all"); similarly ensure the same
validation logic is applied in the other effect referenced (lines 137-141) and
keep languageFilterRef.current?.close(), setActiveCategoryId, and
setActiveLanguage calls intact but only after computing the validated language.
src/components/welcomePage/SelectFrameworkBlock.tsx-30-37 (1)

30-37: ⚠️ Potential issue | 🟠 Major

Use a real default selection here.

Falling back to frameworks[1] makes the snippet/guide render from the second option while no tab is active, and it crashes when only one framework is passed. Default to frameworks[0] and guard the empty-array case.

Suggested fix
-  const selected =
-    frameworks.find((f) => f.value === selectedFramework) ?? frameworks[1]
+  const selected =
+    frameworks.find((f) => f.value === selectedFramework) ?? frameworks[0]
+  if (!selected) {
+    return null
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/welcomePage/SelectFrameworkBlock.tsx` around lines 30 - 37,
The current fallback uses frameworks[1] which can render the wrong item or crash
when frameworks has length < 2; change the selection fallback to use
frameworks[0] and guard an empty array: in SelectFrameworkBlock replace the
selected assignment that references frameworks[1] with one that falls back to
frameworks[0] and then to a safe default object (e.g., { value: "", snippet: ""
}) when frameworks is empty, so selected, snippetPrefix, and snippetRest never
access undefined; keep the existing snippetPrefixes/snippetPrefix/snippetRest
logic but ensure they read from the safe selected.snippet.
src/components/OryArchitectureDiagram.tsx-36-47 (1)

36-47: ⚠️ Potential issue | 🟠 Major

Add identityAnswer to FitViewOnChange dependency and lower the minZoom clamp.

identityAnswer can add/remove the external IdP and switch the graph between compact and multi-row layouts, but FitViewOnChange only watches selectedProducts. The hard minZoom: 1 clamp also prevents the wider layout from fitting on narrow viewports.

Include identityAnswer in the dependency array and pass it to FitViewOnChange at line 231. Review and likely lower the minZoom value across all fitView calls.

Also applies to: 72–74, 226–227

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/OryArchitectureDiagram.tsx` around lines 36 - 47,
FitViewOnChange only depends on selectedProducts but must also depend on
identityAnswer because adding/removing the external IdP changes layout; update
the dependency array in FitViewOnChange to include identityAnswer and update any
call sites that render/use <FitViewOnChange ...> (pass the identityAnswer prop
where FitViewOnChange is instantiated), and relax the hard minZoom clamp (lower
from 1 to a smaller value such as 0.5) in all fitView({ padding..., duration...,
minZoom }) invocations so wider layouts can fit on narrow viewports; locate
references by the FitViewOnChange function name, the identityAnswer variable,
and fitView from useReactFlow.
src/components/OryArchitectureDiagram.tsx-191-198 (1)

191-198: ⚠️ Potential issue | 🟠 Major

Guard the fullscreen API before chaining .then().

requestFullscreen?.() / exitFullscreen?.() can return undefined, and both promises can reject. On unsupported or denied browsers this turns the fullscreen button into a runtime error path. The optional chaining ?.() evaluates to undefined if the method doesn't exist, and calling .then() on undefined throws a TypeError.

Suggested fix
-  const toggleFullscreen = useCallback(() => {
+  const toggleFullscreen = useCallback(async () => {
     const el = containerRef.current
     if (!el) return
-    if (!document.fullscreenElement) {
-      el.requestFullscreen?.().then(() => setIsFullscreen(true))
-    } else {
-      document.exitFullscreen?.().then(() => setIsFullscreen(false))
+    try {
+      if (!document.fullscreenElement) {
+        if (el.requestFullscreen) {
+          await el.requestFullscreen()
+        }
+      } else if (document.exitFullscreen) {
+        await document.exitFullscreen()
+      }
+    } catch {
+      // Ignore rejected / unsupported fullscreen requests.
     }
   }, [])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/OryArchitectureDiagram.tsx` around lines 191 - 198, The
toggleFullscreen function uses optional chaining to call
el.requestFullscreen?.() and document.exitFullscreen?.() but immediately chains
.then(), which will throw if the call returns undefined or rejects; update
toggleFullscreen to first check that the respective methods exist
(el.requestFullscreen and document.exitFullscreen), call them only if present,
capture their return value into a variable (promise), and then safely handle it
by using Promise.resolve(promise).then(() =>
setIsFullscreen(true/false)).catch(() => {/* handle or log error and avoid
changing state on failure */}); ensure you reference and update the
toggleFullscreen function, containerRef, requestFullscreen, exitFullscreen, and
setIsFullscreen usages.
🟡 Minor comments (9)
src/components/welcomePage/GuideLinkBox.tsx-12-22 (1)

12-22: ⚠️ Potential issue | 🟡 Minor

Make the whole card the link.

Lines 12-22 style this as a CTA box, but only the inline text/icon is clickable. The padded body becomes dead space, which is easy to miss on the welcome page. Wrapping the card itself in Link will match the visual affordance.

💡 Proposed fix
 export function GuideLinkBox({ to, label }: GuideLinkBoxProps) {
   return (
-    <div className="mt-ory-4 flex flex-col gap-ory-3 p-ory-6 rounded-ory border border-ory-border-info-tertiary bg-ory-info-tertiary">
-      <Link
-        to={to}
-        className="ory-body-sm font-medium text-ory-info-on-tertiary no-underline inline-flex items-center gap-ory-2"
-      >
+    <Link
+      to={to}
+      className="mt-ory-4 flex flex-col gap-ory-3 rounded-ory border border-ory-border-info-tertiary bg-ory-info-tertiary p-ory-6 no-underline"
+    >
+      <span className="ory-body-sm inline-flex items-center gap-ory-2 font-medium text-ory-info-on-tertiary">
         <IconBulb
-          className="w-5 h-5 shrink-0 text-ory-info-primary"
+          className="h-5 w-5 shrink-0 text-ory-info-primary"
           aria-hidden
         />
         Follow the quickstart guide for {label}
-      </Link>
-    </div>
+      </span>
+    </Link>
   )
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/welcomePage/GuideLinkBox.tsx` around lines 12 - 22, The CTA
card currently only makes the inline text/icon clickable; wrap the entire card
so the whole padded area is a link by replacing the outer <div className="...">
with the <Link to={to} className="..."> (or alternatively wrap the div with a
single Link) and remove the inner Link to avoid nested anchors; keep the same
class names, IconBulb, and the "Follow the quickstart guide for {label}" text so
the full card (GuideLinkBox) is clickable and styling/ARIA are preserved.
src/components/OryHeroDemo.jsx-132-135 (1)

132-135: ⚠️ Potential issue | 🟡 Minor

Expose the terminal stream as a live log.

The demo appends content in place, but this container is just a generic div. Screen-reader users won't be told that output changed or that the final CTA appeared. Mark it as a log/live region and surface running state.

♿ Suggested fix
         <div
           ref={terminalRef}
+          role="log"
+          aria-live="polite"
+          aria-relevant="additions text"
+          aria-busy={isRunning}
           className="p-4 font-mono text-[13px] text-ory-text-primary bg-ory-bg-primary leading-[1.6] overflow-y-auto flex-1 min-h-0"
         >

Also applies to: 189-199, 204-209

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/OryHeroDemo.jsx` around lines 132 - 135, The terminal output
container (the div referenced by terminalRef) needs ARIA live-region semantics
so screen-readers announce updates; add role="log" and aria-live="polite" (or
"assertive" if announcements must interrupt) plus aria-atomic="true" or "false"
as appropriate, and bind aria-busy to the component's running state (e.g.,
isStreaming / isRunning) so updates reflect live activity; apply the same
changes to the other output containers mentioned (the divs around lines 189-199
and 204-209) and ensure the running state variable used in aria-busy is updated
when the stream starts/stops.
src/components/welcomePage/OverviewCard.tsx-49-57 (1)

49-57: ⚠️ Potential issue | 🟡 Minor

Give each inline CTA a unique accessible name.

Every welcome-page card currently renders the same "Learn more" link text here, so assistive tech gets a list of indistinguishable links with no card context. Include title in the link’s accessible name, or make the heading part of the link.

♿ Suggested fix
-          <Link to={to} className="ory-guide-card__link mt-auto">
+          <Link
+            to={to}
+            aria-label={`${linkLabel} about ${title}`}
+            className="ory-guide-card__link mt-auto"
+          >
             {linkLabel}
             <span aria-hidden>→</span>
           </Link>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/welcomePage/OverviewCard.tsx` around lines 49 - 57, The link
text "Learn more" is ambiguous to screen reader users; update the OverviewCard
component so each CTA has a unique accessible name by adding a descriptive title
attribute to the Link (e.g., title={`${title} - ${linkLabel}`}) or alternatively
by making the card heading part of the link so the heading (title) and linkLabel
are read together; modify the Link element (the JSX that uses variables
linkLabel, to, wrapperClass, innerClass, content, and title) to include the
chosen accessible-name change and ensure the aria-hidden decorative arrow
remains aria-hidden.
src/components/welcomePage/SelectFrameworkSection.tsx-17-20 (1)

17-20: ⚠️ Potential issue | 🟡 Minor

Fix TypeScript capitalization in user-facing copy.

Line 17 and Line 20 use Typescript; standard casing is TypeScript. This affects polish and search consistency.

💡 Proposed fix
-    label: "Typescript",
+    label: "TypeScript",
...
-    guideTitle: "Follow the quickstart guide for Typescript",
+    guideTitle: "Follow the quickstart guide for TypeScript",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/welcomePage/SelectFrameworkSection.tsx` around lines 17 - 20,
The displayed user-facing strings use "Typescript" with incorrect
capitalization; update the values for the "label" and "guideTitle" properties in
SelectFrameworkSection (the entries named label and guideTitle) to "TypeScript"
(capital S) so both the option label and the quickstart guide text use the
correct casing and remain consistent for search and polish.
src/components/QuickStarts/constants.ts-109-113 (1)

109-113: ⚠️ Potential issue | 🟡 Minor

Fix the Polis blurb typo.

“SCIM provising” should be “SCIM provisioning”.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/QuickStarts/constants.ts` around lines 109 - 113, The
QuickStarts entry for label "Introduction to Ory Polis" contains a typo in the
description property; change the string value of description from "Enterprise
SSO for SAML and OIDC identity providers and SCIM provising." to "Enterprise SSO
for SAML and OIDC identity providers and SCIM provisioning." so the description
property in the QuickStarts constants (the object with label "Introduction to
Ory Polis") uses the correct spelling.
src/components/QuickStarts/CategoryFilter.tsx-17-31 (1)

17-31: ⚠️ Potential issue | 🟡 Minor

Expose the active category state.

The selected chip is only communicated by styling right now. Add aria-pressed to the buttons so assistive tech can announce which category is currently applied.

Suggested change
-    <div className="flex flex-wrap items-center gap-2 mb-5">
+    <div
+      className="flex flex-wrap items-center gap-2 mb-5"
+      role="group"
+      aria-label="Quickstart categories"
+    >
@@
         <button
           key={cat.id}
           type="button"
+          aria-pressed={activeCategory.id === cat.id}
           className={clsx(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/QuickStarts/CategoryFilter.tsx` around lines 17 - 31, The
category buttons only communicate selection visually; add an accessible state by
setting the button's aria-pressed attribute inside the categories.map render so
assistive tech can announce the active chip. Update the button in
CategoryFilter.tsx (the mapped button using key={cat.id}, activeCategory and
onCategoryChange) to include aria-pressed={activeCategory.id === cat.id} (or the
equivalent boolean expression) so the selected category is exposed to assistive
technologies.
src/components/welcomePage/SolutionDesignStepper.tsx-159-170 (1)

159-170: ⚠️ Potential issue | 🟡 Minor

Use radio semantics for the answer choices.

The current selection is only visible by border color. Because this is a single-choice question, expose it as a radio group (role="radiogroup" + role="radio"/aria-checked) or switch to actual radio inputs so screen readers can announce the selected answer.

Suggested change
-                  <div className="flex flex-col gap-ory-3">
+                  <div
+                    className="flex flex-col gap-ory-3"
+                    role="radiogroup"
+                    aria-label={currentQuestion.question}
+                  >
                     {currentQuestion.options.map((option) => {
                       const selected = currentAnswer === option.value
                       return (
                         <button
                           key={option.value}
                           type="button"
+                          role="radio"
+                          aria-checked={selected}
                           onClick={() =>
                             handleAnswer(currentQuestion.id, option.value)
                           }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/welcomePage/SolutionDesignStepper.tsx` around lines 159 - 170,
The option buttons in SolutionDesignStepper render single-choice answers but
lack radio semantics; update the markup around currentQuestion.options (in the
SolutionDesignStepper component) to expose a proper radio group by either
replacing the buttons with actual <input type="radio"> elements (wired to
handleAnswer and currentAnswer) or by adding role="radiogroup" to the container
and role="radio", aria-checked, and keyboard focus/keydown handling
(Enter/Space) to each option element; ensure keys remain option.value and that
selection styling still reflects currentAnswer so screen readers can announce
the selected option.
src/components/QuickStarts/LanguageFilter.tsx-37-59 (1)

37-59: ⚠️ Potential issue | 🟡 Minor

Expose the popup state on the trigger.

The toggle never tells assistive tech whether the language menu is open. Add aria-expanded, aria-haspopup, and an aria-controls relationship to the popup container so this reads as a real disclosure instead of a generic button.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/QuickStarts/LanguageFilter.tsx` around lines 37 - 59, The
button toggle in LanguageFilter.tsx should expose the popup state to assistive
tech: update the toggle button (the element using onClick={() =>
setMenuOpen(...)} and the activeLanguage display) to include
aria-expanded={menuOpen}, aria-haspopup="true", and aria-controls pointing to
the popup container's id; add a stable id to the popup div (the element rendered
when menuOpen is true) and ensure the popup container has that id and an
appropriate role (e.g., role="menu") so the aria-controls relationship is valid.
src/css/theme.css-1238-1245 (1)

1238-1245: ⚠️ Potential issue | 🟡 Minor

This selector leaks the quickstart reset outside the tabs.

.tabs-container[data-group-id="language-quickstarts"] ~ * [class*="theme-code-block"] matches any descendant code block in any later sibling, so unrelated snippets further down the page inherit the quickstart styling too. Scope the reset to the tab container/panel instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/css/theme.css` around lines 1238 - 1245, The CSS selector
`.tabs-container[data-group-id="language-quickstarts"] ~ *
[class*="theme-code-block"]` leaks styles to later sibling content; restrict the
reset to only code inside the quickstarts tab/panel by replacing the loose
sibling descendant selector with one that targets the tab container/panel scope
(e.g. target descendants of the
`.tabs-container[data-group-id="language-quickstarts"]` panel element such as
`.tabs-container[data-group-id="language-quickstarts"] .tab-panel
[class*="theme-code-block"]` and likewise for the `pre`/`code` rules), so only
code blocks inside the quickstarts tab inherit the quickstart styling.

Comment on lines +54 to +92
export default function SidebarDeploymentModel(): JSX.Element | null {
const history = useHistory()
const location = useLocation()
const sidebar = useDocsSidebar()
const quickstartsDeployment = useQuickstartsDeployment()
if (!sidebar?.name || !QUICKSTARTS_SIDEBAR_NAMES.has(sidebar.name))
return null

const currentFromPath = getCurrentDeployment(location.pathname)
const current = quickstartsDeployment
? DEPLOYMENT_OPTIONS.find(
(o) => o.id === quickstartsDeployment.deployment,
) ?? currentFromPath
: currentFromPath
const [open, setOpen] = useState(false)
const ref = useRef<HTMLDivElement>(null)
const triggerImageUrl = DEPLOYMENT_IMAGES[current.id]

const handleSelect = (opt: (typeof DEPLOYMENT_OPTIONS)[number]) => {
if (quickstartsDeployment) {
quickstartsDeployment.setDeployment(opt.id as QuickstartsDeploymentId)
}
setOpen(false)
history.push("/docs/getting-started/overview")
}

useEffect(() => {
const handleClickOutside = (e: MouseEvent | TouchEvent | FocusEvent) => {
if (!ref.current?.contains(e.target as Node)) setOpen(false)
}
document.addEventListener("mousedown", handleClickOutside)
document.addEventListener("touchstart", handleClickOutside)
document.addEventListener("focusin", handleClickOutside)
return () => {
document.removeEventListener("mousedown", handleClickOutside)
document.removeEventListener("touchstart", handleClickOutside)
document.removeEventListener("focusin", handleClickOutside)
}
}, [])
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Hooks called after conditional early return violates Rules of Hooks.

The useState, useRef, and useEffect hooks are called after the conditional return null on lines 59-60. React requires hooks to be called unconditionally and in the same order on every render. This will cause runtime errors when the sidebar condition changes.

🐛 Proposed fix - move hooks before conditional return
 export default function SidebarDeploymentModel(): JSX.Element | null {
   const history = useHistory()
   const location = useLocation()
   const sidebar = useDocsSidebar()
   const quickstartsDeployment = useQuickstartsDeployment()
+  const [open, setOpen] = useState(false)
+  const ref = useRef<HTMLDivElement>(null)
+
+  useEffect(() => {
+    const handleClickOutside = (e: MouseEvent | TouchEvent | FocusEvent) => {
+      if (!ref.current?.contains(e.target as Node)) setOpen(false)
+    }
+    document.addEventListener("mousedown", handleClickOutside)
+    document.addEventListener("touchstart", handleClickOutside)
+    document.addEventListener("focusin", handleClickOutside)
+    return () => {
+      document.removeEventListener("mousedown", handleClickOutside)
+      document.removeEventListener("touchstart", handleClickOutside)
+      document.removeEventListener("focusin", handleClickOutside)
+    }
+  }, [])
+
   if (!sidebar?.name || !QUICKSTARTS_SIDEBAR_NAMES.has(sidebar.name))
     return null

   const currentFromPath = getCurrentDeployment(location.pathname)
   const current = quickstartsDeployment
     ? DEPLOYMENT_OPTIONS.find(
         (o) => o.id === quickstartsDeployment.deployment,
       ) ?? currentFromPath
     : currentFromPath
-  const [open, setOpen] = useState(false)
-  const ref = useRef<HTMLDivElement>(null)
   const triggerImageUrl = DEPLOYMENT_IMAGES[current.id]
-
-  // ... move handleSelect here ...
-
-  useEffect(() => {
-    // ... effect code ...
-  }, [])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/SidebarDeploymentModel/index.tsx` around lines 54 - 92, The
hooks (useState, useRef, useEffect, useHistory, useLocation, useDocsSidebar,
useQuickstartsDeployment) are being called after an early return which violates
the Rules of Hooks; move all hook calls and any derived values that rely on them
(history, location, sidebar, quickstartsDeployment, currentFromPath, current,
open/setOpen, ref, triggerImageUrl) to the top of SidebarDeploymentModel so they
always run before the conditional `if (!sidebar?.name ||
!QUICKSTARTS_SIDEBAR_NAMES.has(sidebar.name)) return null`, then keep the
conditional return only for rendering (leaving handleSelect and the useEffect
logic intact but relocated to use the hooks declared earlier).

Comment on lines +16 to 17
docs: "/docs/getting-started/integrate-auth/nextjs-app-router-quickstart",
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Find where example.docs is rendered:"
rg -n -C3 'href=\{.*\.docs\}|to=\{.*\.docs\}' src || true

echo
echo "Check for Docusaurus base-url helpers around example.docs:"
rg -n -C3 'useBaseUrl\(.*\.docs|<Link.*to=\{.*\.docs\}' src || true

echo
echo "Consumers of examples-content.tsx:"
rg -n -C2 'examples-content' src || true

Repository: ory/docs

Length of output: 1045


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== OverviewCard component definition ==="
find src -name "OverviewCard*" -o -name "*OverviewCard*" | head -20

echo
echo "=== Search for OverviewCard component ==="
rg -n "OverviewCard" src/components --type ts --type tsx -A 20 | head -60

echo
echo "=== Docusaurus baseUrl configuration ==="
rg -n "baseUrl" . --type ts --type tsx --type js -g "docusaurus*" | head -20

echo
echo "=== Check QuickStarts consumer usage of examples-content ==="
rg -n "examples-content\|example\.docs\|card\.docs" src/components/QuickStarts -A 5 -B 2 | head -80

Repository: ory/docs

Length of output: 225


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== OverviewCard component implementation ==="
cat -n src/components/welcomePage/OverviewCard.tsx

echo
echo "=== Docusaurus config baseUrl ==="
rg -n "baseUrl" . -g "docusaurus*" 2>/dev/null | head -10

echo
echo "=== How QuickStarts hook uses examples ==="
cat -n src/components/QuickStarts/hooks/useExampleFilter.ts | head -50

echo
echo "=== Welcome component usage of OverviewCard ==="
cat -n src/components/Welcome/welcome.tsx | head -40

Repository: ory/docs

Length of output: 5898


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== QuickStarts component that renders examples ==="
find src/components/QuickStarts -name "*.tsx" -o -name "*.ts" | xargs ls -la

echo
echo "=== Search for where examples.docs is rendered in QuickStarts ==="
rg -n "example\.docs\|ex\.docs" src/components/QuickStarts -A 3 -B 1

echo
echo "=== Check if there's a Link component in QuickStarts ==="
rg -n "Link.*to=\|href=" src/components/QuickStarts | head -20

Repository: ory/docs

Length of output: 1245


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== QuickstartGrid.tsx (likely renders examples) ==="
cat -n src/components/QuickStarts/QuickstartGrid.tsx

echo
echo "=== quickstart-filter.tsx (main component) ==="
cat -n src/components/QuickStarts/quickstart-filter.tsx | head -100

echo
echo "=== Search for all Link imports in QuickStarts ==="
rg -n "from.*Link\|import.*Link" src/components/QuickStarts

echo
echo "=== Search broadly for docs field rendering ==="
rg -n "\.docs" src/components/QuickStarts -A 2 -B 1

Repository: ory/docs

Length of output: 6283


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== ExampleList component (uses examples-content) ==="
find src/components/Examples -name "*.tsx" -o -name "*.ts" | xargs ls -la

echo
echo "=== example-list.tsx content ==="
cat -n src/components/Examples/example-list.tsx 2>/dev/null || find src -name "*example-list*" -type f

echo
echo "=== Search for how example.docs is used ==="
rg -n "example\.docs\|\.docs.*Link\|href.*docs" src -A 2 -B 1 | head -60

Repository: ory/docs

Length of output: 8565


Fix baseUrl duplication in example doc links: remove /docs prefix from stored paths.

Both OverviewCard (Welcome page) and ExampleCard (Examples section) render the docs field through Docusaurus <Link> component, which automatically applies the baseUrl ("/docs/" in docusaurus.config.ts) to paths. Storing paths as /docs/getting-started/... causes the baseUrl to be applied twice, resulting in /docs/docs/getting-started/... links.

Change paths from /docs/... format to /... format so baseUrl resolution works correctly. For example: /docs/getting-started/integrate-auth/nextjs-app-router-quickstart/getting-started/integrate-auth/nextjs-app-router-quickstart

Also applies to: 25-26, 34-35, 43-44, 52-53, 61-62, 70-71, 79-80, 106-107

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/_assets/examples-content.tsx` around lines 16 - 17, The stored
example doc paths include a redundant "/docs" prefix which causes Docusaurus
Link to produce "/docs/docs/..." links; update the `docs` string values in
src/pages/_assets/examples-content.tsx (the objects used by OverviewCard and
ExampleCard) to remove the leading "/docs" so they start with "/" (e.g.,
"/getting-started/..." instead of "/docs/getting-started/..."); ensure every
`docs:` entry referenced by the OverviewCard and ExampleCard examples (including
those around the noted ranges) is updated consistently.

Comment on lines +9 to +12
interface MdxJsxAttribute {
name: string;
value: string | string[];
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

In remark-mdx / mdast-util-mdx-jsx, what is the runtime and TypeScript shape of MdxJsxAttribute.valuefor JSX attributes written likelines={['network']}orfeatures={['console']}? Is it ever a native string[], or is it an mdxJsxAttributeValueExpression object?

💡 Result:

In remark-mdx / mdast-util-mdx-jsx, the runtime and TypeScript shape of MdxJsxAttribute.value for JSX attributes like lines={['network']} or features={['console']} is an MdxJsxAttributeValueExpression object, not a native string[]. The TypeScript type for MdxJsxAttribute is: interface MdxJsxAttribute extends Literal { type: 'mdxJsxAttribute' name: string value?: MdxJsxAttributeValueExpression | string | null | undefined } and MdxJsxAttributeValueExpression is: interface MdxJsxAttributeValueExpression extends Literal { type: 'mdxJsxAttributeValueExpression' value: string // The raw JS source: "['network']" data?: {estree?: Program | null | undefined} & Literal['data'] } At runtime, value holds the raw JavaScript expression source code as a string (e.g., ['network']), parsed into an estree AST in data.estree if addResult: true is passed to the parser. It is never a native string[]—arrays remain as unevaluated JS expressions in the mdast.

Citations:


🏁 Script executed:

find . -name "productLinePlugin.ts" -o -name "productLinePlugin.js"

Repository: ory/docs

Length of output: 86


🏁 Script executed:

cat -n src/plugins/productLinePlugin.ts | head -100

Repository: ory/docs

Length of output: 4348


Expression-valued attributes are not decoded correctly; blocks will be unexpectedly filtered out.

The local MdxJsxAttribute type definition masks the actual MDX AST shape. When JSX attributes like lines={['network']} or features={['console']} are parsed, they arrive as mdxJsxAttributeValueExpression objects with raw JavaScript source in the value field, not as native string[]. The current logic:

  • Array.isArray(linesAttr.value) returns false (the value is an object, not an array)
  • Wraps the expression object in an array: [expressionObject]
  • Compares the product line string against the expression object, which never matches

This causes conditional blocks to be unexpectedly filtered out. Either parse the mdxJsxAttributeValueExpression.data.estree AST to extract the actual array value, or constrain the supported syntax to string literals only (e.g., lines="network").

Affects lines 67–86.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugins/productLinePlugin.ts` around lines 9 - 12, The MdxJsxAttribute
type and current logic incorrectly assume attribute.value is a string or
string[]; update the handling in productLinePlugin.ts to detect
expression-valued attributes (value.type === 'mdxJsxAttributeValueExpression')
for symbols like MdxJsxAttribute, linesAttr and featuresAttr and extract the
actual value by reading value.data.estree (parse the ESTree to recover string or
array literals), falling back to supporting only string literal attributes if
parsing fails; then normalize to string[] before doing membership checks so
comparisons against product line names succeed.

Comment on lines +56 to +61
// Replace component with plain text
(node as any).type = 'text';
(node as any).value = productName;
delete (mdxNode as any).name;
delete (mdxNode as any).attributes;
delete (mdxNode as any).children;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

In mdast, is it valid to replace an mdxJsxFlowElementwith atextnode, or to convert it to aparagraphwhile keeping block children such as headings, lists, or othermdxJsxFlowElements? What is the recommended way for a remark plugin to unwrap or remove a flow node?

💡 Result:

No, it is not valid in mdast to directly replace an mdxJsxFlowElement (a flow/block node) with a text node, as text is phrasing content and cannot appear where flow content is expected (such as in root or other block parents). Similarly, converting it to a paragraph while keeping its original block children (e.g., headings, lists, other mdxJsxFlowElements) is invalid, because paragraph requires PhrasingContent children only, not FlowContent or BlockContent like headings or lists. The recommended way for a remark plugin to unwrap or remove a flow node like mdxJsxFlowElement is to use tree-walking utilities such as unist-util-visit to find the node, then either: - Remove it entirely with unist-util-remove (mutates the tree in place). - Replace it by splicing its valid children (which are Array<BlockContent | DefinitionContent>) directly into its parent's children array at the correct index (unwrapping), ensuring the children match the parent's content model. - For selective unwrapping (e.g., single-paragraph children), replace the child paragraph with its contents, as shown in plugins like remark-unravel-mdx and remark-unwrap-images. Examples from unified docs and plugins confirm direct node replacement or removal is common, but must preserve content model validity (e.g., no block children in phrasing-only nodes).

Citations:


🏁 Script executed:

head -120 src/plugins/productLinePlugin.ts | tail -70

Repository: ory/docs

Length of output: 2753


🏁 Script executed:

head -55 src/plugins/productLinePlugin.ts

Repository: ory/docs

Length of output: 1798


Don't retag flow JSX nodes into text / paragraph.

These branches are rewriting mdxJsxFlowElement nodes into node kinds that are only valid in phrasing contexts. A hidden block becomes an invalid text node under a flow container, and a kept <ProductLineContent> turns into a paragraph even if its children contain headings, lists, or other flow nodes. Replace/remove the wrapper in parent.children using splice() instead of changing the node type in place.

Possible direction
-import { visit } from 'unist-util-visit';
+import { SKIP, visit } from 'unist-util-visit';

   return (tree) => {
-    visit(tree, (node: Node) => {
-      const mdxNode = node as MdxJsxFlowElement;
+    visit(tree, 'mdxJsxFlowElement', (mdxNode: MdxJsxFlowElement, index, parent) => {
+      if (index == null || !parent) {
+        return;
+      }

       // ...

       if (mdxNode.type === 'mdxJsxFlowElement' && mdxNode.name === 'ProductLineContent') {
         // ...

-        if (shouldShow) {
-          // Keep the children but remove the wrapper
-          if (mdxNode.children) {
-            (node as any).type = 'paragraph';
-            delete (mdxNode as any).name;
-            delete (mdxNode as any).attributes;
-          }
-        } else {
-          // Remove this entire block from the output
-          (node as any).type = 'text';
-          (node as any).value = '';
-          delete (mdxNode as any).name;
-          delete (mdxNode as any).attributes;
-          delete (mdxNode as any).children;
-        }
+        parent.children.splice(index, 1, ...(shouldShow ? (mdxNode.children ?? []) : []));
+        return [SKIP, index];
       }
     });
   };

Also applies to: lines 89-103

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/plugins/productLinePlugin.ts` around lines 56 - 61, The code is
incorrectly retagging mdxJsxFlowElement nodes by mutating (node as
any).type/value and deleting mdxNode fields, which produces invalid phrasing
nodes; instead locate the wrapper in parent.children and replace or remove it
via parent.children.splice(index, 1, ...) with a new plain text node (or
multiple replacement nodes) so flow-level elements remain proper flow nodes; do
the same fix for the other branch handling lines 89-103 (where similar in-place
type mutation occurs), referencing the local variables node, mdxNode, and
parent.children and use the splice-based replacement to insert the desired
replacement nodes rather than modifying node.type in place.

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.