N
Nuxt2mo ago
Bootsmann

Full static still calls /api/

I have a full static setup, i have a module that ensures all routes i want it to prerender at generate as a static file is there. I still find that if my app is deployed it calls and api route even though i prerendered it. i tried to download the zipped folder from netlify to ensure my route is there and it is. The case i find failing is this: 1. Im on my frontpage 2. Navigate to a language route fx /da/ 3. the page renders as it should 4. I navigate to a sub page of /da/ 5. i click a link navigating back to /da/ 6. i get an error rendering the page with the following /api/da/frontpage/ gets 404. 7. if I refresh the page (just normal refresh) it renders the page. i attached a ss of my zipped folder as you can see does the folder "da" have an index.html I also attached the network. Can someone clarify whats going wrong here? heres the code to clarify:
import { SiteLocale, type SeoField } from "~/generatedTypes";

export default defineNuxtComponent({
async setup() {
const { currentRoute } = useRouter();

const { data, error } = await useAsyncData(currentRoute.value.fullPath, async () => {
const lang = isSiteLocale(currentRoute.value.params.lang as SiteLocale)
? currentRoute.value.params.lang
: SiteLocale.En;

const langPrefix = lang === SiteLocale.En ? "" : `/${lang}`;

const langCheck = lang === SiteLocale.En ? SiteLocale.En : lang;

const cleanPath = currentRoute.value.fullPath.replace(new RegExp(`^${langPrefix}`), "");

const apiRoute = `/api${langPrefix}/route${cleanPath.replace(/\/$/, "").replace(/\?.*$/, "")}`;

let finalApiRoute = "";

if (langCheck !== SiteLocale.En) {
if (
currentRoute.value.fullPath === `/${langCheck}/` ||
!currentRoute.value.fullPath.substring(1 + langCheck.length)
) {
finalApiRoute = `/api/${langCheck}/frontpage`;
} else {
finalApiRoute = apiRoute;
}
} else {
finalApiRoute = `/api/router/${lang}/route${currentRoute.value.fullPath.replace(`/${lang}/`, "").replace(/\?.*$/, "")}`;
}

const fetchedData = await $fetch(finalApiRoute);
if (fetchedData) {
return {
...fetchedData,
lang,
};
}
return null;
});

const headerState = useState("headerState", () => true);


if ((data.value && data.value.pageData && data.value.pageData.seo) || data.value.fallback) {
const seo = data.value.pageData.seo as SeoField;
const globalSeo = data.value.globalSeo;
useSetHead(seo, data.value.fallback, globalSeo, data.value.lang as SiteLocale);
} else {
const globalSeo = data.value.globalSeo;

useSetHead(null, data.value.fallback, globalSeo, data.value.lang as SiteLocale);
}

return { data, headerState, resolvePageView };
},
});
import { SiteLocale, type SeoField } from "~/generatedTypes";

export default defineNuxtComponent({
async setup() {
const { currentRoute } = useRouter();

const { data, error } = await useAsyncData(currentRoute.value.fullPath, async () => {
const lang = isSiteLocale(currentRoute.value.params.lang as SiteLocale)
? currentRoute.value.params.lang
: SiteLocale.En;

const langPrefix = lang === SiteLocale.En ? "" : `/${lang}`;

const langCheck = lang === SiteLocale.En ? SiteLocale.En : lang;

const cleanPath = currentRoute.value.fullPath.replace(new RegExp(`^${langPrefix}`), "");

const apiRoute = `/api${langPrefix}/route${cleanPath.replace(/\/$/, "").replace(/\?.*$/, "")}`;

let finalApiRoute = "";

if (langCheck !== SiteLocale.En) {
if (
currentRoute.value.fullPath === `/${langCheck}/` ||
!currentRoute.value.fullPath.substring(1 + langCheck.length)
) {
finalApiRoute = `/api/${langCheck}/frontpage`;
} else {
finalApiRoute = apiRoute;
}
} else {
finalApiRoute = `/api/router/${lang}/route${currentRoute.value.fullPath.replace(`/${lang}/`, "").replace(/\?.*$/, "")}`;
}

const fetchedData = await $fetch(finalApiRoute);
if (fetchedData) {
return {
...fetchedData,
lang,
};
}
return null;
});

const headerState = useState("headerState", () => true);


if ((data.value && data.value.pageData && data.value.pageData.seo) || data.value.fallback) {
const seo = data.value.pageData.seo as SeoField;
const globalSeo = data.value.globalSeo;
useSetHead(seo, data.value.fallback, globalSeo, data.value.lang as SiteLocale);
} else {
const globalSeo = data.value.globalSeo;

useSetHead(null, data.value.fallback, globalSeo, data.value.lang as SiteLocale);
}

return { data, headerState, resolvePageView };
},
});
No description
No description
2 Replies
kapa.ai
kapa.ai2mo ago
Hi @Bootsmann. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided in your question and the knowledge sources available, it seems that you're encountering an issue with client-side navigation in a statically generated Nuxt 3 application. Let's break down the problem and provide some insights: 1. Static Generation: You've mentioned that you have a full static setup and that you've verified the presence of the prerendered HTML files in your build output. This is good and aligns with the expected behavior of static site generation in Nuxt 3. 2. Client-side Navigation: The issue you're experiencing occurs during client-side navigation, specifically when navigating back to a previously visited page (/da/ in your example). 3. API Call: Despite having prerendered pages, your application is still attempting to make an API call to /api/da/frontpage/ which results in a 404 error. This behavior suggests that there might be an issue with how your application is handling client-side navigation or how it's determining whether to fetch data client-side versus using the prerendered content. Here are a few suggestions to address this issue: 1. Route Rules: Make sure you've properly configured your routeRules in your nuxt.config.ts file. You can use this to specify which routes should be prerendered. For example:
export default defineNuxtConfig({
routeRules: {
'/da/**': { prerender: true },
}
})

export default defineNuxtConfig({
routeRules: {
'/da/**': { prerender: true },
}
})

This tells Nuxt to prerender all routes under /da/. 2. Prerender Configuration: Ensure your Nitro prerender configuration is correct. You can add this to your nuxt.config.ts:
export default defineNuxtConfig({
nitro: {
prerender: {
crawlLinks: true,
routes: ['/'],
}
}
})

export default defineNuxtConfig({
nitro: {
prerender: {
crawlLinks: true,
routes: ['/'],
}
}
})

This will crawl all links from the home page and prerender them. 3. Client-side Navigation: In your component's setup function, you're using useAsyncData which might be triggering unnecessary API calls during client-side navigation. Consider using useLazyAsyncData instead, which won't block navigation and might prevent unnecessary API calls for prerendered pages. 4. Payload Extraction: Make sure you're properly extracting the payload from prerendered pages. Nuxt 3 stores payloads in payload.json files alongside the prerendered HTML. Your client-side code should be able to use this payload instead of making API calls. 5. Debugging: Add some console logs or use the Vue devtools to track when and why your component is making API calls. This can help you understand if the issue is with the initial render or subsequent navigations. If these suggestions don't resolve your issue, you might want to create a minimal reproducible example and open an issue on the Nuxt GitHub repository for further assistance. Sources: Docs > Getting-started > Prerendering Docs > Api > Nuxt Configuration > generate ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@279983933574217730> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?