Skip to content

refactor: swagger viewer - #96

Open
AlyaEngineer wants to merge 11 commits into
developfrom
refactor/general-swagger-viewer
Open

refactor: swagger viewer#96
AlyaEngineer wants to merge 11 commits into
developfrom
refactor/general-swagger-viewer

Conversation

@AlyaEngineer

@AlyaEngineer AlyaEngineer commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes a bug that made every Try-It-Out request fail with a raw 502, plus a border-radius inconsistency in the response body display.

Changes Made

  • fixed requestWithPinnedIp's custom lookup option in try-it-out/route.ts - Node's autoSelectFamily (Happy Eyeballs) sometimes calls the lookup callback expecting an array-based response ((err, addresses[])) instead of the single (err, address, family) form; the callback now checks lookupOptions.all and responds in the correct shape either way;
  • fixed borderRadius: 1 on the Try-It-Out response body block, which resolved to 50px (the theme's capsule-button multiplier) instead of the intended 8px - replaced with an explicit '8px' string, matching the same pattern already used for panels/cards elsewhere in the app;
  • refactoring of the Swagger Viewer feature: the single large component file was split into focused components - grouped Swagger Viewer files into subfolders, split swagger-viewer.tsx, split endpoint-details.tsx into eight single-purpose components, moved swagger-viewer.helpers.ts to try-it-out/try-it-out.helpers.ts;
  • removed the hardcoded English 'No summary' fallback from get-swagger-endpoints.ts;
  • markdown rendering was added for schema descriptions (info.description, operation, parameter, request body and response descriptions).

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would break existing functionality)
  • Documentation update

Checklist

  • Self-review done
  • No console errors / warnings / logs
  • No any / @ts-ignore
  • Tests added / updated and passing

Summary by CodeRabbit

  • New Features

    • Improved the Swagger viewer with expandable endpoint details, Markdown descriptions, schemas, examples, content types, and API metadata.
    • Enhanced “Try It Out” request and cURL generation, validation, and error handling.
    • Unauthenticated requests can be tested without saving request history.
    • Added clearer endpoint summary fallbacks and improved API documentation display.
  • Bug Fixes

    • Reduced proxy lookup wait times and improved pinned-address request handling.
    • Fixed interaction timing and visual consistency in Swagger controls.

@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
swagger-editor-app Ready Ready Preview Jul 31, 2026 11:22am

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The API route now permits unauthenticated proxy requests without saving history. The Swagger viewer is decomposed into reusable endpoint components with Markdown support. Try-it-out request helpers and tests were added, and endpoint summary extraction now uses operation IDs.

Changes

Try-it-out route and request flow

