This page refers to src/index.js
file, which is executed on quasar dev
and quasar build
. This is the main process where you can modify the build to suit the needs of your App Extension. For instance, registering a boot file, modifying the webpack process, registering CSS, registering a UI component, registering a Quasar CLI command, etc.
Example of basic structure of the file:
// can be async
export default function (api) {
// props & methods for "api" Object described below
}
api.ctx
Same as the ctx
from the /quasar.config
file. Helps you make decisions based on the context in which quasar dev
or quasar build
runs.
Example: You might want to use one of the api methods if running for electron mode only.
if (api.ctx.dev === true && api.ctx.mode.electron === true) {
api.beforeDev((api) => {
// do something when running quasar dev and
// with Electron mode
})
}
api.engine
Contains the Quasar CLI engine (as String) being used. Examples: @quasar/app-vite
or @quasar/app-webpack
.
api.hasVite
Boolean - is running on @quasar/app-vite
or not.
api.hasWebpack
Boolean - is running on @quasar/app-webpack
or not.
api.extId
Contains the ext-id
(String) of this App Extension.
api.prompts
Is an Object which has the answers to the prompts when this App Extension got installed. For more info on prompts, check out Prompts API.
api.resolve
Resolves paths within the app on which this App Extension is running. Eliminates the need to import path
and resolve the paths yourself.
// resolves to root of app
api.resolve.app('src/my-file.js')
// resolves to root/src of app
api.resolve.src('my-file.js')
// resolves to root/public of app
// (@quasar/app-webpack v3.4+ or @quasar/app-vite v1+)
api.resolve.public('my-image.png')
// resolves to root/src-pwa of app
api.resolve.pwa('some-file.js')
// resolves to root/src-ssr of app
api.resolve.ssr('some-file.js')
// resolves to root/src-cordova of app
api.resolve.cordova('config.xml')
// resolves to root/src-electron of app
api.resolve.electron('some-file.js')
// resolves to root/src-electron of app
api.resolve.electron('some-file.js')
// resolves to root/src-bex of app
api.resolve.bex('some-file.js')
api.appDir
Contains the full path (String) to the root of the app on which this App Extension is running.
api.hasTypescript @quasar/app-vite 1.6+ @quasar/app-webpack 3.11+
/**
* @return {Promise<boolean>} host project has Typescript active or not
*/
await api.hasTypescript()
api.hasLint @quasar/app-vite 1.6+ @quasar/app-webpack 3.11+
/**
* @return {Promise<boolean>} host project has ESLint or not
*/
await api.hasLint()
api.getStorePackageName @quasar/app-vite 1.6+ @quasar/app-webpack 3.11+
/**
* @return {Promise<string|undefined>} 'pinia' | 'vuex' | undefined
*/
await api.getStorePackageName()
api.getNodePackagerName @quasar/app-vite 1.6+ @quasar/app-webpack 3.11+
/**
* @return {Promise<'npm' | 'yarn' | 'pnpm' | 'bun'>}
*/
await api.getNodePackagerName()
api.compatibleWith
Ensure the App Extension is compatible with a package installed in the host app through a semver condition.
If the semver condition is not met, then @quasar/app errors out and halts execution.
Example of semver condition: '1.x || >=2.5.0 || 5.0.0 - 7.2.3'
.
/**
* @param {string} packageName
* @param {string} semverCondition
*/
api.compatibleWith('@quasar/app', '1.x')
if (api.hasVite === true) {
api.compatibleWith('@quasar/app-vite', '^2.0.0-beta.1')
}
else {
api.compatbileWith('@quasar/app-webpack', '^4.0.0-beta.1')
}
api.hasPackage
Determine if some package is installed in the host app through a semver condition.
Example of semver condition: '1.x || >=2.5.0 || 5.0.0 - 7.2.3'
.
/**
* @param {string} packageName
* @param {string} (optional) semverCondition
* @return {boolean} package is installed and meets optional semver condition
*/
if (api.hasPackage('vuelidate')) {
// hey, this app has it (any version of it)
}
if (api.hasPackage('quasar', '^2.0.0')) {
// hey, this app has Quasar UI v2 installed
}
api.hasExtension
Check if another app extension is npm installed and Quasar CLI has invoked it.
/**
* Check if another app extension is installed
*
* @param {string} extId
* @return {boolean} has the extension installed & invoked
*/
if (api.hasExtension(extId)) {
// hey, we have it
}
api.getPackageVersion
Get the version of a host app package.
/**
* @param {string} packageName
* @return {string|undefined} version of app's package
*/
console.log( api.getPackageVersion(packageName) )
// output examples:
// 1.1.3
// undefined (when package not found)
api.extendQuasarConf
Extends quasar.config file
/**
* @param {function} fn
* (cfg: Object, ctx: Object) => undefined
*/
api.extendQuasarConf ((conf, api) => {
// do something with quasar.config file:
// add, change anything
})
api.extendQuasarConf ((conf, api) => {
if (api.hasVite === true) {
// do something with quasar.config file that is specific
// to @quasar/app-vite
}
else { // api.hasWebpack === true
// do something with quasar.config file that is specific
// to @quasar/app-webpack
}
})
Registering boot and css files
export default function (api, ctx) {
api.extendQuasarConf((conf, api) => {
// make sure my-ext boot file is registered
conf.boot.push('~quasar-app-extension-my-ext/src/boot/my-ext-bootfile.js')
if (api.hasVite !== true) {
// make sure boot file transpiles
conf.build.transpileDependencies.push(/quasar-app-extension-my-ext[\\/]src[\\/]boot/)
// if boot file imports anything, make sure that
// the regex above matches those files too!
}
// make sure my-ext css goes through webpack
conf.css.push('~quasar-app-extension-my-ext/src/component/my-ext.sass')
})
}
TIP
Notice the tidle (~
) in front of the paths. This tells Quasar CLI that the path is a dependency from node_modules instead of a relative path to App Extension index script file.
api.registerCommand
Register a command that will become available as quasar run <ext-id> <cmd> [args]
(or the short form: quasar <ext-id> <cmd> [args]
).
/**
* @param {string} commandName
* @param {function} fn
* ({ args: [ string, ... ], params: {object} }) => ?Promise
*/
api.registerCommand('start', ({ args, params }) => {
// do something here
// this registers the "start" command
// and this handler is executed when running
// $ quasar run <ext-id> start
})
api.registerDescribeApi
Register an API file for $ quasar describe
command.
/**
* @param {string} name
* @param {string} relativePath
* (relative path starting from the file where you have this call)
*/
api.registerDescribeApi(
'MyComponent',
'./relative/path/to/my/component/file.json'
)
The above will then respond to $ quasar describe MyComponent
.
For syntax of such a JSON file, look into /node_modules/quasar/dist/api
(in your project folder). Be aware that your JSON must contain a type
property (“component”, “directive”, “plugin”). For instance:
{
"type": "component",
"props": {
},
...
}
TIP
Always test with the quasar describe
command to ensure you got the syntax right and there are no errors.
api.getPersistentConf
Get the internal persistent config of this extension. Returns empty object if it has none.
/**
* @return {object} cfg
*/
api.getPersistentConf()
api.setPersistentConf
Set the internal persistent config of this extension. If it already exists, it is overwritten.
/**
* @param {object} cfg
*/
api.setPersistentConf({
// ....
})
api.mergePersistentConf
Deep merge into the internal persistent config of this extension. If extension does not have any config already set, this is essentially equivalent to setting it for the first time.
/**
* @param {object} cfg
*/
api.mergePersistentConf({
// ....
})
api.beforeDev
Prepare external services before $ quasar dev
command runs, like starting some backend or any other service that the app relies on.
Can use async/await or directly return a Promise.
/**
* @param {function} fn
* (api, { quasarConf }) => ?Promise
*/
api.beforeDev((api, { quasarConf }) => {
// do something
})
api.afterDev
Run hook after Quasar dev server is started ($ quasar build
). At this point, the dev server has been started and is available should you wish to do something with it.
Can use async/await or directly return a Promise.
/**
* @param {function} fn
* (api, { quasarConf }) => ?Promise
*/
api.afterDev((api, { quasarConf }) => {
// do something
})
api.beforeBuild
Run hook before Quasar builds app for production ($ quasar build
). At this point, the distributables folder hasn’t been created yet.
Can use async/await or directly return a Promise.
/**
* @param {function} fn
* (api, { quasarConf }) => ?Promise
*/
api.beforeBuild((api, { quasarConf }) => {
// do something
})
api.afterBuild
Run hook after Quasar built app for production ($ quasar build
). At this point, the distributables folder has been created and is available should you wish to do something with it.
Can use async/await or directly return a Promise.
/**
* @param {function} fn
* (api, { quasarConf }) => ?Promise
*/
api.afterBuild((api, { quasarConf }) => {
// do something
})
api.onPublish
Run hook if publishing was requested ($ quasar build -P
), after Quasar built app for production and the afterBuild hook (if specified) was executed.
Can use async/await or directly return a Promise.
/**
* @param {function} fn
* () => ?Promise
* @param {object} opts
* * arg - argument supplied to "--publish"/"-P" parameter
* * distDir - folder where distributables were built
*/
api.onPublish((api, opts) => {
// do something
})
@quasar/app-vite only
api.extendViteConf
/**
* @param {function} fn
* (viteConf: Object, invoke: Object {isClient, isServer}, api) => undefined
*/
if (api.hasVite === true) {
api.extendViteConf((viteConf, { isClient, isServer }, api) => {
// add/remove/change Quasar CLI generated Vite config object
})
}
api.extendSSRWebserverConf
/**
* @param {function} fn
* (esbuildConf: Object, api) => undefined
*/
if (api.hasVite === true) {
api.extendSSRWebserverConf((esbuildConf, api) => {
// add/remove/change Quasar CLI generated esbuild config object
// that is used for the SSR webserver (includes SSR middlewares)
})
}
api.extendElectronMainConf
/**
* @param {function} fn
* (esbuildConf: Object, api) => undefined
*/
if (api.hasVite === true) {
api.extendElectronMainConf((esbuildConf, api) => {
// add/remove/change Quasar CLI generated esbuild config object
// that is used for the SSR webserver (includes SSR middlewares)
})
}
api.extendElectronPreloadConf
/**
* @param {function} fn
* (esbuildConf: Object, api) => undefined
*/
if (api.hasVite === true) {
api.extendElectronPreloadConf((esbuildConf, api) => {
// add/remove/change Quasar CLI generated esbuild config object
// that is used for the SSR webserver (includes SSR middlewares)
})
}
api.extendPWACustomSWConf
/**
* @param {function} fn
* (esbuildConf: Object, api) => undefined
*/
if (api.hasVite === true) {
api.extendPWACustomSWConf((esbuildConf, api) => {
// add/remove/change Quasar CLI generated esbuild config object
// that is used for the SSR webserver (includes SSR middlewares)
})
}
api.extendBexScriptsConf
/**
* @param {function} fn
* (esbuildConf: Object, api) => undefined
*/
if (api.hasVite === true) {
api.extendBexScriptsConf((esbuildConf, api) => {
// add/remove/change Quasar CLI generated esbuild config object
// that is used for the SSR webserver (includes SSR middlewares)
})
}
@quasar/app-webpack only
api.chainWebpack
Chain webpack config
/**
* @param {function} fn
* (chain: ChainObject, invoke: Object {isClient, isServer}, api) => undefined
*/
if (api.hasWebpack === true) {
api.chainWebpack((chain, { isClient, isServer }, api) => {
// add/remove/change chain (Webpack chain Object)
})
}
The configuration is a Webpack chain Object. The API for it is described on webpack-chain docs.
api.extendWebpack
Extend webpack config
/**
* @param {function} fn
* (cfg: Object, invoke: Object {isClient, isServer}, api) => undefined
*/
if (api.hasWebpack === true) {
api.extendWebpack((cfg, { isClient, isServer }, api) => {
// add/remove/change cfg (Webpack configuration Object)
})
}
api.chainWebpackMainElectronProcess
Chain webpack config of the main electron process
/**
* @param {function} fn
* (chain: ChainObject) => undefined
*/
if (api.hasWebpack === true) {
api.chainWebpackMainElectronProcess((chain, { isClient, isServer }, api) => {
// add/remove/change chain (Webpack chain Object)
})
}
api.extendWebpackMainElectronProcess
Extend webpack config Object of the main electron process
/**
* @param {function} fn
* (cfg: Object) => undefined
*/
if (api.hasWebpack === true) {
api.extendWebpackMainElectronProcess((cfg, { isClient, isServer }, api) => {
// add/remove/change cfg (Webpack configuration Object)
})
}
api.chainWebpackPreloadElectronProcess
Chain webpack config of the preload electron process
/**
* @param {function} fn
* (chain: ChainObject) => undefined
*/
if (api.hasWebpack === true) {
api.chainWebpackPreloadElectronProcess((chain, { isClient, isServer }, api) => {
// add/remove/change chain (Webpack chain Object)
})
}
api.extendWebpackPreloadElectronProcess
Extend webpack config Object of the preload electron process
/**
* @param {function} fn
* (cfg: Object) => undefined
*/
if (api.hasWebpack === true) {
api.extendWebpackPreloadElectronProcess((cfg, { isClient, isServer }, api) => {
// add/remove/change cfg (Webpack configuration Object)
})
}
api.chainWebpackWebserver
Chain webpack config of SSR webserver (includes the SSR middlewares from /src-ssr/middlewares)
/**
* @param {function} fn
* (chain: ChainObject) => undefined
*/
if (api.hasWebpack === true) {
api.chainWebpackWebserver ((chain, { isClient, isServer }, api) => {
// add/remove/change chain (Webpack chain Object)
// isClient is always "false" and isServer is always "true"
})
}
api.extendWebpackWebserver
Extend webpack config Object of SSR webserver (includes the SSR middlewares from /src-ssr/middlewares)
/**
* @param {function} fn
* (cfg: Object) => undefined
*/
if (api.hasWebpack === true) {
api.extendWebpackWebserver((cfg, { isClient, isServer }, api) => {
// add/remove/change cfg (Webpack configuration Object)
// isClient is always "false" and isServer is always "true"
})
}
api.chainWebpackCustomSW
Chain webpack config for the custom service worker when using InjectManifest (content of /src-pwa/custom-service-worker.js):
/**
* @param {function} fn
* (cfg: ChainObject) => undefined
*/
if (api.hasWebpack === true) {
api.chainWebpackCustomSW ((cfg, { isClient, isServer }, api) => {
// add/remove/change cfg (Webpack chain Object)
})
}
api.extendWebpackCustomSW
Extend webpack config Object for the custom service worker when using InjectManifest (content of /src-pwa/custom-service-worker.js):
/**
* @param {function} fn
* (chain: Object) => undefined
*/
if (api.hasWebpack === true) {
api.extendWebpackCustomSW((chain, { isClient, isServer }, api) => {
// add/remove/change chain (Webpack configuration Object)
})
}