feat: upgrade to Next.js 16, TailwindCSS v4, Storybook 10, and Biome#422
feat: upgrade to Next.js 16, TailwindCSS v4, Storybook 10, and Biome#422
Conversation
hari
commented
Mar 6, 2026
- Upgrade Next.js 14 → 16, TailwindCSS v3 → v4, Storybook 9 → 10
- Replace ESLint + Prettier with Biome for linting and formatting
- Replace contentlayer with velite for content processing
- Migrate CSS config from tailwind.config.ts to CSS-based @theme syntax
- Fix animated-border-trail CSS @Property animation compatibility
- Add (main) route group for layout separation
- Update component preview iframe URLs for Storybook 10 autodocs
- Fix story file issues (titles, exports, autodocs tags)
- Add deploy-v3 GitHub Actions workflow
- Update globals.css with TailwindCSS v4 base layer resets
- Upgrade Next.js 14 → 16, TailwindCSS v3 → v4, Storybook 9 → 10 - Replace ESLint + Prettier with Biome for linting and formatting - Replace contentlayer with velite for content processing - Migrate CSS config from tailwind.config.ts to CSS-based @theme syntax - Fix animated-border-trail CSS @Property animation compatibility - Add (main) route group for layout separation - Update component preview iframe URLs for Storybook 10 autodocs - Fix story file issues (titles, exports, autodocs tags) - Add deploy-v3 GitHub Actions workflow - Update globals.css with TailwindCSS v4 base layer resets Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Important Review skippedToo many files! This PR contains 300 files, which is 150 over the limit of 150. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (300)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 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 |
| runs-on: ubuntu-latest | ||
| environment: v3-deployment | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| - name: Setup Node | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "20" | ||
| - name: Install yarn | ||
| run: npm install -g yarn | ||
| - name: Restore cache | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: | | ||
| .next/cache | ||
| key: ${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} | ||
| restore-keys: | | ||
| ${{ runner.os }}-nextjs-${{ hashFiles('**/yarn.lock') }}- | ||
| - name: Install dependencies | ||
| run: yarn install --immutable | ||
| - name: Build component previews | ||
| run: yarn storybook:build | ||
| - name: Build with Next.js | ||
| env: | ||
| NEXT_PUBLIC_APP_URL: ${{ vars.NEXT_PUBLIC_APP_URL }} | ||
| NEXT_PUBLIC_SUPABASE_URL: ${{ vars.NEXT_PUBLIC_SUPABASE_URL }} | ||
| NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ vars.NEXT_PUBLIC_SUPABASE_ANON_KEY }} | ||
| NEXT_PUBLIC_POSTHOG_KEY: ${{ vars.NEXT_PUBLIC_POSTHOG_KEY }} | ||
| NEXT_PUBLIC_POSTHOG_HOST: ${{ vars.NEXT_PUBLIC_POSTHOG_HOST }} | ||
| NEXT_PUBLIC_PLUNK_API_KEY: ${{ vars.NEXT_PUBLIC_PLUNK_API_KEY }} | ||
| run: yarn build | ||
| - name: Deploy to Cloudflare Pages | ||
| uses: cloudflare/wrangler-action@v3 | ||
| with: | ||
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | ||
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | ||
| command: pages deploy out --project-name=animata-v3 --branch=main | ||
| gitHubToken: ${{ secrets.GITHUB_TOKEN }} |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 6 days ago
To fix the problem, explicitly define a minimal permissions block so that the GITHUB_TOKEN used by this workflow/job is limited to read-only repository contents unless more is required. The safest pattern is to declare permissions at the workflow root (applies to all jobs) or at the deploy-v3 job level. Since there is only a single job and no evidence of needing write permissions (the job checks out code, builds, caches, and then deploys to Cloudflare using Cloudflare credentials), we can safely set contents: read as the only permission.
The best minimal change is to add a permissions block near the top of .github/workflows/deploy-v3.yml, right after the name: line (or before/after on:; all are valid) so that it applies to the entire workflow. No imports or additional methods are needed since this is just YAML configuration. Concretely, in .github/workflows/deploy-v3.yml, insert:
permissions:
contents: readbetween line 1 (name: Deploy v3) and line 3 (on:), keeping indentation consistent. This documents that the workflow only needs read access to repository contents and ensures the GITHUB_TOKEN is not given unnecessary write permissions.
| @@ -1,5 +1,8 @@ | ||
| name: Deploy v3 | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| on: | ||
| push: | ||
| branches: |
Cloudflare Pages defaults to Node 18.17.1, but Next.js 16 requires Node >=20.9.0. The .node-version file is respected by Cloudflare's build system. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deploying animata with
|
| Latest commit: |
f83c244
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://4931795f.animata.pages.dev |
| Branch Preview URL: | https://hari-lamichhane-upgrade-to-l.animata.pages.dev |
- Inline @Property and @Keyframes in AnimatedBorderTrail component so the CSS custom property animation works with TailwindCSS v4 - Remove leftover test files (testingo, navigation-menu) that broke storybook build due to missing @radix-ui/react-navigation-menu dep Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ensures component previews are always built during `yarn build`, including on Cloudflare Pages direct builds where the build command is just `yarn build`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Install @storybook/addon-docs to support autodocs in Storybook 10 - Run Next.js and Storybook dev server concurrently via `yarn dev` - Use NEXT_PUBLIC_STORYBOOK_URL env var to point previews to Storybook dev server in development, falling back to /preview for production - Add prebuild script to build static storybook for production builds - Update all 162 MDX files from --docs to --primary story IDs - Use viewMode=story for component preview iframes - Fix border trail animation by inlining @Property for TailwindCSS v4 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Next.js 16 uses Turbopack by default which skips the webpack velite plugin. Run velite CLI directly: --watch mode for dev, one-shot for prebuild. Fixes stale .velite cache causing --docs IDs to persist. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace bg-opacity-*, text-opacity-*, border-opacity-* with the Tailwind v4 color/opacity modifier syntax (e.g. bg-gray-400/30). Also move complex multi-layer box-shadows to inline styles for algolia buttons since Tailwind v4 can't parse rgba() commas in arbitrary shadow values. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Restore missing styles/storybook.css (lost in migration) which defines storybook-fix class and embedded preview styles - Re-add storybook.css import to storybook preview config - Replace -z-1 with z-0 in components — in Tailwind v3 -z-1 was not a default utility (no-op), but in v4 it generates z-index:-1 which pushes elements behind the parent background Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Marquee and animated-beam: inline @Keyframes and animation styles to bypass @theme variable indirection broken in Storybook webpack context. Jumping text: fix spring animation with keyframe arrays unsupported in Motion v12. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…yping Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch embedded preview from story view to docs view with interactive Controls. Add embedded class to body for proper CSS targeting, measure full docs container height, and hide docs chrome in embedded mode. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add transparent background and no-grid globals to iframe URL. Hide zoom bar and remove story preview borders in embedded mode. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The step counter ::before pseudo-element uses position: absolute but the h3 had no positioned ancestor, making the numbers invisible. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Read theme from URL globals parameter and apply matching Storybook theme (light/dark) to the docs view so controls and chrome match. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
resolvedTheme is undefined during SSR; wait for client mount so the correct light/dark theme is passed to the storybook iframe. Also key the iframe on theme so it remounts on theme change. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Linter removed the semicolon causing max-width to be parsed as part of the @apply directive, breaking the Storybook webpack build. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use context.globals.theme in the decorator instead of manually parsing URL query params. Storybook populates globals from the URL internally. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Storybook globals context was unreliable for embedded iframes. Now detect theme directly from URL (theme:dark) at module load time, and also listen for postMessage from parent for live theme switching. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the Storybook iframe embedding with direct dynamic imports of story files. Renders the Primary story with its args and render function inline, eliminating iframe theme sync and height issues. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Renders editable controls for boolean, number, and string props below the component preview. Reads args/argTypes from the story module and updates the rendered component live when props change. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Split preview and props editor into sibling elements so the preview's overflow/absolute positioning isn't affected by the editor below it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove redundant JSDoc comments, use cn() for className composition in skew-image, remove stale eslint-disable comment, fix Tailwind v4 transition classes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In Tailwind v4, transition-all now transitions ALL properties including display and visibility which causes visual glitches. Replace with transition which only covers common properties (color, background, transform, opacity, shadow). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Convert all tailwind.config.js code blocks in component MDX docs to Tailwind v4 CSS syntax: @Keyframes for animations, @theme for custom values (--animate-*, --ease-*, --bg-*, --shadow-*). Remove color-only config steps (foreground/background already global). Update setup docs to note tailwindcss-animate is no longer needed in v4. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use bg-linear-to-bl (v4 syntax) in led-board, replace hardcoded text-white with text-background in tilted-card for theme support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- bg-gradient-to-* → bg-linear-to-* (v4 gradient syntax) - flex-grow → grow, flex-shrink → shrink (v4 naming) - outline-none → outline-hidden (v4 accessibility change) - Remove transform-gpu (GPU acceleration is default in v4) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Complete shape-shifter @Keyframes (was missing 20%/40%/80%/100%) - Update PR template test command from npm run start to yarn dev - Update setup.mdx: Framer Motion → Motion package, remove tailwind.config.js reference in troubleshooting Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Components like ring-chart, donut-chart, grid, dot, zigzag, subscribe-card, cycling, and shopping-list had empty or complex-only args, making them invisible in the inline PropsEditor. Added their primitive props (size, gap, width, color, title, etc.) to story args. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Audited all 21 component categories and added missing primitive props to story args so they appear in the inline PropsEditor. Changes span background, button, card, carousel, container, hero, image, list, text, and widget categories (28 story files total). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a subtle dot pattern background to preview containers so component content stands out visually against the preview area. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace div/p elements with button/span for proper semantics, add explicit text-black for inactive tabs, and use item value as React key instead of array index. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove invalid leading-2 class from stories, fix important modifier syntax to v4 (! suffix), and clean up border-1 class. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CalculateItemStyle was a function using hooks (useState, useEffect) but called as a regular function inside render, violating Rules of Hooks. Extract it as a proper OrbitingItem component. Also fix storybook-fix → full-content class. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adjust center icon z-index to z-1, use 0/3 range for orbiting items instead of -1/1, and reduce back-scale to 0.9 for better 3D effect. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix double-colon typo in group-hover/orbit::paused that broke the pause-on-hover feature. Replace storybook-fix with full-content. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --animate-rotate-full theme variable so the animate-rotate-full utility works. Replace arbitrary animate-[rotate-full_45s] with the proper utility. Fix pause-on-hover using arbitrary property syntax. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use spring transitions, popLayout mode, semantic button elements, consistent layoutId naming, and cleaner spacing/typography. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace transition with transition-all so font-size changes animate on hover. Tailwind v4's transition utility no longer includes font-size by default. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…eview Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…views Replace storybook-fix with full-content. Add has-[.full-content]:overflow-auto to preview containers so scrollable components like scroll-reveal work instead of being clipped by overflow-hidden. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use after:transition-all instead of after:transition so height and background-color changes animate on hover. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The opacity style is on the motion.span wrapper, not on the icon element itself. Change CSS selectors to target .scroll-baby and .scroll-file as children of the element with the opacity style. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The full-content class caused the preview wrapper to become scrollable (overflow-auto), stealing scroll events from the component's own scroll container. Without full-content, the preview stays overflow-hidden and useScroll correctly tracks the inner container. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…veal Motion v12's useScroll with container ref wasn't triggering scroll progress updates. Replace with a native scroll event listener that manually updates a useMotionValue, which is more reliable across rendering contexts like dynamic imports in ComponentPreview. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>