[Bug]: Nixpacks static site does not respect 200.html
Description
I'm having the same issue as #2562
Seems like Nuxt 3 with generate does not work
You can access the files directly, but index.html is the nginx default page, 200.html is not loaded
These are my settings
Minimal Reproduction (if possible, example repository)
You can use this repo https://github.com/Rule-34/App [NSFW]
Exception or Error
Nginx default page
Version
v4.0.0-beta.323
Cloud?
- [ ] Yes
- [X] No
By default, nginx will load index.html. It seems that your app does not generate an index.html?
By default, nginx will load index.html. It seems that your app does not generate an index.html?
No, Nuxt does not generate index, it generates a 200.html and 404.html
Then you'll have to somehow move it to index.html. Static site assumes that there is an index.html. Maybe an option is to alter the build command and add && mv 200.html index.html or something like that.
Yeah, that would work, but isn’t there an option to support these modern frameworks that generate 200.html, 400.html and 500.html? As seen on my initial screenshot
Nuxt does build a index.html file along with the 200.html, 50x and 404.html page.
Try the above settings
File output of generate command with all the correct expected file:
The Nginx proxy in Coolify manages the pages, but I didnt see the 200.html config, only the index.html. But again over URL the 200.html file is accessible. domain.com/200.html or 200.
Links: https://nuxt-generate.nuxlify.com https://nuxt-generate.nuxlify.com/200 https://nuxt-generate.nuxlify.com/200.html
/nuxt/static path does not work, my settings are the same as yours
Please try to deploy my repo https://github.com/Rule-34/App and you'll see default nginx in index.html
My settings:
Edit: Deleted the URL.
One thing I noticed is I dont have watch paths on my UI?
This is also an issue for me. I'm using a SvelteKit app with adapter-static and encountering routing problems.
My setup:
- SvelteKit app with adapter-static
- Fallback: 200.html (can't use index.html as it would override the pre-rendered content inside index.html)
- The app is partially pre-rendered (some pages), the rest is CSR
- "Is it static site? = true"
Problem:
- Pre-rendered index.html doesn't route files correctly, unless going to '/' and navigating around.
- URLs like
my.domain.com/_app/path-to-file.jsbecomemy.domain.com/admin/_app/path-to-file.js(depending on parent path) (Eg: going to /admin/panel directly, or refreshing on said path) - It loads index.html as the content for all files when accesing any route other thant '/' (including the js files)
Attempted solution: I tried a post-build script to change URLs in index.html:
const scriptDir = dirname(fileURLToPath(import.meta.url));
const indexPath = join(scriptDir, '../build/index.html');
const indexContents = readFileSync(indexPath, 'utf8');
writeFileSync(indexPath, indexContents.replaceAll('./_app/', '/_app/'));
However, this caused all URLs to load index.html, even when navigating around (basically stuck on index.html)
I'm unsure how to solve this correctly. It's also odd that it defaults to index.html, as any unavailable URLs (in a completely pre-rendered site) would load index.html, whereas a 404.html might be preferable for some cases.
This guide resolved my problem (I only adapted it to my usecase): https://billyle.dev/posts/fix-missing-404-pages-for-coolify-static-site-deployments
Essentially you'll have to dockerize your app:
Dockerfile
ARG NODE_VERSION=22.8.0
ARG PNPM_VERSION=9.10.0
FROM node:${NODE_VERSION}-alpine AS builder
WORKDIR /app
COPY package.json pnpm-lock.yaml* ./
RUN npm install -g pnpm@${PNPM_VERSION}
RUN pnpm install
COPY . .
RUN pnpm build
FROM nginx:stable-alpine3.17 AS final
COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 4321
nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
server {
listen 4321;
server_name _;
root /usr/share/nginx/html;
index index.html index.htm;
include /etc/nginx/mime.types;
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
internal;
}
location / {
try_files $uri $uri/index.html /CSR.html;
}
}
}
In coolify under:
Network
Ports Exposes *
4321
(Modify the params to fit your app)
In the above example CSR.html is my fallback html, but it can be anything (for example 200.html), this config also handles 404.html, but in my case it should always fallback to CSR.html (in which it will handle the 404)
@AlejandroAkbal The config also allows to define the index: index index.html index.htm;
You coulld change this to: index 200.html
(I believe this would solve your problem, but I have not tested it myself)
Hope this saves a big headache for anyone else encountering this issue.
💬 Error description
I've encountered the same problem with my Nuxt3 app. I've used the setup from this repo and did everything by the docs.
Problem seems to be in nixpacks. It will use npm run build as build command regardless of static site checked or not. Thus .html files are not generated.
⭐ Solution
You just need to configure the build command to use npm run generate and everything works as expected. This config works for me.
and voila!
[!TIP] You can setup health check like this and check if .output/public was generated with index.html or not.
[!IMPORTANT] I am using v4.0.0-beta.360
@AlejandroAkbal is this still a problem or can we close?
Coolify now allows you to edit the Nginx Configuration when you have Is it a static site? enabled. That should in theory solve your problem.
Could be, I abandoned having a static website since this didn't work, but if you can modify it, then yeah
Feel free to close