{"id":27300771,"url":"https://github.com/soranoo/next-css-obfuscator","last_synced_at":"2026-01-03T08:11:17.529Z","repository":{"id":204783909,"uuid":"712661760","full_name":"soranoo/next-css-obfuscator","owner":"soranoo","description":"A package deeply inspired by PostCSS-Obfuscator but for Next.js.","archived":false,"fork":false,"pushed_at":"2025-04-11T16:15:25.000Z","size":1755,"stargazers_count":93,"open_issues_count":11,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T17:29:44.863Z","etag":null,"topics":["css","nextjs","obfuscation","tailwindcss"],"latest_commit_sha":null,"homepage":"https://next-css-obfuscator.vercel.app","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/soranoo.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},"funding":{"github":[],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2023-10-31T23:32:30.000Z","updated_at":"2025-04-11T16:15:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"42e6a801-0ec2-466e-9dd6-dd0cf2136dcd","html_url":"https://github.com/soranoo/next-css-obfuscator","commit_stats":{"total_commits":76,"total_committers":4,"mean_commits":19.0,"dds":0.3157894736842105,"last_synced_commit":"0dd46b377cca59e59514e3a78b1e6f3b9b92b651"},"previous_names":["soranoo/next-css-obfuscator"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soranoo%2Fnext-css-obfuscator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soranoo%2Fnext-css-obfuscator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soranoo%2Fnext-css-obfuscator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soranoo%2Fnext-css-obfuscator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/soranoo","download_url":"https://codeload.github.com/soranoo/next-css-obfuscator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248451504,"owners_count":21105884,"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","nextjs","obfuscation","tailwindcss"],"created_at":"2025-04-12T01:25:59.655Z","updated_at":"2026-01-03T08:11:17.511Z","avatar_url":"https://github.com/soranoo.png","language":"TypeScript","funding_links":["https://github.com/sponsors/soranoo"],"categories":[],"sub_categories":[],"readme":"# NEXT-CSS-OBFUSCATOR\n\nProject starts on 30-10-2023\n\n![Tests](https://github.com/soranoo/next-css-obfuscator/actions/workflows/auto_test.yml/badge.svg) [![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\u0026nbsp;\u0026nbsp;\u0026nbsp;[![Donation](https://img.shields.io/static/v1?label=Donation\u0026message=❤️\u0026style=social)](https://github.com/soranoo/Donation)\n\n[![banner](./docs/imgs/banner.png)](https://github.com/soranoo/next-css-obfuscator)\n\n[![npm version](https://img.shields.io/npm/v/next-css-obfuscator?color=red\u0026style=flat)](https://www.npmjs.com/package/next-css-obfuscator) [![npm downloads](https://img.shields.io/npm/dt/next-css-obfuscator?color=blue\u0026style=flat)](https://www.npmjs.com/package/next-css-obfuscator)\n\n---\n\nVisit the [GitHub Page](https://github.com/soranoo/next-css-obfuscator/) for better reading experience and latest docs. 😎\n\n---\n\n### 🎉 Version 3 has NOW been released 🎉 (💥 Breaking Changes)\n\n\u003e[!IMPORTANT]\\\n\u003e This version is a major update and has breaking changes. Please read the [migration guide](docs/upgrade-to-v3.md) carefully before upgrading.\n\n\u003e[!TIP]\\\n\u003e Don't upgrade to this version unless you are using TailwindCSS 4.0.0 or above. \"If it works, don't touch it.\" :)\n\n#### 📌 Feature Changes\n  \n- Support TailwindCSS 4.\n- Support nested CSS.\n- Support CSS idents obfuscation.\n\n#### 📌 Configuration Changes\n  \n- `enableJsAst` option is now enabled by default.\n- Default `generatorSeed` not longer fixed to `-1`, but a random string.\n- `simplify-seedable` mode is not longer supported. Use `random` mode instead.\n- Removed `includeAnyMatchRegexes` and `excludeAnyMatchRegexes` options, the `whiteListedFolderPaths` and `blackListedFolderPaths` options will be used instead.\n- Deprecated `classLength` option, not longer supported.\n- Added `ignorePatterns` option to ignore the class names and idents that match the regexes or strings.\n- Not longer preserve TailwindCSS dark mode class names (ie `.dark`). Add the dark mode class name to the `ignorePatterns.selectors` option to preserve it.\n- Merge `classIgnore` into `ignorePatterns.selectors` option.\n- Renamed `classPrefix` and `classSuffix` to `prefix` and `suffix`.\n\n### 💥 Version 2 (Major Update)\n\n  This version is deeply inspired by [PostCSS-Obfuscator](https://github.com/n4j1Br4ch1D/postcss-obfuscator). Shout out to [n4j1Br4ch1D](https://github.com/n4j1Br4ch1D) for creating such a great package and thank you [tremor](https://github.com/tremorlabs) for sponsoring this project.\n\n#### 📌 Changes\n\n- Support basic partial obfuscation\n- Support TailwindCSS Dark Mode\n- New configuration file `next-css-obfuscator.config.cjs`\n- More configuration options\n- Now become a independent solution (no need to patch `PostCSS-Obfuscator` anymore)\n- More tests\n- Better CSS parsing\n  \n### 📚 Migration Guides\n\n- [Migrate from version 1.x to 2.x](docs/upgrade-to-v2.md)\n- [Migrate from version 2.x to 3.x](docs/upgrade-to-v3.md)\n\n[version 1.x README](https://github.com/soranoo/next-css-obfuscator/tree/v.1.1.0)\n\n[version 2.x README](https://github.com/soranoo/next-css-obfuscator/tree/v.2.2.19)\n\nGive me a ⭐ if you like it.\n\n## 📖 Table of Contents\n\n- [🤔 Why this?](#-why-this)\n- [💡 How does it work?](#-how-does-it-work)\n  - [Where is the issue in PostCSS-Obfuscator?](#where-is-the-issue-in-postcss-obfuscator)\n  - [How does this package solve the issue?](#how-does-this-package-solve-the-issue)\n  - [How does this package work?](#how-does-this-package-work)\n- [🗝️ Features](#️-features)\n- [🛠️ Development Environment](#️-development-environment)\n- [📦 Requirements](#-requirements)\n- [🚀 Getting Started](#-getting-started)\n  - [Installation](#installation)\n  - [Setup](#setup)\n  - [Usage 🎉](#usage-)\n- [🔧 My Setting](#-my-setting)\n- [📖 Config Options Reference](#-config-options-reference)\n- [💻 CLI](#-cli)\n- [💡 Tips](#-tips)\n  - [1. Not work at Vercel after updated](#1-not-work-at-vercel-after-updated)\n  - [2. Lazy Setup - Obfuscate all files](#2-lazy-setup---obfuscate-all-files)\n  - [3. It was working normally just now, but not now?](#3-it-was-working-normally-just-now-but-not-now)\n  - [4. Why are some original selectors still in the obfuscated CSS file even the `removeOriginalCss` option is set to `true`?](#4-why-are-some-original-selectors-still-in-the-obfuscated-css-file-even-the-removeoriginalcss-option-is-set-to-true)\n  - [5. Why did I get a copy of the original CSS after partial obfuscation?](#5-why-did-i-get-a-copy-of-the-original-css-after-partial-obfuscation)\n  - [6. How to deal with CSS cache in PaaS like Vercel?](#6-how-to-deal-with-css-cache-in-paas-like-vercel)\n  - [7. When to use `enableJsAst`?](#7-when-to-use-enablejsast)\n- [👀 Demos](#-demos)\n- [⭐ TODO](#-todo)\n- [🐛 Known Issues](#-known-issues)\n- [💖 Sponsors](#-sponsors)\n- [🦾 Special Thanks](#-special-thanks)\n- [🤝 Contributing](#-contributing)\n- [🏛️ Commercial Usage](#️-commercial-usage)\n- [📝 License](#-license)\n- [☕ Donation](#-donation)\n\n## 🤔 Why this?\n\nBecause in the current version of [PostCSS-Obfuscator](https://github.com/n4j1Br4ch1D/postcss-obfuscator) does not work with Next.js. (see [this issue](https://github.com/n4j1Br4ch1D/postcss-obfuscator/issues/15) for more details)\n\n## 💡 How does it work?\n\n### Where is the issue in PostCSS-Obfuscator?\n\n`PostCSS-Obfuscator` will not edit the build files instead it will create a new folder and put the obfuscated source code files in it. This is where the issue is. Next.js will not recognize the obfuscated files and will not include them in the build. I tried to point Nextjs to build the obfuscated files (by simply changing the obfuscated source code folder to `src`) but it didn't work.\n\n### How does this package solve the issue?\n\nEdit the build files directly. (It may not be the best solution but it works.)\n\n### How does this package work?\n\n1. Extract and parse CSS files from the build files.\n2. Obfuscate the CSS selectors and save to a JSON file.\n3. Search and replace the related class names in the build files with the obfuscated class names.\n\n## 🗝️ Features\n\n- WORK WITH NEXT.JS !!!!!!!!!!!!!!!!!!!\n\n\u003e [!IMPORTANT]\\\n\u003e This package is NOT guaranteed to work with EVERYONE. Check the site carefully before using it in production.\n\n\u003e [!IMPORTANT]\\\n\u003e As a trade-off, the obfuscation will make your CSS files larger.\n\n## 🛠️ Development Environment\n\n| Environment           | Version                   |\n| --------------------- | ------------------------- |\n| OS                    | Windows 11 \u0026 Ubuntu 22.04 |\n| Node.js               | v.18.17.1                 |\n| NPM                   | v.10.1.0                  |\n| Next.js (Page Router) | v.13.5.4 \u0026 v.13.4.1       |\n| Next.js (App Router)  | v.14.0.4                  |\n| TailwindCSS           | v.3.3.3                   |\n\n- ✅ Tested and works with Next.js Page Router and App Router.\n- ✅ Tested and works with [Vercel](https://vercel.com/).\n\n(Theoretically it supports all CSS frameworks but I only tested it with TailwindCSS.)\n\n## 📦 Requirements\n\n- ⌛ TIME 🕛\n\n## 🚀 Getting Started\n\n### Installation\n\n```bash\nnpm install -D  next-css-obfuscator\n```\n\nVisit the [npm](https://www.npmjs.com/package/next-css-obfuscator) page.\n\n### Setup\n\n1. Create and add the following code to `next-css-obfuscator.config.cjs` or `next-css-obfuscator.config.ts`:\n\n   ##### Obfuscate all files\n\n    ```javascript\n    /** @type {import(\"next-css-obfuscator\").Options} */\n    module.exports = {\n        enable: true,\n        mode: \"random\", // random | simplify\n        refreshClassConversionJson: false, // recommended set to true if not in production\n        allowExtensions: [\".jsx\", \".tsx\", \".js\", \".ts\", \".html\", \".rsc\"],\n      };\n\n    ```\n\n   ##### Partially obfuscate\n\n\u003e [!CAUTION]\\\n\u003e Partially obfuscate can be EXTREMELY buggy. Be cautious when using this feature.\n\n    ```javascript\n    /** @type {import(\"next-css-obfuscator\").Options} */\n    module.exports = {\n        enable: true,\n        mode: \"random\", // random | simplify\n        refreshClassConversionJson: false, // recommended set to true if not in production\n        allowExtensions: [\".jsx\", \".tsx\", \".js\", \".ts\", \".html\", \".rsc\"],\n\n        enableMarkers: true,\n      };\n\n    ```\n\n    Feel free to checkout [📖 Config Options Reference](#-config-options-reference) for more options and details.\n\n\u003e [!TIP]\\\n\u003e The obfuscation will never work as expected, tweak the options with your own needs.\n\n2. Add the following code to `package.json`:\n\n   ```javascript\n   \"scripts\": {\n    // other scripts ...\n    \"obfuscate-build\": \"next-css-obfuscator\"\n    },\n   ```\n\n   Read [💻 CLI](#-cli) for more details.\n\n### Usage 🎉\n\n1. Run `npm run build` to build the project.\n2. Run `npm run obfuscate-build` to obfuscate the css files.\n\n(You may need to delete the `.next/cache` folder before running `npm run start` to make sure the obfuscation takes effect. And don't forget to `shift + F5` refresh the page.`)\n\n\u003e [!WARNING]\\\n\u003e NEVER run `obfuscate-build` twice in a row. It may mess up the build files and the obfuscation conversion table. You can remove the `classConversionJsonFolderPath`(default: `css-obfuscator`) folder to reset the conversion table.\n\n\u003e [!NOTE]\\\n\u003e For better development experience, it is recommended to enable `refreshClassConversionJson` option in `next-css-obfuscator.config.cjs` and disable it in production.\n\nFor convenience, you may update your build script to:\n\n```javascript\n// package.json\n\n\"scripts\": {\n  // other scripts ...\n  \"build\": \"next build \u0026\u0026 npm run obfuscate-build\"\n},\n```\n\nto make sure the build is always obfuscated and no need to run `obfuscate-build` manually.\n\n\u003e [!NOTE]\\\n\u003e It is a good idea to add the `/css-obfuscator` folder to `.gitignore` to prevent the conversion table from being uploaded to the repository.\n\n#### Partially obfuscate\n\nTo partially obfuscate your project, you have to add the obfuscate marker class to the components you want to obfuscate.\n\n```diff\n// example\n\nexport default function HomePage() {\n  return (\n    \u003cmain className=\"flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#fac3e3] to-[#5c9cbd] text-white\"\u003e\n      \u003cdiv className=\"container flex flex-col items-center justify-center gap-12 px-4 py-16 \"\u003e\n        \u003ch1 className=\"text-5xl font-extrabold tracking-tight text-white sm:text-[5rem]\"\u003e\n          Next14 App Router\n        \u003c/h1\u003e\n      \u003c/div\u003e\n-     \u003cdiv className=\"container flex flex-col items-center justify-center gap-12 px-4 py-16 \"\u003e\n+     \u003cdiv className=\"next-css-obfuscation container flex flex-col items-center justify-center gap-12 px-4 py-16 \"\u003e\n        \u003cspan className=\"text-2xl font-extrabold tracking-tight text-gray-700 border-2 border-blue-950 rounded-lg p-4\"\u003e\n          My classes are obfuscated\n        \u003c/span\u003e\n      \u003c/div\u003e\n    \u003c/main\u003e\n  );\n}\n```\n\nSee [Next 14 App Router Partially Obfuscated Demo](https://github.com/soranoo/next-css-obfuscator/tree/main/demos/next14-app-router-partially-obfuscated) for more details.\n\n## 🔧 My Setting\n\nIf you are interested in my setting, here it is\n\n```javascript\n// next-css-obfuscator.config.cjs\n\n/** @type {import(\"next-css-obfuscator\").Options} */\nmodule.exports = {\n  enable: true,\n  mode: \"random\", // random | simplify\n  refreshClassConversionJson: false, // recommended set to true if not in production\n  allowExtensions: [\".jsx\", \".tsx\", \".js\", \".ts\", \".html\", \".rsc\"],\n\n  blackListedFolderPaths: [\n    \"./.next/cache\",\n    /\\.next\\/server\\/pages\\/api/,\n    /_document..*js/,\n    /_app-.*/,\n    /__.*/, // \u003c= maybe helpful if you are using Next.js Local Fonts [1*]\n  ],\n};\n```\n\n[*1] See this [comment](https://github.com/soranoo/next-css-obfuscator/issues/6#issuecomment-1919495298)\n\nIt may not be the best setting but it works for me. :)\n\n## 📖 Config Options Reference\n\n| Option                       | Type                                                        | Default                  | Description                                                                                                                     |\n| ---------------------------- | ----------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |\n| enable                       | boolean                                                     | true                     | Enable or disable the obfuscation.                                                                                              |\n| mode                         | \"random\" \\| \"simplify\" | \"random\" | Obfuscate mode, \u003cbr\u003e\u003cbr\u003e**random**: Fixed size random class name \u003cbr\u003e\u003cbr\u003e**simplify**: Alphabetic class name, like [medium](https://medium.com/)|\n|buildFolderPath|string|\"./.next\"|The folder path to store the build files built by Next.js.|\n|classConversionJsonFolderPath|string|\"./css-obfuscator\"|The folder path to store the before obfuscate and after obfuscated classes conversion table.|\n|refreshClassConversionJson|boolean|false|Refresh the class conversion JSON file(s) at every obfuscation. Good for setting tweaking but not recommended for production.|\n|prefix.selectors|string|\"\"|The prefix of the obfuscated classname.|\n|prefix.idents|string|\"\"|The prefix of the obfuscated ident name.|\n|suffix.selectors|string|\"\"|The suffix of the obfuscated classname.|\n|suffix.idents|string|\"\"|The suffix of the obfuscated ident name.|\n|ignorePatterns|{selectors: [], idents: []}|{selectors: [], idents: []}|The patterns to be ignored during obfuscation.|\n|allowExtensions|string[ ]|[\".jsx\", \".tsx\", \".js\", \".ts\", \".html\", \".rsc\"]|The file extensions to be processed.|\n|contentIgnoreRegexes|RegExp[ ]|[/\\.jsxs\\)\\(\"\\w+\"/g]|The regexes to match the content to be ignored  during obfuscation.|\n|whiteListedFolderPaths|[string \\| Regex]( )|[ ]|The folder paths/Regex to be processed. Empty array means all folders will be processed.|\n|blackListedFolderPaths|[string \\| Regex]( )|[ ]|The folder paths/Regex to be ignored.|\n|enableMarkers|boolean|false|Enable or disable the obfuscation markers.|\n|markers|string[ ]|[ ]|Classes that indicate component(s) need to obfuscate.|\n|removeMarkersAfterObfuscated|boolean|true|Remove the obfuscation markers from HTML elements after obfuscation.|\n|removeOriginalCss|boolean|false|Delete original CSS from CSS files if it has a obfuscated version. (*NOT recommended* using in partial obfuscation)\n|generatorSeed|string \\| undefined|{random string}|The seed for the random class name generator. \"undefined\" means use random seed. \u003cbr\u003e\u003cbr\u003eFor \"random\" mode only. |\n|logLevel|\"debug\" \\| \"info\" \\| \"warn\" \\| \"error\" \\| \"success\"| \"info\"|The log level.|\n\n### Experimental Features Options 🚧\n\n| Option| Type| Default| Description| Stage |\n| - | - | - | - | - |\n|enableJsAst|boolean|true|Whether to obfuscate JS files using abstract syntax tree parser. \u003cbr\u003e\u003cbr\u003e`contentIgnoreRegexes` option will be ignored if this option is enabled.|Alpha|\n\n\u003e [!NOTE]\\\n\u003e The above options are still at the early stages of development and may not work as expected.\n\u003e\n\u003e Open an [issue](https://github.com/soranoo/next-css-obfuscator/issues) if you encounter any issues.\n\n\u003e [!NOTE]\\\n\u003e **Stages** -\n\u003e\n\u003e 1. **PoC**: Proof of Concept. The feature is still in the concept stage and is not recommended in production.\n\u003e 2. **Alpha**: The feature is still in the early stage of development and may not work as expected.\n\u003e 3. **Beta**: The feature is almost completed and should work as expected but may have some issues. (if no issue is reported in a period, it will be considered stable.)\n\u003e 4. **Stable**: The feature is in the final stage of development and should work as expected.\n\n### All options in one place 📦\n\n```js\n// next-css-obfuscator.config.cjs\n\nmodule.exports = {\n    enable: true, // Enable or disable the plugin.\n    mode: \"random\", // Obfuscate mode, \"random\", \"simplify\" or \"simplify-seedable\".\n    buildFolderPath: \".next\", // Build folder of your project.\n    classConversionJsonFolderPath: \"./css-obfuscator\", // The folder path to store the before obfuscate and after obfuscated classes conversion table.\n    refreshClassConversionJson: false, // Refresh the class conversion JSON file.\n\n    /**\n     * @deprecated Not longer used from v3.0.0 and will be removed in the next major version.\n     */\n    classLength: 5, // Length of the obfuscated class name.\n\n    /**\n     * @deprecated Merged into `prefix` from v3.0.0 and will be removed in the next major version.\n     */\n    classPrefix: \"\", // Prefix of the obfuscated class name.\n\n    /**\n     * @deprecated Merged into `suffix` from v3.0.0 and will be removed in the next major version.\n     */\n    classSuffix: \"\", // Suffix of the obfuscated class name.\n\n    prefix: {\n      selectors: \"\", // Prefix of the obfuscated classname.\n      idents: \"\", // Prefix of the obfuscated ident name.\n    },\n    suffix: {\n      selectors: \"\", // Suffix of the obfuscated classname.\n      idents: \"\", // Suffix of the obfuscated ident name.\n    },\n\n    /**\n     * @deprecated Merged into `ignorePatterns.selectors` from v3.0.0 and will be removed in the next major version.\n     */\n    classIgnore: [], // The class names to be ignored during obfuscation.\n    ignorePatterns: { // The patterns to be ignored during obfuscation.\n        selectors: [], // The selectors to be ignored during obfuscation.\n        idents: [], // The idents to be ignored during obfuscation.\n    },\n\n    allowExtensions: [\".jsx\", \".tsx\", \".js\", \".ts\", \".html\", \".rsc\"], // The file extensions to be processed.\n    contentIgnoreRegexes: [\n        /\\.jsxs\\)\\(\"\\w+\"/g, // avoid accidentally obfuscate the HTML tag\n    ], // The regexes to match the file content to be ignored during obfuscation.\n\n    whiteListedFolderPaths: [], // Only obfuscate files in these folders\n    blackListedFolderPaths: [\"./.next/cache\"], // Don't obfuscate files in these folders\n    enableMarkers: false, // Enable or disable the obfuscate marker classes.\n    markers: [\"next-css-obfuscation\"], // Classes that indicate component(s) need to obfuscate.\n    removeMarkersAfterObfuscated: true, // Remove the obfuscation markers from HTML elements after obfuscation.\n    removeOriginalCss: false, // Delete original CSS from CSS files if it has a obfuscated version.\n    generatorSeed: undefined, // The seed for the random generator. \"undefined\" means use random seed.\n\n    /**\n     * Experimental feature\n     */\n    enableJsAst: true, // Whether to obfuscate JS files using abstract syntax tree parser. (Experimental feature)\n\n    logLevel: \"info\", // Log level\n};\n```\n\n## 💻 CLI\n\n```bash\nnext-css-obfuscator --config ./path/to/your/config/file\n```\n\n## 💡 Tips\n\n### 1. Not work at Vercel after updated ?\n\nIf you are using this package with Vercel, you may find the package does not work as expected after being updated. This is because Vercel will cache the last build for a faster build time. To fix this you have to redeploy with the `Use existing build cache` option disabled.\n\n### 2. Lazy Setup - Obfuscate all files\n\nEnable `enableMarkers` and put the obfuscate marker class at every component included the index page. But if you want to set and forget, you must play with the options to ensure the obfuscation works as expected.\n\n### 3. It was working normally just now, but not now?\n\nYour conversion table may be messed up. Try to delete the `classConversionJsonFolderPath`(default: `css-obfuscator`) folder to reset the conversion table.\n\n### 4. Why are some original selectors still in the obfuscated CSS file even the `removeOriginalCss` option is set to `true`?\n\nIn a normal situation, the package will only remove the original CSS that is related to the obfuscation and you should not see any CSS sharing the same declaration block.\n\nYou are not expected to see this:\n\n```css\n/* example.css */\n\n/* original form */\n.text-stone-300 {\n  --tw-text-opacity: 1;\n  color: rgb(214 211 209 / var(--tw-text-opacity));\n}\n\n/* obfuscated form */\n.d8964 {\n  --d89645: 1;\n  color: rgb(214 211 209 / var(--d89645));\n}\n```\n\nBut this:\n\n```css\n/* example.css */\n\n/* obfuscated form */\n.d8964 {\n  --d89645: 1;\n  color: rgb(214 211 209 / var(--d89645));\n}\n```\n\nIf you encounter the first situation, it means something is wrong with the obfuscation. You may need to raise an [issue](https://github.com/soranoo/next-css-obfuscator/issues) with your configuration and the related code.\n\n### 5. Why did I get a copy of the original CSS after partial obfuscation?\n\nSince the original CSS may be referenced by other components not included in the obfuscation, the package will not remove the original CSS to prevent breaking the the site.\n\n### 6. How to deal with CSS cache in PaaS like [Vercel](https://vercel.com/)?\n\n(I will take [Vercel](https://vercel.com/) as an example)\n\nYou may discover that the obfuscated class conversion table updates every time you deploy your site to [Vercel](https://vercel.com/) even if the `refreshClassConversionJson` option is set to `false`. As a result, the CSS file will update in every deployment and break the CDN cache. This is because [Vercel](https://vercel.com/) will not keep the files generated by the previous deployment. To fix this, you can simply provide a fixed `generatorSeed` to make sure the obfuscated class name will be the same as the previous.\n\n### 7. When to use `enableJsAst`?\n\n~~If you are going to partially obfuscate your site, you may want to enable this option to obfuscate. It gives the ability to trace the variable that is related to the class name in a JS file which the normal basic partial obfuscation can't do.~~ (WIP)\n\n\u003e [!IMPORTANT]\n\u003e Note that if a shared component is under the obfuscation marker, that component will be obfuscated and may affect other components(with no obfuscation marker) that use the same shared component.\n\nIf you are going to obfuscate the whole site, you will get a way more accurate obfuscation by enabling this option without putting a ton of time into tweaking the options.\n\n\u003e [!NOTE]\n\u003e As a trade-off, this will take more time to obfuscate.\n\n\u003e [!NOTE]\n\u003e This method can only trace the variable within the same JS file. It can't trace the variable that is imported from another file.\n\n## 👀 Demos\n\n1. [Next 14 App Router](https://github.com/soranoo/next-css-obfuscator/tree/main/demos/next14-app-router)\n2. [Next 14 App Router Partially Obfuscated](https://github.com/soranoo/next-css-obfuscator/tree/main/demos/next14-app-router-partially-obfuscated)\n3. [hoangnhan.co.uk](https://hoangnhan.co.uk/) (BY [hoangnhan2ka3](https://github.com/hoangnhan2ka3))\n\n## ⭐ TODO\n\n- [x] Partial obfuscation\n- [x] To be a totally independent package (remove dependency on [PostCSS-Obfuscator](https://github.com/n4j1Br4ch1D/postcss-obfuscato))\n- [ ] More tests\n- [ ] More demos ?\n\n## 🐛 Known Issues\n\n- [ ] Partial Obfuscation\n  - Not work with complex components. (eg. A component with shared component(s))\n    - Reason: The obfuscation marker can't locate the correct code block to obfuscate.\n  - Potential Solution: track the function/variable call stack to locate the correct code block to obfuscate.\n\n## 💖 Sponsors\n\nThank you to all the sponsors who support this project.\n\n#### Organizations (1)\n\n\u003ctable\u003e\n  \u003ctr\u003e\n  \u003ctd align=\"center\"\u003e\n    \u003ca href=\"https://github.com/tremorlabs\"\u003e\n      \u003cimg src=\"https://avatars.githubusercontent.com/u/97241560?s=200\u0026v=4\" width=\"100\" alt=\"\"/\u003e\n      \u003cbr\u003e\u003csub\u003e\u003cb\u003etremor\u003c/b\u003e\u003c/sub\u003e\n    \u003c/a\u003e\n  \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Individuals (1)\n\n\u003ctable\u003e\n  \u003ctr\u003e\n  \u003ctd align=\"center\"\u003e\n    \u003ca href=\"https://github.com/nhannt201\"\u003e\n      \u003cimg src=\"https://avatars.githubusercontent.com/u/12721256?v=4\" width=\"100\" alt=\"\"/\u003e\n      \u003cbr\u003e\u003csub\u003e\u003cb\u003enhannt201\u003c/b\u003e\u003c/sub\u003e\n    \u003c/a\u003e\n  \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## 🦾 Special Thanks\n\n\u003ctable\u003e\n  \u003ctr\u003e\n  \u003ctd align=\"center\"\u003e\n    \u003ca href=\"https://github.com/hoangnhan2ka3\"\u003e\n      \u003cimg src=\"https://avatars.githubusercontent.com/u/147973044?v=4\" width=\"100\" alt=\"\"/\u003e\n      \u003cbr\u003e\u003csub\u003e\u003cb\u003ehoangnhan2ka3\u003c/b\u003e\u003c/sub\u003e\n    \u003c/a\u003e\n  \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## 🤝 Contributing\n\nContributions are welcome! If you find a bug or have a feature request, please open an issue. If you want to contribute code, please fork the repository and run `npm run test` before submit a pull request.\n\n## 🏛️ Commercial Usage\n\n#### Individual🕺\n\nAre you using this package for a personal project? That's great! You can support us by starring this repo on Github ⭐🌟⭐.\n\n#### Organization 👯‍♂️\n\nAre you using this package within your organization and generating revenue from it? Fantastic! We depend on your support to continue developing and maintaining the package under an MIT License. You might consider showing your support through [Github Sponsors](https://github.com/sponsors/soranoo).\n\n## 📝 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details\n\n## ⭐ Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=soranoo/next-css-obfuscator\u0026type=Date)](https://star-history.com/#soranoo/next-css-obfuscator\u0026Date)\n\n## ☕ Donation\n\nLove it? Consider a donation to support my work.\n\n[![\"Donation\"](https://raw.githubusercontent.com/soranoo/Donation/main/resources/image/DonateBtn.png)](https://github.com/soranoo/Donation) \u003c- click me~\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoranoo%2Fnext-css-obfuscator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoranoo%2Fnext-css-obfuscator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoranoo%2Fnext-css-obfuscator/lists"}