-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Description
Environment
| Operating system | macOS 25.1.0 |
| CPU | Apple M1 Pro (8 cores) |
| Node.js version | v24.11.0 |
| nuxt/cli version | 3.31.3 |
| Package manager | pnpm@10.20.0 |
| Nuxt version | 4.2.2 |
| Nitro version | 2.12.9 |
| Builder | vite@7.3.0 |
| Config | app, compatibilityDate, debug, devtools, logLevel, ssr |
| Modules | - |
Reproduction
https://github.com/whoiscadenyoung/nuxt-route-test
Describe the bug
When using a base URL that matches part of a page path, Nuxt/Nitro will generate a stub that removes the base URL from the path.
Example:
// `nuxt.config.ts`
app: { baseURL: '/admin/' }
// `app/pages/admin-dashboard.vue`
// Stub is generated in `.output/public` that is just `-dashboard` with no extension.If I use NuxtLink to point to the page, Nuxt/Nitro will generate the page in the output. However, it will also still generate the stub. It will also throw an error in debug mode that didn't exist when there wasn't a link pointing to the page:
// `nuxt.config.ts`
app: { baseURL: '/admin/' }
// `app/app.vue`
<NuxtLink to='/admin-dashboard'>Admin Dashboard</NuxtLink>
// `app/pages/admin-dashboard.vue`
// Stub is generated in `.output/public` that is just `-dashboard` with no extension.
// `.output/public/admin-dashboard/index.html is generated and seems to be normalAdditional context
I'm not sure to what extent this is a Nitro error or a Nuxt error. I would guess the page stub being generated by Nitro when there's no link to the page would indicate that part is a Nitro issue. So I could also file this over there if that would be helpful. I wonder if it has something to do with this file: https://github.com/nitrojs/nitro/blob/main/src/prerender/prerender.ts
However, I believe NuxtLink is supposed to respect baseURL. So perhaps the baseURL isn't being passed to Nitro in the right format, or Nitro is trimming it or something?
The expected behavior would be that the links are constructed and prerendered, respecting the base URL and the full page path. Trimming the baseURL from the page path without using the trailing slash may be a cause.
However, I would expect I'd be able to create a pages/admin/admin-dashboard.vue with baseURL set to /admin/ and, even if bad practice, it would allow me to have a site page that goes to localhost:3000/admin/admin/admin-dashboard/index.html.
The reason I've filed this is because I'm trying to deploy a website to a subdirectory, hence the base URL, and one of the routes I'm required to create includes the base url in the page name/route.
Logs
pnpm generate
> nuxt-route-test@ generate /Users/cadenyoung/Developer/nuxt-route-test
> nuxt generate
┌ Building Nuxt for production...
│
● Nuxt 4.2.2 (with Nitro 2.12.9, Vite 7.3.0 and Vue 3.5.26)
│
● Nitro preset: static
[nitro] types:extend: 0.062ms 12:16:32 PM
ℹ Building client... 12:16:33 PM
ℹ vite v7.3.0 building client environment for production... 12:16:33 PM
ℹ ✓ 130 modules transformed. 12:16:33 PM
ℹ ../node_modules/.cache/nuxt/.nuxt/dist/client/manifest.json 3.23 kB │ gzip: 0.47 kB 12:16:33 PM
ℹ ../node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/error-500.BfidJU9u.css 1.91 kB │ gzip: 0.73 kB 12:16:33 PM
ℹ ../node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/error-404.ChHVs5LJ.css 2.43 kB │ gzip: 0.86 kB 12:16:33 PM
ℹ ../node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/B261XNd-.js 0.16 kB │ gzip: 0.16 kB 12:16:33 PM
ℹ ../node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BL0lCfbO.js 0.17 kB │ gzip: 0.17 kB 12:16:33 PM
ℹ ../node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/C5V0ZhO0.js 3.47 kB │ gzip: 1.55 kB 12:16:33 PM
ℹ ../node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/CjSxg1l4.js 3.76 kB │ gzip: 1.69 kB 12:16:33 PM
ℹ ../node_modules/.cache/nuxt/.nuxt/dist/client/_nuxt/BYKH74-j.js 171.71 kB │ gzip: 64.76 kB 12:16:33 PM
ℹ ✓ built in 752ms 12:16:33 PM
✔ Client built in 759ms 12:16:33 PM
ℹ Building server... 12:16:33 PM
ℹ vite v7.3.0 building ssr environment for production... 12:16:33 PM
ℹ ✓ 78 modules transformed. 12:16:34 PM
ℹ ✓ built in 231ms 12:16:34 PM
✔ Server built in 236ms 12:16:34 PM
[nitro] prerender:routes: 0.039ms 12:16:34 PM
ℹ Initializing prerenderer nitro 12:16:34 PM
[nitro] prerender:config: 0.005ms 12:16:34 PM
[nitro] prerender:init: 0.013ms 12:16:34 PM
[nitro] build:before: 0.013ms 12:16:34 PM
[nitro] rollup:before: 0.015ms 12:16:34 PM
[nitro] types:extend: 0.013ms 12:16:34 PM
[nitro] compiled: 0.011ms 12:16:34 PM
ℹ Prerendering 3 initial routes with crawler nitro 12:16:34 PM
[nitro-runtime] request: 0.097ms 12:16:34 PM
[nitro-runtime] request: 0.098ms 12:16:34 PM
[nitro-runtime] request: 0.098ms 12:16:34 PM
[nitro-runtime] render:before: 0.019ms 12:16:34 PM
[nitro-runtime] render:before: 0.145ms 12:16:34 PM
[nitro-runtime] render:before: 0.225ms 12:16:34 PM
[nitro-runtime] render:html: 0.015ms 12:16:34 PM
[nitro-runtime] render:html: 0.129ms 12:16:34 PM
[nitro-runtime] render:response: 0.026ms 12:16:34 PM
[nitro-runtime] render:response: 0.031ms 12:16:34 PM
[nitro-runtime] beforeResponse: 0.011ms 12:16:34 PM
[nitro-runtime] beforeResponse: 0.094ms 12:16:34 PM
[nitro-runtime] afterResponse: 0.012ms 12:16:34 PM
[nitro] prerender:generate: 0.007ms 12:16:34 PM
[nitro-runtime] afterResponse: 0.004ms 12:16:34 PM
[nitro] prerender:generate: 0.003ms 12:16:34 PM
[nitro] prerender:route: 0.007ms 12:16:34 PM
├─ /200.html (28ms) nitro 12:16:34 PM
[nitro] prerender:route: 0.004ms 12:16:34 PM
├─ /404.html (28ms) nitro 12:16:34 PM
[nitro-runtime] render:html: 0.003ms 12:16:34 PM
[nitro-runtime] render:response: 0.003ms 12:16:34 PM
[nitro-runtime] beforeResponse: 0.003ms 12:16:34 PM
[nitro-runtime] afterResponse: 0.005ms 12:16:34 PM
[nitro] prerender:generate: 0.004ms 12:16:34 PM
[nitro] prerender:route: 0.004ms 12:16:34 PM
├─ / (31ms) nitro 12:16:34 PM
[nitro-runtime] request: 0.112ms 12:16:34 PM
[nitro-runtime] request: 0.108ms 12:16:34 PM
[nitro-runtime] request: 0.108ms 12:16:34 PM
[nitro-runtime] request: 0.112ms 12:16:34 PM
[nitro-runtime] request: 0.118ms 12:16:34 PM
[nitro-runtime] render:before: 0.169ms 12:16:34 PM
[nitro-runtime] render:before: 0.189ms 12:16:34 PM
[nitro-runtime] render:before: 0.201ms 12:16:34 PM
[nitro-runtime] render:before: 0.334ms 12:16:34 PM
[nitro-runtime] error: 0.228ms 12:16:34 PM
[nitro-runtime] render:response: 0.007ms 12:16:34 PM
[nitro-runtime] render:response: 0.047ms 12:16:34 PM
[nitro-runtime] beforeResponse: 0.007ms 12:16:34 PM
[nitro-runtime] beforeResponse: 0.041ms 12:16:34 PM
[nitro] prerender:generate: 0.005ms 12:16:34 PM
[nitro-runtime] afterResponse: 0.003ms 12:16:34 PM
[nitro] prerender:generate: 0.009ms 12:16:34 PM
[nitro] prerender:route: 0.003ms 12:16:34 PM
├─ /admin/_payload.json?1cb2a225-0c46-4cf4-81a7-406bf269de63 (6ms) (skipped) nitro 12:16:34 PM
[nitro-runtime] afterResponse: 0.004ms 12:16:34 PM
[nitro] prerender:generate: 0.003ms 12:16:34 PM
[nitro-runtime] render:html: 0.004ms 12:16:34 PM
[nitro-runtime] render:response: 0.003ms 12:16:34 PM
[nitro-runtime] beforeResponse: 0.003ms 12:16:34 PM
[nitro-runtime] afterResponse: 0.003ms 12:16:34 PM
[nitro] prerender:generate: 0.003ms 12:16:34 PM
[nitro-runtime] render:html: 0.002ms 12:16:34 PM
[nitro-runtime] render:response: 0.002ms 12:16:34 PM
[nitro-runtime] beforeResponse: 0.003ms 12:16:34 PM
[nitro-runtime] afterResponse: 0.003ms 12:16:34 PM
[nitro] prerender:generate: 0.003ms 12:16:34 PM
[nitro] prerender:route: 0.006ms 12:16:34 PM
├─ /admin-dashboard (5ms) nitro 12:16:34 PM
[nitro] prerender:route: 0.003ms 12:16:34 PM
├─ /_payload.json (6ms) nitro 12:16:34 PM
[nitro] prerender:route: 0.004ms 12:16:34 PM
├─ /admin/ (8ms) nitro 12:16:34 PM
[nitro] prerender:route: 0.003ms 12:16:34 PM
├─ /admin/admin-dashboard (8ms) nitro 12:16:34 PM
[nitro-runtime] request: 0.044ms 12:16:34 PM
[nitro-runtime] request: 0.031ms 12:16:34 PM
[nitro-runtime] render:before: 0.032ms 12:16:34 PM
[nitro-runtime] error: 0.013ms 12:16:34 PM
[nitro-runtime] render:response: 0.002ms 12:16:34 PM
[nitro-runtime] beforeResponse: 0.003ms 12:16:34 PM
[nitro] prerender:generate: 0.003ms 12:16:34 PM
[nitro-runtime] afterResponse: 0.003ms 12:16:34 PM
[nitro] prerender:generate: 0.002ms 12:16:34 PM
[nitro] prerender:route: 0.003ms 12:16:34 PM
├─ /admin/admin-dashboard/_payload.json?1cb2a225-0c46-4cf4-81a7-406bf269de63 (1ms) (skipped) nitro 12:16:34 PM
[12:16:34 PM] ERROR EEXIST: file already exists, mkdir '/Users/cadenyoung/Developer/nuxt-route-test/.output/public/-dashboard'
at async Object.mkdir (node:internal/fs/promises:861:10)
at async writeFile (node_modules/.pnpm/nitropack@2.12.9/node_modules/nitropack/dist/kit/index.mjs:53:3)
at async generateRoute (node_modules/.pnpm/nitropack@2.12.9/node_modules/nitropack/dist/core/index.mjs:2166:7)
at async Promise.all (index 1)
at async Promise.all (index 2)
at async Promise.all (index 0)
at async runParallel (node_modules/.pnpm/nitropack@2.12.9/node_modules/nitropack/dist/core/index.mjs:1547:3)
at async prerender (node_modules/.pnpm/nitropack@2.12.9/node_modules/nitropack/dist/core/index.mjs:2192:3)
at async node_modules/.pnpm/@nuxt+nitro-server@4.2.2_db0@0.3.4_ioredis@5.8.2_magicast@0.5.1_nuxt@4.2.2_@parcel+watc_3cc5e96e076713c13d4211d6400a72c9/node_modules/@nuxt/nitro-server/dist/index.mjs:777:5
at async build (node_modules/.pnpm/nuxt@4.2.2_@parcel+watcher@2.5.1_@vue+compiler-sfc@3.5.26_cac@6.7.14_db0@0.3.4_ioredis@_7e801e45073b41cbae17519239ab62f3/node_modules/nuxt/dist/index.mjs:6790:3)
[nitro-runtime] close: 0.004ms 12:16:34 PM
[nitro] prerender:done: 0.003ms 12:16:34 PM
ℹ Prerendered 7 routes in 0.402 seconds nitro 12:16:34 PM
[nitro] build:before: 0.003ms
✔ Generated public .output/public nitro 12:16:34 PM
[nitro] rollup:before: 9.018ms
[nitro] types:extend: 0.025ms
[nitro] compiled: 0.006ms
✔ You can preview this build using npx serve .output/public nitro 12:16:34 PM
[nitro] close: 0.066ms 12:16:34 PM
│ 12:16:34 PM
└ ✨ You can now deploy .output/public to any static hosting!