--- id: inertia-rails/skills/shadcn-vue-inertia version: "404186cc" license: MIT install: manual updated: 2026-02-13 --- # shadcn-vue-inertia — This skill shows how to wire shadcn-vue UI components into Inertia Rails Vue 3 applications, replacing Nuxt-specific patterns with Inertia equivalents. Learn to bind form inputs via name attributes, manage dialogs with router state, render server-sorted tables, and display flash toasts—plus avoid common pitfalls like v-model conflicts and frozen computed values. Publisher: inertia-rails · Stars: 64 · Updated: 2026-02-13 Install (manual): `git clone https://github.com/inertia-rails/skills` ## SKILL.md # shadcn-vue for Inertia Rails shadcn-vue patterns adapted for Inertia.js + Rails + Vue 3. NOT Nuxt. **Before using a shadcn-vue example, ask:** - **Does it use Nuxt-specific APIs?** (`useRouter`, `useFetch`, ``) → Replace with Inertia `router`, server props, `` - **Does it use `vee-validate` + `zod`?** → Replace with Inertia `
` + `name` attributes. Inertia handles CSRF, errors, redirects, processing state. ## Key Differences from Nuxt Defaults | shadcn-vue default (Nuxt) | Inertia equivalent | |---|---| | `useFetch` / `useAsyncData` | Server-rendered props via controller | | `useRouter()` (Nuxt) | `router` from `@inertiajs/vue3` | | `` | `` from `@inertiajs/vue3` | | `vee-validate` + `zod` | Inertia `` component | | `FormField`, `FormItem`, `FormMessage` | Plain `` + `errors.field` | | `useHead()` (Nuxt) | `` from `@inertiajs/vue3` | **NEVER use shadcn-vue's `FormField`, `FormItem`, `FormLabel`, `FormMessage` components** — they depend on vee-validate's form context internally and will crash without it. Use plain shadcn-vue `Input`/`Label`/`Select` with `name` attributes inside Inertia ``, and render errors from the scoped slot's `errors` object. ## Setup `npx shadcn-vue@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-vue Inputs in Inertia `` Use plain shadcn-vue `Input`/`Label`/`Button` with `name` attributes inside Inertia ``. See `inertia-rails-forms` skill (+ `references/vue.md`) for full `` API. **The key pattern:** Replace shadcn-vue's `FormField`/`FormItem`/`FormMessage` with plain components + manual error display: ```vue ``` **`
``` Use `v-model` only with `useForm` (where you explicitly manage `form.name`). **`usePage()` returns a reactive object — use `computed()` for derived values:** ```vue ``` Without `computed()`, destructured values freeze at their initial state and won't update after Inertia navigation. **`@update:open` vs `@close` for Dialog** — shadcn-vue Dialog emits `update:open`, not `close`. Using `@close` silently does nothing: ```vue ``` ## Troubleshooting | Symptom | Cause | Fix | |---------|-------|-----| | `FormField`/`FormMessage` crash | Using shadcn-vue form components that depend on vee-validate | Replace with plain `Input`/`Label` + `errors.field` display | | `Select` value not submitted | Missing `name` prop | Add `name="field"` to `