Skip to content

7. Example [nuxt-04]: Maintaining a client/server session

The [nuxt-04] project addresses the issue of maintaining a client/server session. We’ll use the [nuxt-03] project with the following modifications:

  • the [index] page will have a button that increments the [Vuex] store counter;
  • The [page1] page remains unchanged;
  • we want the server to return the requested page with a [Vuex] store whose counter value is the last value it had on the client side when a page is manually requested from the server;

The [nuxt-04] project is initially created by cloning the [nuxt-03] project:

Image

Only the [index] page changes:


<!-- [index] page -->
<template>
  <Layout :left="true" :right="true">
    <!-- navigation -->
    <Navigation slot="left" />
    <!-- message-->
    <template slot="right">
      <b-alert show variant="warning"> Home - value= {{ value }} </b-alert>
      <!-- button -->
      <b-button @click="incrementCounter" class="ml-3" variant="primary">Increment</b-button>
    </template>
  </Layout>
</template>

<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */

import Layout from '@/components/layout'
import Navigation from '@/components/navigation'
export default {
  name: 'Home',
  // components used
  components: {
    Layout,
    Navigation
  },
  data() {
    return {
      value: 0
    }
  },
  // lifecycle
  beforeCreate() {
    // client and server
    console.log('[home beforeCreate]')
  },
  created() {
    // client and server
    this.value = this.$store.state.counter
    console.log('[home created], value=', this.value)
  },
  beforeMount() {
    // client only
    console.log('[home beforeMount]')
  },
  mounted() {
    // client only
    console.log('[home mounted]')
  },
  // event handling
  methods: {
    incrementCounter() {
      console.log('incrementCounter')
      // increment the counter by 1
      this.$store.commit('increment', 1)
      // update the displayed value
      this.value = this.$store.state.counter
    }
  }
}
</script>
  • line 10: we added a button to increment the [Vuex] store counter;
  • line 54: the method that handles the [click] on the [Increment] button;
  • line 57: the store counter is incremented by 1;
  • line 59: the counter value is assigned to the [value] property so that it is displayed on line 8;

Run the [nuxt-04] project with the following [nuxt.config.js] file:


// source code directory
  srcDir: 'nuxt-04',
  // router
  router: {
    // application URL root
    base: '/nuxt-04/'
  },
  // server
  server: {
    // server port, 3000 by default
    port: 81,
    // network addresses listened to, default is localhost: 127.0.0.1
    // 0.0.0.0 = all network addresses on the machine
    host: 'localhost'
}

When executed, the first page displayed is as follows:

Image

By clicking the [3] button several times, the following new page appears:

Image

If you use link [3], you get the following page:

Image

  • In [2], the [page1] [1] page correctly displays the counter value;

Now, let’s refresh the page with [3]. The new page is as follows:

Image

  • In [2], we have lost the current counter value. We have returned to its initial value;

This result makes perfect sense if you look at the logs:

  • In [1], the server re-executed the [nuxtServerInit] function. However, this function is as follows:
/* eslint-disable no-console */
export const state = () => ({
  // counter
  counter: 0
})

export const mutations = {
  // Increment the counter by a value [inc]
  increment(state, inc) {
    state.counter += inc
  }
}

export const actions = {
  async nuxtServerInit(store, context) {
    // Who executes this code?
    console.log('nuxtServerInit, client=', process.client, 'server=', process.server)
    // waiting for a promise to resolve
    await new Promise(function(resolve, reject) {
      // we normally have an asynchronous function here
      // we simulate it with a one-second delay
      setTimeout(() => {
        // success
        resolve()
      }, 1000)
    })
    // update the store
    store.commit('increment', 53)
    // log
    console.log('nuxtServerInit commit completed')
  }
}

Line 28 sets the counter to 53.

Let’s examine the HTTP request made by the browser when we refreshed the [page1] page:

Image

We can see that in addition to the [page1] page [1], the client requests a number of scripts from the server. Note the scripts [pages_index, pages_page1], which are the scripts associated with the [index, page] pages. These scripts are provided with every request to the server, regardless of the page requested;

In [1], the page [page1] is requested from the server with the following HTTP request:

GET http://localhost:81/nuxt-04/page1
Host: localhost:81
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache

We can see that this request does not send any information to the server. The server therefore has no way of knowing the state of the [Vuex] store on the client side. For that to happen, the client would have had to send this information to the server.

In the following project [nuxt-05], we use a cookie so that the client can send information to the server when it is requested.