Layer / File(s) Summary
Optional authentication and proxy handling
src/app/api/try-it-out/route.ts, src/app/api/try-it-out/route.test.ts
Unauthenticated requests can reach the upstream proxy. History is saved only when userId exists. The lookup timeout is 8 seconds, and pinned-IP lookup supports all: true.
Try-it-out request construction and validation
src/components/swagger-viewer/try-it-out/try-it-out.helpers.ts, src/components/swagger-viewer/try-it-out/try-it-out-panel.tsx, src/components/swagger-viewer/try-it-out/try-it-out-panel.test.tsx, src/components/swagger-viewer/try-it-out/*
Helpers build requests and cURL commands, apply Swagger parameters, map errors, and handle invalid URLs. Tests cover validation, execution, errors, clipboard failures, and cURL updates.

Swagger viewer decomposition

Layer / File(s) Summary
Reusable Markdown and endpoint detail components
package.json, src/components/markdown-text/*, src/components/swagger-viewer/types.ts, src/components/swagger-viewer/api-info-header.tsx, src/components/swagger-viewer/endpoint-*.tsx, src/components/swagger-viewer/endpoint-details/*, src/components/swagger-viewer/path-group.tsx
The viewer now renders API descriptions and endpoint details through reusable components. Markdown supports GFM, external-link security attributes, and scrollable tables.
Viewer integration and endpoint extraction
src/components/swagger-viewer/swagger-viewer.tsx, src/components/swagger-viewer/index.ts, src/components/swagger-viewer/swagger-viewer.test.tsx, src/utils/swagger-editor/get-swagger-endpoints.ts, src/utils/swagger-editor/get-swagger-endpoints.test.ts
SwaggerViewer delegates API and path rendering. Endpoint summaries use operation IDs when needed. Tests cover PUT endpoint extraction and awaited endpoint interactions.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Viewer
  participant TryItOutPanel
  participant TryItOutRoute
  participant SupabaseAuth
  participant Upstream
  Viewer->>TryItOutPanel: Select endpoint and submit request
  TryItOutPanel->>TryItOutRoute: POST generated request
  TryItOutRoute->>SupabaseAuth: Read user
  TryItOutRoute->>Upstream: Proxy request
  TryItOutRoute-->>TryItOutPanel: Return response or error
Loading

Possibly related PRs

Suggested labels: feature-3-editor

Suggested reviewers: yuliademir, lexarudak

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change as a refactor of the Swagger viewer.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/general-swagger-viewer

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/app/api/try-it-out/route.ts (1)

413-436: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Correct fix for the auto-select-family lookup mismatch; add coverage for the all:true branch.

The branch on lookupOptions.all === true correctly matches Node's two DNS lookup callback shapes (single address/family vs. array of addresses), which should resolve the raw 502s from autoSelectFamily. The provided test context only exercises the non-all single-address path (route.test.ts:84-145); the new wantsAll branch (Lines 417-427) appears to lack direct test coverage.

// example addition to route.test.ts
it('resolves via the pinned IP when the lookup requests all addresses', async () => {
  // ...invoke request.options.lookup(hostname, { all: true }, callback) and assert
  // callback is invoked with [{ address, family }]
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/api/try-it-out/route.ts` around lines 413 - 436, Add a focused test
alongside the existing lookup tests for the `lookup` callback in the try-it-out
route, invoking it with `{ all: true }` and asserting the callback receives an
array containing the pinned address and family. Preserve the existing
single-address test and verify the all-address branch returns without invoking
the single-address callback shape.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/app/api/try-it-out/route.ts`:
- Around line 413-436: Add a focused test alongside the existing lookup tests
for the `lookup` callback in the try-it-out route, invoking it with `{ all: true
}` and asserting the callback receives an array containing the pinned address
and family. Preserve the existing single-address test and verify the all-address
branch returns without invoking the single-address callback shape.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 731ff188-21db-4e2e-a3a2-b8f2a13fa9b7

📥 Commits

Reviewing files that changed from the base of the PR and between 57f6b28 and efb0f9c.

📒 Files selected for processing (2)
  • src/app/api/try-it-out/route.ts
  • src/components/swagger-viewer/try-it-out-response-details.tsx

@AlyaEngineer AlyaEngineer changed the title Refactor/general swagger viewer refactor: swagger viewer Jul 14, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/api/try-it-out/route.ts (1)

83-172: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Add an abuse-control gate for the anonymous proxy. This endpoint lets unauthenticated callers proxy arbitrary public URLs. Private IPs are blocked, but there’s no rate limit or other abuse/origin check here, so it can still be used to hide source IPs or burn downstream quotas.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/api/try-it-out/route.ts` around lines 83 - 172, Add an abuse-control
check to the POST handler before calling fetchValidatedUrl, applying a rate
limit or equivalent origin validation to unauthenticated requests while
preserving authenticated access. When the anonymous caller exceeds the
configured limit or fails the origin check, return the established client-error
response and do not proxy the request.
🧹 Nitpick comments (1)
src/app/api/try-it-out/route.ts (1)

413-436: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Correct fix for Node's autoSelectFamily/Happy-Eyeballs lookup contract, but no test exercises the all: true branch.

Confirmed via Node docs: with { all: true }, dns.lookup's callback signature changes to (err, addresses[]), and autoSelectFamily (default true since Node 20) sets all: true on the lookup call made by http/https. The branching here correctly matches that contract, so this should fix the raw 502s described in the PR.

However, this is the primary stated bug fix in the PR, and the test-file diff (route.test.ts lines 179-217) only adds unauthenticated-access tests — no test appears to force lookupOptions.all === true through requestWithPinnedIp to verify this new branch. Consider adding a case that invokes the custom lookup with { all: true } and asserts it returns an addresses array.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/api/try-it-out/route.ts` around lines 413 - 436, The custom lookup
behavior in requestWithPinnedIp needs coverage for Node’s { all: true }
contract. Add a focused test that invokes the lookup callback with
lookupOptions.all set to true and asserts it receives an addresses array
containing the resolved address and family, while preserving the existing
single-address behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/app/api/try-it-out/route.ts`:
- Around line 83-172: Add an abuse-control check to the POST handler before
calling fetchValidatedUrl, applying a rate limit or equivalent origin validation
to unauthenticated requests while preserving authenticated access. When the
anonymous caller exceeds the configured limit or fails the origin check, return
the established client-error response and do not proxy the request.

---

Nitpick comments:
In `@src/app/api/try-it-out/route.ts`:
- Around line 413-436: The custom lookup behavior in requestWithPinnedIp needs
coverage for Node’s { all: true } contract. Add a focused test that invokes the
lookup callback with lookupOptions.all set to true and asserts it receives an
addresses array containing the resolved address and family, while preserving the
existing single-address behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3c79afe7-2c16-4c37-a03f-b418e47d3515

📥 Commits

Reviewing files that changed from the base of the PR and between efb0f9c and 4f24c39.

📒 Files selected for processing (2)
  • src/app/api/try-it-out/route.test.ts
  • src/app/api/try-it-out/route.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/components/swagger-viewer/swagger-viewer.tsx (1)

96-163: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider unmounting collapsed accordion content and adding ARIA linking for accessibility.

Per MUI's official docs, Accordion content is mounted even when collapsed by default; for many/large panels (this app can have many endpoints per path, each mounting a full TryItOutPanel with its own state/inputs) this is called out as a real perf concern, with the fix being slotProps={{ transition: { unmountOnExit: true } }} on Accordion (note: TransitionProps is deprecated in this MUI v9 in favor of slotProps.transition). Separately, WAI-ARIA accordion guidelines recommend linking AccordionSummary and AccordionDetails via id/aria-controls, which MUI's own examples add explicitly.

♻️ Suggested additions
+  const panelId = `${endpoint.method}-${endpoint.path}`;
+
   return (
-    <Accordion disableGutters elevation={0} square>
-      <AccordionSummary expandIcon={<ExpandMoreIcon />}>
+    <Accordion disableGutters elevation={0} slotProps={{ transition: { unmountOnExit: true } }} square>
+      <AccordionSummary
+        aria-controls={`${panelId}-content`}
+        expandIcon={<ExpandMoreIcon />}
+        id={`${panelId}-header`}
+      >

Note: enabling unmountOnExit will reset any in-progress Try-It-Out form state when a panel is collapsed/re-expanded — verify that tradeoff is acceptable for this UI before adopting.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/swagger-viewer/swagger-viewer.tsx` around lines 96 - 163,
Update the Accordion in the endpoint panel to unmount collapsed content using
MUI v9’s slotProps transition unmountOnExit configuration, after confirming
resetting TryItOutPanel state on collapse is acceptable. Add explicit matching
identifiers to AccordionSummary and AccordionDetails, with the summary
referencing the details through aria-controls.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/components/swagger-viewer/swagger-viewer.tsx`:
- Around line 96-163: Update the Accordion in the endpoint panel to unmount
collapsed content using MUI v9’s slotProps transition unmountOnExit
configuration, after confirming resetting TryItOutPanel state on collapse is
acceptable. Add explicit matching identifiers to AccordionSummary and
AccordionDetails, with the summary referencing the details through
aria-controls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e72dedc2-30d7-4d13-9268-ca719ff20321

📥 Commits

Reviewing files that changed from the base of the PR and between 4f24c39 and 3814fc3.

📒 Files selected for processing (2)
  • src/components/swagger-viewer/swagger-viewer.test.tsx
  • src/components/swagger-viewer/swagger-viewer.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/components/swagger-viewer/try-it-out/index.ts (1)

1-3: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove unused barrel exports from try-it-out/index.ts.

Only TryItOutPanel is imported from this barrel. Drop the CurlCommandPreview, TryItOutResponse, and TryItOutResponseDetails re-exports unless consumers need public access through it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/swagger-viewer/try-it-out/index.ts` around lines 1 - 3, Update
the barrel exports in try-it-out/index.ts to retain only TryItOutPanel, removing
CurlCommandPreview, TryItOutResponse, and TryItOutResponseDetails re-exports
unless repository usage demonstrates they are required through this entry point.

Source: Path instructions

src/components/swagger-viewer/path-group.tsx (1)

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the unnecessary 'use client' directive.

PathGroup uses no hooks and no client-only APIs. Remove 'use client' so this component can render on the server.

As per path instructions, "flag unnecessary 'use client' on components with no hooks or client-only APIs."

♻️ Proposed fix
-'use client';
-
 import Box from '`@mui/material/Box`';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/swagger-viewer/path-group.tsx` at line 1, Remove the
unnecessary 'use client' directive from the PathGroup component so it remains
server-renderable; leave the component implementation unchanged.

Source: Path instructions

src/components/swagger-viewer/endpoint-details/examples.tsx (1)

1-7: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add the missing 'use client' directive.

Examples uses the useTranslations hook but has no 'use client' directive. Sibling components in this PR (ApiInfoHeader, EndpointSummaryRow) add 'use client' whenever they call useTranslations. Add the directive here for consistency.

As per path instructions, "Flag components missing 'use client' directive when using hooks."

♻️ Proposed fix
+'use client';
+
 import Box from '`@mui/material/Box`';
 import Stack from '`@mui/material/Stack`';
 import Typography from '`@mui/material/Typography`';
 import { useTranslations } from 'next-intl';

next-intl's useTranslations can run without 'use client' in a non-async Server Component through its react-server conditional export. Confirm whether Examples is meant to stay a Server Component; if so, this is a style-consistency fix rather than a functional necessity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/swagger-viewer/endpoint-details/examples.tsx` around lines 1 -
7, Add the `'use client'` directive at the top of the Examples module before its
imports, matching the convention used by sibling components that call
useTranslations.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/markdown-text/markdown-text.tsx`:
- Line 1: Remove the `'use client'` directive from the `MarkdownText` component
so it remains a Server Component; leave its existing React element construction
logic unchanged.

In `@src/components/swagger-viewer/endpoint-details/parameter-details.tsx`:
- Around line 1-5: Add a top-level 'use client'; directive before the imports in
parameter-details.tsx, request-body-details.tsx, and schema-text.tsx so each
component using useTranslations is explicitly client-side.

---

Nitpick comments:
In `@src/components/swagger-viewer/endpoint-details/examples.tsx`:
- Around line 1-7: Add the `'use client'` directive at the top of the Examples
module before its imports, matching the convention used by sibling components
that call useTranslations.

In `@src/components/swagger-viewer/path-group.tsx`:
- Line 1: Remove the unnecessary 'use client' directive from the PathGroup
component so it remains server-renderable; leave the component implementation
unchanged.

In `@src/components/swagger-viewer/try-it-out/index.ts`:
- Around line 1-3: Update the barrel exports in try-it-out/index.ts to retain
only TryItOutPanel, removing CurlCommandPreview, TryItOutResponse, and
TryItOutResponseDetails re-exports unless repository usage demonstrates they are
required through this entry point.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0cb955f5-66c7-4184-825d-6873bf587768

📥 Commits

Reviewing files that changed from the base of the PR and between 3814fc3 and bde8650.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (28)
  • package.json
  • src/components/markdown-text/markdown-text.tsx
  • src/components/swagger-viewer/api-info-header.tsx
  • src/components/swagger-viewer/endpoint-body.tsx
  • src/components/swagger-viewer/endpoint-details.tsx
  • src/components/swagger-viewer/endpoint-details/content-types.tsx
  • src/components/swagger-viewer/endpoint-details/detail-section.tsx
  • src/components/swagger-viewer/endpoint-details/empty-details.tsx
  • src/components/swagger-viewer/endpoint-details/examples.tsx
  • src/components/swagger-viewer/endpoint-details/index.ts
  • src/components/swagger-viewer/endpoint-details/parameter-details.tsx
  • src/components/swagger-viewer/endpoint-details/request-body-details.tsx
  • src/components/swagger-viewer/endpoint-details/response-details.tsx
  • src/components/swagger-viewer/endpoint-details/schema-text.tsx
  • src/components/swagger-viewer/endpoint-panel.tsx
  • src/components/swagger-viewer/endpoint-summary-row.tsx
  • src/components/swagger-viewer/index.ts
  • src/components/swagger-viewer/path-group.tsx
  • src/components/swagger-viewer/swagger-viewer.tsx
  • src/components/swagger-viewer/try-it-out/curl-command-preview.tsx
  • src/components/swagger-viewer/try-it-out/index.ts
  • src/components/swagger-viewer/try-it-out/try-it-out-panel.test.tsx
  • src/components/swagger-viewer/try-it-out/try-it-out-panel.tsx
  • src/components/swagger-viewer/try-it-out/try-it-out-response-details.tsx
  • src/components/swagger-viewer/try-it-out/try-it-out.helpers.ts
  • src/components/swagger-viewer/types.ts
  • src/utils/swagger-editor/get-swagger-endpoints.test.ts
  • src/utils/swagger-editor/get-swagger-endpoints.ts
💤 Files with no reviewable changes (1)
  • src/components/swagger-viewer/endpoint-details.tsx

@@ -0,0 +1,67 @@
'use client';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Can react-markdown 10.1.0 and @mui/material 9.1.2 render in a Next.js 16 Server Component without a "use client" directive?

💡 Result:

Yes, react-markdown 10.1.0 and @mui/material 9.1.2 can be rendered in a Next.js 16 Server Component, but they achieve this in different ways due to how the 'use client' directive functions [1][2][3]. React-markdown: This library is fundamentally compatible with Server Components because it performs its primary work (parsing and transforming markdown to React elements) on the server [4]. You can import and use react-markdown directly in a Server Component without adding a 'use client' directive to your own file [4]. @mui/material: All components in @mui/material are published with the 'use client' directive already included [5][6][7]. Because these components are marked as client-side entry points by the library itself, you can import and use them directly within your Server Components without needing to add a 'use client' directive to your own file [5][6][7]. Key Considerations: 1. Boundary: While you do not need to add 'use client' to your own Server Component files, these third-party components remain part of the client bundle [1][8]. The 'use client' directive is essentially baked into the library code [2][7]. 2. Context and Hooks: Because @mui/material components are client-side, they can still utilize React hooks and browser APIs (such as those required for styling via Emotion) [3][6]. When using @mui/material, you should use the provided integration packages (like @mui/material-nextjs) in your layout or root files to properly configure server-side styling and CSS injection [9][6]. 3. Plugins: If you use react-markdown with plugins that require browser-specific APIs (such as certain syntax highlighters), you will need to wrap that specific part of your UI in a Client Component (a file with 'use client') [10][4]. In summary, you can import and render these libraries in your Server Components without adding the 'use client' directive yourself, as they either function natively on the server (react-markdown) or have already opted into the client module graph for you (@mui/material) [4][5][7].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
fd -a 'markdown-text\.tsx$' . || true

echo
echo "Target file outline:"
ast-grep outline src/components/markdown-text/markdown-text.tsx --view expanded || true

echo
echo "Target file contents:"
cat -n src/components/markdown-text/markdown-text.tsx

echo
echo "Search react-markdown/MUI package details:"
fd -a 'package.json' . | while read -r f; do
  echo "--- $f"
  rg -n '"next"|"react-markdown"|"`@mui/material`"|"`@mdx-js/react`"|"`@emotion/react`"|"`@emotion/styled`"' "$f" || true
done

Repository: AlyaEngineer/swagger-editor-app

Length of output: 2626


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read-only behavioral/source check: inspect MarkdownText for hooks, browser-only APIs,
# async operations without awaiting, and console.log statements.
python3 - <<'PY'
from pathlib import Path
import re, ast

path = Path('src/components/markdown-text/markdown-text.tsx')
text = path.read_text()
if not text:
    print('MISSING_FILE')
    raise SystemExit

hooks = re.findall(r'\b(use[A-Za-z]+)\s*\(', text)
print('hooks:', hooks)

print('uses client directive:', text.startswith("'use client';") or text.startswith('"use client";'))

# Count distinct console.log statements
log_stmts = re.findall(r'\bconsole\.log\s*\(', text)
print('console.log occurrences:', len(log_stmts))

# Print lines with hooks, console.log, console.error, async/await, fetch/XMLHttpRequest/AbortController.
for i, line in enumerate(text.splitlines(), 1):
    if any(tok in line for tok in ('use[A-Za-z]*(', 'console.log', 'console.error', 'async function', '=>', 'fetch', 'XMLHttpRequest', 'AbortController', 'useEffect', 'useState', 'useRef')):
        print(f'{i}:{line}')
PY

Repository: AlyaEngineer/swagger-editor-app

Length of output: 422


Remove the unnecessary client boundary.

MarkdownText only calls existing React element constructors; it does not use hooks or a browser-only API. Remove 'use client' so the component remains a Server Component.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/markdown-text/markdown-text.tsx` at line 1, Remove the `'use
client'` directive from the `MarkdownText` component so it remains a Server
Component; leave its existing React element construction logic unchanged.

Source: Path instructions

Comment on lines +1 to +5
import Chip from '@mui/material/Chip';
import Paper from '@mui/material/Paper';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import { useTranslations } from 'next-intl';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

for file in \
  src/components/swagger-viewer/endpoint-details/parameter-details.tsx \
  src/components/swagger-viewer/endpoint-details/request-body-details.tsx \
  src/components/swagger-viewer/endpoint-details/schema-text.tsx
do
  echo "=== $file ==="
  sed -n '1,8p' "$file"
done

Repository: AlyaEngineer/swagger-editor-app

Length of output: 1319


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for file in \
  src/components/swagger-viewer/endpoint-details/parameter-details.tsx \
  src/components/swagger-viewer/endpoint-details/request-body-details.tsx \
  src/components/swagger-viewer/endpoint-details/schema-text.tsx
do
  echo "=== $file ==="
  ast-grep outline "$file" --view compact || true
  echo
done

Repository: AlyaEngineer/swagger-editor-app

Length of output: 853


🏁 Script executed:

#!/bin/bash
set -euo pipefail

for file in \
  src/components/swagger-viewer/endpoint-details/parameter-details.tsx \
  src/components/swagger-viewer/endpoint-details/request-body-details.tsx \
  src/components/swagger-viewer/endpoint-details/schema-text.tsx
do
  echo "=== $file ==="
  wc -l "$file"
  sed -n '1,220p' "$file"
  echo
done

Repository: AlyaEngineer/swagger-editor-app

Length of output: 3670


Add 'use client' directives to the hook-using detail components.

These src/components/swagger-viewer/endpoint-details/*.tsx files call useTranslations but have no local client directive, so they violate the src/**/*.{ts,tsx} guideline. Add 'use client'; before the imports in each file:

  • src/components/swagger-viewer/endpoint-details/parameter-details.tsx
  • src/components/swagger-viewer/endpoint-details/request-body-details.tsx
  • src/components/swagger-viewer/endpoint-details/schema-text.tsx
📍 Affects 3 files
  • src/components/swagger-viewer/endpoint-details/parameter-details.tsx#L1-L5 (this comment)
  • src/components/swagger-viewer/endpoint-details/request-body-details.tsx#L1-L4
  • src/components/swagger-viewer/endpoint-details/schema-text.tsx#L1-L2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/swagger-viewer/endpoint-details/parameter-details.tsx` around
lines 1 - 5, Add a top-level 'use client'; directive before the imports in
parameter-details.tsx, request-body-details.tsx, and schema-text.tsx so each
component using useTranslations is explicitly client-side.

Source: Path instructions

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.

1 participant