Back to Skills

Nuxt Core

| Nuxt 4 core framework fundamentals: project setup, configuration, routing, SEO, error handling, and directory structure. Use when: creating new Nuxt 4 projects, configuring nuxt.config.ts, setting up routing and middleware, implementing SEO with useHead/useSeoMeta, handling er…

vue
By secondsky
21030Updated 5 days agoTypeScriptMIT

Skill Content

# Nuxt 4 Core Fundamentals

Project setup, configuration, routing, SEO, and error handling for Nuxt 4 applications.

## Quick Reference

### Version Requirements

| Package | Minimum | Recommended |
|---------|---------|-------------|
| nuxt | 4.0.0 | 4.2.x |
| vue | 3.5.0 | 3.5.x |
| nitro | 2.10.0 | 2.12.x |
| vite | 6.0.0 | 6.2.x |
| typescript | 5.0.0 | 5.x |

### Key Commands

```bash
# Create new project
bunx nuxi@latest init my-app

# Development
bun run dev

# Build for production
bun run build

# Preview production build
bun run preview

# Type checking
bun run postinstall  # Generates .nuxt directory
bunx nuxi typecheck

# Add a page/component/composable
bunx nuxi add page about
bunx nuxi add component MyButton
bunx nuxi add composable useAuth
```

## Secure Installation

Scaffolding tools like `bunx nuxi init` download and execute remote code. Before running, follow supply chain security best practices:

- **Block post-install scripts** — `npm config set ignore-scripts true` (or Bun: disabled by default)
- **Cooldown period** — Wait 7 days for new package versions to be vetted by the community
- **Audit before installing** — Run `socket package score npm <pkg>` or use `socket npm install <pkg>` to check packages

Load the `dependency-upgrade` skill for full security configuration including Socket CLI integration, cooldown setup, lockfile validation, and CI enforcement.

## Directory Structure (Nuxt v4)

```
my-nuxt-app/
├── app/                    # Default srcDir in v4
│   ├── assets/             # Build-processed assets (CSS, images)
│   ├── components/         # Auto-imported Vue components
│   ├── composables/        # Auto-imported composables
│   ├── layouts/            # Layout components
│   ├── middleware/         # Route middleware
│   ├── pages/              # File-based routing
│   ├── plugins/            # Nuxt plugins
│   ├── utils/              # Auto-imported utility functions
│   ├── app.vue             # Main app component
│   ├── app.config.ts       # App-level runtime config
│   ├── error.vue           # Error page component
│   └── router.options.ts   # Router configuration
│
├── server/                 # Server-side code (Nitro)
│   ├── api/                # API endpoints
│   ├── middleware/         # Server middleware
│   ├── plugins/            # Nitro plugins
│   ├── routes/             # Server routes
│   └── utils/              # Server utilities
│
├── public/                 # Static assets (served from root)
├── shared/                 # Shared code (app + server)
├── content/                # Nuxt Content files (if using)
├── layers/                 # Nuxt layers
├── modules/                # Local modules
├── .nuxt/                  # Generated files (git ignored)
├── .output/                # Build output (git ignored)
├── nuxt.config.ts          # Nuxt configuration
├── tsconfig.json           # TypeScript configuration
└── package.json            # Dependencies
```

**Key Change in v4**: The `app/` directory is now the default `srcDir`. All app code goes in `app/`, server code stays in `server/`.

## When to Load References

**Load `references/configuration-deep.md` when:**
- Configuring advanced nuxt.config.ts options
- Setting up modules and plugins
- Customizing Vite or Nitro configuration
- Configuring experimental features

**Load `references/routing-advanced.md` when:**
- Implementing complex routing patterns
- Creating route middleware with authentication
- Using catch-all routes or optional parameters
- Configuring router options

**Load `references/plugins-architecture.md` when:**
- Creating Nuxt plugins
- Injecting global utilities or composables
- Integrating third-party libraries
- Understanding plugin execution order

## Configuration

### Basic nuxt.config.ts

```typescript
export default defineNuxtConfig({
  // Enable Nuxt 4 features
  future: {
    compatibilityVersion: 4
  },

  // Development tools
  devtools: { enabled: true },

  // Modules
  modules: [
    '@nuxt/ui',
    '@nuxt/content',
    '@nuxt/image'
  ],

  // Runtime config (environment variables)
  runtimeConfig: {
    // Server-only (not exposed to client)
    apiSecret: process.env.API_SECRET,
    databaseUrl: process.env.DATABASE_URL,

    // Public (client + server)
    public: {
      apiBase: process.env.API_BASE || 'https://api.example.com',
      appName: 'My App'
    }
  },

  // App config
  app: {
    head: {
      title: 'My Nuxt App',
      meta: [
        { charset: 'utf-8' },
        { name: 'viewport', content: 'width=device-width, initial-scale=1' }
      ]
    }
  },

  // Nitro config (server)
  nitro: {
    preset: 'cloudflare-pages'
  },

  // TypeScript
  typescript: {
    strict: true,
    typeCheck: true
  }
})
```

### Runtime Config Usage

```typescript
// In composables or components
const config = useRuntimeConfig()

// Public values (client + server)
const apiBase = config.public.apiBase

// Server-only values (only in server/)
const apiSecret = config.apiSecret  // undefined on client!
```

**Critical Rule**: Always use `useRuntimeConfig()` instead of `process.env` for environment variables in production.

### App Config vs Runtime Config

| Feature | App Config | Runtime Config |
|---------|------------|----------------|
| Location | `app.config.ts` | `nuxt.config.ts` |
| Hot reload | Yes | No |
| Secrets | No | Yes (server-only) |
| Use case | UI settings, themes | API keys, URLs |

```typescript
// app/app.config.ts - UI settings (hot-reloadable)
export default defineAppConfig({
  theme: {
    primaryColor: '#3490dc'
  },
  ui: {
    rounded: 'lg'
  }
})

// Usage
const appConfig = useAppConfig()
const color = appConfig.theme.primaryColor
```

## Routing

### File-Based Routing

```
app/pages/
├── index.vue              → /
├── about.vue              → /about
├── users/
│   ├── index.vue          → /users
│   └── [id].vue           → /users/:id
└── blog/
    ├── index.vue          → /blog
    ├── [slug].vue         → /blog/:slug
    └── [...slug].vue      → /blog/* (catch-all)
```

### Dynamic Routes

```vue
<!-- app/pages/users/[id].vue -->
<script setup lang="ts">
const route = useRoute()

// Get route params
const userId = route.params.id

// Reactive (updates when route changes)
const userId = computed(() => route.params.id)

// Fetch user data
const { data: user } = await useFetch(`/api/users/${userId.value}`)
</script>

<template>
  <div>
    <h1>{{ user?.name }}</h1>
  </div>
</template>
```

### Navigation

```vue
<script setup>
const goToUser = (id: string) => {
  navigateTo(`/users/${id}`)
}

const goBack = () => {
  navigateTo(-1)  // Go back in history
}

// With options
const goToLogin = () => {
  navigateTo('/login', {
    replace: true,  // Replace current history entry
    external: false // Internal navigation
  })
}
</script>

<template>
  <!-- Declarative navigation -->
  <NuxtLink to="/about">About</NuxtLink>
  <NuxtLink :to="`/users/${user.id}`">View User</NuxtLink>

  <!-- Prefetching (default: on hover) -->
  <NuxtLink to="/dashboard" prefetch>Dashboard</NuxtLink>

  <!-- No prefetch -->
  <NuxtLink to="/admin" :prefetch="false">Admin</NuxtLink>
</template>
```

### Route Middleware

```typescript
// app/middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
  const { isAuthenticated } = useAuth()

  if (!isAuthenticated.value) {
    return navigateTo('/login')
  }
})
```

```vue
<!-- app/pages/dashboard.vue -->
<script setup lang="ts">
definePageMeta({
  middleware: 'auth'
})
</script>
```

### Global Middleware

```typescript
// app/middleware/analytics.global.ts
export default defineNuxtRouteMiddleware((to, from) => {
  // Runs on every route change
  if (import.meta.client) {
    window.gtag?.('event', 'page_view', {
      page_path: to.path
    })
  }
})
```

### Page Meta

