{"id":27069069,"url":"https://github.com/jekyll/jekyll-assets","last_synced_at":"2026-01-12T00:44:43.777Z","repository":{"id":5158060,"uuid":"6326522","full_name":"envygeeks/jekyll-assets","owner":"envygeeks","description":":art: Asset pipelines for Jekyll.","archived":false,"fork":false,"pushed_at":"2024-02-20T15:08:38.000Z","size":6881,"stargazers_count":1112,"open_issues_count":52,"forks_count":169,"subscribers_count":23,"default_branch":"master","last_synced_at":"2024-10-29T17:24:24.820Z","etag":null,"topics":["asset-pipeline","assets","imagemagick","imageoptim","jekyll","jekyll-assets","liquid","sass","scss","sprockets","sprockets-4","uglifier"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"mattruggio/street-address","license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/envygeeks.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/codeowners","security":".github/security","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null},"funding":{"github":"envygeeks"}},"created_at":"2012-10-21T22:43:15.000Z","updated_at":"2024-10-28T16:46:50.000Z","dependencies_parsed_at":"2024-01-11T19:18:37.863Z","dependency_job_id":"085f9e43-3140-4ef4-b8d7-7aac34fd5aa0","html_url":"https://github.com/envygeeks/jekyll-assets","commit_stats":{"total_commits":1285,"total_committers":83,"mean_commits":"15.481927710843374","dds":0.2996108949416343,"last_synced_commit":"056d2c88719ef3b1f90967a606dd1441581dd832"},"previous_names":["ixti/jekyll-assets","jekyll/jekyll-assets"],"tags_count":81,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envygeeks%2Fjekyll-assets","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envygeeks%2Fjekyll-assets/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envygeeks%2Fjekyll-assets/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envygeeks%2Fjekyll-assets/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/envygeeks","download_url":"https://codeload.github.com/envygeeks/jekyll-assets/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247399871,"owners_count":20932876,"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":["asset-pipeline","assets","imagemagick","imageoptim","jekyll","jekyll-assets","liquid","sass","scss","sprockets","sprockets-4","uglifier"],"created_at":"2025-04-05T21:01:57.826Z","updated_at":"2025-04-05T21:04:30.506Z","avatar_url":"https://github.com/envygeeks.png","language":"Ruby","funding_links":["https://github.com/sponsors/envygeeks"],"categories":["Assets \u0026 Converters \u0026 Minifiers"],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.com/envygeeks/jekyll-assets.svg?branch=master)](https://travis-ci.com/envygeeks/jekyll-assets) [![Maintainability](https://api.codeclimate.com/v1/badges/56f67324553069bf51e7/maintainability)](https://codeclimate.com/github/envygeeks/jekyll-assets/maintainability)\n\n# Jekyll Assets\n\nJekyll Assets is a drop in [asset\npipeline](http://guides.rubyonrails.org/asset_pipeline.html) that uses\n[Sprockets](https://github.com/rails/sprockets) to build specifically\nfor Jekyll. It utilizes [Sprockets](https://github.com/rails/sprockets),\nand [Jekyll](https://jekyllrb.com) to try and achieve a clean, and\nextensible assets platform that supports plugins, caching, converting your\nassets. It even supports proxying of said assets in a way that does not\ninterfere with either [Sprockets](https://github.com/rails/sprockets),\nor [Jekyll](https://jekyllrb.com), or your own source.  By default you\ncan add Jekyll Assets to your Gemfile, as a plugin, and have it act as\na drop-in replacement for Jekyll's basic SASS processors, with you only\nhaving to add it to your Gemfile, and updating your `\u003cimg\u003e`, and `\u003clink\u003e`.\n\n## Installing\n\n```ruby\ngem \"jekyll-assets\", group: :jekyll_plugins\ngem \"jekyll-assets\", git: \"https://github.com/envygeeks/jekyll-assets\", group: :jekyll_plugins\ngem \"jekyll-assets\", \"~\u003e x.x.alpha\", group: :jekyll_plugins\n```\n\n---\n\n### System Requirements\n\n* `ruby`: ***2.6+***\n* `sprockets`: ***4.0+***\n* `uglifier`: ***4.0***\n* `jekyll`: ***3.5+***\n\n---\n\n## Configuration\n\nThe configuration file is the same as Jekyll's, which is `_config.yml`.\nExcept we use the special key called `assets` inside of that file.\nAll values listed below are default, you need not copy these into your\nconfiguration file unless you plan to change a value. *Setting a value makes\nit explicit, and shared across both **production**, and **development**.*\n\n```yaml\n# _config.yml\nassets:\n  source_maps: true\n  destination: \"/assets\"\n  compression: false\n  gzip: false\n  defaults:\n    integrity:\n      {css,img,js}: false\n  caching:\n    enabled: true\n    path: \".jekyll-cache/assets\"\n    type: file\n  # --\n  # Assets you wish to always have compiled.\n  #   This can also be combined with raw_precompile which\n  #   copies assets without running through the pipeline\n  #   making them ultra fast.\n  # --\n  precompile: []\n  raw_precompile: [\n    #\n  ]\n  # --\n  # baseurl: whether or not to append site.baseurl\n  # destination: the folder you store them in on the CDN.\n  # url: the CDN url (fqdn, or w/ identifier).\n  # --\n  cdn:\n    baseurl: false\n    destination: false\n    url: null\n  # --\n  # See lib/jekyll/assets/config.rb\n  #   for a list of defaults\n  # --\n  sources:\n    - _assets/custom\n  plugins:\n    css: { autoprefixer: {}}\n    img: { optim: {}}\n```\n\n## Tag `{% asset %}`, `\u003cimg\u003e`\n\n```html\n{% asset src @magick:double alt='This is my alt' %}\n{% asset src @magick:double alt='This is my alt' %}\n\u003cimg src=\"src\" asset=\"@magick:double\" alt=\"This is my alt\"\u003e\n\u003cimg src=\"src\" alt=\"This is my alt\" asset\u003e\n```\n\n## Defaults\n\nWe provide several defaults that get set when you run an asset, depending on\ncontent type, this could be anything from type, all the way to integrity.\n *If there is a default attribute you do not wish to be included, you can\ndisable the attribute with `!attribute`, and it will be skipped over.*\n\n```liquid\n{% asset img.png !integrity %}\n{% asset bundle.css !type   %}\n```\n\n### Arguments\n\nOur tags will take any number of arguments, arbitrary or not... and\nconvert them to HTML, and even attach them to your output if the\nHTML processor you use accepts that kind of data.  ***This applies\nto anything but hashes, and arrays.*** So adding say, a class, or\nid, is as easy as doing `id=\"val\"` inside of your tag arguments.\n\n#### Built In\n\n| Arg | Description | Type | Return Type |\n|---|---|---|---|\n| `@data` | `data` URI | `*/*` | `text` |\n| `@inline` | CSS `\u003cstyle\u003e` | `text/css` | `text/html` |\n| `@path` | Path | `*/*` | `text` |\n\n## Responsive Images\n### `\u003cimg\u003e` usage\n#### Configuration\n\n| Option | Tag Option | Type | Description |\n|---|---|---|---|\n| automatic | @automatic | Boolean | Upscale \u0026 Downscale images |\n| automatic_min_width | @min_width | Integer | Stop scaling before this width |\n| automatic_scales | scales | String | The scales to use |\n| discovery_scales | scales | String | The scales to look for |\n| automatic_upscale | @upscale | Boolean | Upscale, the source instead of downscale |\n| discovery | @discovery | Boolean | Responsive if an img matching source w/ @\u003cscale\u003ex exists |\n\n***Each option is in the responsive namespace regardless\nof whether it's inside of the tag, or configuration.***\n\n#### Example\n\n```liquid\n{% asset img.png @pic\n    srcset:max-width=\"200\"\n    srcset:min-width=\"200\"\n    srcset:scales=1x\n    srcset:scales=2x\n    srcset:scales=3x\n        %}\n```\n\n```html\n\u003cimg srcset=\"\n    img-\u003chash\u003e.png 3x,\n    img-\u003chash\u003e.png 2x,\n    img-\u003chash\u003e.png 1x\"\n        \u003e\n```\n\n#### Discovery\n\nWhen using discovery based responsive images, we will only do responsive\nimages if we can find assets that match your scales based on the source\nfile.  For example if you do `{% asset img.png responsive:discovery\nresponsive:scales=1x responsive:scales=1.5x responsive:scales=2x %}` then\nwe will expect `img.png@1.5x` and `img.png@2x` to exist.  For any image\nthat doesn't exist it will be skipped, and that scale will not be included!\n\n#### Automatic\n\nAutomatic responsive images/scaling can either upscale, or downscale.  This\nis useful if you have a ton of images for blog posts, and you always want to\nprovide a single most high quality version and then have us downscale those,\nor if you have an image and wish us to upscale it! The `argv1` of `{% asset\nimg.png %}` is where the source is derived from.  Given you give `2x`, `1.5x`\nand `1x` if you choose to downscale, the source will be assumed to be 2x,\nand we will downscale to 1.5x and half.  If you chose to upscale, the source\nwill be assumed to be 1x, and we will multiply the width by `1.5` and `2`\n\n\n## Liquid\n\nWe support liquid arguments for tag values (but not tag keys), and we also\nsupport Liquid pre-processing (with your Jekyll context) of most files if they\nend with `.liquid`.  This will also give you access to our filters as well as\ntheir filters, and Jekyll's filters, and any tags that are globally available.\n\n```liquid\n{% asset '{{ site.bg_img }}' %}\n{% asset '{{ site.bg_img }}' proxy:key='{{ value }}' %}\n{% asset {{\\ site.bg_img\\ }} %}\n```\n\n### `.sass`, `.scss`\n\n```scss\nbody {\n  background-image: asset_url(\"'{{ site.bg_img }}'\");\n  background-image: asset_url(\"'{{ site.bg_img }}' proxy:key='{{ value }}'\");\n  background-image: asset_url(\"{{\\ site.bg_img\\ }}\");\n}\n```\n\n### `.liquid.ext`\n### `.ext.liquid`\n\n#### Supported file types:\n\n- .css\n- .sass\n- .scss\n- .js\n- .es6\n- .coffee\n- .svg\n\nYou have full access to your entire global context from any liquid processing\nwe do.  Depending on where you do it, you might or might not also have\naccess to your local (page) context as well. You can also do whatever you\nlike, and be as dynamic as you like, including full loops, and conditional\nLiquid, since we pre-process your text files. *On Sprockets 4.x you can use\n`.liquid.ext` and `.ext.liquid`, but because of the way Sprockets 3.x works, we\nhave opted to only allow the default extension of `.ext.liquid` when running\non \"Old Sprockets\" (AKA 3.x.)  If you would like Syntax + Liquid you should\nopt to install Sprockets 4.x so you can get the more advanced features.*\n\n#### Importing\n\n***In order to import your Liquid pre-processed assets inside of Liquid or JS\n*you should use a Sprockets `//require=`, Sprockets does not integrate that\n*deeply into JavaScript and SASS to allow you to `@import` and pre-process.***\n\n## `.sass`, `.scss` Helpers\n\nWe provide two base helpers, `asset_path` to return the path of an asset,\nand `asset_url` which will wrap `asset_path` into a `url()` for you,\nmaking it easy for you to extract your assets and their paths inside of\nSCSS.  All other helpers that Sprockets themselves provide will use our\n`asset_path` helper, so you can use them like normal, *including with Liquid*\n\n```scss\nbody {\n  background-image: asset_url(\"img.png\");\n}\n```\n\n### Proxies, and Other Arguments\n\nAny argument that is supported by our regular tags, is also supported by\nour `.sass`/`.scss` helpers, with a few obvious exceptions (like `srcset`).\n This means that you can wrap your assets into `magick` if you wish, or\n`imageoptim` or any other proxy that is able to spit out a path for you\nto use.  The general rule is, that if it returns a path, or `@data` then\nit's safe to use within `.scss`/`.sass`, otherwise it will probably throw.\n\n```scss\nbody {\n  background-image: asset_url(\"img.png @magick:half\")\n}\n```\n\n*Note: we do not validate your arguments, so if you send a conflicting\n*argument that results in invalid CSS, you are responsible for that, in\n*that if you ship us `srcset` we might or might not throw, depending on how\n*the threads are ran. So it might ship HTML if you do it wrong, and it will\n*break your CSS, this is by design so that if possible, in the future, we can\n*allow more flexibility, or so that plugins can change based on arguments.*\n\n## Listing Assets in Liquid\n\nWe provide all *your* assets as a hash of Liquid Drops so you can\nget basic info that we wish you to have access to without having to\nprepare the class. **Note:** The keys in the `assets` array are the\nnames of the original files, e.g., use `*.scss` instead of `*.css`.\n\n```liquid\n{{ assets[\"bundle.css\"].content_type }} =\u003e \"text/css\"\n{{ assets[\"images.jpg\"].width  }} =\u003e 62\n{{ assets[\"images.jpg\"].height }} =\u003e 62\n```\n\nThe current list of available accessors:\n\n| Method         | Description                |\n| -------------- | -------------------------- |\n| `content_type` | The RFC content type       |\n| `filename`     | The full path to the asset |\n| `height`       | The asset height           |\n| `width`        | The asset width            |\n| `digest_path`  | The prefixed path          |\n| `integrity`    | The SRI hash               |\n\n### Looping\n\n```liquid\n{% for k,v in assets %}\n  {{ k }}\n{% endfor %}\n```\n\n### Dynamic\n\nUsing Liquid Drop `assets`, you can check whether an asset is present.\n\n```liquid\n{% if assets[page.image] %}{% img '{{ page.image }}' %}\n{% else %}\n  {% img default.jpg %}\n{% endif %}\n```\n\n## Filter\n\n```liquid\n{{ src | asset:\"@magick:double magick:quality=92\" }}\n```\n\n## Hooks\n\n| Point | Name | Instance | Args |\n| ---| --- | --- | --- |\n| `:env` | `:before_init` | ✔ | ✗ |\n| `:env` | `:after_init` | ✔ | ✗ |\n| `:env` | `:after_write` | ✔ | ✗ |\n| `:config` | `:before_merge` | ✗ | `Config{}` |\n| `:asset` | `:before_compile` | ✗ | `Asset`, `Manifest` |\n| `:asset` | `:after_compression` | ✗ | input{}, output{}, type=*/* |\n\n### Example\n\n```ruby\nJekyll::Assets::Hook.register :env, :before_init do\n  append_path \"myPluginsCustomPath\"\nend\n```\n\n```ruby\nJekyll::Assets::Hook.register :config, :init do |c|\n  c.deep_merge!({\n    plugins: {\n      my_plugin: {\n        opt: true\n      }\n    }\n  })\nend\n```\n\n#### Plugin Hooks\n\nYour plugin can also register it's own hooks on our Hook system,\nso that you can trigger hooks around your stuff as well,\nthis is useful for extensive plugins that want more power.\n\n```ruby\nJekyll::Assets::Hook.add_point(\n  :plugin, :hook\n)\n```\n\n```ruby\nJekyll::Assets::Hook.trigger(:plugin, :hook)  { |v| v.call(:arg) }\nJekyll::Assets::Hook.trigger(:plugin, :hook) do |v|\n  instance_eval(\u0026v)\nend\n```\n\n## Default Plugins\n### Google Closure Alternates\n```\ngem \"crass\"\n```\n\nOnce crass is added, we will detect vendor prefixes, and\nadd `/* @alternate */` to them, with or without compression\nenabled, and with protections against compression stripping.\n\n### Font Awesome\n\n```ruby\ngem \"font-awesome-sass\"\n```\n\n```scss\n@import \"font-awesome-sprockets\";\n@import \"font-awesome\";\nhtml {\n  // ...\n}\n```\n\n### CSS Auto-Prefixing\n\n```ruby\ngem \"autoprefixer-rails\"\n```\n\n```yml\nassets:\n  autoprefixer:\n    browsers:\n    - \"last 2 versions\"\n    - \"IE \u003e 9\"\n```\n\n### Bootstrap\n\n```ruby\ngem \"bootstrap-sass\" # 3.x\ngem \"bootstrap\"      # 4.x\n```\n\n```scss\n@import 'bootstrap';\nhtml {\n  // ...\n}\n```\n\n```scss\n//=require _bootstrap.css\n//=require bootstrap/_reboot.css\n```\n\n### ImageMagick\n\n```ruby\ngem \"mini_magick\"\n```\n\n#### Args\n\nSee the [MiniMagick docs](https://github.com/minimagick/minimagick#usage)\nto get an idea what `\u003cvalue\u003e` can be.\n\n| Name                        | Accepts Value |\n| --------------------------- | ------------- |\n| `magick:compress`           | ✔             |\n| `magick:resize`             | ✔             |\n| `magick:format`\u003csup\u003e*\u003c/sup\u003e | ✔             |\n| `magick:quality`            | ✔             |\n| `magick:rotate`             | ✔             |\n| `magick:gravity`            | ✔             |\n| `magick:crop`               | ✔             |\n| `magick:extent`             | ✔             |\n| `magick:flip`               | ✔             |\n| `magick:background`         | ✔             |\n| `magick:transparency`       | ✔             |\n| `@magick:double`            | ✗             |\n| `@magick:half`              | ✗             |\n\n\u003csup\u003e\\*\u003c/sup\u003e *`magick:format` requires an ext or a valid MIME content type like `image/jpeg` or `.jpg`.  We will `ImageMagick -format` on your behalf with that information by getting the extension.*\n\n### ImageOptim\n\n```ruby\ngem \"image_optim\"\ngem \"image_optim_pack\" # Optional\n```\n\n#### Configuration\n\n```yml\nassets:\n  plugins:\n    img:\n      optim:\n        {}\n```\n\nCheck the [ImageOptim](https://github.com/toy/image_optim#configuration) to get idea about configuration options, and to get a list of stuff you need to install on your system to use it, if you do not wish to use \"image_optim_pack\".\n\nTo disable ImageOptim (i.e. for development builds), use following configuration:\n\n```yml\nassets:\n  plugins:\n    img:\n      optim: false\n```\n\n#### Args\n\n| Name                              | Accepts Value |\n| --------------------------------- | ------------- |\n| `optim`                           | ✔             |\n| `@optim`                          | ✗             |\n\n***By default `@optim` will use the default `jekyll`, otherwise you can provide `optim=preset` and have it used that preset.  ImageOptim provides advanced, and default as their default presets, you can define your own preset via Jekyll Assets configuration listed above.***\n\n### LibVIPS\n\n```ruby\ngem \"ruby-vips\"\n```\n\nThe \"ruby-vips\" gem requires a functional install\nof (libvips)[https://github.com/libvips/libvips/].\n\n#### Args\n\n| Name                  | Accepts Value |\n| --------------------- | ------------- |\n| `vips:crop`           | ✔             |\n| `vips:resize`         | ✔             |\n| `vips:format`         | ✔             |\n| `vips:quality`        | ✔             |\n| `vips:compression`    | ✔             |\n| `@vips:near_lossless` | ✗             |\n| `@vips:interlace`     | ✗             |\n| `@vips:lossless`      | ✗             |\n| `vips:strip`          | ✔             |\n| `@vips:strip`         | ✗             |\n| `@vips:double`        | ✗             |\n| `@vips:half`          | ✗             |\n\n##### vips:resize\n\nAccepts an argument of either 'width', 'x\u003cheight\u003e' or '\u003cwidth\u003ex\u003cheight\u003e'.\nAll resize processes keep the original aspect ratio so width and\nheight are used to specify the bounding box for the resize process.\n\nIf no height is specified the image is resized to fit withing a\nbounding box of 'width' x 'width'. Similarly specifying just a\nheight sets the bounding box for the resize to 'height' x 'height'.\nThis form only exists for compatibility with the \"magick\" plugin.\n\n```liquid\n{% asset img.png vips:resize='x100' %}\n{% asset img.png vips:resize='100x50' %}\n{% asset img.png vips:resize='100x' %}\n```\n\n##### vips:format\n\nConvert the image to the specified format. Format support\ndepends on the compile options of the libvips library. Format is\nspecified as the file extension such as '.jpg', '.webp' or '.png'.\n\n```liquid\n{% asset image.png vips:format='.webp' %}\n```\n\n##### vips:crop\n\nOnly has any effect when combined with \"vips:resize\". Use\nthe following arguments (all except \"fill\" are documented\n[here](http://libvips.github.io/libvips/API/current/libvips-conversion.html#VipsInteresting)):\n\n* fill: resize the image to the specified size while maintaining the\n        aspect ratio then fills the \"empty\" background with blurred version\n        of the original image\n* entropy: use an entropy measure\n* high: position the crop towards the high coordinate\n* attention: look for features likely to draw human attention\n* low: position the crop towards the low coordinate\n* centre: crop from the centre\n* none: do nothing\n\n```liquid\n{% asset image.jpg vips:resize='100' vips:crop='fill' %}\n```\n\n##### vips:strip\n\nRemoves metadata from images. This is set \"true\" by\ndefault, but can be disabled by passing \"false\".\n\n```liquid\n{% asset image.jpg vips:strip=false %}\n```\n\n### Building Your Own Plugins\n#### Globals\n\n| Name      | Class                   |\n| --------- | ----------------------- |\n| `env`    | `Jekyll::Assets::Env`   |\n| `args`   | `Liquid::Tag::Parser{}` |\n| `jekyll` | `Jekyll::Site`          |\n| `asset`  | `Sprockets::Asset`      |\n\n#### HTML\n\n| Name   | Class                      | Type            |\n| ------ | -------------------------- | --------------- |\n| `@doc` | `Nokogiri:: XML::Document` | `image/svg+xml` |\n| `@doc` | `Nokogiri::HTML::Document` | `image/*`       |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjekyll%2Fjekyll-assets","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjekyll%2Fjekyll-assets","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjekyll%2Fjekyll-assets/lists"}