NodeJS + React App Hosting
I am brand new to Cloudflare and Web Development in general, so apologize if this question is quite elementary in nature. I have a full stack app whose directory structure looks like this:
app
|-client
|–all client code files (including webpack.config.js)
|-server
|–all server code files (including routes.ts)
Running npm run build inside both the client and server folder, I got client-dist and server-dist folders. I repackaged these specific folders into a big dist folder and deployed using Cloudflare Pages. However, while the React frontend is running just fine, the Node Express Backend server code isn’t. When the enduser submits a request, the server throws a 404 error, with the api endpoint not being found. How can I correctly deploy the server as well? The docs mention something about functions - how do I deploy a node express code into a functions folder?
#workers-help #pages-help
19 Replies
Functions/Workers can't run express, although they can do server side logic
?pages-webserver
Cloudflare Pages is for static content (HTML, CSS, JS, images and other such files). It will not run a webserver such as Express, Koa or the likes. If you're using those to serve static content then you can just remove that part and use Pages!
If you're doing more dynamic content you can use Functions. It will run code on request (so still not a webserver in the conventional sense). This would allow for more dynamic content though especially with KV (Key/Value storage) and Durable Objects (transactional data storage). Functions are natively integrated with Pages so are super easy to get up and running along your website.
Otherwise, a good old VPS or dedicated server from one of the many hosts out there is for you.
@Chaika Thanks! So my server/dist after running
npm run build
folder looks like this:
index.js
routes.js
My routes.js includes the functions to run and my index.js creates the api endpoints as follows:
How can I make this into a Functions call?You can't run Express on Functions
Functions are Cloudflare Workers with some extra stuff like file path based routing included. Workers/Functions run as V8 Isolates (same Javascript engine as Chromium, notably not node.js), and they are spun up per incoming request/just handed it. They are not long running, can't listen on ports, etc.
I understand, how can I convert though?
Sorry, I am a newbie
You'd have to switch to using functions plain or using a framework. Hono is a web framework for Pages/Workers which is close to Express: https://developers.cloudflare.com/pages/framework-guides/deploy-a-hono-site
Cloudflare Docs
Hono | Cloudflare Pages docs
Hono ↗ is a small, simple, and ultrafast web framework for Cloudflare Pages and Workers, Deno, and Bun. In this guide, you will create a new Hono application and deploy it using Cloudflare Pages.
Ok, so start from scratch 😦
and rewrite the entire server-side code
There is no easier way?
yes, although looking at that hono tutorial now it's a bit eh and started a bit high level, I would probably start with just the native stuff: https://developers.cloudflare.com/pages/functions/get-started/
Cloudflare Docs
Get started | Cloudflare Pages docs
This guide will instruct you on creating and deploying a Pages Function.
Some of your code can be ported over, basic JS stuff, just none of the request handling stuff directly, and you'd have to be careful about packages, ones that depend directly on file system existing, or are large (1 mb limit for all deps + code on free) just won't work
If you don't want to get tied into Cloudflare's platform you could always host your Express web server somewhere else like AWS and just take advantage of Page's free and unlimited static asset serving
or use a nice framework like Astro which lets you do stuff more platform agnostic
How would I connect another provider's server with cloudflare?
You'd just have your client side code call your express web app. If you're using CF DNS you can just point a DNS record at it, or if that platform is more managed and offers you a url like pages does, can use that
it'd be all client-side fetches from the react frontend on Pages in your case
Ok. I will study more and let you know if I have any more questions.
Thanks for the help
@Chaika Actually another question: Can the python-cloudflare library be used to set environment variables and deploy pages from a local file directory and .env file?
Let me know if this should be a different thread.
The python-cloudflare library is just for directly accessing the Cloudflare API.
If you want to deploy a folder from a cli tool, you can use wrangler and wrangler pages deploy: https://developers.cloudflare.com/pages/get-started/direct-upload/
Cloudflare Docs
Direct Upload | Cloudflare Pages docs
Upload your prebuilt assets to Pages and deploy them via the Wrangler CLI or the Cloudflare dashboard.
It's not going to read env though, would still have to configure those in the dashboard directly
Pages does support wrangler.toml files which you can specify (non-secret) envirnoment variables in: https://developers.cloudflare.com/pages/functions/wrangler-configuration/#environment-variables but that gets complex quickly, would recommend just using dashboard for now
So just to clarify, wrangler does not support secret variables I want to hide from user?
Also, in many html files I 've seen <script src=cdn...>. How do I make my react app into that script source using the results of npm run build?
From the user? Wrangler supports Pages secrets yea
wrangler pages secret put <KEY> [OPTIONS]
same way you can add them from the dash. Environment variables secret or not wouldn't be directly exposed to the user eitherway though
that's not really a question that makes sense. If your app currently builds fine and you upload it all to pages and it works, you're goodI asked this question because you wrote "Pages does support wrangler.toml files which you can specify (non-secret) envirnoment variables in: "
I thought all env variables were secret
they're all encrypted and not visible to the user, but secrets vs normal env vars cannot be seen later via the dashboard, can only be accessed through build env/pages function, just an extra layer of protection
your wrangler.toml as well is intended to be able to be commited to source control (be public), so you can specify non-secret env vars inside of it and then have actual secrets like api keys be secrets not in the file
@Chaika Sorry if this is in the Function docs, but I couldn't find it so I am asking: can I import node modules in the function/route.js file?