{"id":18932442,"url":"https://github.com/dmantsevich/aem-critical-css","last_synced_at":"2025-04-15T16:33:51.793Z","repository":{"id":46786777,"uuid":"333747936","full_name":"dmantsevich/aem-critical-css","owner":"dmantsevich","description":"Nodejs tool which helps to build/inject critical/component CSS for AEM components (Adobe Experience Manager)","archived":false,"fork":false,"pushed_at":"2024-05-09T10:09:03.000Z","size":760,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T23:43:32.931Z","etag":null,"topics":["adobe-experience-manager","aem","aem-tools","critical-css","css","javascript","js","less","node","node-js","node-module","node-modules","nodejs","sass"],"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/dmantsevich.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":"2021-01-28T12:11:09.000Z","updated_at":"2024-05-09T10:09:06.000Z","dependencies_parsed_at":"2023-10-17T04:22:11.605Z","dependency_job_id":"3e0d0321-3b55-4993-a98e-5063285ab81e","html_url":"https://github.com/dmantsevich/aem-critical-css","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmantsevich%2Faem-critical-css","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmantsevich%2Faem-critical-css/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmantsevich%2Faem-critical-css/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmantsevich%2Faem-critical-css/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmantsevich","download_url":"https://codeload.github.com/dmantsevich/aem-critical-css/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249108584,"owners_count":21214020,"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":["adobe-experience-manager","aem","aem-tools","critical-css","css","javascript","js","less","node","node-js","node-module","node-modules","nodejs","sass"],"created_at":"2024-11-08T11:49:18.230Z","updated_at":"2025-04-15T16:33:51.117Z","avatar_url":"https://github.com/dmantsevich.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AEM Critical CSS 🐝\n\n[Nodejs](https://nodejs.org/en/) tool which helps to build/inject critical/component CSS for [AEM templates/components](https://experienceleague.adobe.com/docs/experience-manager-htl/using/getting-started/getting-started.html?lang=en) ([Adobe Experience Manager](https://www.adobe.com/ru/marketing/experience-manager.html)).\n\nIt can be used as components CSS dependency resolver/injector (not as automatically code splitter/extractor).  \n\n![dmantsevich/aem-critical-css](static/up.gif)\n\n## Table of contents 👈🏻\n- [Install](#install-)\n- [How to use](#how-to-use-)\n- [Regular Workflow](#regular-workflow-)\n- [API](#api-)\n- [Config](#config-)\n- [Injection type - Inline](#injection-type---inline-as-a-part-of-html)\n- [Injection type - Link](#injection-type---link-as-a-css-file)\n- [Best practice](#best-practice-)\n- [FAQ](#faq-)\n- [Links](#links-)\n\n## Features 🐿\n- [x] Fast, flexible, powerful\n- [x] [Configurable](#config-) \n- [x] Inline injection via ``style`` tag\n- [x] Standalone injection via ``link`` tag\n- [x] Single injection (on the page)\n- [x] Auto-resolving injection type by file size\n- [x] Hashes for files injected via ``link`` tag\n- [x] Supports ``.css``, ``.scss``, ``.sass``, ``.less`` files\n- [x] Partial injection (css depends on component configuration)\n- [x] Tested on several AEM projects\n- [x] etc.\n\n\n## Install 🐠\n1) Install **[NodeJs](https://nodejs.org/en/)** (This will also install **[npm](https://www.npmjs.com/)**)\n2) Install [@dmantsevich/aem-critical-css](https://www.npmjs.com/package/@dmantsevich/aem-critical-css) as dependency for your project (👍):\n```shell script\nnpm i @dmantsevich/aem-critical-css --save\n```\n\n\n## How to use 🐟\nThat section shows basic usage for beginners.\n1. Open AEM component template and add next code (where _\"path/to/component-css.less\"_ is path to critical css file, which should be injected. Path is related to ``${config.css.sourceRoot}`` (see [config](#config-)). Supports: **less**, **scss**, **sass**, **css** types):\n```html\n\u003csly data-sly-use.aemCriticalCSS=\"${'./_aem-critical-css.js'}\"\n\t@aem-critical-css=\"path/to/component-css.less\"\u003e${aemCriticalCSS.inject @ context=\"unsafe\"}\u003c/sly\u003e\n```\n2. Go to folder where frontend team are working (``cd ui.frontend`` or ``cd ui.clientlibs`` or other)\n3. Install [AEM Critical CSS](https://www.npmjs.com/package/@dmantsevich/aem-critical-css) module/package as dependency (see [Install](#install-) section):\n```shell script\nnpm i @dmantsevich/aem-critical-css --save\n``` \n4. Create ``aem-critical-css.js`` file (in the future webpack, gulp \u0026 grunt wrappers will be added) with code:\n```js\nconst { process } = require('@dmantsevich/aem-critical-css');\nconst config = {}; // it is configuration for the project\nprocess(config);\n```\n5. Process templates (see [Regular Workflow](#regular-workflow-) section) (it should be a part of frontend build):\n```shell script\nnode aem-critical-css.js\n```\n6. If processing was successful, then you can find generated css file (_aem-critical-css.js_) near AEM component template.\n7. You can deploy code to AEM\n\n\n## Regular Workflow 🐉\n1. Tool is searching all ``\"*.html\"`` files ([HTL](https://experienceleague.adobe.com/docs/experience-manager-htl/using/htl/block-statements.html?lang=en#overview)) under ``${config.AEM.components}`` (by default: **ui.apps/src/main/content/jcr_root/apps/** folder | see [config](#config-)) folder\n2. Analyzing all found files, which contains ``${criticalCSS.file}.${criticalCSS.type}`` (by default: **_aem-critical-css.js** string | see [config](#config-)) string. \n3. Parsing ``${config.criticalCSS.sourceAttr}``, ``${config.criticalCSS.injectionTypeAttr}``, ``${config.criticalCSS.serviceAttr}`` attributes. (by default: **@aem-critical-css**, **@aem-critical-css-injectiontype**, **@aem-critical-css-service** attributes | see [config](#config-))\n4. If parsing was successful, then starts _generating CSS code_ linked in ``${config.criticalCSS.sourceAttr}`` (by default: **@aem-critical-css** attribute | see [config](#config-)) attribute.\n    - Reading source ``${config.css.sourceRoot}/${@aem-critical-css-attribute-value}`` file (by default: **./${aem-critical-css-attribute-value}** | see [config](#config-))\n    - Compile source file with **[less](https://www.npmjs.com/package/less)**, **[node-sass](https://www.npmjs.com/package/node-sass)** compiler (you can create your custom compiler)\n    - Process CSS with [postcss](https://www.npmjs.com/package/postcss) plugins (by default: **autoprefixer**, **cssnano** | see [config](#config-))\n5. Resolve injection type\n    - If **${config.criticalCSS.injectionTypeAttr}** attribute (by default: **@aem-critical-css-injectiontype** | see [config](#config-)) is defined, then it will be used\n    - Otherwise **${config.criticalCSS.injectionType}** value (by default: **auto** | see [config](#config-)) will be used\n    - Resolving for injection type **auto**:\n        - Calculating _filesize_ for generated CSS file (after gzip)\n        - If _filesize_ is lower ``${config.criticalCSS.gzipSize}`` (by default: **10kb** | see [config](#config-)) then file will be injected via ``\u003cstyle\u003e`` tag.\n        - Otherwise file will be injected via ``\u003clink\u003e`` tag.\n6. If injection type is **link**, then css file(file name will contains hash) will be saved under **${config.web.localClientlib}/resources/** folder (by default: **ui.apps/src/main/content/jcr_root/apps/aem-critical-css/resources/** | see [config](#config-))\n7. Generating ``${criticalCSS.file}.${criticalCSS.type}`` (by default: **_aem-critical-css.js** | see [config](#config-)) file in the same folder with [HTL template](https://experienceleague.adobe.com/docs/experience-manager-htl/using/htl/block-statements.html?lang=en#overview) (where it used). \n\n\n## API 🦔\nNext properties \u0026 method exports [@dmantsevich/aem-critical-css](https://www.npmjs.com/package/@dmantsevich/aem-critical-css) module:\n- **process(config)** _{function}_ - process AEM templates \u0026 generate css files for injection.\n- **CRITICAL_CSS_TYPES** _{constants}_ - contains possible types for critical css files. Uses in configuration ``${config.criticalCSS.type}``. See [config](#config-) section\n    - **CRITICAL_CSS_TYPES.TEMPLATE** - generate [HTL](https://experienceleague.adobe.com/docs/experience-manager-htl/using/getting-started/getting-started.html?lang=en#getting-started) files.\n    - **CRITICAL_CSS_TYPES.USEAPI** - generate [JS](https://experienceleague.adobe.com/docs/experience-manager-htl/using/htl/use-api-javascript.html?lang=en#a-simple-example) files.\n- **INJECTION_TYPES** _{constants}_ - contains possible values for configuration ``${config.criticalCSS.injectionType}``. Also that values can be used in \"**@aem-critical-css-inectiontype**\" attribute.\n    - **INJECTION_TYPES.INLINE** - inject css with ``\u003cstyle\u003e`` tag. (see [Injection type - Inline](#injection-type---inline-as-a-part-of-html)) \n    - **INJECTION_TYPES.LINK** -  inject css with ``\u003clink href=\"....\"\u003e`` tag. (see [Injection type - Link](#injection-type---link-as-a-css-file))\n    - **INJECTION_TYPES.AUTO** -  resolve injection type automatically. By default, if _filesize_(after gzip) is lower **10kb**, then **INLINE** type will be used, otherwise **LINK**. See [config](#config-) section\n\n\n## Config 🦖\nDefault config file here: [/main/lib/config.js](https://github.com/dmantsevich/aem-critical-css/blob/main/lib/config.js)\n\n| Property      | Description   |\n| --------      |---------------|\n| `AEM.projectRoot`     |  *{String}* Path to AEM Project root folder. Default value: `./../`(parent folder) |\n| `AEM.components`     | *{String}* Path to [HTL templates](https://experienceleague.adobe.com/docs/experience-manager-htl/using/getting-started/getting-started.html?lang=en#blocks-and-expressions) which should be processed. Path should be relative to `${config.AEM.projectRoot}`. Default value: `ui.apps/src/main/content/jcr_root/apps/` |\n| `criticalCSS.file`     | *{String}* Name for output(generated) files. Result filename: `${config.criticalCSS.file}.${config.criticalCSS.type}`. See [Regular Workflow](#regular-workflow-) section. Default value: `_aem-critical-css` |\n| `criticalCSS.type`     | *{[CRITICAL_CSS_TYPES.USEAPI](#api-) / [CRITICAL_CSS_TYPES.TEMPLATE](#api-)}* Output file type. Default value: `CRITICAL_CSS_TYPES.USEAPI` |\n| `criticalCSS.injectionType`     |  *{[INJECTION_TYPES.AUTO](#api-) / [INJECTION_TYPES.INLINE](#api-) / [INJECTION_TYPES.LINK](#api-)}* Default injection type (if `@aem-critical-css-injectiontype` attribute isn't defined). Default value: `INJECTION_TYPES.AUTO`  |\n| `criticalCSS.injectionTypeAutoResolver`     | *{Function(**criticalCSSDefObj**)}* Function-Resolver for `INJECTION_TYPES.AUTO`. Calling for each AEM Critical CSS definition. Should return `INJECTION_TYPES.INLINE` or `INJECTION_TYPES.LINK`. By default: based on CSS GZip size(`getGzip(css) \u003c config.criticalCSS.gzipSize ? INJECTION_TYPES.INLINE : INJECTION_TYPES.LINK`). See `criticalCSS.gzipSize` option.  |\n| `criticalCSS.gzipSize`     | *{Integer}* Default value: **10kb**. If CSS GZip size lower than is value, then css will be injected - `INJECTION_TYPES.INLINE`. Otherwise: `INJECTION_TYPES.LINK`. Working only with default `criticalCSS.injectionTypeAutoResolver` |\n| `criticalCSS.sourceAttr`     | *{String}* Attribute with path to css source file. Default value: `@aem-critical-css` |\n| `criticalCSS.injectionTypeAttr`     | *{String}* Attribute with injection type configuration. If attribute isn't present, then `criticalCSS.injectionType` value will be used. Default value: `@aem-critical-css-injectiontype` |\n| `criticalCSS.serviceAttr`     | *{String}* Attribute with path (should be relative to jcr_root) to custom injector service. Default value: `@aem-critical-css-service`. Level: _Expert_. |\n| `criticalCSS.useAPIService`     | *{String}* Path (should be relative to jcr_root) to default JS/Java css injector service. By default: **built-in service** ([AEMCriticalCSSService.js](https://github.com/dmantsevich/aem-critical-css/blob/main/lib/aem-critical-css/AEMCriticalCSSService.js)). Level: _Expert_. |\n| `criticalCSS.AEMCriticalCSSServiceDestination`     | *{String}* Path, where build-in ([AEMCriticalCSSService.js](https://github.com/dmantsevich/aem-critical-css/blob/main/lib/aem-critical-css/AEMCriticalCSSService.js)) file will be saved. Default value: `ui.apps/src/main/content/jcr_root/apps/aem-critical-css/utils/`. Level: _Expert_. |\n| `criticalCSS.minifyOutput`     | *{Boolean}* Minify output(for generated *_aem-critical-css.html, _aem-critical-css.js* files). Default value: `true` |\n\n\n\n### Injection type - Inline (as a part of HTML)\nFor **small or important(critical)** css files, that type is more - preferable. Because request to small files can be bigger (+ non-blocking rendition), than css content.\n\nHTML output for component/critical css file will be (just example):\n```html\n\u003c!-- @aem-critical-css: path/to/component-css.less --\u003e\n\u003cstyle\u003e/*2021-2-21 0:49:06*/.my-component{border:1px solid red}.my-component a{border:1px solid green}\u003c/style\u003e\n``` \n\n### Injection type - Link (as a css file)\nThat type is better for rarely used components on site pages. That files can be cached in user browser.\n\nHTML output for component/critical css file will be (just example):\n```html\n\u003c!-- @aem-critical-css: path/to/component-css.less --\u003e\n\u003clink href=\"/etc.clientlibs/aem-critical-css/resources/path/to/component-css.1ha51609gjk2.css\" rel=\"stylesheet\"/\u003e\n```\n\n\n## Partial CSS injection 🐇\nShould helps to split \u0026 inject only necessary CSS for your component (depends on component configuration)\n  \nTBD \n\n## Custom Services\nWill describe how to create own service\n\nTBD\n\n## Best practice 🦗\n- Add **_aem-critical-css.js**, **_aem-critical-css.html** files (see [config](#config-)) to your [.gitignore](https://github.com/github/gitignore) file\n- Add **ui.apps/src/main/content/jcr_root/apps/aem-critical-css/** folder (see [config](#config-)) to your [.gitignore](https://github.com/github/gitignore) file\n\nTBD\n\n## FAQ 🦆\nIf you have any questions or you need help, feel free to ask via github: [Issues](https://github.com/dmantsevich/aem-critical-css/issues)\n\nMost popular questions/answers will be here\n\nTBD\n\n\n## Roadmap 🦙\nTBD\n\n## Links 🐙\n\n[![@dmantsevich/aem-critical-css](static/npm-logo.png)](https://www.npmjs.com/package/@dmantsevich/aem-critical-css)\n\n[![dmantsevich/aem-critical-css](static/github-logo.png)](https://github.com/dmantsevich/aem-critical-css)\n\n[![Adobe Experience Manager](static/AEM-logo.png)](https://www.adobe.com/ru/marketing/experience-manager.html)\n\n\n🧰 \n\n---\n**2021**","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmantsevich%2Faem-critical-css","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmantsevich%2Faem-critical-css","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmantsevich%2Faem-critical-css/lists"}