Nuxt.js: Ajax Server Rendering Problem

Created on 9 Feb 2017  路  4Comments  路  Source: nuxt/nuxt.js

Hello. I use Vuex and Axios.

The code works.
But, the server-side rendering, does not show the component, if I use ajax, in the source code.
I want the search engines to see the content in the source code that I get with ajax.

Static codes look at the page source.
But, I get with ajax data, does not show in the browser source code.

? Code:
<script type="text/javascript" defer>window.__NUXT__={"data":[null],"error":null,"state":{"topics":[],"categories":[]},"serverRendered":true}</script>

But the state is actually(not emty). And the data is coming.

view - not problem
ekran resmi 2017-02-09 16 43 53

vuex store - not problem
ekran resmi 2017-02-09 16 43 44

initial state ? I think the problem
ekran resmi 2017-02-09 16 43 28

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'

Vue.use(Vuex)

const defaultState = {
    topics: [],
    categories: []
}

const inBrowser = typeof window !== 'undefined'

// if in browser, use pre-fetched state injected by SSR
const state = (inBrowser && window.__NUXT__) || defaultState

const mutations = {
    TOPICS_LIST: (state, topics) => {
        state.topics = topics
    },

    CATEGORIES_LIST: (state, categories) => {
        state.categories = categories
    }
}

export default new Vuex.Store({
    state,
    actions,
    mutations,
    getters
})

store/action.js

import request from 'axios'

request.defaults.baseURL = 'http://apiurl.com'

export const getTopics = ({ commit, state }) => {
    return request.get('movies').then((response) => {
        commit('TOPICS_LIST', response.data.data)
    }).catch((error) => {
        console.log(error)
    })
}

export const getCategories = ({ commit, state }) => {
    return request.get('genres').then((response) => {
        commit('CATEGORIES_LIST', response.data.data)
    }).catch((error) => {
        console.log(error)
    })
}

store/getters.js

export const getTopics = state => state.topics
export const getCategories = state => state.categories

component/itemList :

<script>
import { mapGetters } from 'vuex'

const fetchInitialData = store => {
    return store.dispatch(`getTopics`)
}

export default {
    prefetch: fetchInitialData,
    computed: {
        ...mapGetters({
            topics: 'getTopics'
        })
    },
    mounted () {
        fetchInitialData(this.$store)
    }
}
</script>

pages/index :

<template>
  <section class="container">
        <itemList></itemList>
    <nuxt-link class="button" to="/about">
      About page
    </nuxt-link>
  </section>
</template>

<script>
import itemList from '~components/itemList.vue'
export default {
  components: {
    itemList
  }
}
</script>

This question is available on Nuxt.js community (#c194)
question

All 4 comments

Hi @oguzhanaslan

Nuxt.js handle the asynchronous data for you and will fill the store automatically. Please take a look at https://nuxtjs.org/guide/async-data and https://nuxtjs.org/guide/vuex-store

Your pages/index.vue should be like this:

<template>
  <section class="container">
    <itemList></itemList>
    <nuxt-link class="button" to="/about">About page</nuxt-link>
  </section>
</template>

<script>
import itemList from '~components/itemList.vue'

export default {
  fetch ({ store }) {
    // fetch is called on server & client-side before rendering the page
    return store.dispatch(`getTopics`)
  },
  components: {
    itemList
  }
}
</script>

Then, your store can look like this:

import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'

const state = {
    topics: [],
    categories: []
}

const mutations = {
    TOPICS_LIST: (state, topics) => {
        state.topics = topics
    },

    CATEGORIES_LIST: (state, categories) => {
        state.categories = categories
    }
}

export default new Vuex.Store({
    state,
    actions,
    mutations,
    getters
})

If you want to fetch the topics regardless of the page, take a look at the nuxtServerInit action.

@Atinux

how to multiple return dispatch ? add new component ?

<template>
  <section class="container">
        <!-- <nuxt-link class="button" to="/about"> About page</nuxt-link> -->
        <div class="columns">
            <div class="column is-9">
                <itemList></itemList>
            </div>
            <div class="column is-3">
                <sidebarCategory></sidebarCategory>
            </div>
        </div>
  </section>
</template>


import axios from 'axios'
import itemList from '~components/itemList.vue'
import sidebarCategory from '~components/sidebarCategory.vue'

export default {
    fetch ({ store, params }) {
        return store.dispatch(`getCategories`)
    },
    fetch ({ store, params }) {
        return store.dispatch(`getTopics`)  
    },
  components: {
    itemList,
        sidebarCategory
  }
}

Use Promise.all() @oguzhanaslan

export default {
  fetch ({ store, params }) {
    return Promise.all([
      store.dispatch(`getCategories`),
      store.dispatch(`getTopics`)
    ])
  },
  components: {
    itemList,
    sidebarCategory
  }
}

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jaredreich picture jaredreich  路  3Comments

vadimsg picture vadimsg  路  3Comments

uptownhr picture uptownhr  路  3Comments

pehbehbeh picture pehbehbeh  路  3Comments

msudgh picture msudgh  路  3Comments