Access app.config.ts in nuxt module
How to use
app.config.ts in my nuxt module:
- how to declare types
- how to access it in module defined config20 Replies
Hi @Norbiros. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To use and type
See more details<source>https://nuxt.com/docs/4.x/guide/directory-structure/app/app-config</source.> --- 2. Accessing
- Declare types by augmenting
- Typing app.config<source>https://nuxt.com/docs/4.x/guide/directory-structure/app/app-config</source> - useAppConfig composable<source>https://nuxt.com/docs/4.x/api/composables/use-app-config</source> ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
app.config.ts in your Nuxt module, here’s what the official documentation provides:
---
1. Declaring Types for app.config.ts
You can augment the types for app.config.ts by extending the AppConfigInput (for input/validation) or AppConfig (for the output of useAppConfig()) interfaces in a index.d.ts file:
- Use AppConfigInput to declare what valid input options are for your module’s app config.
- Use AppConfig to type the result of useAppConfig() (be careful, as this will overwrite Nuxt’s inferred types)See more details<source>https://nuxt.com/docs/4.x/guide/directory-structure/app/app-config</source.> --- 2. Accessing
app.config.ts in a Nuxt Module
The knowledge sources do not explicitly document a direct API for accessing app.config.ts within the module’s setup function (unlike nuxt.options.runtimeConfig). However, you can define default values for app.config in your module by exporting an object from your module’s appConfig key, and Nuxt will merge it with the user’s app.config.ts.
For example, in your module:
- You can provide default values for app.config via the appConfig key in your module definition.
- There is no documented way to read the final, merged app.config inside the module’s setup function at build time.
---
Summary:- Declare types by augmenting
AppConfigInput and AppConfig in index.d.ts.
- Provide default values for app.config in your module via the appConfig key.
- There is no documented way to access the merged app.config inside the module’s setup function.
If you need to access app config at runtime (in the app, not in the module), use the useAppConfig() composable<source>https://nuxt.com/docs/4.x/api/composables/use-app-config</source.>
If you need more advanced integration, you may need to follow Nuxt’s internal conventions or track future updates to the module API.
---
References:- Typing app.config<source>https://nuxt.com/docs/4.x/guide/directory-structure/app/app-config</source> - useAppConfig composable<source>https://nuxt.com/docs/4.x/api/composables/use-app-config</source> ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@770620808644919307> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai I have component A in my nuxt module, i want to put inside it
<component :is="id">, where id is something provided by the app config ts and based on it i resolve component (also from user app)Let me check the knowledge base for you again. One moment! :books:
----------------------
To achieve dynamic component rendering in your Nuxt module’s component, where the component name (
You cannot dynamically import a component by variable name at runtime; the component must be globally registered for this to work. This is a Nuxt/Vue limitation, as confirmed in the knowledge sources<source>https://stackoverflow.com/questions/78319986</source.> If you need more advanced dynamic resolution (e.g., mapping keys to components), you can create a mapping object in your script and use it with
- Use
- Dynamic imports by variable name are not supported in Nuxt/Vue templates. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
id) is provided via app.config.ts and should resolve to a user-defined component, you can follow this approach:
1. Access the app config in your component using the useAppConfig() composable:
2. Render the dynamic component using the <component :is="id" /> syntax in your template:
Important notes:
- For this to work, the component name provided in app.config.ts (e.g., 'UserButton') must match a globally registered component in the user’s app (e.g., a component in ~/components/ or ~/components/global/). Nuxt auto-imports components from these directories, making them available by name for dynamic rendering.
- If the component is not globally registered, you would need to import and resolve it manually, but the knowledge sources indicate that dynamic imports based on a variable are not supported. The <component :is="id" /> approach only works with globally available components or those imported and mapped explicitly in your script logic<source>https://stackoverflow.com/questions/78319986</source.>
Example app.config.ts:
Example usage in your module’s component:
Limitation:You cannot dynamically import a component by variable name at runtime; the component must be globally registered for this to work. This is a Nuxt/Vue limitation, as confirmed in the knowledge sources<source>https://stackoverflow.com/questions/78319986</source.> If you need more advanced dynamic resolution (e.g., mapping keys to components), you can create a mapping object in your script and use it with
<component :is="getComponent(id)" />, but the components must still be imported or globally available.
---
Summary:- Use
useAppConfig() to get the component name from app.config.ts.
- Use <component :is="id" /> to render the component.
- The component must be globally registered in the user’s app for this to work.- Dynamic imports by variable name are not supported in Nuxt/Vue templates. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@770620808644919307> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai it kinda does not work?:
ANd i get 1. COMPONENT WORKS YAY 2. 3.
Let me check the knowledge base for you again. One moment! :books:
----------------------
You're correct in your observation, and this behavior is confirmed by the knowledge sources.
In Nuxt 3, when you use a globally registered component like
-
<SubmitButton />, it works as expected because Nuxt's auto-import system registers components for direct use in templates.
However, when you try to use <component :is="abc" /> (where abc is a variable holding the component name), or <component :is="resolveComponent('SubmitButton')" />, it does not work as you might expect. This is a known limitation:
- Direct usage (<SubmitButton />): ✅ Works, because the component is auto-imported and registered globally.
- Dynamic by variable (<component :is="abc" />): ❌ Does not work unless the component is globally registered in a specific way (e.g., in components/global/ or with a .global.vue suffix).
- Dynamic with resolveComponent and variable (<component :is="resolveComponent(abc)" />): ❌ Does not work, because resolveComponent expects a literal string, not a variable. The string must be statically analyzable at compile time.
From the knowledge sources:
You cannot pass a variable to the resolveComponent() method. Stack Overflow: Nuxt3 dynamic <component>If you want to use a variable to determine which component to render, the component must be globally registered (e.g., in
components/global/ or with a .global.vue suffix), and you should use <component :is="abc" />. But even then, there are caveats, and it may not work for all auto-imported components unless they are truly global as described above.
Summary:-
<SubmitButton /> works because it's auto-imported.
- <component :is="abc" /> only works if the component is globally registered in a way that Nuxt recognizes for dynamic usage.
- <component :is="resolveComponent('SubmitButton')" /> only works with a literal string, not a variable.
- <component :is="resolveComponent(abc)" /> does not work.
This is a limitation of how Nuxt and Vue handle dynamic component resolution and auto-importsStack Overflow: Nuxt3 dynamic <component>.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@770620808644919307> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai
Okayy. I know the component at build time, but how to code it properly. I can get this from nuxt.config.ts or app.config.ts and the point is for user to specify me a component that i can use instead of my default one
Let me check the knowledge base for you again. One moment! :books:
----------------------
If you want to allow users to specify a component (by name) in their
- Let the user specify a component name in
app.config.ts or nuxt.config.ts, and use that component in your module/component instead of your default, you can do this as long as the component is globally registered (i.e., auto-imported by Nuxt from the user's components/ directory).
How to implement:
1. User sets the component name in app.config.ts:
2. In your module's component, read the config and use <component :is="...">:
Requirements and limitations:
- The user must have a component named UserButton.vue in their components/ directory (or a subdirectory), so Nuxt auto-imports it and makes it globally available.
- This approach works because the component name is known at build time and Nuxt's auto-import system registers it globally, making it available for dynamic rendering by name.
- If the user provides a component name that does not exist or is not globally registered, nothing will render.
Summary:- Let the user specify a component name in
app.config.ts.
- Use useAppConfig() to read it in your component.
- Render it with <component :is="componentName" />.
- The component must be globally registered for this to work.
This approach is supported by Nuxt's auto-import and app config systems, as described in the documentation and knowledge sourcesDocs: app.config.tsStack Overflow: Nuxt3 dynamic <component>.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@770620808644919307> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai docs say If you are using resolveComponent to handle dynamic components, make sure not to insert anything but the name of the component, which must be a literal string and not be or contain a variable. The string is statically analyzed at the compilation step.
Let me check the knowledge base for you again. One moment! :books:
----------------------
You're correct in your reading of the documentation:
When using
-
Nuxt Components Documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
When using
resolveComponent in Nuxt (and Vue), the argument must be a literal string—not a variable or an expression. This is because Nuxt's auto-import and component resolution system relies on static analysis at build time to determine which components to include. If you pass a variable or a non-literal value, Nuxt cannot statically analyze and include the component, so it won't work as expected.
From the docs:
If you are using resolveComponent to handle dynamic components, make sure not to insert anything but the name of the component, which must be a literal string and not be or contain a variable. The string is statically analyzed at the compilation step.
This means:
If you need to use a variable, you should ensure the component is globally registered (e.g., via the components/ directory), and then use <component :is="myComponentName" /> directly, without resolveComponent. This approach works because Nuxt auto-imports and globally registers components, making them available by name at runtime, but only if they are in the right place and named correctly.
Summary:-
resolveComponent only works with literal strings.
- Do not use variables or expressions as arguments to resolveComponent.
- This is a limitation due to Nuxt's static analysis for auto-imports and component registrationNuxt Components Documentation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@770620808644919307> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai I am working on module with custom nuxt components and when building I get:
WARN Build is done with some warnings: 11:03:13 AM
- Implicitly bundling "@vue/runtime-core"
- Implicitly bundling "@vue/reactivity"
- Implicitly bundling "@vue/shared"
I tried adding them to package.json but it ain't working
Let me check the knowledge base for you again. One moment! :books:
----------------------
The warnings you are seeing:
indicate that these Vue internals are being bundled into your build, rather than being externalized. This is not typically resolved by adding them to your
- Ensure
package.json dependencies.
According to the Nuxt documentation, Nuxt has an experimental option called externalVue that controls whether vue, @vue/*, and vue-router are externalized during the build process. By default, this is set to true, which should prevent these packages from being bundled:
If you are still seeing these warnings, it may be due to how your module or its dependencies are importing or resolving Vue packages, or due to a misconfiguration in your build setup. The knowledge sources do not provide a step-by-step solution for all scenarios, but they do confirm that externalVue is the intended mechanism for controlling this behavior. You can read more about this option in the Nuxt documentation on externalVue<source>https://nuxt.com/docs/4.x/api/nuxt-config#externalvue</source.>
If the issue persists even with externalVue: true, it may be related to recent changes in Nuxt's handling of externals and dependency resolution, as discussed in recent pull requests. These changes aim to improve how Nuxt resolves and externalizes dependencies, but edge cases may still exist<source>https://github.com/nuxt/nuxt/pull/31227</source.>
Summary:- Ensure
experimental.externalVue is set to true in your nuxt.config.ts.
- Adding these packages to package.json will not resolve the warning.
- If the warning persists, it may be due to how dependencies are imported or a current limitation in Nuxt's externalization logic.
If you need further troubleshooting, please provide more details about your module's setup or check for related issues in the Nuxt repository.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@770620808644919307> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai i have to import them because this is nuxt MODULE, maybe something related to build.config.ts
Let me check the knowledge base for you again. One moment! :books:
----------------------
If you are developing a Nuxt module and see warnings about implicitly bundling
- The official way to externalize Vue internals in a Nuxt app is with
@vue/runtime-core, @vue/reactivity, and @vue/shared, this typically means these dependencies are being included in your module's output bundle rather than being externalized.
The knowledge sources do not provide a detailed, step-by-step solution specifically for module authors regarding build.config.ts or how to externalize these dependencies in a Nuxt module context. However, the Nuxt documentation does mention the experimental.externalVue option, which, when set to true, should externalize vue, @vue/*, and vue-router during the build process. This is the main documented approach for controlling this behavior in a Nuxt project<source>https://nuxt.com/docs/4.x/api/nuxt-config#externalvue</source.>
If you are building a module (not an app), you may need to ensure your build tool (such as unbuild or rollup) is configured to treat these packages as externals. The Nuxt ecosystem recommends using unbuild for modules, but the knowledge sources do not provide explicit configuration examples for this scenario<source>https://nuxt.com/docs/4.x/community/contribution#conventions-across-ecosystem</source.>
Summary:- The official way to externalize Vue internals in a Nuxt app is with
experimental.externalVue: true.
- For modules, you may need to configure your build tool to externalize these dependencies, but the knowledge sources do not provide explicit instructions for build.config.ts.
- If the warnings persist, it may be due to current limitations or required configuration in your module's build setup, but there is no detailed guidance in the provided sources.
If you need more specific help with build.config.ts for a Nuxt module, the knowledge sources do not contain enough information to provide a confident answer.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@770620808644919307> Kapa.ai is still learning and improving, please let me know how I did by reacting below.