Nuxt.js生产环境部分动态路由返回404(Netlify部署)
Nuxt静态站点部署Netlify后部分动态路由返回404状态码问题
问题描述
- 我的Nuxt项目设置为静态站点(
target: 'static'),部署在Netlify上,包含700-1000个静态和动态页面,其中约300个页面生成正常 - 生产环境中,部分动态生成的路由会返回HTTP 404状态码,但页面实际已生成且能正常加载,仅状态码异常会对SEO造成负面影响
- 本地开发服务器、通过
nuxt start运行生成的dist文件夹时,这些页面均不会出现404状态码,静态生成页面工作正常 - 使用了Nuxt爬虫自动发现动态路由,未手动在
generate()中指定路由
核心配置片段
nuxt.config.js 关键配置
target: 'static', generate: { fallback: true, .... }
package.json 配置
{ "name": "xxxxxxx", "version": "1.0.0", "private": true, "scripts": { "dev": "nuxt", "build": "nuxt build", "start": "nuxt start", "generate": "nuxt generate", "generate_coin_list_file": "node scripts/generate_coin_list.js", "generate_coin_images": "node scripts/download_coin_images.js" }, "dependencies": { "@nuxt/content": "^1.14.0", "@nuxtjs/axios": "^5.13.6", "@nuxtjs/gtm": "^2.4.0", "@nuxtjs/proxy": "^2.1.0", "@nuxtjs/sitemap": "^2.4.0", "core-js": "^3.15.1", "frontmatter-markdown-loader": "^3.7.0", "ipx": "^0.9.4", "lite-youtube-embed": "^0.2.0", "nuxt": "^2.15.8", "nuxt-jsonld": "^1.5.3", "v-click-outside": "^3.2.0", "vue-disqus": "^4.0.1" }, "devDependencies": { "@nuxt/image": "^0.6.2", "@nuxtjs/tailwindcss": "^4.2.0", "eslint-config-prettier": "^8.3.0", "postcss": "^8.3.5", "prettier": "^2.3.2" } }
相关代码示例
_slug.vue 页面组件
export default { name: 'BlogSlug', async asyncData({ $content, params, route, error }) { let author = {} let article = await $content('articles', { deep: true }) .where({ slug: params.slug, }) .fetch() .catch(() => { error({ statusCode: 404, message: 'Page not found' }) }) article = article[0] const allArticles = await $content('articles', { deep: true, }) .sortBy('date', 'desc') .limit(6) .fetch() .catch(() => { error({ statusCode: 404, message: 'Page not found' }) }) if (article.author) { author = await $content('authors') .where({ id: article.author, }) .fetch() .catch(() => { error({ statusCode: 404, message: 'Page not found' }) }) } return { article, allArticles, author } }, ... }
完整nuxt.config.js
import coinList from './data/coin_list.json' export default { target: 'static', head: { title: 'XXXXXX', htmlAttrs: { lang: 'de', }, meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: '' }, { name: 'format-detection', content: 'telephone=no' }, { hid: 'twitter:card', property: 'twitter:card', content: 'summary_large_image', }, ], link: [ { hid: 'apple-touch-icon', rel: 'apple-touch-icon', sizes: '180x180', href: '/favicon.ico', }, { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }, ], }, // Global CSS css: [ '~/assets/css/tailwind.css', 'node_modules/lite-youtube-embed/src/lite-yt-embed.css', ], // Plugins to run before rendering page plugins: [ '~/plugins/metadata', '~/plugins/youtube.client.js', '~/plugins/jsonLd.js', { src: '@/plugins/vClickOutside', ssr: false }, '~/plugins/disqus', ], // Auto import components components: [ '~/components', { path: '~/components/utils', extensions: ['vue'] }, { path: '~/components/global' }, ], // Modules for dev and build buildModules: [ '@nuxtjs/tailwindcss', [ '@nuxt/image', { provider: 'static', }, ], '@/modules/sitemapRouteGenerator.js', ], // Modules modules: [ '@nuxtjs/axios', '@nuxt/content', '@nuxtjs/proxy', '@nuxtjs/gtm', // has to be last '@nuxtjs/sitemap', ], sitemap: { hostname: process.env.NUXT_ENV_BASE_URL, path: '/sitemap.xml', }, // GTM Analytics gtm: { enabled: true, pageTracking: true, }, axios: {}, image: { domains: ['assets.coingecko.com', 'coingecko.com'], presets: { blog: { modifiers: { format: 'webp', }, }, }, }, // Content module configuration content: { // nestedProperties: ['articles.slug'], }, generate: { fallback: true, async routes() { const routes = await _getRoutes() async function _getRoutes($content) { const paths = [] coinList.forEach((coin) => { paths.push({ route: `/coins/${coin.id}/historisch/`, payload: coin.id, }) }) return paths } return routes }, }, router: { routeNameSplitter: '/', }, // Build Configuration build: { extend(config) { config.module.rules.push({ test: /\.md$/, loader: 'frontmatter-markdown-loader', }) }, }, }
sitemapRouteGenerator.js 模块
export default function () { this.nuxt.hook('generate:done', (context) => { const routesToExclude = /\/index|\/articles\/|\/undefined/ // Add any route you don't want in your sitemap. Potentially get this from an .env file. const allRoutes = Array.from(context.generatedRoutes) // console.log(context.generatedRoutes) const routes = allRoutes.filter((route) => !routesToExclude.test(route)) // console.log(routes) this.nuxt.options.sitemap.routes = [...routes] }) }
疑问
该错误无明显规律,本地生成和运行均正常,怀疑是Netlify平台相关问题,求解决方案或排查思路。
内容的提问来源于stack exchange,提问作者Base58
相关产品推荐
相关产品推荐

