{"id":30936133,"url":"https://github.com/humanspeak/svelte-purify","last_synced_at":"2026-05-03T22:33:18.123Z","repository":{"id":313819110,"uuid":"1052747104","full_name":"humanspeak/svelte-purify","owner":"humanspeak","description":"DOMPurify-powered HTML sanitizer for Svelte — SSR-safe, browser-ready, TypeScript-first.","archived":false,"fork":false,"pushed_at":"2025-10-23T20:52:26.000Z","size":652,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-23T22:26:37.221Z","etag":null,"topics":["browser-only","dompurify","frontend","html-sanitizer","runes","safe-html","sanitization","sanitize","security","ssr","svelte","svelte-component","svelte-library","svelte5","sveltekit","typescript","vite","web-security","xss"],"latest_commit_sha":null,"homepage":"https://purify.svelte.page","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/humanspeak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["humanspeak"]}},"created_at":"2025-09-08T13:47:13.000Z","updated_at":"2025-10-23T20:51:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"73f04dea-d0a2-40b3-8300-520661387333","html_url":"https://github.com/humanspeak/svelte-purify","commit_stats":null,"previous_names":["humanspeak/svelte-purify"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/humanspeak/svelte-purify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humanspeak%2Fsvelte-purify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humanspeak%2Fsvelte-purify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humanspeak%2Fsvelte-purify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humanspeak%2Fsvelte-purify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/humanspeak","download_url":"https://codeload.github.com/humanspeak/svelte-purify/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humanspeak%2Fsvelte-purify/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32587819,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T22:12:39.696Z","status":"ssl_error","status_checked_at":"2026-05-03T22:09:10.534Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["browser-only","dompurify","frontend","html-sanitizer","runes","safe-html","sanitization","sanitize","security","ssr","svelte","svelte-component","svelte-library","svelte5","sveltekit","typescript","vite","web-security","xss"],"created_at":"2025-09-10T16:49:22.949Z","updated_at":"2026-05-03T22:33:18.118Z","avatar_url":"https://github.com/humanspeak.png","language":"TypeScript","funding_links":["https://github.com/sponsors/humanspeak"],"categories":[],"sub_categories":[],"readme":"# @humanspeak/svelte-purify\n\nA tiny, friendly sanitizer for Svelte that keeps your HTML shiny and safe using DOMPurify. SSR-ready by default.\n\n[![NPM version](https://img.shields.io/npm/v/@humanspeak/svelte-purify.svg)](https://www.npmjs.com/package/@humanspeak/svelte-purify)\n[![Build Status](https://github.com/humanspeak/svelte-purify/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/humanspeak/svelte-purify/actions/workflows/npm-publish.yml)\n[![Coverage Status](https://coveralls.io/repos/github/humanspeak/svelte-purify/badge.svg?branch=main)](https://coveralls.io/github/humanspeak/svelte-purify?branch=main)\n[![License](https://img.shields.io/npm/l/@humanspeak/svelte-purify.svg)](https://github.com/humanspeak/svelte-purify/blob/main/LICENSE)\n[![Downloads](https://img.shields.io/npm/dm/@humanspeak/svelte-purify.svg)](https://www.npmjs.com/package/@humanspeak/svelte-purify)\n[![CodeQL](https://github.com/humanspeak/svelte-purify/actions/workflows/codeql.yml/badge.svg)](https://github.com/humanspeak/svelte-purify/actions/workflows/codeql.yml)\n[![Install size](https://packagephobia.com/badge?p=@humanspeak/svelte-purify)](https://packagephobia.com/result?p=@humanspeak/svelte-purify)\n[![Code Style: Trunk](https://img.shields.io/badge/code%20style-trunk-blue.svg)](https://trunk.io)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)\n[![Types](https://img.shields.io/npm/types/@humanspeak/svelte-purify.svg)](https://www.npmjs.com/package/@humanspeak/svelte-purify)\n[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/humanspeak/svelte-purify/graphs/commit-activity)\n\n## Features\n\n- 🚀 **Fast and tiny**: DOMPurify under the hood, minimal wrapper\n- 🔒 **XSS protection**: strips scripts, unsafe URLs, and sneaky attributes\n- 🧰 **Options passthrough**: you control DOMPurify via `options`\n- 🧭 **SSR-ready**: default component works on server and client\n- 🧪 **Tested**: unit tests with Vitest/JSDOM\n- 🧑‍💻 **Full TypeScript**: proper types for options and props\n- 🧿 **Svelte 5 runes-friendly**: clean, modern Svelte API\n\n## Installation\n\n```bash\nnpm i -S @humanspeak/svelte-purify\n# or\npnpm add @humanspeak/svelte-purify\n# or\nyarn add @humanspeak/svelte-purify\n```\n\n## Basic Usage\n\n### Default\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n    import { SveltePurify } from '@humanspeak/svelte-purify'\n\n    const html = `\u003cp\u003eHello \u003cstrong\u003eworld\u003c/strong\u003e\u003cscript\u003ealert(1)\u003c/script\u003e\u003c/p\u003e`\n\u003c/script\u003e\n\n\u003cSveltePurify {html} /\u003e\n```\n\n### Limit output length\n\n```svelte\n\u003cSveltePurify {html} maxLength={120} /\u003e\n```\n\n### Render hooks (preHtml/postHtml)\n\nYou can render UI before and after the sanitized HTML. Each hook receives the sanitized HTML length as a number.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n    import { SveltePurify } from '@humanspeak/svelte-purify'\n    const html = `\u003cp\u003e\u003cstrong\u003eHello\u003c/strong\u003e world!\u003c/p\u003e`\n\u003c/script\u003e\n\n\u003cSveltePurify\n    {html}\n    preHtml={(len) =\u003e \u003c\u003eSanitized length: {len}\u003c/\u003e}\n    postHtml={(len) =\u003e \u003c\u003e • {len} chars\u003c/\u003e}\n/\u003e\n```\n\n## Options (DOMPurify)\n\nPass any `DOMPurify.sanitize` options. We don’t hide anything—use the full power of DOMPurify.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n    import { SveltePurify } from '@humanspeak/svelte-purify'\n\n    const html = `\u003ca href=\"javascript:alert(1)\" title=\"nope\"\u003eclick me\u003c/a\u003e`\n    const options = {\n        ALLOWED_TAGS: ['a'],\n        ALLOWED_ATTR: ['href', 'title']\n    }\n\u003c/script\u003e\n\n\u003cSveltePurify {html} {options} /\u003e\n```\n\nNote: The component returns sanitized HTML as a string (not DOM nodes).\n\n## Props\n\n| Component      | Prop        | Type                                       | Description                                    |\n| -------------- | ----------- | ------------------------------------------ | ---------------------------------------------- |\n| `SveltePurify` | `html`      | `string`                                   | Raw HTML to sanitize and render                |\n|                | `options`   | `Parameters\u003ctypeof DOMPurify.sanitize\u003e[1]` | DOMPurify options (all supported)              |\n|                | `maxLength` | `number`                                   | If set, truncates the sanitized HTML string    |\n|                | `preHtml`   | `Snippet\u003c[number]\u003e`                        | Renders before HTML; receives sanitized length |\n|                | `postHtml`  | `Snippet\u003c[number]\u003e`                        | Renders after HTML; receives sanitized length  |\n\n## Exports\n\n```ts\nimport { SveltePurify } from '@humanspeak/svelte-purify'\n```\n\n- **SveltePurify**: SSR-friendly sanitizer component\n\n## Security\n\nThis library delegates sanitization to [DOMPurify](https://github.com/cure53/DOMPurify), a battle-tested sanitizer. It removes script tags, event handler attributes (like `onerror`), and unsafe URLs (`javascript:`), among many other protections.\n\n## Examples\n\nStrip a specific tag with DOMPurify options:\n\n```svelte\n\u003cSveltePurify html=\"\u003cp\u003eHello \u003cstrong\u003eworld\u003c/strong\u003e\u003c/p\u003e\" options={{ FORBID_TAGS: ['strong'] }} /\u003e\n```\n\nAllow an extra tag:\n\n```svelte\n\u003cSveltePurify\n    html=\"\u003ciframe src=\\\"about:blank\\\"\u003e\u003c/iframe\u003e\"\n    options={{ ADD_TAGS: ['iframe'] }}\n/\u003e\n```\n\n## License\n\nMIT © [Humanspeak, Inc.](LICENSE)\n\n## Credits\n\nMade with ❤️ by [Humanspeak](https://humanspeak.com)\n\nSpecial thanks to [@jill64](https://github.com/jill64) — her years of Svelte contributions taught me so much and inspired this work.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhumanspeak%2Fsvelte-purify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhumanspeak%2Fsvelte-purify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhumanspeak%2Fsvelte-purify/lists"}