Skip to content
Meeko
Type to search the guides and the API reference. Open it from any page with / or Ctrl K; move with the arrow keys and open a result with Enter.
Get started

Contents

On this page

createCloudflareAssetReader

Serves only build files listed in the manifest from Cloudflare's Static Assets binding, with the ETag, HEAD, 304 and caching behavior of the other adapters.

adapter Since 1.0.0 @meekojs/meeko/cloudflare Source code
ts
import { createCloudflareAssetReader } from "@meekojs/meeko/cloudflare";

createCloudflareAssetReader({ binding, assets }) is the public file reader for Workers. Meeko's generated wrangler.jsonc declares assets with run_worker_first: true and html_handling/not_found_handling set to "none", so all requests reach the Worker; this reader only responds to paths in the build's asset manifest, reading them from the ASSETS binding, and returns null for all others.

This lets a Worker serve files with the same rules as Node, Bun and Deno: nothing outside the manifest, the same ETag and the same cache policy.

Usage#

ts
import { createCloudflareAssetReader, createWorker } from "@meekojs/meeko/cloudflare";
import type { CloudflareAppContext } from "@meekojs/meeko/cloudflare";

function createCloudflareApp({ env, platform }: CloudflareAppContext<Env>) {
  return createApp({
    production: true,
    platform,
    assets: createCloudflareAssetReader({ binding: env.ASSETS, assets: manifest.assets ?? {} }),
  });
}

export default createWorker(createCloudflareApp);

Type#

ts
function createCloudflareAssetReader(options: CloudflareAssetReaderOptions): AssetReader

CloudflareAssetReaderOptions

ts
interface CloudflareAssetReaderOptions {
	readonly binding: CloudflareAssetsBinding
	readonly assets: AssetManifest
}

CloudflareAssetsBinding

ts
interface CloudflareAssetsBinding {
	fetch(request: Request): Promise<Response>
}

AssetReader

ts
interface AssetReader {
	get(pathname: string, request: Request): Promise<Response | null>
}

Parameters#

Option Type Description
binding CloudflareAssetsBinding The Static Assets binding, usually env.ASSETS: an object with fetch(request).
assets AssetManifest Public paths with their type, etag, size and immutable.

Return value#

An AssetReader with get(pathname, request): null for a path not in assets or a method other than GET or HEAD; 304 if If-None-Match matches, without reading the binding; 200 with the binding's body, content-type, ETag, content-length and cache-control (immutable for one year for hashed files, max-age=0, must-revalidate for the rest).

Examples#

The output of meeko build --adapter cloudflare#

texto
.meeko/output/cloudflare/
  worker.js            ← createWorker and the room class, a single module
  wrangler.jsonc       ← assets: { directory: "./assets", binding: "ASSETS", run_worker_first: true }
  assets/              ← client build and public/
  assets/_meeko/prerender/  ← prerendered pages, which the Worker reads and never serves as files

Checking that a build file is not public#

sh
curl -s -o /dev/null -w "%{http_code}\n" https://mi-app.example/_meeko/prerender/manifest.json   # 404
curl -s -o /dev/null -w "%{http_code}\n" https://mi-app.example/worker.js                         # 404

Common mistakes#

A listed file missing from assets#

Incorrecttexto
assets/ uploaded without the assets/assets/ directory (a partial deployment)

get rejects with Error: Missing build asset /assets/entry-4f2a.js; the application responds with 500 and sends it to onError. Deploy the complete output folder with wrangler deploy --config .meeko/output/cloudflare/wrangler.jsonc.

Correctsh
npx wrangler deploy --config .meeko/output/cloudflare/wrangler.jsonc

A public/_meeko/#

Incorrecttexto
public/_meeko/logo.svg

The assets' _meeko/ is reserved for prerendered pages: meeko build --adapter cloudflare stops with public/_meeko está reservado para la salida de Cloudflare de Meeko; cámbiale el nombre.

Correcttexto
public/brand/logo.svg

Changing assets in server.wrangler#

Incorrectts
server: { adapter: "cloudflare", wrangler: { assets: { directory: "./public", not_found_handling: "single-page-application" } } }

meeko build --adapter cloudflare stops with TypeError: server.wrangler.assets is generated by Meeko and cannot be overridden (the same applies to main, no_bundle and find_additional_modules): the Worker must see every request to apply the manifest, sessions and CSP.

Correctts
server: { adapter: "cloudflare", wrangler: { routes: [{ pattern: "mi-app.example", custom_domain: true }] } }

Notes#

  • Security. Paths are looked up in the manifest without decoding, and the URL requested from the binding comes from the manifest key, never from the request.
  • Cost. With run_worker_first, each file is a Worker invocation; hashed files carry immutable, and Cloudflare's CDN and the browser cache them for a year.
  • CSP and headers (since 1.7). server.headers also applies to these files, except headers they already carry, such as Cache-Control.

Was this page helpful?

Add a comment

It is sent when you choose “Yes” or “No”. Only the page, your answer and the comment are stored: no cookies and no personal data.

0 of 2000 characters

Edit on GitHub: docs/en/reference/adapters/createcloudflareassetreader.md