Skip to content

Runtime & App Config

A prepare script can set runtimeConfig and appConfig values it had to fetch or compute first.

Runtime Config

Use runtimeConfig to conditionally set environment-based configuration that should be accessible via Nuxt's useRuntimeConfig().

ts
import { defineNuxtPrepareHandler } from 'nuxt-prepare/config'

export default defineNuxtPrepareHandler(async () => {
  // Fetch API configuration from a remote source
  const apiConfig = await fetch('https://config.example.com/api')
    .then(res => res.json())

  return {
    runtimeConfig: {
      // Private config (server-only)
      apiSecret: apiConfig.secret,

      public: {
        // Public config (available everywhere)
        apiUrl: apiConfig.url,
        apiVersion: apiConfig.version
      }
    }
  }
})

Access runtime config values anywhere in your app:

ts
const config = useRuntimeConfig()
console.log(config.public.apiUrl) // Set by prepare script

Precedence

A script's result is merged into the runtime config rather than replacing it, so keys you leave out keep the value nuxt.config.ts gave them. Keys you do return win over it, and a later script wins over an earlier one.

App Config

Use appConfig to set application-wide configuration that should be accessible via Nuxt's useAppConfig().

ts
import { defineNuxtPrepareHandler } from 'nuxt-prepare/config'

export default defineNuxtPrepareHandler(async () => {
  // Fetch feature flags from a CMS or feature flag service
  const features = await fetch('https://api.example.com/features')
    .then(res => res.json())

  return {
    appConfig: {
      features: {
        darkMode: features.darkMode,
        analytics: features.analytics,
        betaFeatures: features.beta
      }
    }
  }
})

Access app config values anywhere in your app:

vue
<script setup lang="ts">
const appConfig = useAppConfig()
const isDarkModeEnabled = appConfig.features.darkMode
</script>

Precedence

App config merges the same way, over what app.config.ts defines.

When to Use Each Option

Use state

  • Import data as constants
  • Get full TypeScript type inference from generated types
  • Share data between multiple modules without prop drilling
ts
import { tenant } from '#nuxt-prepare'

// Direct constant access with full type safety
if (tenant.id) {
  // ...
}

Use runtimeConfig

  • Follow Nuxt's runtime configuration patterns
  • Access environment variables and secrets
  • Use Nuxt's built-in public/private config separation
ts
const config = useRuntimeConfig()

// Accessed via composable
const apiUrl = config.public.apiUrl

Use appConfig

  • Define app-wide configuration
  • Support runtime updates with HMR
  • Follow Nuxt's app config patterns
ts
const appConfig = useAppConfig()

// Accessed via composable, supports HMR
const theme = appConfig.theme

Practical Example: Multi-Tenant Configuration

A multi-tenant build uses all three:

ts
import { defineNuxtPrepareHandler } from 'nuxt-prepare/config'
import { ofetch } from 'ofetch'

export default defineNuxtPrepareHandler(async () => {
  const tenantId = process.env.TENANT_ID
  const tenant = await ofetch(`https://api.example.com/tenants/${tenantId}`)

  return {
    // Public tenant data as importable constants
    state: {
      tenant: {
        id: tenant.id,
        name: tenant.name,
        logo: tenant.logo
      }
    },

    // API configuration
    runtimeConfig: {
      tenantApiKey: tenant.apiKey, // Private
      public: {
        tenantApiUrl: tenant.apiUrl // Public
      }
    },

    // Theme configuration
    appConfig: {
      theme: {
        primaryColor: tenant.primaryColor,
        logo: tenant.logo
      }
    }
  }
})

Now you can use each piece of data in the most appropriate way:

vue
<script setup lang="ts">
import { tenant } from '#nuxt-prepare'

const config = useRuntimeConfig()
const appConfig = useAppConfig()

// Direct import for static data
const tenantName = tenant.name

// Runtime config for API calls
const apiUrl = config.public.tenantApiUrl

// App config for theme
const primaryColor = appConfig.theme.primaryColor
</script>

Released under the MIT License.