# Nuxt Configuration

## When to Use

Configuring `nuxt.config.ts`, modules, auto-imports, runtime config, layers.

## Basic Structure

```ts
// nuxt.config.ts
export default defineNuxtConfig({
  devtools: { enabled: true },

  modules: [
    '@nuxtjs/tailwindcss',
    '@pinia/nuxt'
  ],

  runtimeConfig: {
    // Private (server-only)
    apiSecret: process.env.API_SECRET,

    public: {
      // Public (client + server)
      apiBase: process.env.API_BASE || 'http://localhost:3000'
    }
  },

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

## Runtime Config

Access runtime config in app:

```ts
// Server-side
const config = useRuntimeConfig()
console.log(config.apiSecret) // Available

// Client-side
const config = useRuntimeConfig()
console.log(config.public.apiBase) // Available
console.log(config.apiSecret) // undefined (private)
```

### Runtime Config Validation (Recommended)

Use `nuxt-safe-runtime-config` for type-safe runtime config with build-time validation:

```bash
npx nuxi module add nuxt-safe-runtime-config
```

**Benefits:**

- Build-time validation (catches missing env vars early)
- Optional runtime validation (validates when server starts)
- Auto-generated types (no manual type definitions needed)
- No manual env var checks required (schema handles validation)

**Example with Valibot:**

```ts
import { number, object, optional, string } from 'valibot'

export default defineNuxtConfig({
  modules: ['nuxt-safe-runtime-config'],

  runtimeConfig: {
    databaseUrl: process.env.DATABASE_URL,
    secretKey: process.env.SECRET_KEY,
    port: Number.parseInt(process.env.PORT || '3000'),
    public: {
      apiBase: process.env.PUBLIC_API_BASE,
      appName: 'My App',
    },
  },

  safeRuntimeConfig: {
    $schema: object({
      public: object({
        apiBase: string(),
        appName: optional(string()),
      }),
      databaseUrl: string(),
      secretKey: string(),
      port: optional(number()),
    }),
    validateAtRuntime: true, // Optional: validate when server starts
  },
})
```

**Usage:**

```ts
// Auto-typed from schema - no generics needed
const config = useSafeRuntimeConfig()
// config.public.apiBase is string
// config.databaseUrl is string
```

**No manual env checks needed:**

```ts
// ❌ Don't do this with nuxt-safe-runtime-config
if (!config.databaseUrl) throw new Error('Missing DATABASE_URL')

// ✅ Schema validation handles it automatically
// If env var is missing, build fails with detailed error
```

Works with Zod, ArkType, or any Standard Schema library. See: https://github.com/onmax/nuxt-safe-runtime-config

## Auto-Imports

Nuxt auto-imports from these directories:

- `components/` - Vue components
- `composables/` - Composition functions
- `utils/` - Utility functions
- `server/utils/` - Server utilities (server-only)

### Custom Auto-Imports

```ts
export default defineNuxtConfig({
  imports: {
    dirs: [
      'stores',
      'types'
    ]
  }
})
```

### Disable Auto-Import

```ts
export default defineNuxtConfig({
  imports: {
    autoImport: false
  }
})
```

## Modules

```ts
export default defineNuxtConfig({
  modules: [
    '@nuxtjs/tailwindcss',
    '@pinia/nuxt',
    '@vueuse/nuxt',
    ['@nuxtjs/google-fonts', {
      families: {
        Inter: [400, 700]
      }
    }]
  ]
})
```

## App Config

For non-sensitive config exposed to client:

```ts
// app.config.ts
export default defineAppConfig({
  theme: {
    primaryColor: '#3b82f6',
    borderRadius: '0.5rem'
  }
})
```

Access in app:

```ts
const appConfig = useAppConfig()
console.log(appConfig.theme.primaryColor)
```

## TypeScript

```ts
export default defineNuxtConfig({
  typescript: {
    strict: true,
    typeCheck: true,
    shim: false
  }
})
```

## Build Configuration

```ts
export default defineNuxtConfig({
  build: {
    transpile: ['some-package']
  },

  vite: {
    css: {
      preprocessorOptions: {
        scss: {
          additionalData: '@use "@/assets/styles/variables" as *;'
        }
      }
    }
  }
})
```

## Route Rules

Pre-render, cache, or customize routes:

```ts
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/api/**': { cors: true },
    '/admin/**': { ssr: false },
    '/blog/**': { swr: 3600 } // Cache for 1 hour
  }
})
```

### ISR Route Rules

Use `isr` for incremental static regeneration:

```ts
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },        // Static at build time
    '/**': { isr: 60 },              // Regenerate every 60s
    '/package/**': { isr: 60 },      // ISR for dynamic routes
    '/search': { isr: false, cache: false },  // No cache
  }
})
```

### Route Rule Layouts (Nuxt 4.3+)

Apply layouts via route rules for centralized layout management:

```ts
export default defineNuxtConfig({
  routeRules: {
    '/admin/**': { appLayout: 'admin' },
    '/docs/**': { appLayout: 'docs' },
    '/': { appLayout: 'default' }
  }
})
```

**Benefits:** Centralized layout control, no need for `setPageLayout()` in every page.

## Inline Modules

Add conditional logic during nuxt prepare:

```ts
export default defineNuxtConfig({
  modules: [
    // Inline function module
    function (_, nuxt) {
      if (nuxt.options._prepare) {
        // Disable expensive operations during prepare
        nuxt.options.pwa ||= {}
        nuxt.options.pwa.pwaAssets ||= { disabled: true }
      }
    },
    '@nuxtjs/tailwindcss',
  ]
})
```

## Provider-Specific Modules

Use `std-env` to detect platform and configure accordingly:

```ts
// modules/vercel-cache.ts
import { defineNuxtModule } from 'nuxt/kit'
import { provider } from 'std-env'

export default defineNuxtModule({
  meta: { name: 'vercel-cache' },
  setup(_, nuxt) {
    if (provider !== 'vercel') return

    nuxt.hook('nitro:config', (nitroConfig) => {
      nitroConfig.storage ||= {}
      nitroConfig.storage.cache = {
        driver: 'vercel-runtime-cache',
        ...nitroConfig.storage.cache,
      }
    })
  }
})
```

Then register in nuxt.config.ts:

```ts
export default defineNuxtConfig({
  modules: ['~/modules/vercel-cache']
})
```

## Experimental Features

```ts
export default defineNuxtConfig({
  future: {
    compatibilityVersion: 4
  },

  experimental: {
    typedPages: true,
    viewTransition: true,
    payloadExtraction: true // Enable ISR/SWR payload extraction (Nuxt 4.3+)
  }
})
```

**Payload extraction** (Nuxt 4.3+): Enables cached payloads during client navigation for ISR/SWR routes, improving performance.

## Nitro Config

Server engine configuration:

```ts
export default defineNuxtConfig({
  nitro: {
    preset: 'vercel',
    compressPublicAssets: true,
    routeRules: {
      '/api/**': { cors: true }
    }
  }
})
```

## Layers

Extend or share configuration:

```ts
export default defineNuxtConfig({
  extends: [
    './base-layer'
  ]
})
```

## Environment Variables

Use `.env` file:

```env
API_SECRET=secret123
API_BASE=https://api.example.com
```

Access via runtimeConfig:

```ts
export default defineNuxtConfig({
  runtimeConfig: {
    apiSecret: process.env.API_SECRET,
    public: {
      apiBase: process.env.API_BASE
    }
  }
})
```

## Best Practices

- **Use nuxt-safe-runtime-config** for runtime config with validation
- **Public vs private** - keep secrets in private runtimeConfig
- **App config** for non-sensitive client config
- **Route rules** for performance (prerender, cache, SWR)
- **Auto-imports** for cleaner code
- **TypeScript strict mode** for better DX

## Common Mistakes

| ❌ Wrong                   | ✅ Right                     |
| -------------------------- | ---------------------------- |
| Hardcoded API URLs         | Use runtimeConfig.public     |
| Secrets in app.config      | Use runtimeConfig (private)  |
| Import everything manually | Let Nuxt auto-import         |
| process.env in client code | Use useRuntimeConfig()       |
| Manual env var validation  | Use nuxt-safe-runtime-config |
| if (!config.x) throw error | Schema validation handles it |

## Resources

- Nuxt config: https://nuxt.com/docs/api/nuxt-config
- Runtime config: https://nuxt.com/docs/guide/going-further/runtime-config
- App config: https://nuxt.com/docs/guide/directory-structure/app-config
- Modules: https://nuxt.com/modules
