Quasar & Quasar CLI v0.17 aka SSR - Developer Preview


  • Admin

    Final edit: The official v0.17 has been released! Thanks to all contributors and everyone who helped in testing the betas! You rock!

    Edit: CLI beta.22 has been released. New features & perf improvements. Please read the end of this post.
    Edit: CLI beta.21 has been released. New features. Please read the end of this post. There’s a required upgrade step.
    Edit: CLI beta.19 & beta.20 has been released. Many new features. Please read the end of this post.
    Edit: CLI beta.18 has been released. Many important enhancements. Please read the end of this post.
    Edit: CLI beta.17 has been released. The small store/router changes are required ONLY when building with SSR mode. Please read the end of this post.
    Edit: CLI beta.16 has been released. Required changes if you upgraded from beta.15 are at the end of the post.

    Hi,

    We got a great release ahead, but we need some volunteers for some beta-testing before we release it officially. There’s been a lot of refactoring under the hood (but no external API changes), so we just want to make sure nothing gets broken in your apps.

    We’d appreciate it very much if you can make a temporary copy of your project folder and try it with the new Quasar version. Please do not use it in production yet, as the newly added SSR API may change at any time based on your feedback. We want to get it right from the beginning in order to avoid breaking changes in the future.

    There’s only one breaking change, regarding QLayoutDrawer mini-width prop. It is now a Number (instead of String!) defining width in pixels (default: 60).

    You’ll be able to build a SSR out of your app (but please make sure you know what SSR is before digging in). Mainly we’re interested if any app functionality gets broken for the other Quasar modes (SPA, PWA, Cordova, Electron) then we’d like some feedback on SSR too. If you find a bug in Quasar, then open up a ticket and insert “[0.17 beta]” in its title. If there’s a bug on CLI, please do the same on Quasar CLI repo.

    The release notes are going to be edited here as we make progress towards the final v0.17 build.

    So here we go: make a temporary copy of your project folder, edit “quasar-cli” in package.json to point to “^0.17.0-beta.18” then yarn/npm install. If on Quasar UMD, just replace the version on the style and script tags to point to “quasar-framework@next”. Your feedback is very important. Let’s get this done as soon as possible so we can have the new shiny release becoming official. Thanks to all who participate!

    The beta release notes for Quasar CLI & Quasar:

    1. Quasar CLI v0.17.0

    New

    SSR mode (+ optional PWA takeover)

    • quasar.conf.js new prop, specific to SSR (all sub-props are optional)

      // quasar.config.js
      return {
        // ...
        ssr: {
          pwa: true/false, // should a PWA take over (default: false), or just a SPA?
          componentCache: {...} // lru-cache package options
        }
      }
      
    • Production server
      When you add SSR mode ($ quasar mode -a ssr), you will notice a new folder gets created: /src-ssr. This folder contains your production server which you can fully customize. You can learn more about it by opening /src-ssr/index.js file and reading the comments.

    • App plugins

      • Ability to tell if to get embedded only on server or only on client
        // quasar.conf.js
        return {
          // ...
          plugins: [
            'some-plugin',
            { path: 'some-other', server: false } // this plugin gets embedded only on client-side
            { path: 'third', client: false } // this plugin gets embedded only on server-side
          ]
        }
        
      • The default exported function now has one more property received on its Object parameter:
        // some app plugin
        export default ({ app, ..., ssrContext }) => {
          // ssrContext has: { url, req, res }
        
          // You can add props to the ssrContext then use them in the src/index.template.html.
          // Example - let's say we ssrContext.someProp = 'some value', then in index template we can reference it:
          // {{ someProp }}
        }
        
        When you add such references ({{ someProp }}) into your src/index.template.html, make sure you tell Quasar it’s only valid for SSR builds:
        <!-- index.template.html -->
        <% if (htmlWebpackPlugin.options.ctx.mode.ssr) { %>{{ someProp }} <% } %>
        
    • extendWebpack() & chainWebpack() now receive one more parameter (Object), currently containing isServer or isClient boolean props:

      // quasar.conf.js
      build: {
        extendWebpack(cfg, { isServer, isClient }) { ... }
      }
      

      This is because the extendWebpack() & chainWebpack() are called twice, once for the client Webpack config and once for the server Webpack config. So by looking at the two props you can make decisions.

    SSR mode (ONLY) small required changes

    These changes will be required by the Quasar CLI only when you build with SSR mode. After doing these changes you’ll still be able to build the other modes (SPA/PWA/Cordova/Electron) too.

    src/router/index.js

    You need to have a default export set to “function ({ store })” which returns a new instance of Router instead of default exporting the Router instance itself.

    // OLD WAY
      import Vue from 'vue'
      import VueRouter from 'vue-router'
      import routes from './routes'
      Vue.use(VueRouter)
    
      // in the new way, we'll wrap the instantiation into:
      // export default function ({ store }) --> store is optional
      const Router = new VueRouter({
        scrollBehavior: () => ({ y: 0 }),
        routes,
        // Leave these as they are and change from quasar.conf.js instead!
        mode: process.env.VUE_ROUTER_MODE,
        base: process.env.VUE_ROUTER_BASE,
      })
    
      // in the new way, this will be no more
      export default Router
    
    // NEW WAY
      import Vue from 'vue'
      import VueRouter from 'vue-router'
      import routes from './routes'
      Vue.use(VueRouter)
    
      // DO NOT import the store here as you will receive it as
      // parameter in the default exported function:
    
      export default function (/* { store } */) {
        // IMPORTANT! Instantiate Router inside this function
    
        const Router = new VueRouter({
          scrollBehavior: () => ({ y: 0 }),
          routes,
          // Leave these as they are and change from quasar.conf.js instead!
          mode: process.env.VUE_ROUTER_MODE,
          base: process.env.VUE_ROUTER_BASE,
        })
    
        return Router
      }
    
    src/store/index.js

    You need to have a default export set to “function ()” which returns a new instance of Vuex Store instead of default exporting the Store instance itself.

    Some of you might need the Router instance on the Store. It is accessible through this.$router inside your actions, mutations, etc.

    // OLD WAY
      import Vue from 'vue'
      import Vuex from 'vuex'
      import example from './module-example'
      Vue.use(Vuex)
    
      // in the new way, we'll wrap the instantiation into:
      // export default function ()
      const store = new Vuex.Store({
        modules: {
          example
        }
      })
    
      // in the new way, this will be no more
      export default store
    
    // NEW WAY
      import Vue from 'vue'
      import Vuex from 'vuex'
      import example from './module-example'
      Vue.use(Vuex)
    
      export default function () {
        // IMPORTANT! Instantiate Store inside this function
    
        const Store = new Vuex.Store({
          modules: {
            example
          }
        })
    
        return Store
      }
    

    Also, if you want to be able to access the Router instance from vuex actions, mutations, etc, you need to make some simple changes (in all of them):

    // OLD WAY:
    export const someAction = (context) => { ... }
    
    // NEW WAY:
    export function someAction (context) {
      // now we have access to:
      this.$router
    }
    

    Quasar Meta plugin

    The Meta plugin can change page title, manage meta tags, manage <html> & <body> DOM element attributes, add/remove/change <style> tags in head (useful for CDN stylesheets, for example), or manage <noscript> tags. Note that this is not a full description of what the Meta plugin can do (that will be available in the final release notes).

    Installation:

    // quasar.conf.js
    framework: {
      // ...
      plugins: ['Meta']
    }
    

    What this does is that it enables the use of a special property in your Vue components called meta. Example below, with almost all of its features:

    // some .vue file
    
    export default {
      // ...
      meta: {
        title: 'Index Page', // sets document title
        titleTemplate: title => `${title} - My Website`, // optional; sets final title as "Index Page - My Website", useful for multiple level meta
        meta: {
          description: { name: 'description', content: 'Page 1' },
          keywords: { name: 'keywords', content: 'Quasar website' },
          equiv: { 'http-equiv': 'Content-Type' content: 'text/html; charset=UTF-8' }
        },
        link: {
          material: { rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons' }
        },
        script: {
          ldJson: {
            type: 'application/ld+json',
            innerHTML: `{ "@context": "http://schema.org" }`
          }
        },
        htmlAttr: {
          'xmlns:cc': 'http://creativecommons.org/ns#' // generates <html xmlns:cc="http://creativecommons.org/ns#">
        },
        bodyAttr: {
          'action-scope': 'xyz', // generates <body action-scope="xyz">
          empty: undefined // generates <body empty>
        },
        noscript: {
          default: 'This is content for browsers with no JS (or disabled JS)'
        }
      }
    }
    

    Metas are computed from .vue files in the order they are activated by Vue Router (let’s call this a chain for further explanations). Example: App.vue > SomeLayout.vue > IndexPage.vue > …?

    Notice that all properties (except for title and titleTemplate) are Objects; you can override meta props defined in previous Vue components in the chain by using these keys again. Example:

    // first loaded Vue component
    meta: {
      meta: {
        myKey: { name: 'description', content: 'My Website' }
      }
    }
    
    // a subsequent Vue component in the chain;
    // this will override the first definition on "myKey"
    meta: {
      meta: {
        myKey: { name: 'description', content: 'Page 1' }
      }
    }
    

    The “meta” properties can be dynamic. For example, this is how you can bind to the Vue scope with them. Think of them as a Vue computed property.

    export default {
      data () {
        return {
          title: 'Some title' // we define the "title" prop
        }
      },
      meta () {
        return {
          // this accesses the "title" property in your Vue "data";
          // whenever "title" prop changes, your meta will automatically update
          title: this.title
        }
      },
      methods: {
        setAnotherTitle () {
          this.title = 'Another title' // will automatically trigger a Meta update due to the binding
        }
      }
      // ...
    }
    

    App Plugins

    Here’s a full list of the parameters for app plugins:

    // ...
    export default ({
      app, // the Vue instantiation Object for the app
      router, // the instantiated Vue Router of your app
      store, // the instantiated Vuex Store (if using one)
      Vue, // so you don't need to "import Vue from 'vue'"
      ssrContext // the SSR context (when running server-side only)
    }) => {
      // ...
    }
    

    Quasar “serve” command

    “$ quasar serve <…options>” creates a customizable and optimized ad-hoc static webserver that can be used for quick testing (or on production too!).

    Type “$ quasar serve -h” for all the options.

    # example
    $ quasar serve dist/spa-mat
    

    Tree-shaking on Quasar

    This has been improved near to perfection, avoiding some webpack pitfalls. The final build of your app will include ONLY & EXACTLY what you cherry-picked from Quasar.

    New quasar.conf option

    • build > showProgress: true/false – show/hide the compilation progress

    Other new features

    • Vue component new instantiation method: preFetch() support (for all Quasar modes, not just SSR) – works great along with the new LoadingBar Quasar plugin

      // .vue component
      <template>...</template>
      <script>
        export default {
          ...,
          preFetch ({ store, currentRoute, previousRoute, redirect, ssrContext }) {
            // fetch data etc...
            // return a Promise
      
            // ssrContext is available only server-side
      
            // no access to "this" here as preFetch() is called before
            // the component gets instantiated
          }
        }
      </script>
      

      However, preFetch() is a feature on demand, so if you want to use it, you need to enable it in quasar.conf:

      // quasar.conf
      preFetch: true
      
    • In app code, you can now use new booleans process.env.SERVER and process.env.CLIENT which tell if code is run on server or on client. Useful for decision making, since for SSR apps the code must be isomorphic.

    Improvements

    • Updated deps: webpack 4.16.0, register-service-worker 1.4.1, css-loader v1.0.0, quasar-extras v2.0.4 (Material Icons CDN v38, Fontawesome 5.1.0, Ionicons 4.2.4)
    • Extract CSS to /css instead of root #141
    • Ability to specify node_module paths on quasar.conf > css (example: ‘~flag-icon-css/css/flag-icon.css’) #136
    • Improve Cordova deps install after repo clone/fork
    • Quasar CSS addon functionality (injects full responsive flex CSS classes) – more on this on the final release notes
    • Follow webpack recommendations of not using filename hashes for dev build #122
    • Detecting if Quasar CLI is run on a CI or minimal terminal and avoiding some pitfalls (like trying to open up a browser if quasar.conf > devServer: open is “true”)
    • New Webpack compile progress bar – most important feature: takes into account parallel compilations
    • Information banners on dev/build commands at startup and finish
    • Enable webpack scope hoisting by default (can be disabled by quasar.conf > build > scopeHoisting: false)
    • Bring back quasar.conf > vendor > add, remove arrays to configure what gets into the vendor bundle and what not.

    Fixes

    • Quasar commands problem on Windows Node v10.3 #130
    • quasar init -v <any version> returns error #133
    • vuex store presence is not detected if not using .js file extension #135

    2. Quasar v0.17.0

    Breaking Changes

    Only one, regarding QLayoutDrawer mini-width prop. It is now a Number (instead of String!) defining width in pixels (default: 60).

    SSR (Server-Side Rendering) Support

    The long awaited SSR support is here! Quasar code is now isomorphic. It might be a one-liner, but this is where 90% of the development time was spent for this release.

    Some things worth mentioning, in order to best benefit from Quasar SSR:

    • Make sure you read the Vue SSR guide, especially these pages, in this order:

    • Use Platform and Cookies Quasar plugins only in their $q.platform and $q.cookies form. Do not use this outside of Vue components when building with SSR mode. This restriction is required because of the singleton problem when dealing with SSR.

    • The LocalStorage and SessionStorage Quasar plugins cannot be used on server-side. The reasons are obvious since this is a client-side only browser API. DO NOT rely on web storage for your SSR website. You can use Cookies Quasar plugin instead, which does work on server-side too.

    • Make your QBtns SEO-friendly. Quasar offers this functionality out of the box, but you need to know how to enable it:

      Quasar buttons are usually rendered with a <button> HTML tag. But now they can be rendered with <a> tags too. When you want the user to navigate to another route by clicking a QBtn, you were used to add a @click Vue event handler. Now you can use <router-link>-like props on QBtn too. By doing this, Quasar can make your buttons SEO friendly.

      <!-- old way, still works, but not SEO friendly -->
      <q-btn @click="$router.push('/some/route')" ... />
      <!-- new, equivalent way -->
      <q-btn to="/some/route" ... />
      
      <!-- old way, still works, but not SEO friendly -->
      <q-btn @click="$router.replace('/some/route')" ... />
      <!-- new, equivalent way -->
      <q-btn to="/some/route" replace ... />
      
      <!-- old way, still works, but not SEO friendly -->
      <q-btn @click="$router.push({ name: 'special' })" ... />
      <!-- new, equivalent way -->
      <q-btn :to="{ name: 'special' }" ... />
      

    New

    • (NEW) QNoSsr component; highly optimized - takes into consideration client takeover so subsequent renders are as fast as possible.

    • (NEW) QJumbotron component; example

    • (NEW) QTable as grid

    0_1532300337110_qtable-grid.png

    <q-table
      grid
      hide-header
      :data="data"
      :columns="columns"
      :filter="filter"
      :selection="selection"
      :selected.sync="selected"
      :visible-columns="visibleColumns"
      row-key="name"
    >
      <template slot="top-right" slot-scope="props">
        <q-search hide-underline v-model="filter" />
      </template>
    
      <div
        slot="item"
        slot-scope="props"
        class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3 transition-generic"
        :style="props.selected ? 'transform: scale(0.95);' : ''"
      >
        <q-card class="transition-generic" :class="props.selected ? 'bg-grey-2' : ''">
          <q-card-title class="relative-position">
            <q-checkbox v-model="props.selected" :label="props.row.name" />
          </q-card-title>
          <q-card-separator />
          <q-card-main class="q-pa-none">
            <q-list no-border>
              <q-item v-for="col in props.cols.filter(col => col.name !== 'desc')" :key="col.name">
                <q-item-main>
                  <q-item-tile label>{{ col.label }}</q-item-tile>
                </q-item-main>
                <q-item-side right>
                  <q-item-tile>{{ col.value }}</q-item-tile>
                </q-item-side>
              </q-item>
            </q-list>
          </q-card-main>
        </q-card>
      </div>
    </q-table>
    
    • New quasar.conf > framework > config Object

      framework: {
        // ...
        config: {
          brand: { // this will NOT work on IE 11
            primary: '#e46262',
            // ... or all other brand colors
          },
          notify: {...}, // default set of options for Notify Quasar plugin
          loading: {...}, // default set of options for Loading Quasar plugin
          loadingBar: { ... }, // settings for LoadingBar Quasar plugin
          cordova: {
            iosStatusBarPadding: true/false, // add the dynamic top padding on iOS mobile devices
            backButtonExit: true/false // Quasar handles app exit on mobile phone back button
          }
        }
      }
      

      The Quasar UMD version will define the following before including the Quasar script tag:

      <script>
        // optional
        window.quasarConfig = { .... }
      </script>
      
    • Loading & Notify Quasar plugins now support a new method: setDefaults({...}) – use this or through quasar.conf > framework > config: { loading: {...}, notify: {...} }

    • (NEW) LoadingBar Quasar plugin – adds a loading bar a-la Youtube; no need to do anything else in your app code

      It will catch all Ajax calls and even hook into asyncData() automatically, but if you have some custom actions, you can programmatically start/stop it by calling this.$q.loadingBar.start() and this.$q.loadingBar.stop() in your Vue components. Outside of Vue components, you can import { LoadingBar } from 'quasar' then call LoadingBar.start()/stop()/increment(val)

      LoadingBar is using QAjaxBar component under the covers, so you can configure it using QAjaxBar props like this:

      // quasar.conf
      framework: {
        // ...
        plugins: [
          // ...
          'LoadingBar'
        ],
      
        config: {
          // optional:
          loadingBar: { ... } // QAjaxBar props
        }
      }
      
    • Hook AddressbarColor into cordova-plugin-statusbar when available

    • QLayoutDrawer

      • “mini-width” prop is now a Number (instead of String!) defining width in pixels (default: 60)
      • new prop: width defining width in pixels for non-mini mode (default: 300)
      • backdrop animation when in mobile mode
    • Many performance enhancements

      • layout header/footer animation
      • tweaks to make Vue render Quasar components faster by avoiding some children array normalization
    • Ability to cancel frameDebounce() from utils (call .cancel() on the debounced function)

    • QUploader: added upload-factory prop (#2093)

    • QInput: added prop lower-case (#2117)

    • New Quasar language packs: Traditional Chinese, Guarani

    • [Request] Q-Chips-Input: Pass upper-case parameter to underlying q-input #2031

    • [Request] QUploader - new prop: no-content-type #1974

    • Q-Page: ability to disable minHeight prop. (#2120)

    • Allow Dialog and ActionSheet Quasar plugins to receive a resolver token (#1869)

    • Improve out of the box SEO for QItem, QBreadcrumbs, QRouteTab – allow bots to follow links

    • Improve keyboard navigation (#1936)

      • QModal
        • fix not emmiting dismiss on ESC
        • focus after show
        • add back noRefocus
      • QPopover
        • focus after show
        • refocus after hide (noRefocus prop)
        • allow toggle by keyboard ENTER
      • QDialog
        • fix button focus
        • find button by class name (q-btn)
        • add back noRefocus
      • QFab - refocus after hide
      • QTab / QRouteTab
        • focus with keyboard
        • allow select with keyboard ENTER
      • QColor and QDatetime
        • fix tabindex lost on close
        • fix popup not closing on blur
      • QColorPicker
        • fix incorrect tabindex on disable
        • allow to select saturation on click on mobile (was working only on drag)
      • QDatetimePicker.mat - allow keyboard adjustment of all values
      • QActionsheet
        • select option with ENTER/SPACE, navigation with TAB
        • trigger selection on keyup to avoid click on original button
      • QAutocomplete - use QPopup with noFocus
      • QKnob, QSlider, QRange - keyboard updating (UP|RIGHT +, DOWN|LEFT -, CTRL+… 10*)
      • QSelect
        • remove autofocusFilter - always select filter if present
        • move keyboard navigation on QPopover
        • delay popover.reposition on filter to allow resize
      • v-back-to-top, v-close-overlay, v-go-back, v-ripple - trigger by keyboard ENTER
      • QInput - set model on ENTER
    • Flex addons – provide breakpoint aware versions for all flex (and display) related classes – needs to be enabled from quasar.conf > framework > cssAddon: true

        .flex-<bp>-(block|inline)
        .(row|column|flex)-<bp>(|-inline)
        .reverse-<bp>
        .(wrap|no-wrap|reverse-wrap)-<bp>
        .order-<bp>-(first|last|none)
        .justify-<bp>-(start|end|center|between|around)
        .items-<bp>-(start|end|center|baseline|stretch)
        .content-<bp>-(start|end|center|between|around)
        .self-<bp>-(start|end|center|baseline|stretch)
        .flex-<bp>-center
        .gutter-<bp>(|-x|-y)-(xs|sm|md|lg|xl)
        .(col|offset)-<bp>(|0..12)
      
    • QModal: Auto size based on content, can be customized through CSS with (min|max)(Width|Height) passed in :content-css. It’s also applied when using QModalLayout.

    • Flex: .col has higher grow priority than .col-auto and .col-grow, add .(col|offset)-0

    • Material ripple - centered on round buttons (as per Material guidelines)

    • [Request] debounce property in QScrollObservable component #2169

    • QTabs - desktop state hover

    • QScrollArea - added hover effect (#2189)

    • Lots of enhancements to QAjaxBar to best accommodate SSR mode

    • Use round/rounded focus helper for radio/checkbox (#2200)

    • QBtnDropdown - popover-anchor & popover-self props (to align its popover) #1665

    • Enhancements for clearable and clearValue (#2216) #1994

    • Loading plugin default delay was set to 0

    • feat: add v-scroll horizontal position #2296

    • Finalized helper-json files

    Fixes

    • QTab’s count and alert attributes look bad when QTabs’s align is set to justify #2032
    • [Bug] QSelect throws an error when container block disappears #2071
    • QInput shouldn’t have expanding underline animation on focus in iOS theme #2085
    • v-scroll-fire get fired when reload the page #2081
    • Q-Pagination Direction-Links Broken on Cordova #2088
    • v-model on QLayoutDrawer bug #2094 – example: having an input component breaks the model of QLayoutDrawer
    • iPhoneX - avoid toolbar/header top-padding when not in fullscreen #2118
    • [Regression] Dialog is not blurring input element in v0.15.15/v0.16 #2137
    • QBtnDropdown Popover does not scroll #2136
    • QTable: [MS-Edge] Loading indicator not displayed correctly #2122
    • QSearch: propagate upper-case and lower-case #2124
    • Force QChip pointing zIndex (when in an already positioned context) #1982
    • QPullToRefresh causing scroll issues with large tables inside QScrollArea #1884
    • QColorPicker - process unset value #1887
    • Error when navigating to other page while select component is opened #1980
    • Return dismiss function from Notify.create #1913
    • Fix material ripples on IE 11
    • QAutocomplete: Fix focus after tab, fix loop in normalizeInterval, fix reposition, select options on keyboard navigation #2149 #2155 close #2157
    • Override Material Icons CDN default size
    • Colors utils: Fix guard for color type in luminosity (#2180)
    • Japanese Quasar language pack: 2 words changed for more natural Japanese (#2182)
    • Mini layout drawer animates like normal mode when it hides automatically #2080
    • Infinite scroll delay after resume #2187
    • animScrollTo util - bug if duration < 16 after recursion (#2192)
    • Fix dom.ready() util when readyState = “interactive” (#2199)
    • QSelect: fix blur when selecting clear (#2202)
    • QBreadcrumbs and align mixin - fix align prop value check (#2217)
    • className for QSelect, QSearch before|after, QInput focus on marginalia (#2215)
    • Screen plugin doesn’t updates values after setting new sizes #2221
    • QRouterTab: fix double tabindex and hide outline (#2226)
    • QPopover: only refocus on anchorEl when anchorClick (solves refocusing on split dropdown) (#2225)
    • Fix QAutocomplete when not editable and pass readonly to QInputFrame (#2227)
    • Fix internal popups.getPosition corner-case (#2235)
    • QDatetime: use a ±50 years interval from current, use precomputed mins (#2234)
    • QDatetime: format when type is date and formatModel is string (#2231)
    • Fix not caught rejected promises when showing/hiding modals, dialogs, popovers
    • fix: QTable - sort by non visible column #1886
    • fix: QInfiniteScroll concurrency issue #2241
    • fix(QSelect): does not show placeholder text when using chips (fix #2003) #2287
    • fix: Corner case in model-toggle where component gets destroyed & not cleans up history on Cordova

    Upgrading from beta.15 to beta.16

    In src/router/index.js, if you are using a store, replace createRouter (store) with createRouter ({ store }).
    This allows for greater flexibility on the long run.

    Also, if you want to be able to access the Router instance from vuex actions, mutations, etc, you need to make some simple changes (in all of them):

    // OLD WAY:
    export const someAction = (context) => { ... }
    
    // NEW WAY:
    export function someAction (context) {
      // now we have access to:
      this.$router
    }
    

    Upgrading from beta.16 to beta.17

    If you’ve made the earlier requested store/router changes, then please replace export function createRouter and export function createStore with export default function. This allows non-breaking changes when building with non SSR mode.

    // OLD way
      export function createRouter ({ store }) { ... } // in router file
      export function createStore () { ... } // in store file
    
    // NEW way
      export default function ({ store }) { ... } // in router file
      export default function () { ... } // in store file
    

    Upgrading from beta.17 to beta.18

    • PWA enhancements: you now have access to the service-worker and manifest.json file during development too! In order for Hot Module Replacement to work, the PWA is forcing the network-first approach (it reverts back to your original workbox approach for production).

    • LoadingBar is now a Quasar plugin instead of a CLI feature for two reasons: 1. So that UMD users can use it too; 2. So that you can access it in any .js/vue file (from /src).

      // quasar.conf
      
      // OLD WAY
        loadingBar: true / { ... }
      
      // NEW WAY
        framework: {
          // ...
          plugins: [
            // ...
            'LoadingBar'
          ],
      
          config: {
            // optional:
            loadingBar: { ... }
          }
        }
      

      In any .js or .vue src file you can then:

      import { LoadingBar } from 'quasar'
      
      LoadingBar.start()
      LoadingBar.stop()
      LoadingBar.increment(val)
      
    • asyncData() has been renamed to the more appropriate name preFetch() and it now needs to be enabled in quasar.conf.js. The reason is that not all apps need it so it’s best to avoid the additional overhead when you don’t use this feature.

      // quasar.conf
      preFetch: true / false
      
    • Updated to latest babel 7 & webpack 4.16.0

    • Fixed: dev server not starting when using no-vuex template #145

    Upgrading from beta.18 to beta.19/20

    Quasar core:

    • Quasar Meta plugin (details in above sections)
    • When on SSR, now you can use Platform and Cookies Quasar plugins with the global form too, through the parseSSR(..) method (details in above sections).
    • fix(QInput): “length undefined” when viewing on a mobile device
    • Fixes for flex - only set max-height|width when inside column|row (#2257)
    • QChip: add small horizontal padding and limit size (#2260)
    • CSS cosmetics - remove some outlines (#2259)

    Quasar CLI:

    • App plugins & preFetch can take two additional parameters: currentRoute (instead of route; vue route object) and redirect(url) (which can redirect to another page; useful for making decisions in app plugins or prefetch – example: if not logged in, redirect to some specific page)
    • preFetch now works in src/App.vue too – there you can, as an example, initialize the store or make final App validations.

    Upgrading from beta.20 to beta.21

    You’ll need to remove then add SSR mode again due to one of the new features.

    # this will DELETE the src-ssr folder
    $ quasar mode -r ssr
    # then create it again
    $ quasar mode -a ssr
    

    New features:

    1. SSR error page when developing and server encounters an error
    2. SSR - dev & prod common code through src-ssr/extension.js

    Fixes:

    1. preFetch() currentRoute parameter
    2. Force “/” as publicPath for SSR

    Quasar just got the Danish translation pack too.

    Upgrading from beta.21 to beta.22

    Quasar core:

    • NEW! QTable as grid.
    • Loading plugin default delay was set to 0
    • feat: add v-scroll horizontal position #2296
    • fix: QTable - sort by non visible column #1886
    • fix: QInfiniteScroll concurrency issue #2241
    • feat: Add “script” support for Quasar Meta plugin
    • Finalized helper-json files
    • fix(QSelect): does not show placeholder text when using chips (fix #2003) #2287
    • fix: Corner case in model-toggle where component gets destroyed & not cleans up history on Cordova

    CLI:

    • perf: Improve preFetch performance; add preFetch param (previousRoute)
    • fix: HMR failing in certain scenarios for SSR
    • perf: Enhance dev-server cleanup
    • feat: index.template.html support for <%= htmlWebpackPlugin.process.env %>
    • Various minor fixes & further deps update


  • stunning work again!



  • What an amazing update! Brilliant stuff.



  • Congrats to all contributors, amazing stuff ! SSR + PWA gonna be 😍. Now waiting for official Quasar v0.17 😄


  • Admin

    @Scorpion Don’t wait. Beta test it. Report bugs. Give feedback. It’s important. If no one tests it I might as well release it as is. But then, for example, the SSR API will be frozen. So trying to get feedback on: 1. does it breaks my current app as is (for spa/pwa/electron/cordova)? 2. “I’m interested in SSR, so I think this option needs to be added/changed/removed.”

    The sooner more devs test it out - the better, so any help is appreciated!



  • Great work!!!, I’ll try it out!



  • This is great stuff! It should be the “notch in the tool belt” that makes Quasar a leading component framework!

    Scott


  • Admin

    Beta.16 available with some fixes. Read the initial post again. If upgrading from beta.15, then the end of the initial post has one required change.


  • Admin

    CLI beta.17 has been released. The small store/router changes are required ONLY when building with SSR mode now. Please read the end of the initial post.



  • @rstoenescu Yeah I know, I’m actually focusing on a Full-stack Template mixing Quasar Framework for Frontend and Rails Backend, but as I just learnt how GraphQL was 😍 I’m spending a lot of time on Backend to make something nice so I didn’t get really focused on Quasar these last weeks. I’m however looking at all your commits to understand what’s really done overtime, and this beta made me really smile, it’s really awesome and hope that Quasar Community will be able to give the feedback you need to finish this release :). #RoadTo1.0



  • Great work has always. Thank you for your dedication !



  • Really awesome as usual. Thank u very much. Is there future plans to add support for the new project vue native… https://vue-native.io/


  • Admin

    CLI beta.18 has been released. Enhancements and new features. PWA devs will be thrilled by this update as service-worker and manifest.json are now served during development too!


  • Admin

    CLI beta.19 & beta.20 has been released. Fixes and new features: Quasar Meta plugin; new preFetch params (currentRoute & redirect); preFetch() for App.vue too.


  • Admin

    The last beta (beta.21) has been released. New features:

    1. SSR error page when developing and server encounters an error
    2. SSR - dev & prod common code through src-ssr/extension.js


  • Hello. Just trying a new build created with Beta.21.
    I did:

    1. npm i -g quasar-cli@next
    2. quasar init ~~~~
    3. run through the process, I had to npm i quasar-cli inside the project as well, as this was still on v0.16
    4. quasar dev -m ssr -t ios

    Then it says:

    Dev mode.......... ssr
     Quasar theme...... ios
     Quasar CLI........ v0.17.0-beta.21
     Quasar Framework.. v0.17.0-beta.15
    

    Question 1:

    Is it normal that Quasar Framework beta and CLI beta is a different version?

    Question 2:

    With the new method of instantiating the vuex Store, it exports a function instead of the actual store. I used to import the store into several places of my app (js helper files etc.) and use it, however, how would I do this with the SSR version?

    Question 3:

    After building the app with quasar build -m ssr -t ios it didn’t seem to give me a folder that was compatible with static-site host services like Netlify. With Next I just need to do Nuxt generate and it gives me a public folder with an index.ssr.html and I can just drag that folder in Netlify and it’s hosted.

    How to best do this with Quasar? The ssr folder in dist has index.js and template.html. Which is my main endpoint?



  • To answer my own Question 3:
    Quasar SSR only gives actual SSR not a pre-rendered site. Since you can do Nuxt generate and then upload a prerendered site to a static-website host, I thought this must have also been possible with Quasar as well. But this is not the case!

    After everything cools down with v0.17 SSR, I’d love a pre-render build method for Quasar! : D as I realised, I need pre-rendered sites for my Netlify host!



  • @rstoenescu when the v0.17 will be released? just estimated expectations.



  • @Mohammed the work in finalizing v17 is on full speed and will be be soon, once everything is done and the documentation is up to date.

    would expect it next week or the one after that at most.

    cheers max


  • Admin

    Released beta.22. At this point we’re ready to roll unless some major issue is detected on this beta.
    Cool additions: QTable as grid; Many perf enhancements. Documentation is almost ready too.


Locked