SSR Data are loaded only after refresh (SSR BUG related with useAsyncData - so every composable)
Environment
- Operating System:
Darwin - Node Version:
v18.13.0 - Nuxt Version:
3.1.1 - Nitro Version:
2.1.1 - Package Manager:
[email protected] - Builder:
vite - User Config:
debug,ssr,css,build,vite,modules,runtimeConfig - Runtime Modules:
() - Build Modules:
-
Describe the bug
Fetching data from Apollo server works only after refresh. On Page loading, the setup function doesn't fire the request to the Apollo server, but it waits until a refresh is performed. The request then appear in the console network, and everything works fine (on page loading the request/fetch doesn't exist).
This happens only when the ssr option is set to true in nuxt.config (by default it is set to true). The behavior changes, and the fetch is performed also on page load when the ssr option is set to false (clearly).
Expected behaviour
I would expect that the first time I load a page, the request is normally performed to the apollo server, in this way I can populate the page with the data.
Reproduction
Someone in December opened an issue and tagged it as BUG, unfortunately the issue was closed just before the end of the year without a real resolution. For reference the following is the link to the issue: https://github.com/nuxt-modules/apollo/issues/452#issue-1451729190
Additional context
I tried to investigate a bit the issue, and I noticed that under the hood, the module uses the useAsyncData (form the nuxt composable). This is amazing but it's worth probably point out that (the yellow alert in particular):
Maybe the problem is just here??
Logs
No response
The way in which I "hacked" this is issue is the following:
<script setup>
const query = gql`
query getCategories {
categories {
data {
id
attributes {
name
}
}
}
}
`
const { data, refresh } = await useAsyncQuery(query)
if (!data.value) {
refresh()
}
</script>
So I am conditionally refreshing the data if they are indeed null. This trick allow me to perform the SSR :)
Maybe it's worth allowing an automatic refresh option when data are null and contemporarily we are using SSR.
@Dinuz can you share apollo config in nuxt.config.ts and @nuxtjs/apollo version?
i used node v18.12.1 @nuxtjs/apollo": "5.0.0-alpha.5 " nuxt": "^3.1.1" nuxt3": "3.1.2-rc.0-27922414.cb0860b"
export const getUsersQuery = gql`
query users(
$limit: Float
$orderBy: [UserOrderByInput!]
$page: Float
$where: UserWhereInput
) {
users(limit: $limit, orderBy: $orderBy, page: $page, where: $where) {
pageInfo {
page
limit
currentPage
totalCount
}
docs {
id
firstName
lastName
email
username
roles
avatar
status
}
}
}
`
/**
* query data my user
* if @data null return login
*/
const variables = {
limit: 10,
page: 1,
}
const { data } = await useAsyncQuery(getUsersQuery, variables)
if (!data.value) {
navigateTo('/user')
}
const users = JSON.parse(JSON.stringify(data.value)).users
mine still return normal.
@devhoangkien sure (what do you mean still return normal??),
node version 18.13.0 "@nuxtjs/apollo": "^5.0.0-alpha.5" "nuxt": "^3.1.1"
my nuxt.config is super basic:
export default defineNuxtConfig({
debug: true,
ssr: true,
modules: ['@nuxtjs/apollo',],
apollo: {
clients: {
default: {
httpEndpoint: 'http://localhost:1337/graphql',
},
},
},
})
I was having the exact same issues here but ensuring I was on beta-5 of nuxt apollo and nuxt 3.1.2 and everything began working as expected.
Context
I use a Laravel Lighthouse backend and this only occurs to me when auth is required.
System and versions
Operating System: Windows 10 Pro
Node Version: v19.6.0
Nuxt Version: ^3.5.2
Nitro Version: 2.4.1
Package Manager: [email protected]
Builder: vite
@nuxtjs/apollo: 5.0.0-alpha.6
My nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: ["@nuxtjs/apollo"],
apollo: {
clients: {
default: {
// Tried this too but results in same behavior.
// httpLinkOptions: {
// credentials: "include"
// },
httpEndpoint: "http://myapp.test/graphql"
}
},
},
});
Behavior
If I protect the query (requiring auth) It does not load on initial load (like after refresh). Only when I manually press a button to request the data when the page has been loaded.
If I remove the protection from the query (no auth required anymore) Everything works as intended. It does work on initial load and after refresh.
Visual example of behavior
Removing the guard makes it work for ssr, but leaves the query unprotected.
It appears when the server is making the request it does so without auth. But I'd like to be able to protect my queries and have them loaded on initial load when authenticated.
The only way to get data is by calling the refresh method returned by the query method.
Workaround
Adding a plugin utilizing the apollo:auth hook and setting the token from the cookie seems to fix this issue for me in this case:
// plugins/apollo.ts
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('apollo:auth', ({ client, token }) => {
// access cookie for auth
const cookie = useCookie(`apollo:${client}.token`)
// apply apollo client token
token.value = cookie.value ?? null
})
})
Other
- I noticed useLazyAsyncQuery documentation shows
useAsyncQueryinstead ofuseLazyAsyncQueryin the example. - Using
useQuerythrows a 500 with message "Unauthenticated" which I assume is intended behavior if unauthenticated, but in this case I am authenticated.
I have a similar issue as @timyourivh, but in my case it works on refresh(SSR) and not on the client side. I am using the apollo:auth hook inside plugins/apollo.ts like so:
export default defineNuxtPlugin((nuxtApp) => {
const { value } = useCookie("session_token");
nuxtApp.hook("apollo:auth", ({ client, token }) => {
token.value = `Bearer ${value}`;
});
});
This works fine for SSR requests (like on refresh), but returns Bearer undefined for client side requests, like navigating between routes.
How can I get the cookie to work for client side requests? Any ideas?
Saw that I replied in this thread and encountered this same thing not that long ago, again. This time I ended up solving it with using a solution similar to a solution mentioned in this comment: https://github.com/nuxt-modules/apollo/issues/312#issuecomment-2007195065 Hope this helps anyone solve this.