```vue
<script setup lang="ts">
definePageMeta({
  title: 'Dashboard',
  middleware: ['auth'],
  layout: 'admin',
  pageTransition: { name: 'fade' },
  keepalive: true
})
</script>
```

## SEO & Meta Tags

### useSeoMeta (Recommended)

```vue
<script setup lang="ts">
useSeoMeta({
  title: 'My Page Title',
  description: 'Page description for search engines',
  ogTitle: 'My Page Title',
  ogDescription: 'Page description',
  ogImage: 'https://example.com/og-image.jpg',
  ogUrl: 'https://example.com/my-page',
  twitterCard: 'summary_large_image',
  twitterTitle: 'My Page Title',
  twitterDescription: 'Page description',
  twitterImage: 'https://example.com/og-image.jpg'
})
</script>
```

### useHead (More Control)

```vue
<script setup lang="ts">
useHead({
  title: 'My Page Title',
  meta: [
    { name: 'description', content: 'Page description' },
    { property: 'og:title', content: 'My Page Title' }
  ],
  link: [
    { rel: 'canonical', href: 'https://example.com/my-page' }
  ],
  script: [
    { src: 'https://example.com/script.js', defer: true }
  ]
})
</script>
```

### Dynamic Meta Tags

```vue
<script setup lang="ts">
const { data: post } = await useFetch(`/api/posts/${route.params.slug}`)

useSeoMeta({
  title: () => post.value?.title,
  description: () => post.value?.excerpt,
  ogImage: () => post.value?.image
})
</script>
```

### Title Template

```typescript
// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      titleTemplate: '%s | My App'  // "Page Title | My App"
    }
  }
})
```

## Error Handling

### Error Page

```vue
<!-- app/error.vue -->
<script setup lang="ts">
import type { NuxtError } from '#app'

const props = defineProps<{
  error: NuxtError
}>()

const handleError = () => {
  clearError({ redirect: '/' })
}
</script>

<template>
  <div class="error-page">
    <h1>{{ error.statusCode }}</h1>
    <p>{{ error.message }}</p>
    <button @click="handleError">Go Home</button>
  </div>
</template>
```

### Error Boundaries (Component-Level)

```vue
<template>
  <NuxtErrorBoundary @error="handleError">
    <template #error="{ error, clearError }">
      <div class="error-container">
        <h2>Something went wrong</h2>
        <p>{{ error.message }}</p>
        <button @click="clearError">Try again</button>
      </div>
    </template>

    <!-- Your component content -->
    <MyComponent />
  </NuxtErrorBoundary>
</template>

<script setup>
const handleError = (error: Error) => {
  console.error('Component error:', error)
  // Send to error tracking service
}
</script>
```

### Throwing Errors

```typescript
// In pages or components
throw createError({
  statusCode: 404,
  statusMessage: 'Page Not Found',
  fatal: true  // Shows error page, stops rendering
})

// Non-fatal error (shows inline)
throw createError({
  statusCode: 400,
  message: 'Invalid input'
})
```

### API Error Handling

```typescript
const { data, error } = await useFetch('/api/users')

if (error.value) {
  // Handle error gracefully
  showError({
    statusCode: error.value.statusCode,
    message: error.value.message
  })
}
```

## Common Anti-Patterns

### Using process.env Instead of Runtime Config

```typescript
// WRONG - Won't work in production!
const apiUrl = process.env.API_URL

// CORRECT
const config = useRuntimeConfig()
const apiUrl = config.public.apiBase
```

### Missing Middleware Guards

```typescript
// WRONG - No return, middleware continues
export default defineNuxtRouteMiddleware((to) => {
  const { isAuthenticated } = useAuth()
  if (!isAuthenticated.value) {
    navigateTo('/login')  // Missing return!
  }
})

// CORRECT
export default defineNuxtRouteMiddleware((to) => {
  const { isAuthenticated } = useAuth()
  if (!isAuthenticated.value) {
    return navigateTo('/login')  // Return stops middleware chain
  }
})
```

### Non-Reactive Route Params

```typescript
// WRONG - Not reactive
const userId = route.params.id

// CORRECT - Reactive
const userId = computed(() => route.params.id)
```

