Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement nuxtServerInit Action to load data from server-side on the initial load #1080

Open
MarceloLuis1997 opened this issue Feb 18, 2022 · 8 comments

Comments

@MarceloLuis1997
Copy link

MarceloLuis1997 commented Feb 18, 2022

What problem is this solving

Implement something like NuxtServerInit Action, so we can load data from the server-side and give it directly to the client-side on the initial load/render.

Proposed solution

Include an index.js file inside /stores with a nuxtServerInit action which will be called from the server-side on the initial load.

Describe alternatives you've considered

The only way I found to do this is using Pinia with Vuex, using the nuxtServerInit from Vuex:

// store/index.js
import { useSessionStore } from '~/stores/session'

export const actions = {
  async nuxtServerInit ({ dispatch }, { req, redirect, $pinia }) {
    if (!req.url.includes('/auth/')) {
      const store = useSessionStore($pinia)

      try {
        await store.me() // load user information from the server-side before rendering on client-side
      } catch (e) {
        redirect('/auth/login') // redirects to login if user is not logged in
      }
    }
  }
}
@MarceloLuis1997
Copy link
Author

#947

@posva
Copy link
Member

posva commented Feb 22, 2022

There should be a way to add this for both setup and option stores. Maybe a specific name for an action is enough.

One important thing to note is that given the nature of stores in pinia, you need explicitly say somewhere in your server code which stores must run this action as they need to be instantiated on the server. By default, if no store is ever user, no store is ever instantiated and therefore no server init function can run.

@AustinMusiku
Copy link

What problem is this solving

Implement something like NuxtServerInit Action, so we can load data from the server-side and give it directly to the client-side on the initial load/render.

Proposed solution

Include an index.js file inside /stores with a nuxtServerInit action which will be called from the server-side on the initial load.

Describe alternatives you've considered

The only way I found to do this is using Pinia with Vuex, using the nuxtServerInit from Vuex:

// store/index.js
import { useSessionStore } from '~/stores/session'

export const actions = {
  async nuxtServerInit ({ dispatch }, { req, redirect, $pinia }) {
    if (!req.url.includes('/auth/')) {
      const store = useSessionStore($pinia)

      try {
        await store.me() // load user information from the server-side before rendering on client-side
      } catch (e) {
        redirect('/auth/login') // redirects to login if user is not logged in
      }
    }
  }
}

Thanks for this workaround, I would also love to see the feature implemented

@matifanger
Copy link

What problem is this solving

Implement something like NuxtServerInit Action, so we can load data from the server-side and give it directly to the client-side on the initial load/render.

Proposed solution

Include an index.js file inside /stores with a nuxtServerInit action which will be called from the server-side on the initial load.

Describe alternatives you've considered

The only way I found to do this is using Pinia with Vuex, using the nuxtServerInit from Vuex:

// store/index.js
import { useSessionStore } from '~/stores/session'

export const actions = {
  async nuxtServerInit ({ dispatch }, { req, redirect, $pinia }) {
    if (!req.url.includes('/auth/')) {
      const store = useSessionStore($pinia)

      try {
        await store.me() // load user information from the server-side before rendering on client-side
      } catch (e) {
        redirect('/auth/login') // redirects to login if user is not logged in
      }
    }
  }
}

Thanks for this workaround, I would also love to see the feature implemented

Did the stores are shared?

@nestle49
Copy link

nestle49 commented Aug 22, 2022

This solution is workaround for me:

nuxt.config.ts

plugins: [
   { src: '~/plugins/init.server.ts' }, // must be the first server plugin
 ]

plugins/init.server.ts

import { useGlobalStateStore } from '~/store/globalState';

const initServer: () => void = async () => {
    // example code
    const host = req.hostname;
    const globalStateStore = useGlobalStateStore();
    globalStateStore.SET_HOST({ host });
};

export default initServer;

@MuhammadM1998
Copy link

@nestle49 Can this be placed as a nitro plugin in a nuxt project instead?

@posva posva added ⛰ pkg:nuxt Related to @pinia/nuxt contribution welcome and removed ⛰ pkg:nuxt Related to @pinia/nuxt discussion labels Dec 12, 2022 — with Volta.net
@mrleblanc101
Copy link

Any update on this ?

@yshrsmz
Copy link

yshrsmz commented Dec 2, 2023

It looks like currently, we can't use a store with inject() call inside, from the nuxt plugin.

inject() call simply throws the following error.

[Vue warn]: inject() can only be used inside setup() or functional components.

Tested with Nuxt/Bridge btw.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants