Closed jaystacey closed 1 week ago
What does your functions/api/contact.ts
file look like? I suspect you aren't correctly exporting any onRequest*
handlers.
contact.ts exports a onRequestPost()
function, previously been working however after a recent merge (not relating to that file) wrangler no longer detects any functions routes.
I did a test with a 'test.js' function at the base functions directory (/functions/test.js) using example code:
export async function onRequest() { return new Response("Hello, world!"); }
and it doens't detect that as a route either...
also the garbled log output.
Same problem but deployed from Gitlab repo (not really significant I suppose)
A previous commit works with the same code in /functions
directory.
If I redeploy this working commit all is fine.
Do you have a link to the repository (or one that is similarly configured) and copy of your root directory/build command/output directory settings?
Note that the functions/
directory should be in the root directory of your repo (usually that's just the top-level folder).
I will send you the complete directory. If you want I can invite you to the Gitlab repo
Any news about this problem ? @jaystacey I see in you deploy log "You can now deploy .output/public to any static hosting!", is it a Nuxt 3 project ?
yep, using nuxt3 3.0.0-rc.10, coincidence that we are both using nuxt and facing this issue?
I'm using nuxt3 3.0.0-rc.11.
I made a little test by generating with nuxi generate
in my local environment,
then add .output/public
folder to my git repo,
I used npm ci
instead of nuxt genreate
in the build script in CF deployment settings to get dependencies,
and guess what ... the scripts of functions folder was correctly compiled and the routes are available.
I restore the generation on CF side, and I list files of functions folder before and after generation.
Before nuxt generate
(----ls-before
line in log), functions folder is ok,
but after generation it does not exist anymore (----ls-after
line in log).
I think it's not a wrangler problem but a Nuxt or Nitro issue instead
<html>
<body>
<!--StartFragment-->
16:14:24.368 | > cfgenerate
-- | --
16:14:24.368 | > echo ----ls-before && ls functions -l -R && nuxt generate && echo ----ls-after && ls functions -l -R
16:14:24.368 |
16:14:24.386 | ----ls-before
16:14:24.399 | functions:
16:14:24.399 | total 5
16:14:24.399 | drwxr-xr-x 2 buildbot nogroup 4096 Oct 5 14:13 api
16:14:24.399 | -rw-r--r-- 1 buildbot nogroup 158 Oct 5 14:13 tsconfig.json
16:14:24.399 |
16:14:24.399 | functions/api:
16:14:24.400 | total 5
16:14:24.400 | -rw-r--r-- 1 buildbot nogroup 3729 Oct 5 14:13 contact.ts
16:14:24.400 | -rw-r--r-- 1 buildbot nogroup 325 Oct 5 14:13 index.ts
16:14:24.499 | Nuxi 3.0.0-rc.11
16:14:24.519 | Nuxt 3.0.0-rc.11 with Nitro 0.5.4
16:14:31.237 | ℹ Client built in 3614ms
16:14:31.239 | ℹ Building server...
16:14:32.888 | ✔ Server built in 1649ms
16:14:32.953 | ✔ Generated public .output/public
16:14:32.954 | ℹ Initializing prerenderer
16:14:34.029 | ℹ Prerendering 3 initial routes with crawler
16:14:34.169 | ├─ / (140ms)
16:14:34.180 | ├─ /mentions-legales (11ms)
16:14:34.183 | ├─ /200.html (2ms)
16:14:34.184 | ├─ /_payload.js (1ms)
16:14:34.186 | ├─ /mentions-legales/_payload.js (2ms)
16:14:34.188 | ✔ You can now deploy .output/public to any static hosting!
16:14:34.209 | ----ls-after
16:14:34.223 | functions:
16:14:34.224 | total 0
16:14:34.237 | Finished
16:14:34.817 | 🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose
16:14:34.825 |
16:14:34.929 | [31m✘ [41;31m[[41;97mERROR[41;31m][0m [1mNo routes found when building Functions directory: /opt/buildhome/repo/functions[0m
<!--EndFragment-->
</body>
</html>
Finally, Nitro seems to detect the deployment environment (see Zero-Config Providers doc), and select the right preset (in this case cloudflare_pages
I presume).
In the Nitro clouldflare.ts, we can see :
...
output: {
serverDir: '{{ rootDir }}/functions'
},
...
The server directory /functions
folder is emptied before each Nitro prerender.
I suppose that Nuxt 3 /server
folder should be used as source of functions folder but there's some issues.
I fixed the problem by setting the environment variable NITRO_PRESET=node-server
in CF settings.
@chri70 great find, can confirm that NITRO_PRESET=node-server
resolves issue with no obvious drawbacks.
@chri70 great find, can confirm that NITRO_PRESET=node-server resolves issue with no obvious drawbacks.
@jaystacey seems fine, but if that does not work with the preset "cloudflare_pages" I'd consider the bug still unresolved - so let's re-open this?
uhm, this should be a nitro bug though
Hi, sorry to jump on an old issue, but I had this same problem and came across a different solution. I thought it would be worth sharing for anyone else stumbling across this topic.
Rather than setting the envrionment variable, I added the following to my nuxt.config.ts
:
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
nitro: {
preset: "cloudflare_pages",
},
});
Also, it's important that you run nuxt build
rather than nuxt generate
. When you choose the Nuxt preset, it chooses npm run generate
as the default build command and /dist
as the output directory.
After setting the build command to yarn build
and the output directory to .output/public
and adding the config above, it built successfully and I could see the SSR activity thanks to the new real-time logs.
@luc122c
Also, it's important that you run
nuxt build
rather thannuxt generate
. When you choose the Nuxt preset, it choosesnpm run generate
as the default build command and/dist
as the output directory.
Unfortunately that does not help those of us that that DO NOT want SSR, but still want the Cloudflare functions. With is preset you should be able to do either a SPA or SSR. nuxt build
is for SSR and nuxt generate
is for static/SPA. Currently it will not create the Cloudflare functions if you use nuxt generate
@luc122c You could however use the prerender
config to generate the static html and then run nuxt build
, works for me because I only have one page... would not be great with 10+
nitro: {
preset: 'cloudflare-pages',
prerender: {
ignore: ['/404'],
routes: ['/']
},
serveStatic: true
}
Plus, this bug still needs to get fixed for server routes to work properly... https://github.com/unjs/nitro/issues/497
(Edit: Forgot to add that I intended to ask @luc122c about this - thanks for any input!)
I am a bit confused by this issue: Is the intended behaviour that both the native /functions
folder from Cloudflare Pages and the /server/api/
folder from Nuxt 3 are supposed to work in parallel. Or will the /server
folder from Nuxt be "transformed" into the Cloudflare Pages /functions
folder?
By setting the build step to nuxt build && ls functions
and setting the Nitro preset to "cloudflare_pages" I have success with putting my API functions in /server/api
, and I can see that the functions folder is then created and populated with two files during deployment on Cloudflare Pages:
03:19:44.892 | functions:
03:19:44.892 | total 702
03:19:44.892 | -rw-r--r-- 1 buildbot nogroup 305165 Feb 26 02:19 [[path]].js
03:19:44.893 | -rw-r--r-- 1 buildbot nogroup 412466 Feb 26 02:19 [[path]].js.map
However, I cannot get it to work by simply creating the /functions
folder in my Nuxt project and adding a HelloWorld function as described on https://developers.cloudflare.com/pages/platform/functions/get-started/ - when I deploy, I get this:
03:03:00.842 | Found Functions directory at /functions. Uploading.
03:03:01.419 |
03:03:01.523 | ✘ [ERROR] No routes found when building Functions directory: /opt/buildhome/repo/functions
03:03:01.523 |
03:03:01.523 |
03:03:01.524 | If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose
03:03:01.535 | Warning: Wrangler did not find routes when building functions. Skipping.
I am mostly curious if I am misunderstanding how this is supposed to work. Thanks in advance!
I am facing this error. Any solution yet?
Appears that there is mroe to this issue, reopening. @trapcodeio can you please post nuxt version and reproduction code.
I can do nothing...
⛅️ wrangler 3.0.1
------------------
wrangler dev now uses local mode by default, powered by 🔥 Miniflare and 👷 workerd.
To run an edge preview session for your Worker, use wrangler dev --remote
⎔ Starting local server...
service core:user:worker: Uncaught TypeError: Cannot read properties of undefined (reading 'split')
at ivsvnonyb4d.js:4962:32
✘ [ERROR] MiniflareCoreError [ERR_RUNTIME_FAILURE]: The Workers runtime failed to start. There is likely additional logging output above.
(Edit: Forgot to add that I intended to ask @luc122c about this - thanks for any input!)
I am a bit confused by this issue: Is the intended behaviour that both the native
/functions
folder from Cloudflare Pages and the/server/api/
folder from Nuxt 3 are supposed to work in parallel. Or will the/server
folder from Nuxt be "transformed" into the Cloudflare Pages/functions
folder?By setting the build step to
nuxt build && ls functions
and setting the Nitro preset to "cloudflare_pages" I have success with putting my API functions in/server/api
, and I can see that the functions folder is then created and populated with two files during deployment on Cloudflare Pages:03:19:44.892 | functions: 03:19:44.892 | total 702 03:19:44.892 | -rw-r--r-- 1 buildbot nogroup 305165 Feb 26 02:19 [[path]].js 03:19:44.893 | -rw-r--r-- 1 buildbot nogroup 412466 Feb 26 02:19 [[path]].js.map
However, I cannot get it to work by simply creating the
/functions
folder in my Nuxt project and adding a HelloWorld function as described on https://developers.cloudflare.com/pages/platform/functions/get-started/ - when I deploy, I get this:03:03:00.842 | Found Functions directory at /functions. Uploading. 03:03:01.419 | 03:03:01.523 | ✘ [ERROR] No routes found when building Functions directory: /opt/buildhome/repo/functions 03:03:01.523 | 03:03:01.523 | 03:03:01.524 | If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose 03:03:01.535 | Warning: Wrangler did not find routes when building functions. Skipping.
I am mostly curious if I am misunderstanding how this is supposed to work. Thanks in advance!
Would really like some clarity regarding this as well.
hi folks, can anyone confirm whether you're still experiencing this issue with latest wrangler version? And if so, a repro repository would be much appreciated. Thank you <3
I am experiencing this issue. I'm not using Nuxt... I was using Hono for the Functions. I initially had the functions directory in the src/functions
directory, but that's the src
directory is the "output" directory.
I moved that up to be /functions
and it found the functions. However, it did not auto-generate any routes. So when I submit a post to that URL I get a 405 Method not Allowed
error.
I couldn't figure out where to put my custom _routes.json
file since I was trying to get it to work. I only need Functions to pay attention when going to the /api/*
route. Everything else is static. I finally figured out it recognized it when I placed it at src/_routes.json
.
I have the code on Gitlab. It is a private repository, but I don't mind providing access to the repository if it would be helpful. It's a fully static site where I'm trying to make a contact form submit data through a Cloudflare Worker to the Mailgun RESTful API. I never get to the Worker code executed due to the 405
mentioned above.
I did see someone mention that the onRequest
needs to be exported. I'm exporting the whole of the api
variable at the bottom of the file. Maybe I need Hono to do a specific build command?
Here's my one file located at /functions/api/contact.ts
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { logger } from 'hono/logger';
import {util, z} from 'zod';
import { zValidator } from "@hono/zod-validator";
import objectKeys = util.objectKeys;
type Bindings = {
MAILGUN_API_KEY: string;
MAILGUN_BASE_URL: string;
MAILGUN_SENDER_DOMAIN: string;
TURNSTILE_SECRET_KEY: string;
}
const api = new Hono<{ Bindings: Bindings }>().basePath('/api');
const formSubmission = z.object({
name: z.string(),
email: z.string().email(),
subject: z.string(),
body: z.string(),
"cf-turnstile-response": z.string(),
});
api.use('/*', logger());
api.use('/*', cors());
api.post('/contact', zValidator('form', formSubmission), async (c, next) => {
const secret = c.env.TURNSTILE_SECRET_KEY;
const ip = c.req.header('CF-Connecting-IP') || "";
const formValid = c.req.valid('form')
const token = formValid['cf-turnstile-response'];
const errors: {[key: string]: string[]} = {}
const requiredFields = ['name', 'email', 'subject', 'body'];
// Validate data from the form
// Generic validation to make sure required fields have some sort of non-empty value
// Shouldn't need this as the site is checking for empty values before sending the form data to this service
for (let field in formValid) {
if (requiredFields.includes(field)) {
const formKey = field as keyof typeof formValid;
if (formValid[formKey] === undefined || formValid[formKey] === null || formValid[formKey] === '') {
errors[field] = errors[field] || [];
errors[field].push('This field is required!');
}
}
}
// We have error(s)
if (Object.keys(errors).length > 0) {
// HTTP_400: Bad Request
return c.json(errors, 400);
}
// Validate Turnstile before Sending Email
if (! await validateToken(ip, token, secret)) {
// HTTP_400: Bad Request
return c.text('Invalid humanity check!', 400);
}
// console.log('Form Data', formData);
console.log('IP:', ip);
console.log('Errors', errors);
console.log('Form Valid', formValid);
return c.text('Email sent. Thank you for reaching out to us!');
});
async function validateToken(ip: string, token: string, secret: string) {
const formData = new FormData();
formData.append('secret', secret);
formData.append('response', token);
formData.append('remoteip', ip);
const url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
const result = await fetch(url, {
body: formData,
method: 'POST',
});
const outcome = await result.json();
return outcome.success;
}
export default api
Here's the output from my most recent build...
2024-09-13T21:00:47.364587Z Cloning repository...
2024-09-13T21:00:49.128534Z warning: redirecting to https://gitlab.com/anchorarm/website.git/
2024-09-13T21:00:49.129144Z From https://gitlab.com/anchorarm/website
2024-09-13T21:00:49.129263Z * branch e5c29d5a321f25622c7ce27408b0753bd7b10565 -> FETCH_HEAD
2024-09-13T21:00:49.129422Z
2024-09-13T21:00:49.188286Z HEAD is now at e5c29d5 Moved routes again (1)
2024-09-13T21:00:49.188841Z
2024-09-13T21:00:49.275746Z
2024-09-13T21:00:49.276365Z Using v2 root directory strategy
2024-09-13T21:00:49.300358Z Success: Finished cloning repository files
2024-09-13T21:00:51.036517Z Checking for configuration in a wrangler.toml configuration file (BETA)
2024-09-13T21:00:51.037145Z
2024-09-13T21:00:51.146803Z No wrangler.toml file found. Continuing.
2024-09-13T21:00:51.227567Z No build command specified. Skipping build step.
2024-09-13T21:00:51.228514Z Found Functions directory at /functions. Uploading.
2024-09-13T21:00:51.236126Z ⛅️ wrangler 3.60.1
2024-09-13T21:00:51.236367Z -------------------
2024-09-13T21:00:52.128881Z
2024-09-13T21:00:52.221308Z [31m✘ [41;31m[[41;97mERROR[41;31m][0m [1mNo routes found when building Functions directory: /opt/buildhome/repo/functions[0m
2024-09-13T21:00:52.221629Z
2024-09-13T21:00:52.221772Z
2024-09-13T21:00:52.225495Z 🪵 Logs were written to "/root/.config/.wrangler/logs/wrangler-2024-09-13_21-00-51_921.log"
2024-09-13T21:00:52.237394Z Warning: Wrangler did not find routes when building functions. Skipping.
2024-09-13T21:00:52.237776Z Found _routes.json in output directory. Uploading.
2024-09-13T21:00:52.250739Z Validating asset output directory
2024-09-13T21:00:54.118569Z Deploying your site to Cloudflare's global network...
2024-09-13T21:00:56.363975Z Uploading... (203/203)
2024-09-13T21:00:56.364728Z ✨ Success! Uploaded 0 files (203 already uploaded) (0.57 sec)
2024-09-13T21:00:56.364846Z
2024-09-13T21:00:56.620314Z ✨ Upload complete!
2024-09-13T21:00:58.756997Z Success: Assets published!
2024-09-13T21:01:00.097997Z Success: Your site was deployed!
Hi @BallisticPain,
I think that Hono does not use the /functions
folder since hono is in charge of route handling. The backend script is managed by generating a _worker.js
file (even in Cloudflare Pages environment).
See these topics :
We haven't heard any updates here in a while so I'm going to close this issue for now. If anyone is still running into problems feel free to open a new issue with more details and we can investigate further.
@BallisticPain I think in your specific case this is an issue with your Hono setup—you should be able to follow the guides that @chri70 linked to setup & deploy your site.
What version of
Wrangler
are you using?2
What operating system are you using?
Cloudflare Pages
Describe the Bug
Wrangler is not detecting functions routes, when deploying with Cloudflare Pgaes from github repo.
output below, when '/functions/api/contact.ts' function file exists.