## Troubleshooting

**Build Errors / Type Errors:**
```bash
rm -rf .nuxt .output node_modules/.vite && bun install && bun run dev
```

**Route Not Found:**
- Check file is in `app/pages/` (not root `pages/`)
- Verify file extension is `.vue`
- Check for typos in dynamic params `[id].vue`

**Middleware Not Running:**
- Ensure file has `.global.ts` suffix for global middleware
- Check `definePageMeta({ middleware: 'name' })` matches filename
- Verify middleware returns `navigateTo()` or nothing

**Meta Tags Not Updating:**
- Use reactive values: `title: () => post.value?.title`
- Ensure `useSeoMeta` is called in `<script setup>`

## Related Skills

- **nuxt-data**: Composables, data fetching, state management
- **nuxt-server**: Server routes, API patterns, database integration
- **nuxt-production**: Performance, testing, deployment
- **nuxt-ui-v4**: Nuxt UI component library

## Templates Available

See `templates/` directory for:
- Production-ready `nuxt.config.ts`
- `app.vue` with proper structure
- Middleware examples

---

**Version**: 4.0.0 | **Last Updated**: 2025-12-28 | **License**: MIT

How to use

  1. Copy the skill content above
  2. Create a .claude/skills/claude-skills-nuxt-core directory in your project (or ~/.claude/skills/claude-skills-nuxt-core to use it in every project)
  3. Save the content as .claude/skills/claude-skills-nuxt-core/SKILL.md
  4. Claude Code loads it automatically when the task matches, or run /claude-skills-nuxt-core to invoke it directly

Claude Code Skills Collection

142 production-ready skills for Claude Code CLI

Version 3.6.3 | Last Updated: 2026-08-06

<div align="center">

🔌 Platform / Harness Support

These plugins ship as Claude Code marketplace plugins (.claude-plugin/ manifests) and Codex CLI plugins (.codex-plugin/ manifests). Other harnesses consume the same skills via skills.sh — the cross-harness bridge.

HarnessMarketplace supportHow to install
Claude CodeNative (federated)/plugin marketplace add secondsky/claude-skills, then /plugin install <name>@claude-skills
ZCodeNative (reads .claude-plugin/ manifests)Add this repo as a marketplace in the ZCode GUI
Codex CLINative (federated)codex plugin marketplace add secondsky/claude-skills, then /plugins in the Codex TUI
Cursor⚠️ Adaptation neededCursor has an official marketplace, but expects .cursor-plugin/plugin.json (UI "Add to Cursor") this repo does not generate yet. Use skills.sh.
opencode❌ No marketplacenpm plugins only (opencode.json plugin[]). Use skills.sh or vendor manually.
Gemini CLI❌ No marketplacegemini extensions install <url> only. Use skills.sh or vendor manually.
</div>

A curated collection of battle-tested skills for building modern web applications with Cloudflare, AI integrations, React, Tailwind, and more.


Quick Start

Marketplace Installation (Recommended)

# Add the marketplace
/plugin marketplace add https://github.com/secondsky/claude-skills

# Install individual skills as needed
/plugin install cloudflare-d1@claude-skills
/plugin install tailwind-v4-shadcn@claude-skills
/plugin install gemini-cli@claude-skills

See MARKETPLACE.md for complete catalog of all 142 skills.

Codex CLI Installation

This repo generates .codex-plugin/ manifests and a .agents/plugins/marketplace.json for all 142 plugins, so Codex CLI can install them natively:

# Add the marketplace (from GitHub)
codex plugin marketplace add secondsky/claude-skills

# Browse and install plugins in the Codex TUI
#   /plugins          # opens the plugin browser
#   Space             # enable/disable a plugin

Skills are auto-discovered from each plugin's skills/ directory — the same SKILL.md files Claude Code uses. Claude-specific slash commands and subagents are not carried into Codex (use Codex's /import command for that).


Installing with skills.sh

skills.sh is an open agent-skills registry and npx skills CLI (maintained by Vercel) that auto-detects your coding agent — Claude Code, Cursor, Codex, Copilot, Cline, opencode, and 70+ others — and installs each skill into the correct directory for that harness. It is the universal cross-harness path for harnesses without a marketplace (opencode, Gemini CLI) or where this repo's manifest format isn't generated yet (Cursor).

