{"id":15715732,"url":"https://github.com/drsensor/safe-html-rewriter","last_synced_at":"2026-01-20T14:34:22.532Z","repository":{"id":65768166,"uuid":"598531726","full_name":"DrSensor/safe-html-rewriter","owner":"DrSensor","description":"Safe (fault-tolerant) wrapper around https://github.com/cloudflare/html-rewriter-wasm","archived":false,"fork":false,"pushed_at":"2023-03-25T13:09:35.000Z","size":29,"stargazers_count":1,"open_issues_count":5,"forks_count":0,"subscribers_count":2,"default_branch":"trunk","last_synced_at":"2025-04-06T07:53:03.668Z","etag":null,"topics":["cloudflare","html","lol","rewriting","worker","workers"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DrSensor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2023-02-07T09:58:08.000Z","updated_at":"2023-12-25T09:40:52.000Z","dependencies_parsed_at":null,"dependency_job_id":"1db2fe61-5779-48d3-9f84-51fbb14bff0f","html_url":"https://github.com/DrSensor/safe-html-rewriter","commit_stats":{"total_commits":17,"total_committers":1,"mean_commits":17.0,"dds":0.0,"last_synced_commit":"6ace95957149e325a8fc4c2eb4f0d9d9073edc8b"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrSensor%2Fsafe-html-rewriter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrSensor%2Fsafe-html-rewriter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrSensor%2Fsafe-html-rewriter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrSensor%2Fsafe-html-rewriter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DrSensor","download_url":"https://codeload.github.com/DrSensor/safe-html-rewriter/tar.gz/refs/heads/trunk","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247611434,"owners_count":20966528,"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":["cloudflare","html","lol","rewriting","worker","workers"],"created_at":"2024-10-03T21:42:35.336Z","updated_at":"2026-01-20T14:34:22.502Z","avatar_url":"https://github.com/DrSensor.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# safe-html-rewriter\nSafe (fault-tolerant) wrapper around [WebAssembly version of Cloudlflare HTMLRewriter][html-rewriter-wasm][^1]\n\n```ts\nimport { HTMLRewriter, type RewriterHandlers } from \"npm:safe-html-rewriter\";\nimport { expandGlob } from \"https://deno.land/std/fs/mod.ts\";\n\nconst rewrite = new HTMLRewriter();\n\nconst handler = {\n  element(el) { el.remove() }\n} satisfies RewriterHandlers\n\nfor await (const { path } of expandGlob(\"your/index.{html,njk,jinja,tmpl}\")) {\n  const content = await Deno.readTextFile(path);\n\n  rewrite.on('script[src*=\"unwanted-script\"]', handler); // share same handler\n\n  rewrite.on('link[rel=\"stylesheet\",href*=\"unwanted-css\"]', { // single selector with many handlers\n    element(el) {\n      el.remove()\n      console.log(`remove ${el.getAttribute(href)} from ${path}`)\n      console.log(\"--------------------------------------------\")\n      console.log(content)\n      console.log(\"--------------------------------------------\")\n    }\n  });\n\n  const output = await rewrite.transform(content);\n  console.log(\"\\n\", path);\n  console.log(\"-------------------------------------------------------------\");\n  console.log(output);\n  console.log(\"-------------------------------------------------------------\");\n}\nrewrite.off('script[src*=\"unwanted-script\"]', handler); // only remove specific handler\nrewrite.off('link[rel=\"stylesheet\",href*=\"unwanted-css\"]'); // remove all handlers for specific selector\n\nrewrite.free(); // remove all handlers and free memory\n```\n\n[^1]: https://developers.cloudflare.com/workers/runtime-apis/html-rewriter/\n\n## Why?\n[html-rewriter-wasm][] designed to operate on per-chunk basis which is suitable for streaming response.\nHowever, it can be [tricky](https://github.com/cloudflare/html-rewriter-wasm#caveats) when you use it in non-streaming response.\nFor example, adding another handler after calling `rewriter.write` will give an error.\nThis package solve that and also give you an easier API.\n\n[html-rewriter-wasm]: https://github.com/cloudflare/html-rewriter-wasm\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrsensor%2Fsafe-html-rewriter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrsensor%2Fsafe-html-rewriter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrsensor%2Fsafe-html-rewriter/lists"}