Polish Agent Orchestrator landing page#2260
Conversation
|
React Doctor found 28 issues in 10 files · 28 warnings · score 58 / 100 (Critical) · vs 28 warnings
Reviewed by React Doctor for commit |
785500f to
7057753
Compare
| return ( | ||
| <html lang="en" suppressHydrationWarning> | ||
| <head> | ||
| <script dangerouslySetInnerHTML={{ __html: themeScript }} /> |
There was a problem hiding this comment.
React Doctor · react-doctor/nextjs-no-native-script (warning)
Plain <script> has no Next.js loading strategy, so it can block rendering.
Fix → Use next/script with strategy="afterInteractive" or "lazyOnload" so third-party scripts do not block rendering.
| ]; | ||
|
|
||
| export function LandingAgentsBar() { | ||
| const marqueeAgents = [...agents, ...agents]; |
There was a problem hiding this comment.
React Doctor · react-doctor/prefer-module-scope-static-value (warning)
marqueeAgents inside LandingAgentsBar uses no local state but is rebuilt every render, so it looks new each time & breaks memoized children. Move it to the top of the file, outside the component.
Fix → Move the value above the component, at the top of the file. It doesn't use local state, so rebuilding it each update is wasted and makes it look new every time.
| className="group flex h-[78px] w-[118px] shrink-0 flex-col items-center justify-end gap-2 px-2 py-2" | ||
| > | ||
| <div className="flex h-10 items-end justify-center"> | ||
| <img |
| Star on GitHub · 7.7k | ||
| <ArrowRightIcon className="h-4 w-4 transition-transform group-hover:translate-x-0.5" /> | ||
| </a> | ||
| <a |
There was a problem hiding this comment.
React Doctor · react-doctor/nextjs-no-a-element (warning)
Plain reloads the whole page for internal links, so Next.js loses client-side navigation and prefetching.
Fix → import Link from 'next/link' for client-side navigation, prefetching, and preserved scroll position
| <article className="surface relative overflow-hidden bg-[#010102] p-0"> | ||
| <div className="flex items-center justify-between border-b border-[color:var(--border)] px-5 py-4"> | ||
| <div className="flex items-center gap-3"> | ||
| <img src="/ao-logo-transparent.png" alt="" className="h-7 w-7 object-contain" /> |
| </a> | ||
| ); | ||
| })} | ||
| <a |
There was a problem hiding this comment.
React Doctor · react-doctor/nextjs-no-a-element (warning)
Plain reloads the whole page for internal links, so Next.js loses client-side navigation and prefetching.
Fix → import Link from 'next/link' for client-side navigation, prefetching, and preserved scroll position
| const [theme, setTheme] = useState("dark"); | ||
|
|
||
| useEffect(() => { | ||
| setTheme(document.documentElement.dataset.theme || "dark"); |
There was a problem hiding this comment.
React Doctor · react-doctor/no-initialize-state (warning)
Your users see an extra render with empty "theme" because a useEffect sets its starting value.
Fix → Pass the initial value directly to useState() instead of setting it from a mount-only useEffect. For SSR hydration, prefer useSyncExternalStore().
| const observer = new MutationObserver(() => { | ||
| setTheme(document.documentElement.dataset.theme || "dark"); | ||
| }); | ||
| observer.observe(document.documentElement, { |
There was a problem hiding this comment.
React Doctor · react-doctor/no-initialize-state (warning)
Your users see an extra render with empty "theme" because a useEffect sets its starting value.
Fix → Pass the initial value directly to useState() instead of setting it from a mount-only useEffect. For SSR hydration, prefer useSyncExternalStore().
| for (const post of posts) { | ||
| const id = postId(post); | ||
| const node = tweetRefs.current[id]; | ||
| if (!node || node.dataset.tweetRendered === `${id}-${theme}`) continue; |
There was a problem hiding this comment.
React Doctor · react-doctor/js-cache-property-access (warning)
This slows the loop because node.dataset.tweetRendered is read 3 times inside it, so read it once into a variable at the top
Fix → Read the value once into a variable at the top of the loop: const { x, y } = obj.deeply.nested
| data-testid="video-frame" | ||
| className="glow-accent relative aspect-video overflow-hidden rounded-2xl border border-[color:var(--border-strong)] bg-black" | ||
| > | ||
| <iframe |
There was a problem hiding this comment.
React Doctor · react-doctor/iframe-missing-sandbox (warning)
An <iframe> with no sandbox is a security hole: the embedded page gets full access to your site.
Fix → Add sandbox="" or a curated value so embedded pages cannot get full access to your site by default.
Preview
Validation