# Install one skill (auto-detects your agent)
npx skills add secondsky/claude-skills --skill cloudflare-d1

# Install several specific skills
npx skills add secondsky/claude-skills --skill cloudflare-d1 --skill tailwind-v4-shadcn

# Try a skill once without installing (pipes its prompt to your agent)
npx skills use secondsky/claude-skills@cloudflare-d1 | claude

# Target a specific agent explicitly
npx skills add secondsky/claude-skills --skill cloudflare-d1 --agent codex

# List what's installed, search, update, remove
npx skills ls -g
npx skills find cloudflare
npx skills update cloudflare-d1
npx skills remove cloudflare-d1

Bulk install note: npx skills add secondsky/claude-skills --all installs every discovered skill at once, but discovery walks skills.sh's standard container directories (skills/, .claude/skills/, …). This repo nests skills under plugins/<name>/skills/<skill>/, so --all may not pick up everything in one pass — install the skills you need by name with --skill, or run npx skills add secondsky/claude-skills -l to list what it finds.

Security scanning caveat

skills.sh runs every published skill through three scanners (Gen Agent Trust Hub, Socket, Snyk) plus an LLM-based meta-analyzer, and publishes the results at skills.sh/audits. The LLM analysis stage has been publicly shown (Trail of Bits, June 2026) to both miss genuinely malicious skills and flag unfamiliar version pins (e.g. newest dependency versions) as suspicious false positives. Treat skills.sh warnings as advisory, not authoritative — and verify against this repo's own version pins before acting on a warning.


Repository Structure

This repository contains 142 production-tested skills for Claude Code, each focused on a specific technology or capability.

Individual Skills: Each skill is a standalone unit with:

  • SKILL.md - Core knowledge and guidance
  • Templates - Working code examples
  • References - Extended documentation
  • Scripts - Helper utilities

Installation Options:

  1. Marketplace (recommended) - Install individual skills via /plugin install <name>@claude-skills
  2. Cross-harness - Install into any supported agent with npx skills add secondsky/claude-skills --skill <name> (see Installing with skills.sh)

Available Skills (142 Individual Skills)

Each skill is individually installable. Install only the skills you need.

Full Catalog: See MARKETPLACE.md for detailed listings.

Categories

CategorySkillsExamples
tooling24turborepo, plan-interview, code-review
frontend26nuxt-v4, nuxt-v5, tailwind-v4-shadcn, tanstack-query, nuxt-studio, maz-ui, threejs
cloudflare21cloudflare-d1, cloudflare-workers-ai, cloudflare-agents
api16api-design-principles, graphql-implementation
ai7gemini-cli, ml-model-training, tanstack-ai
web10hono-routing, firecrawl-scraper, web-performance
security6csrf-protection, xss-prevention, cybersecurity
mobile5react-native-app, react-native-skills
woocommerce4woocommerce-backend-dev
testing4vitest-testing, playwright-testing
design4design-review, design-system-creation
auth4better-auth
architecture3microservices-patterns, architecture-patterns
data2recommendation-engine, recommendation-system
cms2hugo, wordpress-plugin-core
database1drizzle-orm-d1
seo2seo-optimizer, seo-keyword-cluster-builder
documentation1technical-specification

How It Works

Auto-Discovery

Claude Code automatically checks ~/.claude/skills/ for relevant skills before planning tasks:

User: "Set up a Cloudflare Worker with D1 database"
           ↓
Claude: [Checks skills automatically]
           ↓
Claude: "Found cloudflare-d1 skills.
         These prevent 12 documented errors. Use them?"
           ↓
User: "Yes"
           ↓
Result: Production-ready setup, zero errors, ~65% token savings

Note: Due to token limits, not all skills may be visible at once. See ⚠️ Important: Token Limits below.

Skill Structure

Each plugin is a directory under plugins/<plugin-name>/ containing one or more skills:

