Vector
Bitmap
Font
- Backgrounds
- Logos
- Tokens
- Templates
- Layouts
- Themes
- Components
Nuxt 3 Environment Configuration Setup
1. Configure Runtime Config in nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
// Private keys (server-side only)
apiSecret: '',
// Public keys (exposed to client and server)
public: {
baseUrl: process.env.NUXT_PUBLIC_BASE_URL || 'http://localhost:3000',
assetsPath: process.env.NUXT_PUBLIC_ASSETS_PATH || '/resources',
apiPath: process.env.NUXT_PUBLIC_API_PATH || '/api',
}
},
// Optional: Configure asset handling
app: {
baseURL: process.env.NUXT_APP_BASE_URL || '/',
buildAssetsDir: '/_nuxt/',
cdnURL: process.env.NUXT_APP_CDN_URL || ''
}
})
2. Environment Variables Setup
Development (.env)
# Base configuration
NUXT_PUBLIC_BASE_URL=http://localhost:3000
NUXT_PUBLIC_ASSETS_PATH=/resources
NUXT_PUBLIC_API_PATH=/api
# Optional: App-level configuration
NUXT_APP_BASE_URL=/
NUXT_APP_CDN_URL=
Production (.env.production)
# Production configuration
NUXT_PUBLIC_BASE_URL=https://yourdomain.com
NUXT_PUBLIC_ASSETS_PATH=/assets
NUXT_PUBLIC_API_PATH=/api/v1
# Optional: Production CDN
NUXT_APP_CDN_URL=https://cdn.yourdomain.com
Staging (.env.staging)
# Staging configuration
NUXT_PUBLIC_BASE_URL=https://staging.yourdomain.com
NUXT_PUBLIC_ASSETS_PATH=/resources
NUXT_PUBLIC_API_PATH=/api
# Optional: Staging CDN
NUXT_APP_CDN_URL=https://staging-cdn.yourdomain.com
3. Asset URL Builder Composable
Create composables/useAssetUrl.ts:
export const useAssetUrl = () => {
const config = useRuntimeConfig()
const buildAssetUrl = (path: string): string => {
// Remove leading slash if present to avoid double slashes
const cleanPath = path.startsWith('/') ? path.slice(1) : path
// Combine base URL, assets path, and the specific asset path
return `${config.public.baseUrl}${config.public.assetsPath}/${cleanPath}`
}
const buildApiUrl = (endpoint: string): string => {
// Remove leading slash if present to avoid double slashes
const cleanEndpoint = endpoint.startsWith('/') ? endpoint.slice(1) : endpoint
// Combine base URL, API path, and the specific endpoint
return `${config.public.baseUrl}${config.public.apiPath}/${cleanEndpoint}`
}
// Helper for building full URLs with query parameters
const buildAssetUrlWithQuery = (path: string, params?: Record<string, string>): string => {
const baseUrl = buildAssetUrl(path)
if (!params) return baseUrl
const searchParams = new URLSearchParams(params)
return `${baseUrl}?${searchParams.toString()}`
}
return {
buildAssetUrl,
buildApiUrl,
buildAssetUrlWithQuery,
config: config.public
}
}
Auto-Import Setup (Optional)
To make the composable available globally without imports, add to nuxt.config.ts:
export default defineNuxtConfig({
// ... your existing config
// Auto-import the composable globally
imports: {
dirs: ['composables/**']
}
})
4. Usage Examples
In Vue Components
<template>
<div>
<!-- Method 1: Pre-computed reactive variables (Recommended) -->
<img :src="backgroundImageUrl" alt="Background" />
<!-- Method 2: Direct function calls in template -->
<img :src="buildAssetUrl('images/hero/hero-banner.jpeg')" alt="Hero" />
<!-- Method 3: Using computed properties for complex logic -->
<img :src="dynamicImageUrl" alt="Dynamic" />
<!-- Method 4: Template string interpolation -->
<div>Background URL: {{ backgroundImageUrl }}</div>
<!-- Direct access to config -->
<div>Base URL: {{ config.baseUrl }}</div>
<div>Assets Path: {{ config.assetsPath }}</div>
<div>API Path: {{ config.apiPath }}</div>
</div>
</template>
<script setup lang="ts">
// Using the composable
const { buildAssetUrl, buildApiUrl, config } = useAssetUrl()
// Method 1: Pre-computed reactive variables (Best for performance)
const backgroundImageUrl = buildAssetUrl('images/backgrounds/background-slide.jpeg')
// Method 2: Functions are automatically available in template when destructured
// Method 3: Computed properties for dynamic URLs
const imageName = ref('background-slide.jpeg')
const dynamicImageUrl = computed(() =>
buildAssetUrl(`images/backgrounds/${imageName.value}`)
)
// Example API URL building
const usersApiUrl = buildApiUrl('users')
console.log('Background Image URL:', backgroundImageUrl)
// Output: http://localhost:3000/resources/images/backgrounds/background-slide.jpeg
console.log('Users API URL:', usersApiUrl)
// Output: http://localhost:3000/api/users
// Direct access to runtime config
const runtimeConfig = useRuntimeConfig()
console.log('All public config:', runtimeConfig.public)
</script>
Template Usage Patterns
<template>
<div>
<!-- ✅ CORRECT: Direct function call -->
<img :src="buildAssetUrl('images/backgrounds/background-slide.jpeg')" alt="Background" />
<!-- ✅ CORRECT: Pre-computed variable -->
<img :src="heroImage" alt="Hero" />
<!-- ✅ CORRECT: Computed property -->
<img :src="dynamicImage" alt="Dynamic" />
<!-- ✅ CORRECT: String interpolation -->
<div>{{ buildAssetUrl('images/logo.png') }}</div>
<!-- ❌ INCORRECT: Double curly braces in attributes -->
<!-- <img src="{{buildAssetUrl('image.jpg')}}" alt="Wrong" /> -->
<!-- ❌ INCORRECT: Missing v-bind or : -->
<!-- <img src="buildAssetUrl('image.jpg')" alt="Wrong" /> -->
</div>
</template>
<script setup lang="ts">
const { buildAssetUrl } = useAssetUrl()
// Pre-computed for better performance
const heroImage = buildAssetUrl('images/hero/main-banner.jpeg')
// Dynamic computed property
const imageType = ref('jpeg')
const dynamicImage = computed(() =>
buildAssetUrl(`images/gallery/photo.${imageType.value}`)
)
</script>
In Server API Routes
// server/api/example.ts
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig(event)
// Access public config on server
const baseUrl = config.public.baseUrl
const apiPath = config.public.apiPath
// Build URLs on server-side
const externalApiUrl = `${baseUrl}${apiPath}/external-service`
return {
message: 'Server response',
apiUrl: externalApiUrl
}
})
In Plugins
// plugins/api.client.ts
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig()
// Configure API client with runtime config
const apiClient = $fetch.create({
baseURL: `${config.public.baseUrl}${config.public.apiPath}`
})
return {
provide: {
apiClient
}
}
})
5. Alternative: Using App Config for Static Values
If you have static configuration that doesn't need environment overrides, use app.config.ts:
// app.config.ts
export default defineAppConfig({
assets: {
imageSizes: ['sm', 'md', 'lg', 'xl'],
formats: ['webp', 'jpeg', 'png']
},
ui: {
theme: 'dark',
primary: '#ff0000'
}
})
Access in components:
<script setup lang="ts">
const appConfig = useAppConfig()
console.log(appConfig.assets.imageSizes)
</script>
6. Production Deployment
When deploying to production, set environment variables:
# For Node.js deployment
NUXT_PUBLIC_BASE_URL=https://yourdomain.com \
NUXT_PUBLIC_ASSETS_PATH=/assets \
NUXT_PUBLIC_API_PATH=/api/v1 \
node .output/server/index.mjs
# Or via Docker environment
docker run -e NUXT_PUBLIC_BASE_URL=https://yourdomain.com \
-e NUXT_PUBLIC_ASSETS_PATH=/assets \
-e NUXT_PUBLIC_API_PATH=/api/v1 \
your-nuxt-app
7. TypeScript Support
Add type safety by augmenting the runtime config types:
// types/runtime-config.d.ts
declare module 'nuxt/schema' {
interface PublicRuntimeConfig {
baseUrl: string
assetsPath: string
apiPath: string
}
}
// Ensure this file is treated as a module
export {}
Key Benefits
- Environment Flexibility: Different configs for dev, staging, production
- Security: Sensitive values can be server-only (not in
public) - Type Safety: Full TypeScript support with proper typing
- Reusability: Composables make URL building consistent across your app
- Hot Reload: Environment changes are picked up automatically in development
Migration from Hardcoded URLs
Replace your current hardcoded URLs:
// Before
const imageUrl = 'http://localhost:3000/resources/images/backgrounds/background-slide.jpeg'
// After
const { buildAssetUrl } = useAssetUrl()
const imageUrl = buildAssetUrl('images/backgrounds/background-slide.jpeg')
This setup provides a robust, scalable solution for managing environment-specific configurations in your Nuxt 3 application.