Nuxt 3 SSR:动态页SWR配置下NuxtLink跳转仍客户端请求Strapi
问题:如何实现Nuxt3动态页面的SWR预渲染,避免客户端发起API请求?
环境配置
- Nuxt 13.14.159
- @nuxtjs/strapi 1.12.0
预期行为
在Nuxt 3应用中,动态页面pages/articles/[slug].vue需每小时通过服务端渲染更新内容(从Strapi 4 CMS获取)。无论用户通过NuxtLink导航还是直接访问完整URL,都希望服务器返回预渲染好的页面,不在客户端发起任何API请求。
当前问题
通过NuxtLink访问/articles/abc时,浏览器网络面板会出现https://api-domain/articles?filters[slug]=abc的客户端请求,不符合预期;但直接访问完整URL时,客户端无API请求,表现正常。
相关代码
/pages/articles/[slug].vue
<script setup> const route = useRoute(); const { find } = useStrapi4(); const slug = route.params.slug; const { data } = await useAsyncData( slug, async () => { const response = await find( "articles", { filters: {slug: slug} }); return response.data } ); ... </script>
nuxt.config.ts
export default defineNuxtConfig({ modules: [ "@nuxtjs/strapi", ], routeRules: { "/": { prerender: true }, "/articles/**": { swr: 3600 }, }, strapi: { url: "<strapi url>", prefix: "api", version: "v4", }, });
解决方案
核心修改:强制数据仅在服务端获取
问题根源是useAsyncData默认会在客户端导航时重新执行数据获取逻辑。只需给useAsyncData添加server: true选项,就能强制数据获取仅在服务端完成,客户端直接复用服务端预渲染时生成的payload数据,不会发起新请求。
同时优化几个细节:
- 给
useAsyncData设置更唯一的缓存key,避免不同slug的数据冲突 - 直接返回strapi响应数组的第一个元素(单个slug应仅匹配一篇文章)
修改后的页面代码:
<script setup> const route = useRoute(); const { find } = useStrapi4(); const slug = route.params.slug; const { data } = await useAsyncData( `article-${slug}`, // 唯一缓存键 async () => { const response = await find( "articles", { filters: { slug: slug } } ); return response.data[0]; // 取匹配的第一篇文章 }, { server: true, // 仅在服务端执行数据获取 initialCache: true // 启用初始缓存,客户端直接复用payload } ); </script>
验证配置
确保nuxt.config.ts中的routeRules配置正确:/articles/**的swr: 3600会让服务端每小时重新渲染页面并更新缓存,满足你每小时更新内容的需求。
另外,确认Strapi的URL配置为服务端可访问的地址(比如本地开发时用http://localhost:1337,部署时用对应服务器地址),服务端请求Strapi不会有跨域问题,而客户端不再发起请求,也规避了跨域风险。
内容的提问来源于stack exchange,提问作者Robin Klöckner
相关产品推荐
相关产品推荐

