Quasar and Nuxt are not rivals. Quasar gives you the components, Nuxt gives you routing, server rendering and the server API. The nuxt-quasar-ui module joins them, and it is what quasarui.com itself runs on. This guide walks through the setup we use in production, with the exact config, so you can get a Quasar app running inside Nuxt 3 in a few minutes.
If you are starting a plain Quasar app with no Nuxt, use yarn create quasar and the Quasar CLI instead. Pick Nuxt when you want file-based routing, SSR or prerendered pages for SEO, and server routes in the same project.
From the root of a Nuxt 3 project:
yarn add quasar @quasar/extras
npx nuxi@latest module add quasar
yarn add -D sassnuxi module add quasar installs nuxt-quasar-ui and registers it in nuxt.config.ts. @quasar/extras holds the fonts and icon sets. sass is only needed if you want Quasar's Sass variables (the next step), but most real apps do.
For reference, this site runs nuxt 3.17, quasar 2.18 and nuxt-quasar-ui 2.1.
Here is the quasar block from our own nuxt.config.ts, trimmed to the parts that matter. We only use Dialog; Notify is added here because almost every app wants toasts:
export default defineNuxtConfig({
modules: ["nuxt-quasar-ui"],
quasar: {
plugins: ["Dialog", "Notify"],
sassVariables: "/assets/quasar-variables.scss",
extras: {
font: null,
fontIcons: ["material-icons", "mdi-v7"],
},
config: {
dark: false,
},
cssAddon: true,
},
});What each line does:
plugins: Quasar plugins are opt-in. List the ones you call from code, such as Dialog and Notify. Leave out the rest to keep the bundle small.sassVariables: points at a file that sets $primary, $secondary, $dark and the rest. Every Quasar component reads its colors from here.extras.font: null skips Roboto. We load our own font with @nuxt/fonts, so there is no reason to ship two.extras.fontIcons: icon fonts to load. With mdi-v7 listed you can write <q-icon name="mdi-credit-card-outline" /> anywhere.config.dark: the starting dark mode. false, true or "auto" to follow the OS.cssAddon: adds breakpoint-aware versions of the flex, display and spacing classes, like justify-md-center, flex-md-block or q-pa-md-lg. It makes the CSS noticeably bigger, so turn it on only if you use them. We do.Components and directives are auto-imported, so <q-btn>, <q-card> and v-ripple work in any page without an import line. useQuasar() is auto-imported too.
Create the file that sassVariables points to:
// assets/quasar-variables.scss
$primary : #0ea5e9;
$secondary : #26A69A;
$accent : #9C27B0;
$dark : #0f172a;
$dark-page : #121212;
$positive : #21BA45;
$negative : #C10015;
$info : #31CCEC;
$warning : #F2C037;Now color="primary" on any component uses your blue, and the text-primary and bg-primary classes follow it.
Choosing a palette by hand is the slow part. The free Quasar Theme Builder lets you pick brand, semantic and dark colors, preview them on real Quasar components, and export a ready quasar-variables.scss file. Drop it into assets/ and you are done.
If you would rather not install sass, the module also accepts colors at runtime under config.brand. Sass variables are the better choice for a fixed brand, because they also drive the generated color classes.
With Notify and Dialog in plugins, both are one call away:
<script setup lang="ts">
const $q = useQuasar();
function save() {
$q.notify({ message: "Settings saved", color: "positive", icon: "mdi-check" });
}
function confirmDelete() {
$q.dialog({
title: "Delete project?",
message: "This cannot be undone.",
cancel: true,
}).onOk(() => {
// delete it
});
}
</script>
<template>
<div class="q-gutter-sm">
<q-btn color="primary" unelevated no-caps label="Save" @click="save" />
<q-btn color="negative" flat no-caps label="Delete" @click="confirmDelete" />
</div>
</template>If $q.notify is undefined, the plugin is missing from plugins. That is the most common setup error we see.
Nuxt has layouts/, Quasar has q-layout. Put one inside the other. A layouts/default.vue like this gives every page a header and a drawer:
<script setup lang="ts">
const drawerOpen = ref(false);
</script>
<template>
<q-layout view="hHh lpR fFf">
<q-header bordered class="bg-white text-dark">
<q-toolbar>
<q-btn flat round icon="mdi-menu" @click="drawerOpen = !drawerOpen" />
<q-toolbar-title>My app</q-toolbar-title>
</q-toolbar>
</q-header>
<q-drawer v-model="drawerOpen" bordered show-if-above>
<!-- navigation -->
</q-drawer>
<q-page-container>
<slot />
</q-page-container>
</q-layout>
</template>Each file in pages/ then starts with <q-page>. For more on the view string and drawer behavior, see our guide to the Quasar layout system.
Toggle it from anywhere with the Dark API:
const $q = useQuasar();
$q.dark.toggle();Quasar adds body--dark to the body, and components switch to the $dark and $dark-page colors from your variables file. Use the dark prop only on single components that need to stay dark in a light page.
Meta plugin, useMeta or AddressbarColor in a Nuxt app. Nuxt owns the <head>; use useHead and useSeoMeta.useId. Since Quasar 2.15, Quasar's useId is not auto-imported, because Nuxt has its own. Import Quasar's explicitly if you need it.nitro.prerender works with them. Prerender public pages if you care about search: crawlers get full HTML.$q.screen cannot know the window size during SSR. Prefer Quasar's responsive classes (gt-sm, col-md-6) over v-if="$q.screen.gt.sm" for anything visible on first paint, or the server and client markup can differ.extras.fontIcons. A name like mdi-… needs mdi-v7 listed.People search "quasar vs nuxt" as if it were a choice. It mostly isn't. Quasar's CLI can build SPA, SSR, PWA, mobile and desktop apps on its own. Nuxt can't build the mobile or desktop targets, but for a web app it brings file routing, server routes and a large module ecosystem. If your app is web-only and you want Nuxt's server side, use Quasar inside Nuxt with this module. If you need Capacitor or Electron builds, stay with the Quasar CLI.
Your Nuxt app now speaks Quasar. The fastest way to fill it is to start from screens that are already built. Every Quasar component on QuasarUI is plain Quasar markup with no extra CSS framework. Preview any of them free; once you unlock the code, it drops straight into a page in the project you just set up.