Recently, while developing some interesting personal projects using Nuxt3 and deploying them on Cloudflare Pages, I encountered several frustrating issues. Here’s a record of those.
Node.js Issues on Cloudflare Pages
Despite Cloudflare’s claim to be all-encompassing, even they have their limitations.
In reality, the Node.js environment on Cloudflare Pages is not a full version and is fixed without any options for
customization. This means certain JavaScript libraries cannot be used. A notable example is when trying to use
aws-sdk-js to interact with AWS S3 via Cloudflare’s R2 storage, which results in a cryptic error
t is not a function. This error does not occur during local development but fails at build time.
The reason is that aws-sdk-js depends on @aws-sdk/s3-request-presigner, which in turn relies on @smithy, requiring
the node:fs module. Clearly, Cloudflare’s Node.js environment does not provide node:fs. As an alternative,
Cloudflare Pages recommends using the more primitive SDK aws4fetch.
Many similar issues can arise, often due to unsupported modules in Cloudflare’s Node.js environment.
Some Routes Work Fine in Development but Return 404 in Production?
We know that if a project has static files that need to be accessed, placing them in the public directory is standard
practice. Typically, frameworks are designed to look for corresponding files if a route is undefined or return a 404 if
the file doesn’t exist.
Recently, I encountered a peculiar issue where some static files in the public directory could be accessed normally,
while others returned a 404 Not Found error. In development mode, all addresses worked fine.
Checking the console revealed an error
[nuxt] error caught during app initialization Wa: Page not found: /content/xxxx. This clearly indicated that the
routing logic was being handled internally by the application, even though these were supposed to be static files.
Based on previous experience, this issue was likely related to Cloudflare Pages. Checking the deployment information, I
found that Cloudflare Pages has its own routing mechanism for determining when to execute Functions scripts. This
routing configuration is generated based on files in the /functions directory.
To control when functions are called, one can write custom functions. However, Nuxt does not provide relevant configurations or documentation for this.
_routes.json
Another solution is to create a _routes.json file to control which routes call functions. This file should be placed
in the project’s output directory.
Reviewing the deployment details, I noticed that the routing content listed was from _routes.json.
{
"version": 1,
"include": [
"/*"
],
"exclude": [
"/_nuxt/*",
"/_robots.txt",
"/favicon.ico",
"/images/pvz.jpg",
"/js/jquery.js",
"/content"
//...
]
}
By comparing the errors, I identified the root cause: the 404 Not Found pages were not listed in the exclude list.
This issue was very subtle; _routes.json only excluded some static files, so the missing ones were treated as
application routes, leading to the error
[nuxt] error caught during app initialization Wa: Page not found: /content/xxxx.
The solution was straightforward—manually control the content generation of _routes.json.
Unfortunately, there is no documentation in Nuxt3 for this. Since Nuxt3 uses nitro for the backend, I looked into
nitro’s documentation regarding Cloudflare Pages.
Nitro automatically generates a _routes.json file to control which routes are served by files and which by Worker
scripts. You can override the auto-generated routing file using the cloudflare.pages.routes configuration option.
Thus, we can configure it directly in nuxt.config.ts:
export default defineNuxtConfig({
nitro: {
modules: [nitroPublic()],
preset: 'cloudflare_pages',
prerender: {
autoSubfolderIndex: false
},
cloudflare: {
pages: {
routes: {
"version": 1,
"include": [
"/*"
],
"exclude": [
"/_nuxt/*",
"/_robots.txt",
"/favicon.ico",
"/fonts/FUTRSTI.TTF",
"/images/bg.jpg",
"/images/logo.jpg",
"/js/jquery.js",
"/js/jquery.mobile-1.4.5.min.js",
"/content/*"
]
}
}
}
},
})
Thoughts on the Nuxt 3 Framework
My impression of Nuxt3 is that it has no major problems but plenty of minor ones. For instance, it starts slowly, and the server-side performance is also slow. Error debugging messages are often unhelpful. Some routing behaviors work as expected sometimes but not others.
In the Vue ecosystem, the closest equivalent to Next.js that I know of is Nuxt.
Recently, I came across a framework called Tuono, which implements SSR full-stack with Rust on the backend. It would be interesting to see if someone develops a Vue version.