diff --git a/docs/content/3.docs/1.usage/5.runtime-config.md b/docs/content/3.docs/1.usage/5.runtime-config.md
new file mode 100644
index 0000000000..78aba9ff16
--- /dev/null
+++ b/docs/content/3.docs/1.usage/5.runtime-config.md
@@ -0,0 +1,108 @@
+# Runtime Config
+
+Nuxt provides a runtime config API to share within App and API routes.
+
+## Exposing runtime config
+
+To expose config and environment variables to the rest of your app, you will need to define runtime configuration in your `nuxt.config` file, using either the [`publicRuntimeConfig` or `privateRuntimeConfig` options](/docs/directory-structure/nuxt.config#privateruntimeconfig). Based on whether you want it to be accessible on the client-side part of your app or not.
+
+**Example:**
+
+```ts [nuxt.config.ts]
+export default defineNuxtConfig({
+ publicRuntimeConfig: {
+ API_BASE: '/api'
+ },
+ privateRunimeConfig: {
+ API_SECRET: '123'
+ }
+})
+```
+
+When adding `API_BASE` to the `publicRuntimeConfig`, Nuxt adds it to the pages payload. This way we can universally access `API_BASE` in both server and browser.
+
+### Environment Variables
+
+The most common way to provide configuration, is using [Environment Variables](https://medium.com/chingu/an-introduction-to-environment-variables-and-how-to-use-them-f602f66d15fa).
+Nuxt CLI has built-in [dotenv](https://github.com/motdotla/dotenv) support.
+
+In addition to any process environment variables, if you have a `.env` file in your project root directory, it will be automatically loaded into `process.env` and accessible within your `nuxt.config` file and Modules.
+
+**Example:**
+
+```sh [.env]
+BASE_URL=https://nuxtjs.org
+API_SECRET=api_secret_token
+```
+
+```ts [nuxt.config.ts]
+export default defineNuxtConfig({
+ publicRuntimeConfig: {
+ BASE_URL: process.env.BASE_URL
+ },
+ privateRuntimeConfig: {
+ API_SECRET: process.env.API_SECRET
+ }
+})
+```
+
+**💡 Tip:** While it is not necessary, by using identical runtime config names as env variables, you can easily override them in production using platform environment variables.
+
+## Accessing runtime config
+
+### Vue app
+
+Within the Vue part of your Nuxt app, you will need to call `useRuntimeConfig()` to access the runtime config.
+
+**Note:** Behavior is different between client side and server side:
+
+- On Client-Side, only `publicRuntimeConfig` is available and object is writable + reactive
+- On Server-Side, both `publicRuntimeConfig` and `privateRuntimeConfig` are merged and object is readonly to avoid context sharing
+
+```vue
+
+
+
Token: {{ config.API_AUTH_TOKEN }}
+
+
+
+
+```
+
+**🛑 Security note:** Never use example above if `API_AUTH_TOKEN` is a private config. Even if you use `privateRuntimeConfig`, you have to be still careful you do not expose such config to either payload or html!
+
+### API routes
+
+Within the API routes, you can access runtime config by directly importing from virtual `#config`.
+
+```ts
+import config from '#config'
+
+export default async () => {
+ const result = await $fetch('https://my.api.com/test', {
+ headers: {
+ Authorization: `Bearer ${config.API_AUTH_TOKEN}`
+ }
+ })
+ return result
+}
+```
+
+### Typing runtime config
+
+Currently it is possible to manually type your runtime config.
+
+```ts [index.d.ts]
+declare module '@nuxt/kit' {
+ interface PublicRuntimeConfig {
+ testConfig: string
+ }
+ interface PrivateRuntimeConfig {
+ token: string
+ }
+}
+// It is always important to ensure you import/export something when augmenting a type
+export {}
+```
diff --git a/packages/bridge/src/nitro.ts b/packages/bridge/src/nitro.ts
index ddbb26df20..f8d1e16e2d 100644
--- a/packages/bridge/src/nitro.ts
+++ b/packages/bridge/src/nitro.ts
@@ -129,11 +129,6 @@ export function setupNitroBridge () {
// Add typed route responses
nuxt.hook('prepare:types', (opts) => {
opts.references.push({ path: resolve(nuxt.options.buildDir, 'nitro.d.ts') })
-
- for (const stub of ['#storage', '#assets']) {
- // The `@nuxt/nitro` types will be overwritten by packages/nitro/types/shims.d.ts
- opts.tsConfig.compilerOptions.paths[stub] = ['@nuxt/nitro']
- }
})
// nuxt build/dev
diff --git a/packages/bridge/src/runtime/composables.ts b/packages/bridge/src/runtime/composables.ts
index aa758901a4..d3fb9cb875 100644
--- a/packages/bridge/src/runtime/composables.ts
+++ b/packages/bridge/src/runtime/composables.ts
@@ -3,6 +3,7 @@ import type { CombinedVueInstance } from 'vue/types/vue'
import type { MetaInfo } from 'vue-meta'
import type VueRouter from 'vue-router'
import type { Route } from 'vue-router'
+import type { RuntimeConfig } from '@nuxt/kit'
import { useNuxtApp } from './app'
export * from '@vue/composition-api'
@@ -18,7 +19,7 @@ export const useRuntimeConfig = () => {
if (!nuxtApp.$config) {
nuxtApp.$config = reactive(nuxtApp.nuxt2Context.app.$config)
}
- return nuxtApp.$config
+ return nuxtApp.$config as RuntimeConfig
}
// Auto-import equivalents for `vue-router`
diff --git a/packages/kit/src/index.ts b/packages/kit/src/index.ts
index c2678e8cef..a7532a50f2 100644
--- a/packages/kit/src/index.ts
+++ b/packages/kit/src/index.ts
@@ -25,3 +25,4 @@ export * from './types/module'
export * from './types/nuxt'
export * from './types/components'
export * from './types/imports'
+export * from './types/runtime-config'
diff --git a/packages/kit/src/types/runtime-config.ts b/packages/kit/src/types/runtime-config.ts
new file mode 100644
index 0000000000..91b70d14fe
--- /dev/null
+++ b/packages/kit/src/types/runtime-config.ts
@@ -0,0 +1,5 @@
+export interface PublicRuntimeConfig extends Record { }
+export interface PrivateRuntimeConfig extends PublicRuntimeConfig { }
+
+type _RuntimeConfig = PublicRuntimeConfig & Partial
+export interface RuntimeConfig extends _RuntimeConfig { }
diff --git a/packages/nitro/types/shims.d.ts b/packages/nitro/types/shims.d.ts
index 335b973e11..b6fce00665 100644
--- a/packages/nitro/types/shims.d.ts
+++ b/packages/nitro/types/shims.d.ts
@@ -9,3 +9,11 @@ declare module '#assets' {
export function statAsset (id: string): Promise
export function getKeys() : Promise
}
+
+declare module '#config' {
+ import type { PublicRuntimeConfig, PrivateRuntimeConfig } from '@nuxt/kit'
+ export const privateConfig: PrivateRuntimeConfig
+ export const publicConfig: PublicRuntimeConfig
+ const runtimeConfig: PrivateRuntimeConfig & PublicRuntimeConfig
+ export default runtimeConfig
+}
diff --git a/packages/nuxi/src/utils/prepare.ts b/packages/nuxi/src/utils/prepare.ts
index f2a5010ab5..7b00901bb1 100644
--- a/packages/nuxi/src/utils/prepare.ts
+++ b/packages/nuxi/src/utils/prepare.ts
@@ -31,6 +31,7 @@ export const writeTypes = async (nuxt: Nuxt) => {
...nuxt.options.alias,
'#build': nuxt.options.buildDir,
// The `@nuxt/nitro` types will be overwritten by packages/nitro/types/shims.d.ts
+ '#config': '@nuxt/nitro',
'#storage': '@nuxt/nitro',
'#assets': '@nuxt/nitro'
}
diff --git a/packages/nuxt3/src/app/nuxt.ts b/packages/nuxt3/src/app/nuxt.ts
index f91dad518f..10ac1fab8b 100644
--- a/packages/nuxt3/src/app/nuxt.ts
+++ b/packages/nuxt3/src/app/nuxt.ts
@@ -2,6 +2,7 @@
import { getCurrentInstance, reactive } from 'vue'
import type { App, VNode } from 'vue'
import { createHooks, Hookable } from 'hookable'
+import type { RuntimeConfig } from '@nuxt/kit'
import { legacyPlugin, LegacyContext } from './legacy'
type NuxtMeta = {
@@ -192,7 +193,7 @@ export function useNuxtApp (): NuxtApp {
return vm.appContext.app.$nuxt
}
-export function useRuntimeConfig (): Record {
+export function useRuntimeConfig (): RuntimeConfig {
return useNuxtApp().$config
}