К основному содержанию
скилл CX Codex

shadcn-inertia — скилл для Claude Code: что делает и как установить

Адаптирует компоненты shadcn/ui для связки Inertia.js, Ruby on Rails и React вместо Next.js. Помогает переписать формы и диалоги без react-hook-form.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add inertia-rails/skills --skill shadcn-inertia -a claude-code
Открыть на GitHub

Что делает shadcn-inertia

Скилл задаёт правила переноса компонентов shadcn/ui в стек Inertia Rails React. Стандартные примеры shadcn рассчитаны на Next.js, поэтому напрямую они вызывают ошибки. Инструкция убирает директивы 'use client', заменяет вызовы next/link и next/head на Inertia <Link> и <Head>, а роутер переводит на @inertiajs/react.

Формы строятся через компонент <Form> из Inertia, куда передаются нативные поля с атрибутом name. Использовать shadcn-обёртки вроде FormField, FormItem или FormMessage нельзя. Внутри них зашит useFormContext из библиотеки react-hook-form, и без неё приложение упадёт во время рендера. Ошибки валидации выводятся напрямую из объекта errors.

Для тёмной темы скилл заменяет next-themes инлайновым скриптом в шаблоне application.html.erb, чтобы предотвратить мерцание стилей до гидратации React. Настраивать алиас @/ в vite.config.ts не нужно: его уже предоставляет vite-plugin-ruby.

Какие задачи решает

  • адаптировать компоненты shadcn/ui под стек Inertia.js и Rails
  • переписать формы shadcn без использования react-hook-form и zod
  • устранить мигание темы оформления при загрузке страницы без next-themes
  • настроить серверную сортировку в таблицах shadcn через роутер Inertia

Примеры запросов агенту

  • Перепиши форму создания пользователя из примера shadcn под Inertia Form без react-hook-form
  • Сделай серверную сортировку колонок для таблицы shadcn через router.get
  • Настрой переключение тёмной темы для Inertia Rails без библиотеки next-themes

Как установить shadcn-inertia

1Через Skills CLI (Vercel)

npx skills add inertia-rails/skills --skill shadcn-inertia -a claude-code

2Вручную: положить файлы

~/.claude/skills/shadcn-inertia/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/shadcn-inertia/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о shadcn-inertia

Как установить shadcn-inertia в Claude Code?

Выполните команду npx skills add inertia-rails/skills --skill shadcn-inertia -a claude-code. Файл инструкций сохранится по пути ~/.claude/skills/shadcn-inertia/SKILL.md.

Зачем нужен скилл shadcn-inertia?

Он учит агента адаптировать компоненты shadcn/ui для связки Rails и Inertia.js. Это исключает лишние зависимости Next.js и предотвращает сбои из-за отсутствия react-hook-form.

Почему нельзя использовать FormField и FormMessage из shadcn?

Эти обёртки жёстко зависят от хука useFormContext библиотеки react-hook-form. В связке с Inertia поля ввода подключаются напрямую через атрибут name, а ошибки рендерятся из объекта errors.

Исходный текст

SKILL.md · MIT
---
name: shadcn-inertia
description: >-
  shadcn/ui component integration for Inertia Rails React (NOT Next.js): forms, dialogs, tables, toasts, dark mode,
  command palette, and more. Use when building UI with shadcn/ui components in an Inertia app or adapting shadcn
  examples from Next.js. NEVER react-hook-form/zod — wire shadcn inputs to Inertia Form via name attribute. Flash
  toasts require Rails flash_keys initializer config.
---

# shadcn/ui for Inertia Rails

shadcn/ui patterns adapted for Inertia.js + Rails + React. NOT Next.js.

**Before using a shadcn example, ask:**
- **Does it use `react-hook-form` + `zod`?** → Replace with Inertia `<Form>` + `name` attributes. Inertia handles CSRF, errors, redirects, processing state — react-hook-form would fight all of this.
- **Does it use `'use client'`?** → Remove it. Inertia has no RSC — all components are client components.
- **Does it use `next/link`, `next/head`, `useRouter()`?** → Replace with Inertia `<Link>`, `<Head>`, `router`.

## Key Differences from Next.js Defaults

