Building app using `strategy: 'prefix'` throws pre-render `(Error: [301])`
Environment
- Operating System:
Darwin - Node Version:
v16.16.0 - Nuxt Version:
3.6.5 - Nitro Version:
2.5.2 - Package Manager:
[email protected] - Builder:
vite - User Config:
- - Runtime Modules:
- - Build Modules:
-
Reproduction
https://stackblitz.com/edit/nuxt-starter-jkohmm?file=nuxt.config.ts
Describe the bug
When trying to use strategy: 'prefix', Im getting (Error: [301])
Additional context
No response
Logs
✔ Server built in 920ms 12:55:12 PM
✔ Generated public .output/public nitro 12:55:12 PM
ℹ Initializing prerenderer nitro 12:55:12 PM
ℹ Prerendering 2 routes nitro 12:55:13 PM
├─ /test (64ms) (Error: [301] ) nitro 12:55:13 PM
├─ / (65ms) (Error: [301] ) nitro 12:55:13 PM
nitro 12:55:13 PM
Errors prerendering:
├─ /test (301) nitro 12:55:13 PM
├─ / (301) nitro 12:55:13 PM
nitro 12:55:13 PM
ERROR Exiting due to prerender errors. 12:55:13 PM
at Module.prerender (node_modules/nitropack/dist/shared/nitro.1db3349c.mjs:204:11)
at async eval (node_modules/nuxt/dist/index.mjs:2658:7)
at async build (node_modules/nuxt/dist/index.mjs:3811:5)
at async Object.invoke (node_modules/nuxi/dist/chunks/build.mjs:74:5)
at async _main (node_modules/nuxi/dist/cli.mjs:64:20)
Thank you for your reporting!
This issue is not with the nuxt i18n module, because you are prerendering the build with the routeRules option in order to make it work in SSR mode.
The prefix strategy redirects to a URL with the target locale when accessing root /.
(Error: [301]) occurs because you have set a prerender in your routeRules options, which is redirected by the prefix strategy described above.
I saw your nuxt.config.ts and the nuxi build is a build to run on a server in SSR mode.
I don`t know why you are prerendering (I would like to know the reason why you will prerender), but there is a way to work around this error below.
- stop prerender
- set
ssr: falseon nuxt.config - set
nitro.prerender.failOnError: falseon nuxt.config: (ref: https://github.com/nuxt/nuxt/issues/22159#issuecomment-1639851186)
@kazupon
My app is heavily relaying on routeRules, some pages needs to be prerendered (landing page & some other commercial pages) while others are meant to be fully client only pages (dashboard, kyc & more)
If I'll remove ssr and prerender the entire app will act as an spa.
whats the best / right way to use strategy prefix with routeRules?
Thank you for your use-cases.
Your reproduction of the routing strategy uses prefix. And your locale code is en and he. So you can prerender your application and build it with SSR by setting the routeRules option as follows:
routeRules: {
'/en': { prerender: true },
'/he': { prerender: true },
'/en/test': { prerender: true },
'/he/test': { prerender: true },
},
Thank you for your use-cases.
Your reproduction of the routing strategy uses
prefix. And your locale code isenandhe. So you can prerender your application and build it with SSR by setting therouteRulesoption as follows:routeRules: { '/en': { prerender: true }, '/he': { prerender: true }, '/en/test': { prerender: true }, '/he/test': { prerender: true }, },
Thank you for adding some examples on how to fix it, your solution could help
But I keep getting 301 for the main index page (/). it seems that even if I remove the entire routeRules object it still prerendering the index page. This one is a bit tricky and I couldn't reproduce it on Stackblitz..
You can specifically set your root to not prerender. This solved it for me:
routeRules: {
"/": { prerender: false },
"/de": { prerender: true },
"/en": { prerender: true },
},
And its fine to not have a root index.html file ?
@kazupon @martflu any suggestions on how to handle the root index.html file while using strategy prefix?
I cant publish my app without having a root index.html.
@kazupon and btw, any reason why other strategies totally ignores routeRules? my build is failing for pages that shouldn't be pre-rendered, for example, the build will fail for all the following rules: "/kyc/**": { ssr: false },
the only strategy that respects the routeRules object is prefix. but Im actually looking for a prefix_except_default strategy.
Any suggestions?
@Dananz I am using prefix with an index page. With this setting, root will always forward to one of the prefixes. This forward was the reason for the Error during prerender.
Specifically setting the unprefixed root to be excluded during prerender solved the problem for me.
I also use crawlLinks: true for prerendering all other routes of the page.
@Dananz I am using
prefixwith an index page. With this setting, the root will always forward to one of the prefixes. This forward was the reason for the Error during prerender. Specifically setting the unprefixed root to be excluded during prerender solved the problem for me. I also usecrawlLinks: truefor prerendering all other routes of the page.
Can some expert verify this gentleman's statement? seems correct to me.
When I set { prerender: false } in the "/" route, it works. However, it doesn't work for "/nl, "/nl/", and any other routes generated by nuxt-i18n :/
disclaimer
i am not planning on running this static so nuxt generate was a mistake in my case for this particular project.
i18n: {
lazy: true,
langDir: "locales/",
defaultLocale: "en",
strategy: "prefix",
detectBrowserLanguage: {
useCookie: true,
cookieKey: "i18n_redirected",
fallbackLocale: "en",
redirectOn: "root",
},
customRoutes: "config",
pages: {
about: {
de: "/ueber-mich",
en: "/about",
},
},
locales: [
{
name: "Deutsch",
code: "de",
iso: "de-DE",
file: "de",
icon: "i-circle-flags-de",
},
{
name: "English",
code: "en",
iso: "en-US",
file: "en",
icon: "i-circle-flags-en",
},
],
},
│ .gitignore
│ app.config.ts
│ app.vue
│ nuxt.config.ts
│ package-lock.json
│ package.json
│ README.md
│ tailwind.config.js
│ tsconfig.json
├───locales
│ ├───de
│ │ index.ts
│ │
│ └───en
│ index.ts
└───pages
│ about.vue
│ index.vue
running generate results in an error Error: [404] Page not found: /
Prerendering 7 initial routes with crawler
├─ /200.html (37ms)
├─ /404.html (38ms)
├─ / (108ms)
│ └── Error: [404] Page not found: /
├─ /en (103ms)
├─ /en/about (83ms)
├─ /de (104ms)
├─ /de/ueber-mich (104ms)
├─ /en/about/_payload.json (0ms)
├─ /en/_payload.json (1ms)
├─ /de/_payload.json (3ms)
├─ /de/ueber-mich/_payload.json (1ms)
Errors prerendering:
├─ / (108ms)
│ └── Error: [404] Page not found: /
ERROR Exiting due to prerender errors.
I need to use generate and have the same problem. In my case i switched to prefix because of SEO Issues.
@Sazzels I'm facing the same issue for the default route. / seems to throw a 404 when running generate.
In my case I "fixed" it by adding a rootRedirect to the i18n options:
i18n: {
rootRedirect: 'en' // use default locale
}
But this also throws a warning when running dev: [Vue Router warn]: No match found for location with path "/en/en". The redirect seems to be correct though.
This issue should be (at least partially) fixed by #2894 which is included in the edge release, I have updated the original reproduction to demonstrate here.
Please let me know if any of you still run into this issue when using the edge release, install with npm i -D @nuxtjs/i18n@npm:@nuxtjs/i18n-edge, you may need to remove lockfiles before installing.
@BobbieGoede the nuxt generate command seems to work as expected now, except the root redirect is always to /en when I configure my i18n as follows:
i18n: {
locales: [
{
code: 'nl',
iso: 'nl-NL',
},
{
code: 'en',
iso: 'en-US',
},
],
defaultLocale: 'nl',
strategy: 'prefix',
vueI18n: './i18n.config.ts',
},
import en from '@/i18n/messages/en';
import nl from '@/i18n/messages/nl';
export default defineI18nConfig(() => ({
legacy: false,
locale: 'nl',
locales: [
{
code: 'en',
iso: 'en-US',
},
{
code: 'nl',
iso: 'nl-NL',
},
],
messages: {
en,
nl,
},
}));
I would expect the redirect from / to go to the configured defaultLocale if set.
@bnachtweh Can you provide a minimal reproduction project?
@bnachtweh Can you provide a minimal reproduction project?
Never mind, it seems that the cookie was set to en, so that would make sense. Thanks anyway!
Since the original issue should be resolved I'll close this issue. If anyone is running into issues please open a new issue with a minimal reproduction!