Add aurora shader background to empty chat state#250
Conversation
Uses shaders.com <Shader><Aurora> instead of react-three/fiber — no GLSL, no render loop, WebGPU-first with WebGL2 fallback built in. ShapeShift brand palette (purple-500 / green-500 / purple-300) with slow drift. Gated behind useIsMobile (768px) and a WebGL capability check; falls back to a CSS radial-gradient on mobile or when WebGL is unavailable. Shader chunk is lazy-loaded so it doesn't hit the main bundle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ttom Animation fix: shaders.com IntersectionObserver only calls startAnimation() on a not-visible → visible transition. Mounting with display:none then flipping to block on the next animation frame forces that transition. UI: header, suggestion strip, and composer get bg/80 backdrop-blur-md so the aurora bleeds through. Header and suggestion strip get a border to ground them visually against the background. Built with Claude
The shaders/react Shader component has a StrictMode bug: cleanup doesn't reset isInitializedRef, so the second (real) mount returns early from initializeRenderer() and the animation loop never starts. Switch to createShader() from shaders/js — a plain async function we call in a useEffect with proper cancel/destroy handling. Lifecycle is now fully under our control and StrictMode-safe. Also cranked props: intensity 90, speed 3.5, waviness 70, curtainCount 4. Built with Claude
…leak, WGSL id
- Add `three` as direct dep so Vite can resolve `three/tsl` (was only in
bun's internal cache, not on the node_modules resolution path)
- Add `optimizeDeps: { include: ['three'] }` to vite config so Vite
pre-bundles it before the dynamic `import('shaders/js')` fires
- Cache `isWebGLAvailable()` at module scope and immediately release the
test context via WEBGL_lose_context — previously leaked one context per
render, exhausting the browser limit and killing the aurora's context
- Pass explicit `id: 'aurora'` on the shader component so the library
doesn't auto-generate an ID containing a dot (Math.random()), which
produced invalid WGSL struct member names and crashed the GPU pipeline
- Add `.nx/` to .gitignore
Built with Claude
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR adds an animated WebGL aurora background component to the agentic chat dashboard with automatic fallback to CSS gradients on unsupported devices. It introduces Three.js and Shaders dependencies, implements WebGL capability detection, updates UI styling with glassmorphism effects, and configures Vite for Three.js pre-bundling. ChangesAurora Background Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
apps/agentic-chat/src/components/AuroraBackground.tsx (1)
6-21: 💤 Low value
isWebGLAvailable()called during render with DOM side-effect — verify SSR safety.
document.createElementis called synchronously on the first render to probe WebGL. Thetry/catchhandles SSR gracefully (returnsfalse→ CSS fallback), but be aware that repeated hot-reloads in development will re-execute this module and the cached result from a previous build run may be stale. This is a known limitation of module-level mutable state in HMR environments.No change needed if SSR is not in scope — just noting the edge case.
🤖 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 `@apps/agentic-chat/src/components/AuroraBackground.tsx` around lines 6 - 21, The function isWebGLAvailable() performs document.createElement and caches the result in cachedWebGLAvailable at module/runtime time which can produce DOM side-effects during render and stale state across HMR; to fix, avoid running DOM checks during SSR or synchronous render by making the probe lazy and client-only: move the WebGL probe into a client-only effect or a safe runtime check invoked inside useEffect or a guard like typeof window !== 'undefined' before calling document.createElement, and remove or reset module-level cachedWebGLAvailable on HMR if necessary (reference: isWebGLAvailable, cachedWebGLAvailable, and the code that calls isWebGLAvailable so it uses the new client-only check).apps/agentic-chat/vite.config.mjs (1)
7-9: ⚡ Quick win
optimizeDepsaddition is correct; consider removing the duplicate.mjsconfig.The
optimizeDeps: { include: ['three'] }change is the right fix. However, bothvite.config.mjsandvite.config.mtsnow exist with near-identical content. Vite will prefervite.config.mtsover.mjs; keeping both risks them silently diverging on future edits (as just demonstrated — the same change had to be applied to both files).♻️ Suggested cleanup
Delete
vite.config.mjsand keep onlyvite.config.mts, since.mtsprovides TypeScript checking of the config itself.🤖 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 `@apps/agentic-chat/vite.config.mjs` around lines 7 - 9, Remove the duplicate JavaScript config file and keep the TypeScript config: delete the vite.config.mjs file and ensure vite.config.mts contains the intended optimizeDeps change (include: ['three']) so only vite.config.mts remains as the authoritative Vite config to avoid future drift between vite.config.mjs and vite.config.mts.
🤖 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 `@apps/agentic-chat/src/components/AuroraBackground.tsx`:
- Line 82: The current .catch(console.error) on the createShader promise
swallows runtime shader failures and leaves the canvas blank; update the
AuroraBackground component to track a fallback state (e.g., useState boolean
like showCSSFallback), replace the .catch(console.error) with a handler that
logs the error and sets that fallback state, and then render the CSSFallback
component when showCSSFallback is true (same fallback used for mobile/no-WebGL).
Ensure any existing createShader success path clears the fallback state and that
you perform the same cleanup/disposing logic on error as on unmount.
---
Nitpick comments:
In `@apps/agentic-chat/src/components/AuroraBackground.tsx`:
- Around line 6-21: The function isWebGLAvailable() performs
document.createElement and caches the result in cachedWebGLAvailable at
module/runtime time which can produce DOM side-effects during render and stale
state across HMR; to fix, avoid running DOM checks during SSR or synchronous
render by making the probe lazy and client-only: move the WebGL probe into a
client-only effect or a safe runtime check invoked inside useEffect or a guard
like typeof window !== 'undefined' before calling document.createElement, and
remove or reset module-level cachedWebGLAvailable on HMR if necessary
(reference: isWebGLAvailable, cachedWebGLAvailable, and the code that calls
isWebGLAvailable so it uses the new client-only check).
In `@apps/agentic-chat/vite.config.mjs`:
- Around line 7-9: Remove the duplicate JavaScript config file and keep the
TypeScript config: delete the vite.config.mjs file and ensure vite.config.mts
contains the intended optimizeDeps change (include: ['three']) so only
vite.config.mts remains as the authoritative Vite config to avoid future drift
between vite.config.mjs and vite.config.mts.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 093972cc-c323-48db-b69c-a37a406f063c
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
.gitignoreapps/agentic-chat/package.jsonapps/agentic-chat/src/app/dashboard/page.tsxapps/agentic-chat/src/components/AuroraBackground.tsxapps/agentic-chat/src/components/Chat.tsxapps/agentic-chat/vite.config.mjsapps/agentic-chat/vite.config.mts

Summary
shaders.com) as the background of the empty chat state on desktopbg-background/80 backdrop-blur-mdglass treatment when the empty state is visibleBug fixes uncovered during implementation
Three bugs had to be resolved before the shader would render:
threedep —shaders/jsimportsthree/tslinternally butthreewas only in bun's internal cache, not on the node_modules resolution path Vite uses. Fixed by addingthreeas an explicit dependency and addingoptimizeDeps: { include: ['three'] }to the Vite config.isWebGLAvailable()was called on every render and leaked a WebGL context each time. With React Strict Mode doubling renders in dev, the browser hit its ~16-context limit and started killing the aurora's context. Fixed by caching the result at module scope and immediately releasing the test context viaWEBGL_lose_context.shaderslibrary auto-generates node IDs usingMath.random(), which produces values like0.959.... The dot ends up in WGSL struct member names and the WebGPU pipeline rejects the shader. Fixed by passing an explicitid: 'aurora'on the component.Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Style