6. Example [nuxt-03]: nuxtServerInit
The [nuxt-03] project aims to demonstrate a [Vuex] store function called [nuxtServerInit]. It allows the server to initialize the [Vuex] store, just as the [fetch] function does. But unlike the [fetch] function, the [nuxtServerInit] function is never executed by the client.

The [nuxt-03] project is initially created by cloning the [nuxt-01] project, from which the [page2] page in the [pages] folder and the [navigation] component are removed. The [store] folder is created by cloning the [nuxt-02/store] folder.
6.1. The [Vuex] store
The [Vuex] store will be implemented by the following [store/index.js] file:
/* 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', 34)
// log
console.log('nuxtServerInit commit completed')
}
}
- lines 1–12: are similar to what they were in the [nuxt-02] project;
- lines 14–32: we export an [actions] object. This is a reserved term in the [Vuex] store;
- line 15: we define the [nuxtServerInit] function. This will be executed by the server when the application starts. Its usual role is to initialize a [Vuex] store using external data obtained via an asynchronous function. [nuxt] waits for this function to return its results before beginning the lifecycle of the requested page. The function takes two parameters:
- the [Vuex] store to initialize;
- the current [Nuxt] context;
- lines 19–26: we wait for the asynchronous action to complete, here an artificial wait of one second (line 15);
- line 28: the counter is set to 34;
- lines 17 and 30: logs to track the execution of the [nuxtServerInit] function;
6.2. The [index] page
The [index] page will be as follows:
<!-- [index] page -->
<template>
<Layout :left="true" :right="true">
<!-- navigation -->
<Navigation slot="left" />
<!-- message-->
<b-alert slot="right" show variant="warning"> Home - value= {{ value }} </b-alert>
</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]')
}
}
</script>
- Line 37: The value of the counter initialized by the [nuxtServerInit] function is assigned to the [value] property on line 27. This value is displayed by line 7;
- line 37 will be executed by both the server and the client. In both cases, the [value] property will receive the same value, ensuring that the page generated by the server matches the one generated by the client;
6.3. The [page1] page
The [page1] page is obtained by copying the [index] page. We then modify its text to replace [home] with [page1]:
<!-- page [page1]] -->
<template>
<Layout :left="true" :right="true">
<!-- navigation -->
<Navigation slot="left" />
<!-- message-->
<b-alert slot="right" show variant="warning"> Page1 - value= {{ value }} </b-alert>
</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: 'Page1',
// components used
components: {
Layout,
Navigation
},
data() {
return {
value: 0
}
},
// lifecycle
beforeCreate() {
// client and server
console.log('[page1 beforeCreate]')
},
created() {
// client and server
this.value = this.$store.state.counter
console.log('[page1 created], value=', this.value)
},
beforeMount() {
// client only
console.log('[page1 beforeMount]')
},
mounted() {
// client only
console.log('[page1 mounted]')
}
}
</script>
This page is only there to enable navigation between two pages.
6.4. Execution
The [nuxt.config.js] file is modified as follows:
// source code directory
srcDir: 'nuxt-03',
// router
router: {
// application URL root
base: '/nuxt-03/'
},
// 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'
}
The page displayed upon execution is then as follows:

- in [5], we see that the [nuxtServerInit] function was executed by the server before the [index] page's lifecycle. [nuxt] waited for the asynchronous function to finish its work before proceeding to the lifecycle;
- in [4], we see that the client did not execute the [nuxtServerInit] function;
Now let’s navigate twice: index --> page1 --> index. The logs are then as follows:

- In [1-2], we see that the [nuxtServerInit] function is not executed by the client;
Now let’s manually type the URL for the [page1] page to force a call to the server:

In [3-4], we see the same mechanism that preceded the loading of the [index] page at startup. Let’s recap what was previously mentioned: when we force a page to call the server, it’s as if the application were restarting with a home page that is the requested page;