| shadcn default (Next.js) | Inertia equivalent |
|---|---|
| `'use client'` directive | Remove — not needed (no RSC) |
| `react-hook-form` + `zod` | Inertia `<Form>` component |
| `FormField`, `FormItem`, `FormMessage` | Plain `<Input name="...">` + `errors.field` |
| `next-themes` | CSS class strategy + `@custom-variant` |
| `useRouter()` (Next) | `router` from `@inertiajs/react` |
| `next/link` | `<Link>` from `@inertiajs/react` |
| `next/head` | `<Head>` from `@inertiajs/react` |

**NEVER use shadcn's `FormField`, `FormItem`, `FormLabel`, `FormMessage` components** —
they depend on react-hook-form's `useFormContext` internally and will crash without it.
Use plain shadcn `Input`/`Label`/`Select` with `name` attributes inside Inertia `<Form>`,
and render errors from the render function's `errors` object (see examples below).

## Setup

`npx shadcn@latest init`. add `@/` resolve aliases to `tsconfig.json` if not present,
**Do NOT add `@/` resolve aliases to `vite.config.ts`** — `vite-plugin-ruby` already provides them.

## shadcn Inputs in Inertia `<Form>`

Use plain shadcn `Input`/`Label`/`Button` with `name` attributes inside Inertia `<Form>`.
See `inertia-rails-forms` skill for full `<Form>` API — this section covers shadcn-specific adaptation only.

**The key pattern:** Replace shadcn's `FormField`/`FormItem`/`FormMessage` with plain
components + manual error display:

```tsx
// shadcn error display pattern (replaces FormMessage):
<Label htmlFor="name">Name</Label>
<Input id="name" name="name" />
{errors.name && <p className="text-sm text-destructive">{errors.name}</p>}
```

**`<Select>` requires `name` prop** for Inertia `<Form>` integration — shadcn examples
omit it because react-hook-form manages values differently:

```tsx
<Select name="role" defaultValue="member">
  <SelectTrigger><SelectValue placeholder="Select role" /></SelectTrigger>
  <SelectContent>
    <SelectItem value="admin">Admin</SelectItem>
    <SelectItem value="member">Member</SelectItem>
  </SelectContent>
</Select>
```

## Dialog with Inertia Navigation

```tsx
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { router } from '@inertiajs/react'

function UserDialog({ open, user }: { open: boolean; user: User }) {
  return (
    <Dialog
      open={open}
      onOpenChange={(isOpen) => {
        if (!isOpen) {
          router.replaceProp('show_dialog', false)
        }
      }}
    >
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{user.name}</DialogTitle>
        </DialogHeader>
        {/* content */}
      </DialogContent>
    </Dialog>
  )
}
```

## Table with Server-Side Sorting

shadcn `<Table>` renders normally. The Inertia-specific part is sorting via `router.get`:

```tsx
const handleSort = (column: string) => {
  router.get('/users', { sort: column }, { preserveState: true })
}

<TableHead onClick={() => handleSort('name')} className="cursor-pointer">
  Name {sort === 'name' && '↑'}
</TableHead>
```

Use `<Link>` (not `<a>`) for row links to preserve SPA navigation.

## Toast with Flash Messages

Flash config (`flash_keys`) is in `inertia-rails-controllers`. Flash access
(`usePage().flash`) is in `inertia-rails-pages`. This section covers **toast UI wiring only**.

**MANDATORY — READ ENTIRE FILE** when implementing flash-based toasts with Sonner:
[`references/flash-toast.md`](references/flash-toast.md) (~80 lines) — full `useFlash`
hook and Sonner toast provider. **Do NOT load** if only reading flash values without toast UI.

Key gotcha: `flash_keys` in the Rails initializer MUST match your `FlashData`
TypeScript type — do NOT use `success`/`error` unless you also update both.

## Dark Mode (No next-themes)

`npx shadcn@latest init` generates CSS variables for light/dark and
`@custom-variant dark (&:is(.dark *));` in your CSS (Tailwind v4). No extra
setup needed for the variables themselves.

**CRITICAL — prevent flash of wrong theme (FOUC):** Next.js handles this
automatically; Inertia does NOT. Add an inline script in `<head>` (before React
hydrates) and call `initializeTheme()` in your Inertia entrypoint:

```erb
<%# app/views/layouts/application.html.erb — in <head>, before any stylesheets %>
<script>
  document.documentElement.classList.toggle(
    "dark",
    localStorage.appearance === "dark" ||
      (!("appearance" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches),
  );
</script>
```

```tsx
// app/frontend/entrypoints/inertia.tsx
import { initializeTheme } from '@/hooks/use-appearance'
initializeTheme() // must run before createInertiaApp
```

