Cloudflare recently announced static assets for workers.
You can now deploy static files with a worker, instead of shipping worker code in your Cloudflare Pages project.
This makes it possible to add things like websockets using durable objects which are not deployable via Cloudflare Pages.
Here are the steps to deploy a static site from scratch. You can follow along or find the code in GitHub.
Less patient users can run pnpm create cloudflare --experimental
and choose a static asset template as described in the docs.
These instructions assume that you already have node and pnpm.
mkdir minimal-static-site
cd minimal-static-site
pnpm install wrangler
You can choose your own worker name and content directory for assets.
#:schema node_modules/wrangler/config-schema.json
name = "minimal-static-site"
compatibility_date = "2024-09-25"
assets = { directory = "./content" }
The worker will serve all files in the assets directory on routes starting at the worker root.
Here is some sample HTML to get started. Use any HTML, CSS and JavaScript files you like. Everything in the content directory will be uploaded and served, including images.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<style>
body {
font-family: sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #255;
}
h1 {
color: orange;
font-size: 20vw;
padding: 0.5ch;
}
</style>
</head>
<body>
<h1>Helloπ Workers</h1>
</body>
</html>
$ pnpm wrangler deploy
β
οΈ wrangler 3.78.10
--------------------
π Building list of assets...
π Starting asset upload...
π Found 1 new or modified file to upload. Proceeding with upload...
+ /index.html
Uploaded 1 of 1 assets
β¨ Success! Uploaded 1 file (1.68 sec)
Total Upload: 0.34 KiB / gzip: 0.24 KiB
Uploaded minimal-static-site (9.81 sec)
Deployed minimal-static-site triggers (5.77 sec)
https://minimal-static-site.jldec.workers.dev
Current Version ID: d0ecd041-b9a3-4e89-b168-baa394567839
The result is live at minimal-static-site.jldec.workers.dev
Here are some suggestions for next steps:
For more thoughts about workers and assets, see Read-write Static Assets bindings for Cloudflare Workers.
{ "path": "/blog/building-a-static-site-with-cloudflare-workers", "attrs": { "title": "Building a mimimal static site with Cloudflare Workers", "layout": "BlogPostLayout", "splash": { "image": "/images/minimal-static-site.jldec.workers.dev.webp" }, "date": "2024-09-27" }, "md": "# Building a mimimal static site with Cloudflare Workers\n\nCloudflare recently announced [static assets](https://blog.cloudflare.com/builder-day-2024-announcements/#static-asset-hosting) for workers.\n\nYou can now deploy static files with a worker, instead of shipping worker code in your Cloudflare Pages project.\n\nThis makes it possible to add things like websockets using [durable objects](https://developers.cloudflare.com/durable-objects/) which are [not deployable](https://developers.cloudflare.com/workers/static-assets/compatibility-matrix/) via Cloudflare Pages.\n\n## DIY\n\nHere are the steps to deploy a static site **from scratch**. You can follow along or find the code in [GitHub](https://github.com/jldec/minimal-static-site).\n\nLess patient users can run `pnpm create cloudflare --experimental` and choose a static asset template as described in the [docs](https://developers.cloudflare.com/workers/static-assets/get-started/#1-create-a-new-worker-project-using-the-cli).\n\n### 1. Create an empty directory and install wrangler\nThese instructions assume that you already have [node](https://nodejs.org/) and [pnpm](https://pnpm.io/).\n```sh\nmkdir minimal-static-site\ncd minimal-static-site\npnpm install wrangler\n```\n\n### 2. Create wrangler.toml\nYou can choose your own worker name and content directory for assets.\n```toml\n#:schema node_modules/wrangler/config-schema.json\nname = \"minimal-static-site\"\ncompatibility_date = \"2024-09-25\"\nassets = { directory = \"./content\" }\n```\nThe worker will serve all files in the assets directory on [routes](https://developers.cloudflare.com/workers/static-assets/routing/) starting at the worker root.\n\n### 3. Create index.html in your content directory\nHere is some sample HTML to get started. Use any [HTML](https://developer.mozilla.org/en-US/docs/Web/HTML), [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS) and [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) files you like. Everything in the content directory will be uploaded and served, including [images](https://developer.mozilla.org/en-US/docs/Web/Media/images).\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <style>\n body {\n font-family: sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n margin: 0;\n background-color: #255;\n }\n h1 {\n color: orange;\n font-size: 20vw;\n padding: 0.5ch;\n }\n </style>\n </head>\n <body>\n <h1>Helloπ Workers</h1>\n </body>\n</html>\n```\n\n### 4. Ship it π’\n\n```txt\n$ pnpm wrangler deploy\n\n β οΈ wrangler 3.78.10\n--------------------\n\nπ Building list of assets...\nπ Starting asset upload...\nπ Found 1 new or modified file to upload. Proceeding with upload...\n+ /index.html\nUploaded 1 of 1 assets\nβ¨ Success! Uploaded 1 file (1.68 sec)\n\nTotal Upload: 0.34 KiB / gzip: 0.24 KiB\nUploaded minimal-static-site (9.81 sec)\nDeployed minimal-static-site triggers (5.77 sec)\n https://minimal-static-site.jldec.workers.dev\nCurrent Version ID: d0ecd041-b9a3-4e89-b168-baa394567839\n```\n\nThe result is live at [minimal-static-site.jldec.workers.dev](https://minimal-static-site.jldec.workers.dev)\n\n### What's next?\nHere are some suggestions for next steps:\n- Connect a [GitHub](https://developers.cloudflare.com/workers/ci-cd/builds/#get-started) repo.\n- Add a [custom domain](https://developers.cloudflare.com/workers/configuration/routing/custom-domains/).\n- Build your site with a [framework](https://developers.cloudflare.com/workers/frameworks/) like [Astro](https://developers.cloudflare.com/workers/frameworks/framework-guides/astro/).\n\n---\n_For more thoughts about workers and assets, see [Read-write Static Assets bindings for Cloudflare Workers](read-write-static-asset-bindings-for-cloudflare-workers)._", "html": "<h1>Building a mimimal static site with Cloudflare Workers</h1>\n<p>Cloudflare recently announced <a href=\"https://blog.cloudflare.com/builder-day-2024-announcements/#static-asset-hosting\">static assets</a> for workers.</p>\n<p>You can now deploy static files with a worker, instead of shipping worker code in your Cloudflare Pages project.</p>\n<p>This makes it possible to add things like websockets using <a href=\"https://developers.cloudflare.com/durable-objects/\">durable objects</a> which are <a href=\"https://developers.cloudflare.com/workers/static-assets/compatibility-matrix/\">not deployable</a> via Cloudflare Pages.</p>\n<h2>DIY</h2>\n<p>Here are the steps to deploy a static site <strong>from scratch</strong>. You can follow along or find the code in <a href=\"https://github.com/jldec/minimal-static-site\">GitHub</a>.</p>\n<p>Less patient users can run <code>pnpm create cloudflare --experimental</code> and choose a static asset template as described in the <a href=\"https://developers.cloudflare.com/workers/static-assets/get-started/#1-create-a-new-worker-project-using-the-cli\">docs</a>.</p>\n<h3>1. Create an empty directory and install wrangler</h3>\n<p>These instructions assume that you already have <a href=\"https://nodejs.org/\">node</a> and <a href=\"https://pnpm.io/\">pnpm</a>.</p>\n<pre><code class=\"language-sh\">mkdir minimal-static-site\ncd minimal-static-site\npnpm install wrangler\n</code></pre>\n<h3>2. Create wrangler.toml</h3>\n<p>You can choose your own worker name and content directory for assets.</p>\n<pre><code class=\"language-toml\">#:schema node_modules/wrangler/config-schema.json\nname = "minimal-static-site"\ncompatibility_date = "2024-09-25"\nassets = { directory = "./content" }\n</code></pre>\n<p>The worker will serve all files in the assets directory on <a href=\"https://developers.cloudflare.com/workers/static-assets/routing/\">routes</a> starting at the worker root.</p>\n<h3>3. Create index.html in your content directory</h3>\n<p>Here is some sample HTML to get started. Use any <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML\">HTML</a>, <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS\">CSS</a> and <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript\">JavaScript</a> files you like. Everything in the content directory will be uploaded and served, including <a href=\"https://developer.mozilla.org/en-US/docs/Web/Media/images\">images</a>.</p>\n<pre><code class=\"language-html\"><!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <style>\n body {\n font-family: sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n margin: 0;\n background-color: #255;\n }\n h1 {\n color: orange;\n font-size: 20vw;\n padding: 0.5ch;\n }\n </style>\n </head>\n <body>\n <h1>Helloπ Workers</h1>\n </body>\n</html>\n</code></pre>\n<h3>4. Ship it π’</h3>\n<pre><code class=\"language-txt\">$ pnpm wrangler deploy\n\n β οΈ wrangler 3.78.10\n--------------------\n\nπ Building list of assets...\nπ Starting asset upload...\nπ Found 1 new or modified file to upload. Proceeding with upload...\n+ /index.html\nUploaded 1 of 1 assets\nβ¨ Success! Uploaded 1 file (1.68 sec)\n\nTotal Upload: 0.34 KiB / gzip: 0.24 KiB\nUploaded minimal-static-site (9.81 sec)\nDeployed minimal-static-site triggers (5.77 sec)\n https://minimal-static-site.jldec.workers.dev\nCurrent Version ID: d0ecd041-b9a3-4e89-b168-baa394567839\n</code></pre>\n<p>The result is live at <a href=\"https://minimal-static-site.jldec.workers.dev\">minimal-static-site.jldec.workers.dev</a></p>\n<h3>What's next?</h3>\n<p>Here are some suggestions for next steps:</p>\n<ul>\n<li>Connect a <a href=\"https://developers.cloudflare.com/workers/ci-cd/builds/#get-started\">GitHub</a> repo.</li>\n<li>Add a <a href=\"https://developers.cloudflare.com/workers/configuration/routing/custom-domains/\">custom domain</a>.</li>\n<li>Build your site with a <a href=\"https://developers.cloudflare.com/workers/frameworks/\">framework</a> like <a href=\"https://developers.cloudflare.com/workers/frameworks/framework-guides/astro/\">Astro</a>.</li>\n</ul>\n<hr>\n<p><em>For more thoughts about workers and assets, see <a href=\"read-write-static-asset-bindings-for-cloudflare-workers\">Read-write Static Assets bindings for Cloudflare Workers</a>.</em></p>\n" }