Incomplete SSR rendering with NuxtJS
Posted: 14 May 2021, 19:37
I installed Nuxt JS with and added PrimeVue as described in https://github.com/primefaces/primevue- ... quickstart.
The nuxt.config.js is:
The page used is:
It shows the page as expected in the client, but if you check the generate HTML it does not includes the TabPanels, so the SSR is incomplete.
The generate HTML (excluding CSS, and formatted a little) shows the TabPanels are missing from the HTML:
I tried putting the data inside the `data` and asyncData` methods, but none work.
If the property is set to a value other than 0, it breaks rendering the page in the client with:
This is due to the missing elements in the dom.
Code: Select all
npx create-nuxt-app <project-name>
The nuxt.config.js is:
Code: Select all
export default {
ssr: true,
target: 'server',
server: {
host: '0',
port: 3060
},
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'ch-www-vue',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
'primeflex/primeflex.css'
/*
'primevue/resources/themes/bootstrap4-dark-purple/theme.css',
'primevue/resources/primevue.min.css',
'primeicons/primeicons.css'
*/
],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
// https://go.nuxtjs.dev/typescript
'@nuxt/typescript-build'
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/axios
'@nuxtjs/axios',
'primevue/nuxt'
],
primevue: {
theme: 'arya-green', // name of the theme, defaults to saga-blue
ripple: false, // whether the ripple animation is enabled, defaults to false
components: [
'Button', 'Card', 'TabPanel', 'TabView'
], // an array of components to be registered
directives: [] // an array of directives to be registered
},
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {},
// Build Configuration: https://go.nuxtjs.dev/config-build
// https://github.com/primefaces/primevue/issues/844#issuecomment-836684415
build: {
transpile: ['primevue']
}
}
Code: Select all
<template>
<TabView>
<TabPanel v-for="tab in tabs" :key="tab.title" :header="tab.title">
<p>{{tab.content}}</p>
</TabPanel>
</TabView>
</template>
<script>
export default {
name: 'treeView',
data () {
return {
tabs: [
{ title: 'Title 10', content: 'Content 1' },
{ title: 'Title 20', content: 'Content 2' },
{ title: 'Title 30', content: 'Content 3' }
]
}
},
asyncData () {
return {
tabs: [
{ title: 'Title 1', content: 'Content 1 async' },
{ title: 'Title 2', content: 'Content 2 async' },
{ title: 'Title 3', content: 'Content 3 async' }
]
}
}
}
</script>
<style scoped>
</style>
The generate HTML (excluding CSS, and formatted a little) shows the TabPanels are missing from the HTML:
Code: Select all
<!doctype html>
<html data-n-head-ssr lang="en" data-n-head="%7B%22lang%22:%7B%22ssr%22:%22en%22%7D%7D">
<head >
<title>ch-www-vue</title>
<meta data-n-head="ssr" charset="utf-8">
<meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1">
<meta data-n-head="ssr" data-hid="description" name="description" content="">
<link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="preload" href="/_nuxt/runtime.js" as="script"><link rel="preload" href="/_nuxt/commons/app.js" as="script"><link rel="preload" href="/_nuxt/vendors/app.js" as="script"><link rel="preload" href="/_nuxt/app.js" as="script"><link rel="preload" href="/_nuxt/pages/tabview2.js" as="script"><link rel="preload" href="/_nuxt/pages/tabview2.62ab2bafa2bc0d813431.hot-update.js" as="script"
<body >
<div data-server-rendered="true" id="__nuxt"><!----><!----><div id="__layout"><div>
<div class="p-tabview p-component" data-v-d806bd9e><!----><!----><!---->
<ul role="tablist" class="p-tabview-nav"><li class="p-tabview-ink-bar"></li></ul>
<div class="p-tabview-panels"></div>
</div></div></div></div>
<script>window.__NUXT__=(function(a){return {layout:"default",data:[{tabs:[{title:"Title 1",content:"Content 1 async"},{title:"Title 2",content:"Content 2 async"},{title:"Title 3",content:"Content 3 async"}]}],fetch:{},error:a,serverRendered:true,routePath:"\u002Ftabview2",config:{_app:{basePath:"\u002F",assetsPath:"\u002F_nuxt\u002F",cdnURL:a}},logs:[]}}(null));</script><script src="/_nuxt/runtime.js" defer></script><script src="/_nuxt/pages/tabview2.js" defer></script><script src="/_nuxt/pages/tabview2.62ab2bafa2bc0d813431.hot-update.js" defer></script><script src="/_nuxt/commons/app.js" defer></script><script src="/_nuxt/vendors/app.js" defer></script><script src="/_nuxt/app.js" defer></script>
</body>
</html>
If the
Code: Select all
TabView.activeIndex
Code: Select all
client.js:224 TypeError: Cannot read property 'offsetWidth' of undefined
at Function.getWidth (DomHandler.js:327)
at VueComponent.updateInkBar (index.js?!./node_modules/vue-loader/lib/index.js?!./node_modules/primevue/tabview/TabView.vue?vue&type=script&lang=js&:60)
at VueComponent.mounted (index.js?!./node_modules/vue-loader/lib/index.js?!./node_modules/primevue/tabview/TabView.vue?vue&type=script&lang=js&:37)
at invokeWithErrorHandling (vue.runtime.esm.js:1853)
at callHook (vue.runtime.esm.js:4213)
at Object.insert (vue.runtime.esm.js:3136)
at invokeInsertHook (vue.runtime.esm.js:6336)
at Vue.patch [as __patch__] (vue.runtime.esm.js:6484)
at Vue._update (vue.runtime.esm.js:3939)
at Vue.updateComponent (vue.runtime.esm.js:4054)