Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
secondsky avatar

Nuxt Core

  • 313 installs
  • 202 repo stars
  • Updated August 4, 2026
  • secondsky/claude-skills

nuxt-core is an agent skill that teaches Nuxt 5 project setup, file-based routing, SEO meta tags, error handling, and Vite 8/Nitro v3 configuration for developers building production Nuxt applications.

About

nuxt-core is a Claude agent skill in secondsky/claude-skills (metadata version 5.0.0) covering Nuxt 5 core framework fundamentals. It documents minimum versions for nuxt 5.0.0, vue 3.5.0, nitro 3.0.0, vite 8.0.0, and typescript 5.0.0, plus bunx nuxi commands for init, dev, build, and scaffolding pages or composables. The skill explains Nuxt 5 directory layout with app/pages routing, route middleware, useSeoMeta and useHead patterns, error.vue and NuxtErrorBoundary handling, runtime versus app config, and Vite 8 Rolldown rolldownOptions migration from rollupOptions. Developers reach for nuxt-core when creating new Nuxt 5 apps, configuring nuxt.config.ts, implementing file-based routes and auth middleware, adding SEO metadata, handling SSR errors, or migrating Nuxt 4 config patterns to Nuxt 5 compatibilityVersion 5 defaults.

  • nuxt-core

Nuxt Core by the numbers

  • 313 all-time installs (skills.sh)
  • +13 installs in the week ending Aug 5, 2026 (Skillselion tracking)
  • Ranked #1,306 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/secondsky/claude-skills --skill nuxt-core

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs313
repo stars202
Last updatedAugust 4, 2026
Repositorysecondsky/claude-skills

How do you set up routing and SEO in Nuxt 5?

Use nuxt-core for development tasks

Who is it for?

Frontend developers creating or configuring Nuxt 5 applications who need routing, SEO, middleware, and Vite 8/Nitro v3 setup guidance.

Skip if: Teams needing Nuxt server API design, data-fetching composables, or production deployment pipelines without core app scaffolding.

When should I use this skill?

User creates a Nuxt 5 app, configures nuxt.config.ts, sets up routing/middleware, implements useSeoMeta, or handles error.vue patterns.

What you get

nuxt.config.ts, app/pages routes, middleware files, SEO meta setup, and error.vue error handling patterns.

  • nuxt.config.ts configuration
  • app/pages route structure
  • SEO and error-handling component patterns

By the numbers

  • Metadata version 5.0.0 targeting Nuxt 5.0.0, Vue 3.5.0, Nitro 3.0.0, and Vite 8.0.0
  • Documents 5 minimum package version requirements in quick reference

Files

SKILL.mdMarkdownGitHub ↗

Nuxt 4 Core Fundamentals

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

Quick Reference

Version Requirements

PackageMinimumRecommended
nuxt4.0.04.2.x
vue3.5.03.5.x
nitro2.10.02.12.x
vite6.0.06.2.x
typescript5.0.05.x

Key Commands

# 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 scriptsnpm 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

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

// 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

FeatureApp ConfigRuntime Config
Locationapp.config.tsnuxt.config.ts
Hot reloadYesNo
SecretsNoYes (server-only)
Use caseUI settings, themesAPI keys, URLs
// 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

<!-- 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

<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

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

  if (!isAuthenticated.value) {
    return navigateTo('/login')
  }
})
<!-- app/pages/dashboard.vue -->
<script setup lang="ts">
definePageMeta({
  middleware: 'auth'
})
</script>

Global Middleware

// 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

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

SEO & Meta Tags

useSeoMeta (Recommended)

<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)

<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

<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

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

Error Handling

Error Page

<!-- 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)

<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

// 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

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

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

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

Missing Middleware Guards

// 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

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

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

Troubleshooting

Build Errors / Type Errors:

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

Related skills

How it compares

Pick nuxt-core over nuxt-data or nuxt-server skills when the task is app scaffolding, routing, SEO, and core config rather than data fetching or API routes.

FAQ

Which Nuxt version does nuxt-core target?

nuxt-core targets Nuxt 5.0.0 with metadata version 5.0.0, recommending vue 3.5.0, nitro 3.0.0, vite 8.0.0, and typescript 5.0.0 minimum versions for new projects.

What Nuxt 5 changes does nuxt-core document?

nuxt-core documents Nuxt 5 shifts including Vite 8 Rolldown bundling, Nitro v3 with Web Standard APIs, normalized page component names, clearNuxtState resetting to defaults, and optional JSX plugin installation.

Backend & APIsbackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.