Editable runtime config with HMR
See original GitHub issueCurrently, providing runtimeconfig from nuxt.config
, .env
and environment variables is possible but DX is not great because for each change, we need to restart Nuxt instance and there is no browser HMR.
We can introduce new app.config.[ext]
(2) file that basically extends runtimeConfig.app
namespace but is directly loaded by bundler (vite/webpack/nitro) and accepts hot module replacements and exposed as useAppConfig()
/ $appConfig
(1). This file can also have more JS native types (non POJO).
import { defineAppConfig } from 'nuxt/app'
export default defineAppConfig ({
title: 'My Website',
seo: {
ogImage: '/og/card.png'
},
theme: {
primaryColor: '#ababab'
}
})
Typing:
Same as RuntimeConfig, types can be inferred directly from config and extended from NuxtAppConfig
interface from @nuxt/schema
by modules and theme layers
HMR support:
Since the idea is to add a virtual template and dependency to the bundlers, HMR is expected to work out of the box. But we can make it even better to toggle reactivity for useRuntimeConfig()
ref in app.
-
Discussing with @Tahul, alongside with this feature, we might also introduce injected
$appConfig
for easier usage and access within templates. -
Alongside with this feature, discussing with and by experience @nuxt/content-module team, there is a very common pattern to have a theme configuration. I personally vote for the simplicity of having one
app.config
and$appConfig
interface withtheme
subkey. But we can also introducetheme.config
anduseThemeConfig()
/$themeConfig
namespaced shortcuts from app config.
Issue Analytics
- State:
- Created a year ago
- Reactions:2
- Comments:7 (7 by maintainers)
Top GitHub Comments
Stepping back from the particular question about theming and thinking more about the infrastructure Nuxt can provide to modules, what about a hybrid approach?
built-in support for modules ‘registering’ config files - these get automatically watched and merged across layers. Maybe a hook gets called that lets modules decide what to do when these get updated - of course this could be runtime config but it might also be direct module config (e.g. tailwindcss, windi, prisma, etc.). By using this hook the module would opting out of the whole nuxt lifecycle and indicating that it could handle all updates required within the hook itself. Nuxt could handle extensions, etc., even schema. API could be something like:
built-in support for modules initiating a hmr of app config - modules can inject their own config into this and initiate an update when something happens on module side, e.g. update from their own config file, or possibly a WS update or something else.
One pattern that I would love to see applied here is strong data validation for the runtime config: In the
python
+fastapi
ecosystem it is common to have a rootsettings.py
file with runtime config definition like so ([1]):The main point about this is that
pydantic
is used to validate the data to avoid a lot of trouble for developers, devops, … down the road:database_dsn
will be a valid, non-empty PostgreSQL DSN,items_per_user
will be a valid numberFor me this has been a huge boost in productivity and DX when working with fastapi: I could be sure that my configuration at least contained correctly formed data and could debug in other places when stuff was not working.
In TypeScript it would probably be possible to add similar validation via:
reflect-metadata
(deriving automatically from native typescript, cleanest solution but probably also requires most overhead / leads to potential compability / dep errors) ([2])joi
andyup
([3], [4])For me a feature like this would be a huge differentiator + I can see further use-cases like server / API data validation derived from regular typescript classes.
sources: [1]: https://fastapi.tiangolo.com/advanced/settings/#create-the-settings-object [2]: https://www.npmjs.com/package/reflect-metadata [3]: https://www.npmjs.com/package/joi [4]: https://www.npmjs.com/package/yup