Provide initial data for pinia on the server side #2418
-
Hello everyone, I’m using vike-vue + vike-vue-pinia in my project. Initially, following the documentation, I tried fetching the page’s initial data from a trpc server-side call inside the data.server.ts hook and injecting it into Pinia like this:
However, I noticed this doesn’t work properly. After some experimentation, I discovered that onCreateApp is called after data.server, which means I can’t provide data to the store in data.server because ctx.pinia doesn’t exist yet. Where should I perform this work instead? I tried onBeforeRender, onBeforeRenderHtml, etc., but none of them meet my needs. Currently, I’m using data.server + Vue’s onBeforeMounted to inject data into Pinia on the client side, but this causes a hydration node mismatch issue. Any suggestions? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 15 replies
-
Quick reply: vikejs/vike-react#87 (comment). I'll read your question more thoroughly later. CC @4350pChris |
Beta Was this translation helpful? Give feedback.
-
After some testing, I finally found an implementation that I'm fairly satisfied with. It roughly looks like this: // +onBeforeRenderClient.ts
export const onBeforeRenderClient = (ctx: PageContext) => {
const { _piniaInitState } = ctx;
if (_piniaInitState) {
ctx.globalContext.pinia!.state.value = {
...ctx.globalContext.pinia!.state,
..._piniaInitState,
};
}
};
// +onBeforeRoute.ts
export const onBeforeRoute = (ctx: PageContext) => {
// _piniaInitState store the reference of pinia.state
ctx._piniaInitState = ctx.pinia?.state.value;
};
// +onCreateApp.ts
export const onCreateApp = (ctx: PageContext) => {
const { app } = ctx;
if (!app) return;
if (!import.meta.env.SSR) {
ctx.globalContext.pinia = createPinia();
}
// client: GlobalContext
// server: PageContext
app.use(ctx.globalContext.pinia ?? ctx.pinia!);
};
// +onCreatePageContext.server.ts
export const onCreatePageContext = (ctx: PageContext) => {
ctx.pinia = createPinia();
}; Through the above implementation, I can achieve:
|
Beta Was this translation helpful? Give feedback.
-
@YKDZ (or anyone else) I'm curious: why do you want to populate your store with |
Beta Was this translation helpful? Give feedback.
vikejs/vike-react@3e8a2e5
I believe this answers your question.
In case you're up for it, contribution welcome to add a to-do list example at
examples/vue-pinia/
by porting the to-do list example from here.