{"id":15681335,"url":"https://github.com/genaker/cloudflare_fpc_worker","last_synced_at":"2026-03-03T08:24:51.979Z","repository":{"id":255607921,"uuid":"852538049","full_name":"Genaker/CloudFlare_FPC_Worker","owner":"Genaker","description":"CloudFlare CDN Edge Worker Full Page Cache(FPC) Microservice Layer for Magento 2, ORO Commerce and Shopify and other platforms","archived":false,"fork":false,"pushed_at":"2025-02-08T20:57:07.000Z","size":304,"stargazers_count":37,"open_issues_count":1,"forks_count":10,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-21T14:09:24.510Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Genaker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-05T01:27:33.000Z","updated_at":"2025-03-22T12:51:45.000Z","dependencies_parsed_at":"2024-09-06T09:26:13.068Z","dependency_job_id":"88dbeac7-269f-4121-b38c-0dafe04644cc","html_url":"https://github.com/Genaker/CloudFlare_FPC_Worker","commit_stats":null,"previous_names":["genaker/cloudflare_fpc_worker"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Genaker%2FCloudFlare_FPC_Worker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Genaker%2FCloudFlare_FPC_Worker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Genaker%2FCloudFlare_FPC_Worker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Genaker%2FCloudFlare_FPC_Worker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Genaker","download_url":"https://codeload.github.com/Genaker/CloudFlare_FPC_Worker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251352638,"owners_count":21575865,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T16:52:52.441Z","updated_at":"2026-03-03T08:24:51.973Z","avatar_url":"https://github.com/Genaker.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"CloudFlare(CF) CDN Worker Full Page Cache(FPC) Layer for Magento 2.\nIt has become true. Now, it is Open Source and free. \nThe original idea was the Shopify FPC cache from the CloudFlare CDN, AWS Cloud Front Lambda Edge S3 Buket, Akamai EdgeWorkers with Object Storage etc. and it is a part of our true Magento SaaS solution(Magneto)\n\n![image](https://github.com/user-attachments/assets/1dcb535e-3d0d-4e0a-b399-9f331807420d)\n\n# Deployment\n\nYou can deploy the worker in several ways:\n\n## Deploy via Cloudflare Dashboard (Quick Start)\n\n1. Create a Worker in Cloudflare Dashboard → Workers \u0026 Pages → Create Worker\n2. Edit Code → Insert Code from Git → Connect to `https://github.com/Genaker/CloudFlare_FPC_Worker`\n3. Configure KV binding and deploy\n4. Add a route for your domain (e.g. `*yoursite.com/*`)\n\nSee the [Installation](#installation) section below for detailed steps.\n\n## Deploy via Wrangler CLI\n\nIf you use Wrangler:\n\n```bash\ngit clone https://github.com/Genaker/CloudFlare_FPC_Worker.git\ncd CloudFlare_FPC_Worker\nnpm install\ncp wrangler.toml.example wrangler.toml   # if available\n# Edit wrangler.toml with your KV namespace and account ID\nnpx wrangler deploy\n```\n\n## Deploy via CI/CD (GitHub Actions, etc.)\n\nYou can add the worker to your CI pipeline. Example GitHub Actions step:\n\n```yaml\n- name: Deploy Cloudflare Worker\n  run: |\n    npm install -g wrangler\n    wrangler deploy\n  env:\n    CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}\n    CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}\n```\n\nStore your secrets in the repository settings and ensure your `wrangler.toml` has the correct KV namespace binding.\n\n## Deploy via Terraform\n\nUse the [cloudflare Terraform provider](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs) to deploy the worker as infrastructure-as-code:\n\n```hcl\nterraform {\n  required_providers {\n    cloudflare = {\n      source  = \"cloudflare/cloudflare\"\n      version = \"~\u003e 4.0\"\n    }\n  }\n}\n\nvariable \"cloudflare_account_id\" {}\nvariable \"cloudflare_api_token\" {}\n\nprovider \"cloudflare\" {\n  api_token = var.cloudflare_api_token\n}\n\nresource \"cloudflare_workers_kv_namespace\" \"fpc_kv\" {\n  account_id = var.cloudflare_account_id\n  title      = \"fpc-cache\"\n}\n\nresource \"cloudflare_worker_script\" \"fpc\" {\n  account_id = var.cloudflare_account_id\n  name       = \"magento-fpc\"\n  content    = file(\"${path.module}/FPC.js\")\n\n  kv_namespace_binding {\n    name         = \"KV\"\n    namespace_id = cloudflare_workers_kv_namespace.fpc_kv.id\n  }\n}\n\nresource \"cloudflare_worker_route\" \"fpc_route\" {\n  zone_id     = var.cloudflare_zone_id\n  pattern     = \"*yoursite.com/*\"\n  script_name = cloudflare_worker_script.fpc.name\n}\n```\n\nRun `terraform init`, `terraform plan`, then `terraform apply`. Ensure `FPC.js` and any required files are in the Terraform module path.\n\n## Deploy via Python (cloudflare Python SDK)\n\nUse the [cloudflare Python package](https://github.com/cloudflare/cloudflare-python) to deploy programmatically:\n\n```python\nfrom cloudflare import Cloudflare\n\napi = Cloudflare(api_token=\"YOUR_API_TOKEN\")\naccount_id = \"YOUR_ACCOUNT_ID\"\n\n# Read worker script\nwith open(\"FPC.js\", \"r\") as f:\n    script_content = f.read()\n\n# Create or update worker\napi.workers.scripts.upload(\n    account_id=account_id,\n    script_name=\"magento-fpc\",\n    body={\"script\": script_content},\n)\n\n# Add KV binding (create namespace first via API or dashboard)\n# api.workers.scripts.settings.update(...)\n```\n\nInstall: `pip install cloudflare`. For full deployment including KV bindings and routes, use the Workers API endpoints for [Workers Scripts](https://developers.cloudflare.com/api/operations/worker-scripts-upload-worker), [KV Namespaces](https://developers.cloudflare.com/api/operations/workers-kv-namespace-create-namespace), and [Worker Routes](https://developers.cloudflare.com/api/operations/worker-routes-create-route).\n\n# How it works\nThe Edge Worker Magento full-page cache feature helps you optimize eCommerce performance by caching your Magento backend server's generated HTML or API response. \n\n# Integration Jest tests\nAll functionality is covered with the Jest integration tests. You can test your website and you rule as well. \nRunning the test:\n```\nexport TEST_URL=\"https://******.com/\"\nnpm install\nnpm test\n```\n\n## Run integration tests with Docker\n\n```bash\nTEST_URL=https://yoursite.com/ docker compose run --rm fpc-tests\n```\n\n## Unit tests (Vitest + Miniflare)\n\nUnit tests run locally without a live site. They use Miniflare to emulate the Cloudflare Workers runtime.\n\n```bash\nnpm run test:unit\n```\n\nOr with Docker:\n\n```bash\ndocker compose run --rm fpc-unit\n```\n\n# Generate static HTML objects \nRun next command\n```\nnode generate.js\n```\n\n# HTML CACHE VERSION\nCF Edge Worker Magent Full-page cache intercepts incoming requests and checks if a cached version of the requested content is available in the CloudFlare locations or in the cache Reserve. This check for the cached version can have the following outcomes, depending on its state:\n\n - If a cached version is found and it's not stale, then the cached content is served to the user. No request is made to the Magento Server.\n - If a cached version is found and it is stale, then the cached content is served to the user. The CF worker is executed in the background and requests a new version of the page caches from the Magento backend server for future requests. CF FPC is revalidated from the server asynchronously after 5 minutes or so, but you can change the time and logic.\n - If a cached version isn't found, the CF FPC worker sends a request to the Magento server to be used for future requests.\n\nCF Worker “softpurge” the cache by changing cache Version stored in the KV(Key Value)storage. Cloud flare serve the stale content untill it will not be updayed asynchronously (in the background) fetches the new page. Cloud Front ignores any cache rules from Magento and has own logic which serve web pages from the CDN cache even if Magento 2 website is broken. \n\u003cbr/\u003e\nNow, you can set *HTML_CACHE_VERSION* via the Cloud Flare dashboard by adding the variable **ENV_HTML_CACHE_VERSION**. It will override the default cache version logic and can't be purged except to set a new version from the dashboard.\n\u003cimg width=\"401\" alt=\"image\" src=\"https://github.com/user-attachments/assets/0da62145-fe10-4b05-9fb6-23c12780567d\"\u003e\n\n# ENV VARIABLES\nYou can override many variables by setting the from the dashboard by adding **ENV_** prefix to the var name:\n![image](https://github.com/user-attachments/assets/6fdc73d8-fe6e-41ad-ba7e-abc88aa1e12d)\n\n# Worker GET parameters:\n\n- **\u0026cfw=false** - disable Cloud worker, bypass all worker logic \n- **\u0026cf-cdn=false** - bypass Cloud Flare EDGE CDN cache, but R2 cache still works\n- **\u0026r2-cdn=false** - bypass R2 cache\n- **\u0026cf-revalidate=true** - revalidate URL in the cache\n- **\u0026cf-delete=true** - delete from the edge cache but not from R2\n- **\u0026cf-purge** - purge entire cache by changing cache version. called ONCE(1) - soft purge. TWICE(2) - hard purge. \n\n# Speculative Rules\nSpeculation is added to the worker response.\n\nTo Debug speculative rules, go to **DevTools** → Application → Speculative Load → Speculation:\n![image](https://github.com/user-attachments/assets/9a14a6fe-9f5b-490d-a78e-a85d8d1eae40)\n\n\n# Caching criteria\nFor CF FPC Worker to consider a response from a Magento backend as cacheable, the response must meet the following criteria:\n\n - Be a response to a GET request\n - Have a 2XX or 3XX status code.\n - Have a public Cache-Control header set with a non-zero max-age, or s-maxage, value\n - Url doesn't match the worker's blacklist\n\n# Aditional features\n- URL Query String Filtering and sorting \n- Traffic filtering and control\n- Cache logic adjustment. You don't need any VCL now you can do everething in pure JavaScript\n- Content manipulation\n- Speculation rules prerender and prefetch\n- Link header resource preload\n- Custom CORS\n- ESI (Edge Server Include - AJAX requests) blocks with auth and HTTPS support. Easy to use with microservices.\n- GOD MOD - cache can't be invalidated. It can be but not easy.\n- PWA installable APP \n\n# R2 and Cache Reserve\n\nWhen R2 is configured (Ultra version), the worker can store and serve cached content from Cloudflare R2. This provides a persistent cache layer beyond the edge. The worker races R2 and the origin — whichever responds first is served. When the origin wins, the response is marked as `server-first` or `r2-null-server` in the `R2-cache` header. Both outcomes are valid; the cache is updated asynchronously.\n\nCache Reserve uses R2 under the hood and integrates with the worker for higher hit rates. Enable Cache Reserve in the Cloudflare dashboard to improve cache persistence.\n\n# Worker and CF cache limitations:\n - The full-page cache is designed to work with the default magento cache, which is PHP Built-in FPC, FAST FPC (See repo: https://github.com/Genaker/FastFPC), or Varnish. You can try to use it as a main cache (see Cache Reserve), but it is not what it was designed for. ***The main idea of the CF Worker FPC Cache is Magento 2 pages are always served from the CF cache with async revalidation.**\n - You can't clear the cache by page. You can clear the entire cache only. That is why you need a default magento cache. However, it is designed to work without any cache clears. The worker will update it asynchronously. You mark the entire cache stale by changing its version. To hard clear the cache, you need to change the version twice. CF Worker checks the previous cache version to see if it is a stale cache.\n\n## Installation\n\n**Navigation:** Cloudflare Dashboard → **Workers \u0026 Pages** (or go to [dash.cloudflare.com](https://dash.cloudflare.com) and select Workers \u0026 Pages from the sidebar).\n\n![image](https://github.com/user-attachments/assets/9366da1d-8c40-4d38-9834-7f16f9805c3b)\n\nIt is better to Upgrade the plan to a Bundle of 5$ per month. It is better and has no limitations.\n\n![image](https://github.com/user-attachments/assets/51a1cbc3-0089-4b2b-bd3a-4ddf2ec35f55)\n\nBundle: \n![image](https://github.com/user-attachments/assets/9bcbee80-fe05-47a9-a075-6c9f5ee73c32)\n\nWorkers features\nIncludes 10 million requests per month 3\n\nUp to 50ms CPU time per request\nAlways lowest latency\nKey-value storage features 4\n10 million read operations per month\n1 million write, delete, list operations per month\n\n# Create KV (KeyValue) Storage to keep the cache version and some global settings \n\n![image](https://github.com/user-attachments/assets/243248a6-1a90-4a66-a569-3561f94e3df7)\n**Path:** Workers \u0026 Pages → **KV** → Create a namespace. (Alternatively: create the Worker first, then add a KV binding under Settings → Bindings; you can create a new namespace from there.) \n![image](https://github.com/user-attachments/assets/c1ec9f72-e60f-4a38-9f14-38439f3b8528)\n\n\n# Create Worker \n\n**Path:** Workers \u0026 Pages → **Create** (or **Create application**) → Create Worker. If using Git: choose **Clone and bootstrap a public repository** and enter `https://github.com/Genaker/CloudFlare_FPC_Worker`, then Deploy.\n\n![image](https://github.com/user-attachments/assets/1f9b47eb-e5b7-473b-9d0f-f226f836cf97)\n\n![image](https://github.com/user-attachments/assets/9ccc8bb9-2279-40bf-ab15-6a04029db33f)\n\n# Insert CF Worker FPC Code from The repo \n![image](https://github.com/user-attachments/assets/bc2f608f-5df0-46cf-98c6-641bf785bca7)\n**Path:** Edit Code → **Insert Code from Git** (or Connect to Git). Connect to `https://github.com/Genaker/CloudFlare_FPC_Worker`. If you created the worker from the Git repo in the previous step, skip this. \n\n![image](https://github.com/user-attachments/assets/5a39b35a-3b21-4f53-963d-7678b47b40f4)\n\n\n# Configure Worker\n**Path:** Your Worker → **Settings** → **Variables and Secrets** (for ENV vars) and **Settings** → **Bindings** (for KV).\n![image](https://github.com/user-attachments/assets/3ba61a60-1f19-488a-903e-88416054911e)\n\n![image](https://github.com/user-attachments/assets/ccb4ba67-bc60-492e-a6d7-99ac6cdf983b)\n\n![image](https://github.com/user-attachments/assets/1d8955ec-a08f-44a6-a4fb-e0c0a46fc600)\n\n![image](https://github.com/user-attachments/assets/3b27e50d-40c8-4b1c-872a-671b863d515e)\n\nWorker *Variable name* must be **KV**. KV name doesn't matter (Select from the drop-down) \u003cbr/\u003e\n**R2** storage is not available in the open source version, only in the ***Ultra*** Version. Please contact for more details.  \u003cbr/\u003e\n\nNOTE: OTHER_HOST is not required settings \n\n![image](https://github.com/user-attachments/assets/8500a84b-931d-448f-9a7c-578e109399a4)\nConfigure the **OTHER_HOST** variable with your actual domain (e.g. `www.yoursite.com`) to test the worker through the worker domain. This replaces the worker domain with your staging or prod domain so responses are fetched from your Magento server. This variable is not required for production. \n\nNOTE: OTHER_HOST is not required settings \n\n\n# Set your website route and worker to trigger:\n**Path:** Your Worker → **Settings** → **Triggers** (or **Routes**). Add route pattern e.g. `*yoursite.com/*` or `yoursite.com/*` (replace with your domain).\n\n![image](https://github.com/user-attachments/assets/405b8681-ed58-470f-8627-d5cde01f3dfc)\n\n![image](https://github.com/user-attachments/assets/da91073b-7982-4b12-8b2a-b0fb92424168)\n\n![image](https://github.com/user-attachments/assets/0d410e59-41bf-4a58-9d4e-4b62ca107b43)\n\n\nDone! Test it using Dev Console. \n\n![image](https://github.com/user-attachments/assets/7545b416-b5e5-4f3e-82c2-142e7edb2522)\n\nYou can also exclude some page rules, such as static and media, from workers. It will save money on request. \n\n![image](https://github.com/user-attachments/assets/2b6efc70-99ae-49a7-bbba-3eb4f174e636)\n\nAlso, Enable CF Cache Reserve to increase edge cache HIT rate. To reduce CF costs, you can exclude media and static from the cache reserve. However, cache reserve is a nice stuff, and you can benefit from storing images in it. \n\n![image](https://github.com/user-attachments/assets/0c1bc4df-483e-45c8-b3a2-44cfe6dab817)\n\nDisable Cloudflare Cache for Static and Media; save and serve from the **Cache Reserve** \u003cbr/\u003e\n**Path:** Select your domain (zone) → **Caching** → **Cache Rules**\n![image](https://github.com/user-attachments/assets/bb3cca02-d45e-4f2b-bf5a-18bfee851c46)\n\nAdd Rule \n\n![image](https://github.com/user-attachments/assets/24233c85-4a75-4462-b78c-2bd3c91f4b11)\nExpression : \n\n```\n(http.request.full_uri wildcard \"*.yoursite.com/static/*\") or (http.request.full_uri wildcard \"*.yoursite.com/media/*\")\n```\nReplace **yoursite** with your domain. \u003cbr/\u003e\n\nPlease update this documentation when you will do it yourself. It is just a fast-written manual. \nFor detailed information, check the Worker code. \n\nIf you have any issues, create an issue or email me: egorshitikov[A]gmail.com\n\n# Magento extension \n\nWe also developed a Magento Extension designed to enhance communication and performance between CF Workers and the cache system. \u003cbr\\\u003e\nWhile this extension is not yet publicly available, feel free to contact me directly if you’re interested in receiving it.\n\n# Cache Debug Cockies\nYou can add any cookies you want just by changing the script.\n\n# Default Cookies: \n![image](https://github.com/user-attachments/assets/cdc29850-b8cf-4549-ad73-6b494927931a)\n\n# Cloud Flare Default cookies: \n\n![image](https://github.com/user-attachments/assets/94f38f9f-1fa1-4119-96ef-1ffa4c7867b2)\n\n# Cache Reserve \n\nCache Reserve is a large, persistent data store implemented on top of CF R2. Your website’s cacheable FPC content will be written to Cache Reserve. Cache Reserve serves as the ultimate upper-tier cache, reserving storage space for your FPC for as long as you want. This ensures that your FPC is served from the cache. Cache Reserve is a CF feature that allows the use of Claud Flare as a main cache solution. \n\n![image](https://github.com/user-attachments/assets/e8facd2a-0240-4c69-941d-8dd04b18055c)\n\nLike the standard CDN, Cache Reserve also uses the cf-cache-status header to indicate cache statuses like MISS, HIT, and REVALIDATED. Cache Reserve cache misses and hits are factored into the dashboard’s cache hit ratio.\n\nIndividual sampled requests that were filled or were served by Cache Reserve are viewable via the CacheReserveUsed Logpush field.\n\nCache Reserve monthly operations and storage usage are viewable in the dashboard.\n\n# Statistic\n\nWith the CF FPC Workers, you can achieve 91%+ page cache rate from CDN\n\n![image](https://github.com/user-attachments/assets/481cf2a3-bb7a-477f-a2cf-a014123a3643)\n\n# Test \nOpen the page. Check **Cf-Cache-Status** header.\n![image](https://github.com/user-attachments/assets/859734b2-4aa1-489c-b16a-56dbd8b4481c)\n\n![image](https://github.com/user-attachments/assets/4a37c78f-08a4-4572-94b4-d5ee0d4535d9)\n\nTiming: Server response time must be less than 60ms. \n![image](https://github.com/user-attachments/assets/5d20a929-e2c3-4a42-9adf-7f703c9a2a2b)\n\n\n# Verification and Troubleshooting\n\n**Check cache status:** Open DevTools → Network, select a request, and look at the response headers. `Cf-Cache-Status: HIT` means the page was served from cache. `DYNAMIC` or `MISS` means it was fetched from the origin.\n\n**Worker debug headers:** The worker adds `x-html-edge-cache-status`, `x-html-edge-cache-version`, `worker-time`, and `js-time` headers. Use these to verify the worker is running and to debug cache behavior.\n\n**Bypass worker for testing:** Add `\u0026cfw=false` to any URL to bypass the worker and compare behavior.\n\n**R2 race:** When using `cf-cdn=false`, responses can come from R2 or from the origin (race). If you see `R2-cache: server-first` or `r2-null-server`, the origin responded first — this is normal. The cache is updated asynchronously.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgenaker%2Fcloudflare_fpc_worker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgenaker%2Fcloudflare_fpc_worker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgenaker%2Fcloudflare_fpc_worker/lists"}