{"id":24983730,"url":"https://github.com/posthtml/posthtml-safe-class-names","last_synced_at":"2025-10-07T20:48:18.613Z","repository":{"id":38844330,"uuid":"251033898","full_name":"posthtml/posthtml-safe-class-names","owner":"posthtml","description":"Replace escaped characters in CSS selectors and HTML class names.","archived":false,"fork":false,"pushed_at":"2025-04-11T15:30:00.000Z","size":2102,"stargazers_count":7,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-11T20:52:43.497Z","etag":null,"topics":["css-selectors","escape-char","html-emails","maizzle","posthtml","posthtml-plugin","replace-escaped-characters","tailwindcss"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/posthtml.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},"funding":{"github":null,"patreon":"posthtml","open_collective":"posthtml","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["https://mailviews.com"]}},"created_at":"2020-03-29T13:05:52.000Z","updated_at":"2025-04-01T11:11:39.000Z","dependencies_parsed_at":"2022-08-09T06:15:54.775Z","dependency_job_id":"fc1e2364-421a-492c-9aec-b94dfc621048","html_url":"https://github.com/posthtml/posthtml-safe-class-names","commit_stats":{"total_commits":201,"total_committers":4,"mean_commits":50.25,"dds":0.417910447761194,"last_synced_commit":"796ae6479787398a0dfcc5d8dd76f284b3f8b995"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posthtml%2Fposthtml-safe-class-names","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posthtml%2Fposthtml-safe-class-names/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posthtml%2Fposthtml-safe-class-names/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posthtml%2Fposthtml-safe-class-names/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/posthtml","download_url":"https://codeload.github.com/posthtml/posthtml-safe-class-names/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248480515,"owners_count":21110936,"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":["css-selectors","escape-char","html-emails","maizzle","posthtml","posthtml-plugin","replace-escaped-characters","tailwindcss"],"created_at":"2025-02-04T09:20:46.448Z","updated_at":"2025-10-07T20:48:13.538Z","avatar_url":"https://github.com/posthtml.png","language":"JavaScript","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg width=\"150\" height=\"150\" title=\"PostHTML\" src=\"https://posthtml.github.io/posthtml/logo.svg\"\u003e\n  \u003ch1\u003eSafe Class Names\u003c/h1\u003e\n  \u003cp\u003eReplace escaped characters in class names and CSS selectors\u003c/p\u003e\n\n  [![Version][npm-version-shield]][npm]\n  [![Build][github-ci-shield]][github-ci]\n  [![License][license-shield]][license]\n  [![Downloads][npm-stats-shield]][npm-stats]\n\u003c/div\u003e\n\n## Introduction\n\nThis plugin replaces escaped characters in class names from your `\u003cstyle\u003e` tags and inside `class=\"\"` attributes with safe characters, that do not need escaping.\n\nBy default, it replaces:\n\n- `\\:` and `\\/` with `-`\n- `\\%` with `pc`\n- `\\.` with `_`\n\nSee the full [list of replacements](lib/index.js#L19-L51).\n\n### But... why?\n\nSo you can use those cool [Tailwind CSS](https://tailwindcss.com) selectors in HTML emails. 😎\n\nEscaped characters in CSS selectors are not currently supported by all email clients, so you can use this plugin to replace them with HTML email-safe alternatives.\n\n## Install\n\n```\nnpm i posthtml posthtml-safe-class-names\n```\n\n## Usage\n\nConsider `example.html`:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cstyle\u003e\n    .w-3\\/5 {\n      width: 60%;\n    }\n    \n    .bg-\\[\\#1da1f1\\] {\n      background-color: #1da1f1;\n    }\n\n    @media (max-width: 600px) {\n      .sm\\:w-1\\/2 {\n        width: 50%;\n      }\n    }\n  \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cdiv class=\"w-3/5 sm:w-1/2 bg-[#1da1f1]\"\u003eLorem ipsum\u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n```js\nimport posthtml from 'posthtml'\nimport {readFileSync, writeFileSync} from 'node:fs'\nimport safeClassNames from 'posthtml-safe-class-names'\n\nconst source = readFileSync('./example.html')\n\nposthtml([\n    safeClassNames()\n  ])\n  .process(source)\n  .then(result =\u003e fs.writeFileSync('./after.html', result.html))\n```\n\nResult:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cstyle\u003e\n    .sm-w-3-5 {\n      width: 60%;\n    }\n\n    .bg-_1da1f1 {\n      background-color: #1da1f1;\n    }\n\n    @media (max-width: 600px) {\n      .sm-w-1-2 {\n        width: 50%;\n      }\n    }\n  \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cdiv class=\"w-3-5 sm-w-1-2 bg-_1da1f1\"\u003eLorem ipsum\u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Options\n\n### `replacements`\n\nType: `Object`\\\nDefault: [see list](lib/index.js#L19-L51)\n\nThe plugin accepts an options object where you can define character replacement mappings:\n\n```js\n{\n  ':': '-',\n  '\\/': '-',\n  '%': 'pc',\n  '.': '_',\n  // ...\n}\n```\n\nSee the full [list of replacements](lib/index.js#L19-L51).\n\nBesides adding new mappings, you can of course override the default ones.\n\nUsing the same `example.html`, let's replace `\\:` in our class names with `__` instead of `-`:\n\n```js\nposthtml([\n    safeClassNames({\n      replacements: {\n        ':': '__',\n      }\n    })\n  ])\n  .process(source)\n  .then(result =\u003e writeFileSync('./after.html', result.html))\n```\n\nResult:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cstyle\u003e\n    .sm__w-3-5 {\n      width: 60%;\n    }\n\n    .bg-_1da1f1 {\n      background-color: #1da1f1;\n    }\n\n    @media (max-width: 600px) {\n      .sm__w-1-2 {\n        width: 50%;\n      }\n    }\n  \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cdiv class=\"w-3-5 sm__w-1-2 bg-_1da1f1\"\u003eLorem ipsum\u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n### `ignored`\n\nType: `Array`\\\nDefault: `[{heads: '{{', tails: '}}'}, {heads: '{{{', tails: '}}}'}]`\n\nAn array of objects each containing heads/tails strings that mark the start and end of a class name to ignore. If a class name matches a pattern defined here, it will not be processed.\n\n```js\nposthtml([\n    safeClassNames({\n      ignored: [\n        {heads: '[[', tails: ']]'},\n      ]\n    })\n  ])\n  .process('\u003cdiv class=\"foo:bar [[ biz ]]\"\u003e')\n  .then(result =\u003e console.log(result.html))\n\n  // \u003cdiv class=\"foo-bar [[ biz ]]\"\u003e\n```\n\n[npm]: https://www.npmjs.com/package/posthtml-safe-class-names\n[npm-version-shield]: https://img.shields.io/npm/v/posthtml-safe-class-names.svg\n[npm-stats]: http://npm-stat.com/charts.html?package=posthtml-safe-class-names\n[npm-stats-shield]: https://img.shields.io/npm/dt/posthtml-safe-class-names.svg\n[github-ci]: https://github.com/posthtml/posthtml-safe-class-names/actions\n[github-ci-shield]: https://github.com/posthtml/posthtml-safe-class-names/actions/workflows/nodejs.yml/badge.svg\n[license]: ./LICENSE\n[license-shield]: https://img.shields.io/npm/l/posthtml-safe-class-names.svg\n","funding_links":["https://patreon.com/posthtml","https://opencollective.com/posthtml","https://mailviews.com"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposthtml%2Fposthtml-safe-class-names","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fposthtml%2Fposthtml-safe-class-names","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposthtml%2Fposthtml-safe-class-names/lists"}