Nuxt 3: SSR, VUE 3, Quasar, Pinia, KeyCloak & PWA.

Ai generated from night cafe.

Modern way of UI Development!

If you need to quickly build an SEO-friendly and production-ready UI with SSR enabled for optimal performance, then start reading….

Before getting started with Nuxt 3 + SSR, VUE 3, Quasar, Pinia, KeyCloak, and PWA, make sure to install Node and either VSCode or Fleet (I personally liked the preview version of the fleet).

🚛 To set up the basic project, create and run a basic Nuxt App using the following commands:

>> npx nuxi init new_ui
>> cd new_ui
>> npm install
>> code . <-- Opens VS Code
>> npm run dev <-- to test the basic app
a quick test

🚛 To add Quasar, run the following commands:

npm install quasar @quasar/extras
npm install --save-dev nuxt-quasar-ui
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: ["nuxt-quasar-ui"],
quasar: {
extras: {
font: 'roboto-font',
fontIcons: ['material-icons'],
}
},
});

Then, add the following snippet to app.vue:

<template>
<div>
<q-btn color="primary" label="Primary" />
<QBtn color="secondary" label="Secondary" />
<LazyQBtn color="amber" glossy label="Amber" />
<NuxtWelcome />

</div>
</template>
A Quick Test with Quasar Buttons

🚛 Add Aya Vue3 Extension Packs + Volar!

🚛 To install the necessary plugins and modules, run the following commands:


>> npm install @nuxtjs/i18n@next --save-dev
>> npm install @pinia/nuxt
>> npm install @nuxtjs/robots
>> npm install @nuxtjs/eslint-module
>> npm install @nuxtjs/html-validator

>> npx nuxi@latest devtools enable

🚛 Install the Dev Tools: Useful for further debugging.

>> npx nuxi@latest devtools enable

Restart your server and take a look at the Dev Tools.

🚛 To add PWA, run the following command:

npm i --save-dev @nuxtjs/pwa

Then, add the following code to the Nuxt config:

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: ["nuxt-quasar-ui"],
buildModules: ["@nuxtjs/pwa"],
quasar: {
extras: {
font: "roboto-font",
fontIcons: ["material-icons"],
},
},
pwa: {
meta: {
name: "abc",
author: "abc Inc",
description: "abc desc",
},
manifest: {
name: "My Awesome App",
lang: "en",
useWebmanifestExtension: false,
start_url: "abc.com",
display: "standalone",
background_color: "#fff3e0",
theme_color: "#fff3e0",
},
workbox: {
runtimeCaching: [
{
urlPattern: "https://assets.abc.com/.*",
strategyOptions: {
cacheName: "pwa-image-cache",
},
strategyPlugins: [
{
use: "Expiration",
config: {
maxEntries: 100,
maxAgeSeconds: 60 * 60 * 24 * 30,
},
},
],
},
],
},
},
});
  1. Create a static folder and add your icon (512x512) to it, as Nuxt PWA will auto-generate the necessary icons using this.
  2. Also, add “sw.*” to .gitignore as this file will be auto-generated as well.

Restart the app by running `npm run dev`. Just to ensure you are not breaking the app with your configs so far!

🚛 Next, create the Nuxt folder structure (here) and add Pinia, the intuitive store for Vue.js, by adding the following code to package.json and running “npm install”:

🚛 Add Pinia: The intuitive store for Vue.js (More details here)

for package.json add the below snippet and run “npm install”

"overrides": {
"vue": "latest"
}
npm install pinia @pinia/nuxt

nuxt.config.ts

modules: ["@pinia/nuxt"],
pinia: {
autoImports: ["defineStore", "acceptHMRUpdate"],
},

If you like to maintain all the stores in one place, create a “stores” dir and let the nuxt know about it for auto imports. Add the below line in nuxt.config.ts

imports: { dirs: ["stores"] },

🚛 To enable SSR, add the following code to nuxt.config.ts:

  ssr: true

Retstrat the app to check you are not breaking any configs.

  • To add LogRocket and KeyCloak as needed use the following commands:
npm install logrocket
<script setup lang="ts">
import LogRocket from 'logrocket';
LogRocket.init('ulrfwc/test');
LogRocket.identify('Gopi', {
name: 'GOPI',
email: 'test@test.com',
subscriptionType: 'pro',
});
</script>

Add the above snippet to app.vue

🚛 Dot Env:

Set your runtimeConfig inside nuxt.config.ts

runtimeConfig: {
gwEndPoint: '',

public: {
authClientId: '',
authRealm: '',
authUrl: '',
stripeKey: '',
},
},

Create your .env files

.env
.env.local
.env.qa
.env.prod

Have the naming compatible as follows inside the .env files:

NUXT_PUBLIC_AUTH_URL=http://keycloak:9080/auth/
NUXT_GW_ENDPOINT=http://localhost:8080
NUXT_STRIPE_KEY=test_key
NUXT_PUBLIC_AUTH_REALM=Test
NUXT_PUBLIC_AUTH_CLIENT_ID=Test_APP

Now modify the package.json scripts

 "dev": "nuxt dev --dotenv .env.local",

Now, you should be able to access the configuration in plugins and files as below:

 const runtimeConfig = useRuntimeConfig();

const initOptions: KeycloakConfig = {
url: runtimeConfig.authUrl,
realm: runtimeConfig.authRealm,
clientId: runtimeConfig.authClientId,
};

🚛 KeyClaok:

npm i keycloak-js

over all package.json

"devDependencies": {
"@nuxt/content": "^2.5.2",
"@nuxtjs/pwa": "^3.3.5",
"nuxt": "^3.3.2",
"nuxt-quasar-ui": "^1.3.1"
},
"dependencies": {
"@pinia/nuxt": "^0.4.7",
"@quasar/extras": "^1.16.1",
"keycloak-js": "^21.0.2",
"logrocket": "^4.0.0",
"nuxt-icons": "^3.1.0",
"pinia": "^2.0.33",
"quasar": "^2.11.9",
"sass": "^1.60.0"
},
"overrides": {
"vue": "latest"
}

Create a Keycloak Plugin: (keycloak.client.ts)

import Keycloak, { KeycloakConfig } from 'keycloak-js';

export default defineNuxtPlugin((nuxtApp) => {
const runtimeConfig = useRuntimeConfig();

const initOptions: KeycloakConfig = {
url: runtimeConfig.authUrl,
realm: runtimeConfig.authRealm,
clientId: runtimeConfig.authClientId,
};

const keycloak = new Keycloak(initOptions);

nuxtApp.$keycloak = keycloak;
keycloak
.init({
// Use 'login-required' to always require authentication
// If using 'login-required, check-sso', there is no need for the router guards in router.js - check-sso
onLoad: 'check-sso',
});

console.log('KeyCloak Plugin Loaded: ', nuxtApp.$keycloak);
});

Create a button and click on that in the index.vue

<template>
<q-page-container>
<q-page class="q-pa-md">

<q-btn label="Test KeyCloak" @click="login()"></q-btn>

<q-page-scroller position="bottom">
<q-btn fab icon="keyboard_arrow_up" color="red"></q-btn>
</q-page-scroller>
</q-page-container>
</template>

<style lang="scss" scoped></style>

<script setup lang="ts">
import Keycloak from 'keycloak-js';
function login() {
console.log('----> ', useNuxtApp().$keycloak);
(useNuxtApp().$keycloak as Keycloak).login();
}
</script>

That's all!

Find my other articles @ my publication: ThinkSpecial

--

--