vuejs3server-side-renderingquasar

How to fetch and render data on server side


I'm using Quasar in SSR mode.

and components are rendered in server side and it returns html .

but there is just one thing that it is not right .

I want to fetch data in server side and get rendered data but I can't .

quasar.config.ts


const { configure } = require('quasar/wrappers');
const path = require('path');

module.exports = configure(function (/* ctx */) {
  return {
    eslint: {

      warnings: true,
      errors: true,
    },

    // https://v2.quasar.dev/quasar-cli-vite/prefetch-feature
    preFetch: true,

    // app boot file (/src/boot)
    // --> boot files are part of "main.js"
    // https://v2.quasar.dev/quasar-cli-vite/boot-files
    boot: ['i18n', 'axios', 'tanstack'],

    // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
    css: ['app.scss'],

    // https://github.com/quasarframework/quasar/tree/dev/extras
    extras: [
      'material-icons', // optional, you are not bound to it
    ],

    // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
    build: {
      rtl: true,
      target: {
        browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
        node: 'node20',
      },

      vueRouterMode: 'hash', // available values: 'hash', 'history'


      vitePlugins: [
        [
          '@intlify/vite-plugin-vue-i18n',
          {

            include: path.resolve(__dirname, './src/i18n/**'),
          },
        ],
      ],
    },

    // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
    devServer: {
      // https: true
      open: true, // opens browser window automatically
    },

    // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
    framework: {
      config: {},
      lang: 'fa-IR',
      iconSet: 'mdi-v7',

      plugins: ['Notify', 'Dialog'],
    },

    // animations: 'all', // --- includes all animations
    // https://v2.quasar.dev/options/animations
    animations: [],


    ssr: {
      ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name!
      // will mess up SSR

      // eslint-disable-next-line @typescript-eslint/no-empty-function
      extendSSRWebserverConf(esbuildConf) {},
      extendPackageJson(json) {},

      pwa: false,
      manualStoreSerialization: false,
      manualStoreSsrContextInjection: false,
      manualStoreHydration: false,
      manualPostHydrationTrigger: false,

      prodPort: 3000, // The default port that the production server should use
      // (gets superseded if process.env.PORT is specified at runtime)

      middlewares: [
        'render', // keep this as last one
      ],
    },

    // https://v2.quasar.dev/quasar-cli-vite/developing-pwa/configuring-pwa
    pwa: {
      workboxMode: 'generateSW', // or 'injectManifest'
      injectPwaMetaTags: true,
      swFilename: 'sw.js',
      manifestFilename: 'manifest.json',
      useCredentialsForManifestTag: false,

    },

    // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-cordova-apps/configuring-cordova
    cordova: {
      // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
    },

    // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-capacitor-apps/configuring-capacitor
    capacitor: {
      hideSplashscreen: true,
    },

    // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/configuring-electron
    electron: {
      // extendElectronMainConf (esbuildConf)
      // extendElectronPreloadConf (esbuildConf)

      inspectPort: 5858,

      bundler: 'packager', // 'packager' or 'builder'

      packager: {

      },

      builder: {
        // https://www.electron.build/configuration/configuration

        appId: 'vedika',
      },
    },

    // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex
    bex: {
      contentScripts: ['my-content-script'],

    },
  };
});

and package.json

{
  "name": "vedika",
  "version": "0.0.1",
  "description": "A Quasar Project",
  "productName": "vedik",
  "author": "morteza <mrtz.mrtzi.1989@gmail.com>",
  "private": true,
  "scripts": {
    "lint": "eslint --ext .js,.ts,.vue ./",
    "format": "prettier --write \"**/*.{js,ts,vue,scss,html,md,json}\" --ignore-path .gitignore",
    "test": "echo \"No test specified\" && exit 0",
    "dev": "quasar dev",
    "dev1": "quasar dev -m ssr",
    "build": "quasar build -m ssr",
    "serve": "vite preview",
    "build1": "vite build"
  },
  "dependencies": {
    "@quasar/extras": "^1.16.4",
    "@tanstack/vue-query": "^5.17.19",
    "@tanstack/vue-query-devtools": "^5.17.21",
    "@vee-validate/yup": "^4.12.5",
    "axios": "^1.2.1",
    "pinia": "^2.0.11",
    "quasar": "^2.8.0",
    "vee-validate": "^4.12.5",
    "vue": "^3.2.29",
    "vue-i18n": "^9.2.2",
    "vue-router": "^4.0.12",
    "yup": "^1.3.3"
  },
  "devDependencies": {
    "@intlify/vite-plugin-vue-i18n": "^3.3.1",
    "@quasar/app-vite": "^1.4.3",
    "@types/node": "^12.20.21",
    "@typescript-eslint/eslint-plugin": "^5.10.0",
    "@typescript-eslint/parser": "^5.10.0",
    "autoprefixer": "^10.4.2",
    "eslint": "^8.11.0",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-vue": "^9.0.0",
    "postcss-rtlcss": "^5.1.0",
    "prettier": "^2.5.1",
    "typescript": "^5.3.3"
  },
  "engines": {
    "node": "^20 || ^18 || ^16",
    "npm": ">= 6.13.4",
    "yarn": ">= 1.21.1"
  }
}

and this is index.vue

<template>
  <div class="medium ">
 {{ d }}
  </div>
</template>

<script setup lang="ts">
import { watch,ref, } from 'vue';
import useMedia from 'src/services/media';
import { useFilterStore } from 'src/stores/media-list-filters';
import { storeToRefs } from 'pinia'

// init
const { getAllMedia } = useMedia()
const store = useFilterStore()

// methods

const d = ref<any>()
async function getData() {
  try {
    const data = await getAllMedia({}as any)
    d.value = data
  } catch (error) {

  }
}
getData()
</script>

now , when I run the app in ssr mode like this :

quasar dev -m ssr

and then I see page resource

I cant see fetched data in page resource

enter image description here

where is the problem ?


Solution

  • this the answer worked for me

    <script setup lang="ts">
    import { useAnyStore } from 'stores/any.store'
    import { preFetch } from 'quasar/wrappers'
    
    defineOptions({
      preFetch: preFetch(({ store }) => {
        return useAnyStore(store).fetch()
      })
    })
    
    const anyStore = useUsersStore()
    </script>
    
    <template>
      <div class="medium ">
        {{ anyStore.data }}
      </div>
    </template>