Use a `useAppearance` hook (light/dark/system modes, localStorage persistence,
`matchMedia` listener) instead of `next-themes`. Toggle via `.dark` class on
`<html>` — no provider needed.

## Troubleshooting

| Symptom | Cause | Fix |
|---------|-------|-----|
| `FormField`/`FormMessage` crash | Using shadcn form components that depend on react-hook-form | Replace with plain `Input`/`Label` + `errors.field` display |
| `Select` value not submitted | Missing `name` prop | Add `name="field"` to `<Select>` — shadcn examples omit it |
| Dialog closes unexpectedly | Missing or wrong `onOpenChange` handler | Use `onOpenChange={(open) => { if (!open) closeHandler() }}` |
| Flash of wrong theme (FOUC) | Missing inline `<script>` in `<head>` | Add dark mode script before stylesheets (see Dark Mode section) |

## Related Skills
- **Form component** → `inertia-rails-forms` (`<Form>` render function, useForm)
- **Flash config** → `inertia-rails-controllers` (flash_keys initializer)
- **Flash access** → `inertia-rails-pages` (usePage().flash)
- **URL-driven dialogs** → `inertia-rails-pages` (router.get pattern)

## References

Load [`references/components.md`](references/components.md) (~300 lines) when building
shadcn components beyond those shown above (Accordion, Sheet, Tabs, DropdownMenu,
AlertDialog with Inertia patterns).

**Do NOT load** `components.md` for basic Form, Select, Dialog, or Table usage —
the examples above are sufficient.

© inertia-rails · MIT · inertia-rails/skills

Похожие скиллы

Всё по теме «Фронтенд и UI» →
frontend-design официальный anthropics Скилл задаёт осмысленное визуальное направление для новых интерфейсов и редизайна. Подойдёт, когда стандартный шаблонный UI не устраивает. 1 025 790установок design-taste-frontend Leonxlnx Скилл задаёт арт-дирекцию для публичных страниц и рабочих экранов, а затем проверяет результат в браузере по скриншотам. Нужен, когда интерфейс выглядит шаблонным или недоработанным. CX Codex +1 678 700установок prototype Matt Pocock Создаёт временный прототип, чтобы проверить логику, модель состояния или вид интерфейса до работы над основным кодом. 986 201установок hyperframes heygen-com Скилл задаёт агенту правила рендера HTML-кода в видео через HyperFrames. Помогает собирать проморолики, эксплейнеры и титры прямо в коде проекта. CX Codex +1 1 200 000установок hyperframes-cli heygen-com Управляет проектами HyperFrames через терминал: собирает таймлайн, проверяет контраст кадров, запускает предпросмотр и рендерит видео локально или в облаке. CX Codex +1 1 300 000установок webapp-testing официальный anthropics Скилл запускает проверки локальных веб-приложений через Playwright: помогает отлаживать UI, делать скриншоты и смотреть логи браузера. 186 758установок

Из того же набора8

inertia-rails-architecture Задаёт серверные шаблоны для Rails + Inertia.js + React и разводит по нужным скиллам, когда вы строите страницу, форму или CRUD. CX Codex +1 537установок inertia-rails-pages Скилл для работы со страницами Inertia Rails: постоянные лейауты, навигация через Link и router, состояние из URL, отложенная загрузка и бесконечный скролл. CX Codex +1 504установок inertia-rails-controllers Подсказывает агенту, как правильно отдавать данные из Rails-контроллеров в Inertia.js: render inertia, типы пропсов, общие данные, flash и ошибки валидации. CX Codex +1 491установок inertia-rails-forms Скилл для работы с формами Inertia.js + Rails: создание, редактирование, удаление, визарды и загрузка файлов. Пригодится, когда нужно связать форму с контроллером Rails. CX Codex +1 486установок inertia-rails-typescript Скилл настраивает строгую типизацию TypeScript в Inertia Rails для React, Vue и Svelte. Помогает исправить ошибки TS2344 и TS2339. CX Codex +1 468установок inertia-rails-testing Скилл для тестов Inertia Rails на RSpec и Minitest: проверка компонента, пропсов и flash без ручного разбора JSON. CX Codex +1 465установок inertia-rails-setup Скилл анализирует стек Inertia Rails в проекте, подбирает недостающие библиотеки и генерирует блок конфигурации в CLAUDE.md. Помогает при первом старте или смене инструментов. CX Codex +1 419установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой