Configuration File (nxh.config.js)
Configure generation options for useFetch and useAsyncData composables using a configuration file instead of CLI arguments.
Overview
The configuration file allows you to:
- ✅ Set default generation options
- ✅ Configure
baseURLfor all generated composables - ✅ Specify which generators to use
- ✅ Filter by OpenAPI tags
- ✅ Automate generation without interactive prompts
For useFetch and useAsyncData Only
Important: The configuration file (especially baseUrl) applies to:
- ✅ useFetch composables
- ✅ useAsyncData composables
It does NOT apply to:
- ❌ nuxtServer routes (server routes use Nuxt's
runtimeConfiginstead)
See Server Routes Configuration for nuxtServer configuration.
Creating the Config File
Create a configuration file in the root of your project (same level as package.json):
Supported File Names
The CLI will look for these files in order:
nxh.config.js← Recommendednxh.config.mjsnuxt-openapi-hyperfetch.jsnuxt-openapi-hyperfetch.mjs
Example:
// nxh.config.js (in project root)
export default {
input: './openapi.yaml',
output: './swagger', // OpenAPI files + composables go here
generator: 'heyapi', // 'openapi' (requires Java) | 'heyapi' (Node.js only)
baseUrl: 'https://api.example.com',
generators: ['useFetch', 'useAsyncData', 'nuxtServer'],
serverRoutePath: './server/api', // nuxtServer routes go here (separate)
}Configuration Options
input
Type: string
Required: Yes (or provide via CLI)
Path or URL to your OpenAPI/Swagger specification.
// Local file
input: './openapi.yaml'
input: './specs/api-v2.json'
// Remote URL
input: 'https://api.example.com/openapi.json'
input: 'https://petstore3.swagger.io/api/v3/openapi.json'output
Type: string
Default: './composables'
Output directory where generated files will be placed.
output: './composables'
output: './src/api'
output: './api/generated'Generated structure:
The top-level structure differs depending on the backend chosen during generation.
OpenAPI Generator (official):
output/ # e.g. ./swagger
├── apis/ # API classes (one per tag)
│ ├── PetApi.ts
│ └── ...
├── models/ # Model types
│ ├── Pet.ts
│ └── ...
└── composables/ # Our generated composables
├── use-fetch/
│ ├── composables/
│ ├── runtime/
│ ├── shared/
│ └── index.ts
└── use-async-data/
├── composables/
├── runtime/
├── shared/
└── index.ts@hey-api/openapi-ts:
output/ # e.g. ./swagger
├── client/ # HTTP client implementation
├── core/ # Core runtime utilities
├── client.gen.ts
├── index.ts
├── sdk.gen.ts # All SDK operations
├── types.gen.ts # All model types
└── composables/ # Our generated composables
├── use-fetch/
│ ├── composables/
│ ├── runtime/
│ ├── shared/
│ └── index.ts
└── use-async-data/
├── composables/
├── runtime/
├── shared/
└── index.tsTIP
composables/ lives alongside the backend-generated files inside the same output directory.
baseUrl
Type: string
Optional
Applies to: useFetch and useAsyncData only
Base URL that will be automatically added to all generated composables.
Only for Client Composables
baseUrl is only used by useFetch and useAsyncData generators.
For nuxtServer routes, configure the API base URL via Nuxt's runtimeConfig instead. See Server Routes.
Without baseUrl:
// Generated composable
export const useFetchGetPets = (params, options) => {
return useApiRequest('/pets', {
method: 'GET',
...options
})
}
// Usage - must specify full URL or rely on Nuxt's proxy
const { data } = useFetchGetPets({})
// Calls: /pets (relative)With baseUrl:
// nxh.config.js
export default {
baseUrl: 'https://api.example.com'
}// Generated composable
export const useFetchGetPets = (params, options) => {
return useApiRequest('/pets', {
method: 'GET',
baseURL: 'https://api.example.com', // ✅ Automatically added
...options
})
}
// Usage - works immediately
const { data } = useFetchGetPets({})
// Calls: https://api.example.com/petsCommon baseUrl patterns:
// Development
baseUrl: 'http://localhost:3001'
// Production
baseUrl: 'https://api.example.com'
// With API version
baseUrl: 'https://api.example.com/v1'
// Subdomain
baseUrl: 'https://api.myapp.com'generators
Type: Array<'useFetch' | 'useAsyncData' | 'nuxtServer'>
Default: ['useFetch', 'useAsyncData']
Which generators to use when creating composables.
// Generate only useFetch
generators: ['useFetch']
// Generate useFetch and useAsyncData
generators: ['useFetch', 'useAsyncData']
// Generate server routes only
generators: ['nuxtServer']
// Generate everything
generators: ['useFetch', 'useAsyncData', 'nuxtServer']What each generator creates:
useFetch: Composables using Nuxt'suseFetch(simpler, auto cache keys)useAsyncData: Composables using Nuxt'suseAsyncData(more control, auto cache keys with optional custom key, includes Raw variant with headers)nuxtServer: Nuxt server API routes (BFF pattern)
generator
Type: 'openapi' | 'heyapi'
Default: interactive prompt (first run)
The backend engine used to generate the API client code before composables are created.
// Use OpenAPI Generator (official) — requires Java 11+
generator: 'openapi'
// Use @hey-api/openapi-ts — Node.js only, no Java required
generator: 'heyapi'| Value | Tool | Requirement | Output |
|---|---|---|---|
'openapi' | OpenAPI Generator (official) | Java 11+ | apis/, models/ |
'heyapi' | @hey-api/openapi-ts | Node.js only | client/, core/, sdk.gen.ts, types.gen.ts |
TIP
If generator is omitted from the config, the CLI will prompt you to choose interactively on the first run. Set it explicitly to skip the prompt in CI/CD or team setups.
tags
Type: string[]
Optional
Generate only endpoints with specific OpenAPI tags.
// Only generate pets and users endpoints
tags: ['pets', 'users']
// Only public APIs
tags: ['public']OpenAPI example:
paths:
/pets:
get:
tags: ['pets'] # ← Will be included if tags: ['pets']
/users:
get:
tags: ['users'] # ← Will be excluded
/orders:
get:
tags: ['orders'] # ← Will be excludedexcludeTags
Type: string[]
Optional
Exclude endpoints with specific OpenAPI tags.
// Exclude internal and deprecated endpoints
excludeTags: ['internal', 'deprecated']
// Exclude admin endpoints
excludeTags: ['admin']Use case:
// Generate everything except admin and internal
export default {
input: './openapi.yaml',
output: './composables',
excludeTags: ['admin', 'internal'],
generators: ['useFetch']
}overwrite
Type: boolean
Default: false
Overwrite existing files without prompting.
// Prompt before overwriting
overwrite: false
// Always overwrite without asking
overwrite: trueUseful for:
- CI/CD pipelines
- Automated regeneration
- Development workflows
dryRun
Type: boolean
Default: false
Preview what would be generated without writing files.
dryRun: trueUseful for:
- Testing configuration
- Seeing what will be generated
- Validating OpenAPI spec
verbose
Type: boolean
Default: false
Enable detailed logging.
verbose: trueShows:
- Configuration loaded
- Files being processed
- Generation progress
- Detailed error messages
watch
Type: boolean
Default: false
Watch OpenAPI file for changes and regenerate automatically.
watch: trueUseful for:
- Development
- API design workflow
- Keeping composables in sync
Complete Examples
Example 1: Basic Setup
// nxh.config.js
export default {
input: './openapi.yaml',
output: './composables',
generator: 'heyapi', // no Java required
baseUrl: 'https://api.example.com',
generators: ['useFetch', 'useAsyncData']
}Usage:
# Just run generate - no arguments needed
npx nxh generateExample 2: Development + Production
Development:
// nxh.config.dev.js
export default {
input: 'http://localhost:3001/openapi.json',
output: './composables',
generator: 'heyapi',
baseUrl: 'http://localhost:3001',
generators: ['useFetch'],
watch: true,
verbose: true
}Production:
// nxh.config.js
export default {
input: 'https://api.example.com/openapi.json',
output: './composables',
generator: 'heyapi',
baseUrl: 'https://api.example.com',
generators: ['useFetch', 'useAsyncData'],
overwrite: true
}Usage:
# Development
npx nxh generate --config nxh.config.dev.js --watch
# Production
npx nxh generateExample 3: Selective Generation
// nxh.config.js
export default {
input: './openapi.yaml',
output: './composables',
baseUrl: 'https://api.example.com',
// Only generate public endpoints
tags: ['public', 'users', 'products'],
// Exclude admin and internal
excludeTags: ['admin', 'internal'],
// Only useFetch (simpler)
generators: ['useFetch']
}Example 4: Multi-Environment
Use environment variables:
// nxh.config.js
const apiUrl = process.env.API_URL || 'http://localhost:3001'
export default {
input: './openapi.yaml',
output: './composables',
baseUrl: apiUrl,
generators: ['useFetch', 'useAsyncData']
}Usage:
# Development
API_URL=http://localhost:3001 npx nxh generate
# Staging
API_URL=https://staging-api.example.com npx nxh generate
# Production
API_URL=https://api.example.com npx nxh generateExample 5: Monorepo
// packages/api-client/nxh.config.js
export default {
input: '../../specs/openapi.yaml',
output: './src/generated',
baseUrl: 'https://api.example.com',
generators: ['useFetch'],
overwrite: true
}CLI Override Behavior
CLI arguments always override config file settings.
// nxh.config.js
export default {
input: './openapi.yaml',
output: './composables',
baseUrl: 'https://api.example.com'
}# Override baseUrl via CLI
npx nxh generate --base-url https://staging-api.example.com
# Override output via CLI
npx nxh generate -o ./src/api
# Override input via CLI
npx nxh generate -i ./specs/api-v2.yamlPriority order:
- CLI arguments ← Highest priority
- Config file
- Default values ← Lowest priority
Server Routes Use Different Config
Different Configuration Method
The baseUrl option in nxh.config.js does NOT affect nuxtServer routes.
Server routes use Nuxt's runtimeConfig instead:
Why? Server routes run on the Nuxt server and need dynamic configuration based on environment.
Configuring nuxtServer baseUrl
Use Nuxt's runtimeConfig in nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
// Private (server-side only)
apiBaseUrl: process.env.API_BASE_URL || 'https://api.example.com'
}
})Environment variables:
# .env
API_BASE_URL=https://api.example.comGenerated server routes automatically use this:
// server/api/pets.get.ts (generated)
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig()
const baseUrl = config.apiBaseUrl // ✅ From runtimeConfig
const data = await $fetch(`${baseUrl}/pets`)
return data
})Why separate configuration?
- ✅ Server routes need environment-based URLs (dev/staging/prod)
- ✅ API URLs should be private (not exposed to client)
- ✅ Server-side configuration is more secure
- ✅ Follows Nuxt best practices
Summary:
| Generator | Configuration Method | Config Location |
|---|---|---|
| useFetch | baseUrl in nxh.config.js | Project root |
| useAsyncData | baseUrl in nxh.config.js | Project root |
| nuxtServer | apiBaseUrl in runtimeConfig | nuxt.config.ts |
Package.json Alternative
You can also configure in package.json:
{
"name": "my-app",
"nuxt-generator": {
"input": "./openapi.yaml",
"output": "./composables",
"baseUrl": "https://api.example.com",
"generators": ["useFetch"]
}
}Note: Config file (nxh.config.js) takes precedence over package.json.
Best Practices
✅ Do
- Use
nxh.config.jsfor consistent team setup - Commit config file to version control
- Use environment variables for dynamic values
- Set
overwrite: truein CI/CD - Use
watch: trueduring development
// ✅ Good - environment aware
export default {
input: './openapi.yaml',
output: './composables',
baseUrl: process.env.API_URL || 'http://localhost:3001',
generators: ['useFetch'],
overwrite: process.env.CI === 'true' // Auto-overwrite in CI
}❌ Don't
- Don't hardcode secrets/tokens in config file
- Don't commit environment-specific URLs
- Don't use relative paths for remote APIs
- Don't mix config file with heavy CLI arguments
// ❌ Bad - hardcoded production URL
export default {
baseUrl: 'https://api.production.com' // Should use env var
}Troubleshooting
Config Not Loading
Check:
- File is in project root (same level as
package.json) - File name is correct (
nxh.config.js, notnxh-config.js) - File has valid JavaScript syntax
- File exports default object
// ✅ Correct
export default {
input: './openapi.yaml'
}
// ❌ Wrong - no export
const config = {
input: './openapi.yaml'
}baseUrl Not Working in Server Routes
Remember: baseUrl in nxh.config.js only works for useFetch and useAsyncData.
For server routes, use runtimeConfig in nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
apiBaseUrl: process.env.API_BASE_URL
}
})CLI Arguments Not Overriding
Make sure you're using the correct argument format:
# ✅ Correct
npx nxh generate --base-url https://api.example.com
# ❌ Wrong
npx nxh generate --baseUrl https://api.example.comWatch Mode Not Working
Ensure:
- File path is correct
- File exists
- You have permissions to read the file
// ✅ Good - absolute or relative path
input: './openapi.yaml'
input: '/absolute/path/to/openapi.yaml'
// ❌ Bad - invalid path
input: 'openapi.yaml' // Missing ./Migration from CLI-Only
Before (CLI only):
npx nxh generate \
-i ./openapi.yaml \
-o ./composables \
--base-url https://api.example.com \
--generators useFetch,useAsyncDataAfter (with config):
// nxh.config.js
export default {
input: './openapi.yaml',
output: './composables',
baseUrl: 'https://api.example.com',
generators: ['useFetch', 'useAsyncData']
}# Much cleaner!
npx nxh generateTypeScript Config
You can use TypeScript for your config file:
// nxh.config.mts
import type { GeneratorConfig } from 'nuxt-generator'
export default {
input: './openapi.yaml',
output: './composables',
baseUrl: 'https://api.example.com',
generators: ['useFetch', 'useAsyncData']
} satisfies GeneratorConfigNote: Rename file to .mts for TypeScript.
