nuxt-quasar-vite

Quasar Framework UI for Nuxt
2,482 31
Install
npm install nuxt-quasar-vite
Latest Version:1.4.1
Vue:3
License:MIT
Last Updated:Oct 12, 2026
Links: GitHub  ·  npm
Maintainer: memotux

Quasar for Nuxt

npm version npm downloads license

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 q prefix.
  • 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
  • quasar and sass-embedded are peer dependencies of the module.
  • @quasar/extras is 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/content and @nuxt/image, with ProseImg modified to use QImg.

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 — typically assets/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 before prepack and the test* 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 (or pnpm dev:generate for 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; Firefox waitUntil: '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

nuxt-define

One utility function for module authors to define compiler constants for all bui...

13,412,511
@lg2/nuxt3-module-create-dato-map

nuxt3-module-create-dato-map

2,869 0
nuxt-csurf

Nuxt Cross-Site Request Forgery (CSRF) Prevention

6,263,746 91
@bg-dev/nuxt-naiveui

Unofficial Naive UI module for Nuxt

144,316 187
@ztl-uwu/nuxt-content

Write your content inside your Nuxt app

34,108

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