N
Nuxt5mo ago
salomon_.

Server side fetch refetches on client 3 times

I call useFetch() in 3 components and when I do switch locale it refetches 3 times on client. Why? Shouldn't it cached after 1st call? I followed recipe on nuxt docs so I got: Custom fetch
export default defineNuxtPlugin(() => {
const { apiDomain } = useAppConfig();

const api = $fetch.create({
baseURL: apiDomain,
onRequest({ options }) {
const localeCookie = useCookie('i18n_redirected');

if (localeCookie.value) {
const headers = (options.headers ||= {});
if (Array.isArray(headers)) {
headers.push(['X-Localization', localeCookie.value]);
} else if (headers instanceof Headers) {
headers.set('X-Localization', localeCookie.value);
} else {
headers['X-Localization'] = localeCookie.value;
}
}
},
});

// Expose to useNuxtApp().$api
return {
provide: {
api,
},
};
});
export default defineNuxtPlugin(() => {
const { apiDomain } = useAppConfig();

const api = $fetch.create({
baseURL: apiDomain,
onRequest({ options }) {
const localeCookie = useCookie('i18n_redirected');

if (localeCookie.value) {
const headers = (options.headers ||= {});
if (Array.isArray(headers)) {
headers.push(['X-Localization', localeCookie.value]);
} else if (headers instanceof Headers) {
headers.set('X-Localization', localeCookie.value);
} else {
headers['X-Localization'] = localeCookie.value;
}
}
},
});

// Expose to useNuxtApp().$api
return {
provide: {
api,
},
};
});
Composable
import type { UseFetchOptions } from 'nuxt/app';

export function useAPI<T>(
url: string | (() => string),
options?: Omit<UseFetchOptions<T>, 'default'> & { default?: () => T | Ref<T> },
) {
return useFetch(url, {
...options,
$fetch: useNuxtApp().$api,
});
}
import type { UseFetchOptions } from 'nuxt/app';

export function useAPI<T>(
url: string | (() => string),
options?: Omit<UseFetchOptions<T>, 'default'> & { default?: () => T | Ref<T> },
) {
return useFetch(url, {
...options,
$fetch: useNuxtApp().$api,
});
}
API method
import { useAPI } from '~/shared/composables/use-api';
import type { Menu } from './types';

export const getMenus = () => {
// We call this api method in app.vue which is not re-render on locale switch
// so we manually watch changing this cookie to trigger re-fetch with new locale
const cookie = useCookie('i18n_redirected');
return useAPI<{ data: { menus: Menu[] } }>('/menus', { watch: [cookie] });
};
import { useAPI } from '~/shared/composables/use-api';
import type { Menu } from './types';

export const getMenus = () => {
// We call this api method in app.vue which is not re-render on locale switch
// so we manually watch changing this cookie to trigger re-fetch with new locale
const cookie = useCookie('i18n_redirected');
return useAPI<{ data: { menus: Menu[] } }>('/menus', { watch: [cookie] });
};
4 Replies
salomon_.
salomon_.5mo ago
Anyone?
warflash
warflash5mo ago
Nesting useFetch composables most of the time is a bad idea, they generally should be top level it not retriggering hint's towards it not being bound properly to a setup function, as that should rerun on locale change. (assuming the locale is part of the url and you don't have custom :keys set)
salomon_.
salomon_.5mo ago
So there is no way in nuxt to fetch some data here and there and it auto deduped repeatable calls? Like in tanstack query? So I should fetch it on top and pass through 5+ components?
warflash
warflash5mo ago
You can do that just fine, however they way you are registering it is probably the issue https://nuxt.com/docs/api/composables/use-fetch#params getCachedData, key and dedupe are all things to consider
Want results from more Discord servers?
Add your server