nuxt-quasar-vite
Quasar for Nuxt
This Nuxt module exposes UI Components and Utils (Composables, Directives and Plugins) from Quasar Framework to Nuxt. It works on Vite-based Nuxt projects (nuxt >= 3.0.0-rc.2, Nuxt 3 and 4).
Features
- Nuxt SSR for Quasar components, with Quasar SSR hydration takeover.
- Quasar components (
Q*) auto-imported by Nuxt. - Quasar directives installed globally.
- Quasar composables auto-imported by Nuxt.
- Quasar plugins, opt-in and validated at setup time.
- Quasar variables on SFC styles.
- Quasar utils auto-imported by Nuxt with a
qprefix. - Works with Nuxt development, production and universal Nitro servers (API and middlewares), and with Nuxt SSG.
Limitations
- No Quasar Develop Modes (Electron, Capacitor, BEX, etc.): web apps only.
Setup
In your Nuxt project folder:
# Install dependencies
pnpm add -D quasar sass-embedded @quasar/extras nuxt-quasar-vite
quasarandsass-embeddedare peer dependencies of the module.@quasar/extrasis optional (fonts and icon sets).
Add the module to nuxt.config.ts:
export default defineNuxtConfig({
modules: ['nuxt-quasar-vite'],
})
Add Quasar components to your Vue files:
<!-- app.vue or layouts/default.vue -->
<template>
<QLayout view="hHh lpR fFf">
<QPageContainer>
<QPage padding class="column flex-center q-gutter-xl">
<!-- on layouts use `slot`; on app.vue use `NuxtPage` -->
<slot />
</QPage>
</QPageContainer>
</QLayout>
</template>
Starter Template
There is a starter template available: Repository
It comes configured with:
- Default layout:
layouts/default.vue - Default pages like
index.vue @nuxt/contentand@nuxt/image, withProseImgmodified to useQImg.
Install
# <nuxt-app> is the name of your project folder
pnpx nuxi init -t gh:memotux/nuxt-quasar-template <nuxt-app>
cd <nuxt-app>
pnpm install
Configuration
Defaults
quasar: {
sassVariables: true,
css: ['quasar/src/css/index.sass'],
animations: [],
plugins: ['Notify'],
config: {
dark: true,
},
}
Options
Set a quasar config key on nuxt.config.ts:
export default defineNuxtConfig({
// ...
quasar: {
// Inject Quasar variables on your SASS/SCSS files.
// - `true`: default Quasar variables
// - string: path to your custom variables file
sassVariables: 'assets/quasar.variables.scss',
// Extra CSS files, injected on the module plugin template (not `nuxt.config`).
css: ['@quasar/extras/material-icons/material-icons.css'],
// Quasar CSS animations, or 'all' to include the complete animation bundle.
// Unknown names fail at setup time with a did-you-mean suggestion.
animations: ['fadeIn'],
// List of opt-in Quasar plugins. Unknown names fail at setup time
// with the list of valid plugins.
plugins: ['Dialog'],
// Quasar UI config — see the Quasar docs when you need it.
config: {
dark: false,
},
},
// ...
})
| Option | Type | Default | Description |
|---|---|---|---|
sassVariables |
boolean | string |
true |
Auto-inject Quasar variables into all your SASS/SCSS. A string is a path to your custom variables file (relative to the project root, e.g. assets/quasar.variables.scss), imported before Quasar's so it can override defaults. |
css |
string[] |
['quasar/src/css/index.sass'] |
CSS imported by the generated Quasar plugin. Use as an escape hatch for custom fonts or non-typed CSS. |
animations |
'all' | string[] |
[] |
Quasar CSS animations imported from @quasar/extras. |
iconLibraries |
string[] |
[] |
Quasar CSS icon font libraries imported from @quasar/extras. Validated at setup. |
iconSet |
string |
— (Quasar's bundled material-icons) |
Selects the Quasar Icon Set mapping passed to installQuasar. One of the typed names derived from the installed Quasar package, validated at setup. svg-* names require @quasar/extras. |
lang |
string |
— (Quasar's bundled en-US) |
Selects the Quasar Language Pack passed to installQuasar. One of the typed modern names derived from the installed Quasar package, validated at setup. |
plugins |
string[] |
['Notify'] |
Opt-in Quasar plugins, validated at setup. |
config |
QuasarUIConfiguration |
{ dark: true } |
Quasar UI config passed to installQuasar. Fully typed using Quasar's QuasarUIConfiguration interface. |
Animations
Enable named animations from @quasar/extras and use them with the animated base class:
<div class="animated fadeIn">Content</div>
The .animated base class and the --animate-duration, --animate-delay, and --animate-repeat CSS variables come from Quasar's own CSS. Keep quasar/src/css/index.sass in the css option so those definitions remain available. The prefers-reduced-motion guard is included there as well.
Use animations: 'all' to include every typed animation. This adds approximately 30 KB of raw CSS (about 5 KB gzipped), so prefer individual names when possible. The option requires the optional @quasar/extras package.
Two CSS files, lightSpeedIn and lightSpeedOut, are intentionally not in the typed animation list or the 'all' bundle. Use the css option as an escape hatch:
css: ['@quasar/extras/animate/lightSpeedIn.css']
See the Quasar animations documentation.
Icon libraries
Enable typed CSS icon font libraries from @quasar/extras:
quasar: {
iconLibraries: ['material-icons', 'mdi-v7'],
}
The option accepts an array of library names. Unknown names fail at setup time with a did-you-mean suggestion. The option requires the optional @quasar/extras package.
Valid libraries: bootstrap-icons, eva-icons, fontawesome-v7, ionicons-v4, line-awesome, material-icons, material-icons-outlined, material-icons-round, material-icons-sharp, material-symbols-outlined, material-symbols-rounded, material-symbols-sharp, mdi-v7, themify.
If you were previously importing icon libraries via css, migrate to iconLibraries:
// Before (deprecated, still works with a warning):
css: ['@quasar/extras/material-icons/material-icons.css']
// After (typed and validated):
iconLibraries: ['material-icons']
Icon set
Select which Quasar Icon Set mapping your components use:
quasar: {
iconSet: 'mdi-v7',
}
The option accepts a single name — Quasar supports exactly one active Icon Set, so arrays and the 'all' shorthand are rejected. Unknown names fail at setup time with a did-you-mean suggestion. Valid names are the publicly licensed mappings shipped by the installed Quasar package: webfont sets (e.g. bootstrap-icons, material-icons and its -outlined/-round/-sharp variants, mdi-v3 through mdi-v7, themify) and their svg-* counterparts (see src/internal/generated-quasar-lists.ts for the exact snapshot).
Webfont mappings are pure JS lookups; bring the matching font CSS yourself, typically via iconLibraries:
quasar: {
iconSet: 'mdi-v7',
iconLibraries: ['mdi-v7'],
}
svg-* variants import their icons from @quasar/extras and therefore require the optional @quasar/extras package — setup fails with a clear error when it is missing:
quasar: {
iconSet: 'svg-mdi-v7',
}
When the option is omitted, Quasar's bundled material-icons mapping is used automatically and no extra import is emitted.
Font Awesome Pro variants (fontawesome-v5-pro, fontawesome-v6-pro, fontawesome-v7-pro) exist in Quasar but require paid fonts not shipped by @quasar/extras; set them up manually via the css option and $q.iconSet.set(...).
Language pack
Select which Quasar Language Pack your components use:
quasar: {
lang: 'es',
}
The option accepts a single name — Quasar supports exactly one active Language Pack, so arrays, objects, non-strings, the empty string and the 'all' shorthand are rejected. Unknown names fail at setup time with a did-you-mean suggestion. Valid names are the modern language packs shipped by the installed Quasar package (see src/internal/generated-quasar-lists.ts for the exact snapshot). Language packs are pure JS lookup tables and never require @quasar/extras.
When the option is omitted, Quasar's bundled en-US pack is used automatically and no extra import is emitted.
Quasar also ships deprecated aliases (kur-CKB, mm, sr-CYR) that re-export the modern names — use the modern names (ckb, my, sr-Cyrl) instead, or set an alias manually via a Lang.set(...) boot file.
Quasar plugins
These Quasar core plugins are always auto-installed by installQuasar:
Platform, Body, Dark, Screen, History, Lang, IconSet.
The following opt-in plugins can be added via the plugins option:
AddressbarColor, AppFullscreen, AppNetwork, AppVisibility, AppWakeLock, BottomSheet, Dialog, LoadingBar, Loading, Notify, LocalStorage, SessionStorage.
AppNetwork and AppWakeLock are opt-in and never enabled by default: request them explicitly via plugins: ['Notify', 'AppNetwork'] (or 'AppWakeLock'). Both require a Quasar version that exports them (2.34+). Setup validates the request against the consumer's installed quasar/src/plugins.js; on an older Quasar (e.g. 2.27) the setup fails with an actionable error naming the plugin, the installed version, and the 2.34+ requirement — baseline plugins keep working.
Browser caveats: AppNetwork needs a browser environment and its connection-detail fields are optional (not every browser reports them); AppWakeLock needs a secure context, its request can fail, and the lock can auto-release (e.g. when the tab loses visibility). Neither plugin adds Quasar Electron/Capacitor/BEX mode support.
Unknown plugin names throw at setup time with the list of valid plugins.
Auto-imports
Components
All Quasar components (Q*) are auto-imported by Nuxt, tree-shaken per usage — use them directly in templates without imports.
Composables
Baseline (Quasar 2.27+, all supported versions): useQuasar, useDialogPluginComponent and useFormChild are auto-imported.
Conditional first wave (Quasar 2.34+): useFilePicker, useSoftFullscreen and useKeyboardShortcut are auto-imported only when the consumer's installed Quasar source exports them. Quasar 2.27 consumers keep exactly the baseline imports and never receive references to missing composables; when only a subset is exported, only that subset is registered. If the resolved quasar/src/composables.js cannot be read or yields no export names, setup fails with a nuxt-quasar-vite-prefixed error instead of silently claiming (or denying) support.
<script setup lang="ts">
const $q = useQuasar()
$q.notify('Hello!')
</script>
Utils
For the Quasar Utils auto-import feature, prefix the util name with a q character. This differs from Quasar Framework itself, but makes using utils safe.
<script setup lang="ts">
// Auto-import Quasar util `date` as `qdate`
const newDate = qdate.addToDate(new Date(), { days: 7, months: 1 })
// Or use explicit #imports if you want to destructurate
import { qdate } from '#imports'
const { addToDate } = qdate
const newDate = addToDate(new Date(), { days: 7, months: 1 })
</script>
Available utils: qclone, qcolors, qcopyToClipboard, qcreateMetaMixin, qcreateUploaderComponent, qdate, qdebounce, qdom, qevent, qexportFile, qextend, qformat, qframeDebounce, qgetCssVar, qnoop, qmorph, qopenURL, qpatterns, qscroll, qsetCssVar, qthrottle, quid.
Directives
All Quasar directives (e.g. v-ripple) are installed globally by the plugin, as with a standard Quasar installation.
Quasar SCSS variables
Quasar variables are auto-injected into every SASS/SCSS compilation — including <style lang="scss"> blocks in your SFCs — via the Vite preprocessor additionalData option. You don't import them yourself.
The sassVariables option (configured on nuxt.config under quasar.sassVariables) has two modes:
true(default): injects Quasar's own variables (quasar/src/css/variables.sass).'<path>': additionally injects your custom variables file — typicallyassets/quasar.variables.scss— imported before Quasar's variables, so its values override the defaults:
// nuxt.config.ts
export default defineNuxtConfig({
// ...
quasar: {
sassVariables: 'assets/quasar.variables.scss',
},
})
// assets/quasar.variables.scss
$primary: #9c27b0;
With that in place, Quasar variables are available in any style:
.container {
border-color: $primary;
}
For more information, read the Quasar Vite Plugin docs and the quasar.config.ts framework docs.
Generated Quasar name lists
The option types, validators, and generated plugin/import code share one
internal source: src/internal/generated-quasar-lists.ts, a deterministic
snapshot of the names shipped by the quasar and @quasar/extras packages
installed in this repository. Project policy stays handwritten on top of it:
Pro icon-set exclusions (src/internal/icon-set.ts), the animations: 'all'
shorthand semantics (src/internal/animations.ts), deprecated language
aliases (src/internal/lang.ts), the curated plugin subset
(src/internal/plugins.ts), and the curated composable/util import selection
(src/internal/import-presets.ts) are never edited by the generator.
- Regenerate:
node scripts/generate-quasar-lists.mjs(runs automatically beforeprepackand thetest*scripts). - Check freshness without writing:
node scripts/generate-quasar-lists.mjs --check(CI fails on a stale snapshot instead of rewriting it).
Development
- Clone the repo:
git clone https://github.com/memotux/nuxt-quasar.git - Install dependencies:
pnpm install - Generate type stubs:
pnpm dev:prepare - Start the playground in dev mode:
pnpm dev - Build the playground:
pnpm dev:build(orpnpm dev:generatefor SSG) - Run all tests, including the browser layer:
pnpm test - Run the fast layer only (no browser required):
pnpm test:no-browser - Run the browser layer only (chromium required):
pnpm test:browser - Install the browser for the e2e suite once:
npx playwright install chromium(the suite is chromium-only; FirefoxwaitUntil: 'hydration'is broken upstream, see nuxt/test-utils#1671)
The two layers partition the suite: the browser layer is every test whose path contains e2e/browser,
and the fast layer is everything else. Name browser tests browser-*.test.ts in an e2e/ directory.
The fast layer's exclusion is deliberately narrower than the browser layer's filter, so no test can
fall outside both layers — a test that is excluded but not included runs in no CI job at all. The fast
layer installs no browser on purpose, so a browser test that lands there fails loudly instead of
passing unverified. vitest --exclude adds to the default excludes rather than replacing them — vitest's
CLI reference describes the value as "additional file globs to be excluded" (v4.1.11) — and that is what
keeps node_modules out of this layer. Confirm it by measurement, not by reading the resolved config: the
config shape does not show the defaults.
- Lint:
pnpm lint - Type-check:
pnpm test:types
Related Packages
One utility function for module authors to define compiler constants for all bui...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.4.1 | MIT | ||
| 1.4.0 | MIT | ||
| 1.3.0 | MIT | ||
| 1.2.1 | MIT | ||
| 1.2.0 | MIT | ||
| 1.1.6 | MIT | ||
| 1.1.5 | MIT | ||
| 1.1.4 | MIT | ||
| 1.1.3 | MIT | ||
| 1.1.2 | MIT | ||
| 1.1.1 | ^3.0 | MIT | |
| 1.1.0 | ^3.0 | MIT | |
| 1.0.14 | ^3.0 | MIT | |
| 1.0.13 | ^3.0 | MIT | |
| 1.0.12 | ^3.0 | MIT | |
| 1.0.11 | ^3.0 | MIT | |
| 1.0.10 | ^3.0 | MIT | |
| 1.0.9 | ^3.0 | MIT | |
| 1.0.8 | ^3.0 | MIT | |
| 1.0.7 | ^3.0 | MIT | |
| 1.0.6 | ^3.0 | MIT | |
| 1.0.5 | ^3.0 | MIT | |
| 1.0.4 | ^3.0 | MIT | |
| 1.0.3 | ^3.0 | MIT | |
| 1.0.2 | ^3.0 | MIT | |
| 0.1.7 | ^3.0 | MIT | |
| 0.1.6 | ^3.0 | MIT |