plugins/[plugin-name]/
├── .claude-plugin/
│   └── plugin.json       # Plugin manifest (marketplace metadata)
├── README.md
├── skills/
│   └── [skill-name]/
│       ├── SKILL.md          # Core knowledge and guidance
│       ├── templates/        # Ready-to-copy templates
│       ├── scripts/          # Helper utilities
│       └── references/       # Extended documentation
└── (optional) agents/, commands/, hooks/

Recent Additions

July 2026

Offensive Security (new category):

  • cybersecurity — Unified OSS-only cybersecurity skill with progressive disclosure. Fuses 7 community skills (mukul975 business-logic/XSS/host-header/forced-browsing/open-redirect, rysweet/amplihack cybersecurity-analyst, Aradotso security-detections-mcp) ported to fully open-source tooling (OWASP ZAP, Dalfox, ffuf, Nuclei, mitmproxy, interact.sh, Semgrep, Sigma). Covers threat modeling (STRIDE/PASTA/VAST, MITRE ATT&CK), web-vuln testing, SAST, code audit, AI/LLM-app security, and detection engineering. Live-target testing is gated behind an authorization disclaimer; static analysis, code review, and threat modeling are always available. Cross-references the 5 existing defensive security plugins (csrf-protection, xss-prevention, vulnerability-scanning, security-headers-configuration, defense-in-depth-validation) for remediation. Integrates 20 Aradotso dev-security skills across 5 grouped reference docs.

May 2026

Supply Chain Security (cross-cutting):

  • dependency-upgrade expanded with Socket CLI integration — proactive malicious package detection, typosquatting alerts, and CI/CD security gates. New 418-line reference guide, 2 GitHub Actions templates, and expanded supply chain security comparison (3 tools)
  • 31 skills now include "Secure Installation" guidance — contextually-tailored security sections across all high-risk skill categories (scaffolding, MCP/agent SDKs, multi-provider installs, Docker, CI/CD). Covers 8 Bun skills, 5 Nuxt skills, 6 Cloudflare skills, 4 AI/agent skills, and 8 frontend/tooling skills
  • Supply chain security is now a first-class cross-cutting concern woven into the skill collection — not a standalone topic

February - April 2026

Full-Stack Frameworks:

  • nuxt-v5 (v1.0.0) - Full Nuxt 5 support with 4 skills (core, data, server, production), 3 diagnostic agents, and interactive setup wizard
  • threejs (v1.0.0) - 3D web graphics: scenes, geometries, shaders, animations, post-processing

Infrastructure:

  • JSON schema validation - Automated plugin.json validation with CI support
  • GitHub issue templates - Skill-specific issue templates for bug reports, feature requests, and submissions

Plugin Enhancements:

  • mutation-testing - Added Bun native runner support
  • dependency-upgrade - Added supply chain security content

December 2025 - January 2026

Frontend Expansion:

  • nuxt-studio (v1.0.0) - Visual CMS for Nuxt Content with live preview, OAuth auth, and R2 storage integration
  • maz-ui (v1.0.0) - 50+ Vue/Nuxt components with theming, i18n, form generation, and 14 composables

Developer Workflow:

  • plan-interview (v2.0.0) - Adaptive interview-driven spec generation with autonomous quality review
  • turborepo (v2.8.0) - Updated to official Vercel skill with enhanced monorepo build optimization

Mobile Development:

  • react-native-skills (v1.0.0) - React Native & Expo best practices with performance optimization patterns

Enhanced Authentication:

  • better-auth (v2.2.0) - Expanded to 18 framework integrations with 30+ authentication plugins

⚠️ Important: Token Limits

Skill Visibility Constraint

Claude Code has a 15,000 character limit for the total size of skill descriptions in the system prompt. This limit also applies to commands and agents.

What this means:

  • Not all 142 skills may be visible in Claude's context at once
  • Skills are loaded based on relevance and available token budget
  • You can verify how many skills Claude currently sees by asking: "How many skills do you see in your system prompt?"

Checking Visible Skills

To verify which skills are currently loaded:

# Ask Claude Code directly
"Check what skills/plugins you see in your system prompt"

Claude will report something like: "85 of 142 skills visible due to token limits"

Workaround: Increase Token Budget

You can double the headroom for s

View source on GitHub