Hello ! on my site (https://yineo.fr/), my right sidebar is a component called from layouts/default.vue
Because i don't want to call it in every page component.
I know asyncData() is only for pages and not layouts but maybe they are some workarounds ?
So my sidebar with last articles is not server side rendered and google bot can not see it ( see picture below, the left one is what google bot see and probably index )
How can i have server side rendering for my "Sidebar" Component called from layouts/default.vue ( code below the picture ) ?
thanks !
<!-- main layout -->
<template>
<div>
<AppNavigation />
<AppHeader/>
<div class="container">
<div class="columns">
<div class="column is-two-thirds">
<nuxt/>
</div>
<div class="column">
<section class="section">
<TwitterFollowMe/>
<hr/>
<h2 class="title is-2">Derniers billets</h2>
<PostsSidebar :posts="posts" />
</section>
</div>
</div>
</div>
<AppFooter />
</div>
</template>
<script>
import AppHeader from '~/components/AppHeader'
import AppNavigation from '~/components/AppNavigation'
import AppFooter from '~/components/AppFooter'
import TwitterFollowMe from '~/components/TwitterFollowMe'
import PostsSidebar from '~/components/PostsSidebar'
import { getPosts } from '~/services/wpContentApi'
export default {
components: { AppHeader, AppNavigation, AppFooter, TwitterFollowMe, PostsSidebar },
data () {
return {
posts: []
}
},
async created () {
this.posts = await getPosts(20)
}
}
</script>
Hi. The best workaround is using global Vuex store and using either nuxtServerInit
or a Plugin with exported function to fill store or a middleware
which one is more suitable depending on your needs
@pi0 hi, thanks ! suppose i want to add 3 ou 4 blocks (with async datas) on the right sidebar, which one if the three solutions would be the better according to you : VueServerInit, Plugin or middleware ?
If I was, would choose plugins as nuxtServerInit is not working on SPA mode. We can fetch async data and call store commits within plugin like this:
export default async function( { store, app: { $axios }} ) {
let posts = (await $axios.get('...')).data
store.commit('posts/update', posts)
// Or delegate it to store actions
await store.dispatch('posts/fetch', { $axios })
}
@pi0 that works !
Here is my full code to help the others :
store/index.js :
import Vuex from 'vuex'
/**
* This our global state for our app.
*/
const createStore = () => new Vuex.Store({
state: {
menuMobileIsOpened: false,
postsSidebar: []
},
mutations: {
setMenuMobileIsOpened (state, value) {
state.menuMobileIsOpened = value
},
setPostsSidebar (state, value) {
state.postsSidebar = value
}
}
})
export default createStore
plugins/hydrate-layout-data.js
import axios from "axios"
import { getPosts } from '~/services/wpContentApi'
/**
* We do this to achieve server side rendering for
* content displayed by layouts components
* ( layouts does not have an asyncData() method )
*/
export default async function( { store } ) {
let posts = await getPosts(20)
store.commit('setPostsSidebar', posts)
}
layouts/default.vue
<!-- main layout -->
<template>
<div>
<AppNavigation />
<AppHeader/>
<div class="container">
<div class="columns">
<div class="column is-two-thirds">
<nuxt/>
</div>
<div class="column">
<section class="section">
<TwitterFollowMe/>
<hr/>
<h2 class="title is-2">Derniers billets</h2>
<PostsSidebar :posts="this.$store.state.postsSidebar" />
</section>
</div>
</div>
</div>
<AppFooter />
</div>
</template>
<script>
import AppHeader from '~/components/AppHeader'
import AppNavigation from '~/components/AppNavigation'
import AppFooter from '~/components/AppFooter'
import TwitterFollowMe from '~/components/TwitterFollowMe'
import PostsSidebar from '~/components/PostsSidebar'
import { getPosts } from '~/services/wpContentApi'
export default {
components: { AppHeader, AppNavigation, AppFooter, TwitterFollowMe, PostsSidebar },
}
</script>
nuxt.config.js : add call to plugin
plugins: [
'~/plugins/hydrate-layout-data'
]
And here is the result in google search explorer , sidebar is now here :
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
@pi0 that works !
Here is my full code to help the others :
store/index.js :
plugins/hydrate-layout-data.js
layouts/default.vue
nuxt.config.js : add call to plugin