Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
HTML Compressor in Shopify Liquid
{% comment %}
Input
{% endcomment %}{% capture _content %}{{ content }}{% endcapture %}{% comment %}
Remove redundant closing tags
{% endcomment %}{% assign _endings = "html head body li dt dd p rt rp optgroup option colgroup caption thead tbody tfoot tr td th" | split: " " %}{% for _element in _endings %}
{% capture _end %}</{{ _element }}>{% endcapture %}
{% assign _content = _content | remove: _end %}
{% endfor %}{% comment %}
Create a variable to match newlines
{% endcomment %}{% capture nl %}
{% endcapture %}{% comment %}
Prepare inline <script>'s for compression
- We have to ensure a space after every </script> otherwise Liquid won't match, and blow up everything if two elements comes straight after eachother: <script></script><div></div>
{% endcomment %}{% assign _content = _content | replace: '</script>', '</script><!-- [SPACE] -->' | replace: '<!-- [SPACE] -->', " " %}{% assign _script_befores = _content | split: "<script" %}{% assign _content = "" %}{% for _script_before in _script_befores %}
{% assign _scripts = _script_before | split: "</script>" %}
{% case _scripts.size %}
{% when 2 %}
{% assign _script = _scripts.first |
replace: "// //", "/*[COMMENT]*/ " |
replace: "// //", "/*[COMMENT]*/ " |
replace: "// ", "/*[COMMENT]*/ " |
replace: " //", "/*[COMMENT]*/ " |
replace: " //", "/*[COMMENT]*/ " |
replace: "// ", "/*[COMMENT]*/ " |
replace: "//<![CDATA[", "/*[COMMENT]*/ " |
replace: "//]]>", "/*[COMMENT]*/ " |
%}
{% assign _script_comment_befores = _script | split: "/*[COMMENT]*/ " %}{% for _script_comment_before in _script_comment_befores %}
{% assign _script_comment_content = _script_comment_before | split: nl | first %}
{% if _script_comment_content %}
{% capture _script_comment %}{{ "/*[COMMENT]*/ " }}{{ _script_comment_content }}{{ nl }}{% endcapture %}
{% assign _script = _script | remove: _script_comment %}
{% endif %}
{% endfor %}
{% assign _script_comment_befores = _script | split: "/*" %}{% for _script_comment_before in _script_comment_befores %}
{% assign _script_comment_content = _script_comment_before | split: "*/" | first %}
{% if _script_comment_content %}
{% capture _script_comment %}{{ "/*" }}{{ _script_comment_content }}{{ "*/" }}{% endcapture %}
{% assign _script = _script | remove: _script_comment %}
{% endif %}
{% endfor %}
{% capture _content %}{{ _content }}<script {{ _script }}</script>{{ _scripts.last }}{% endcapture %}
{% when 1 %}
{% capture _content %}{{ _content }}{{ _scripts.last }}{% endcapture %}
{% endcase %}
{% endfor %}{% comment %}
Cleanup
- There is an 'missing semicolon' issue with Shopify's Enhanced Ecommerce for Google Analytics, which gets corrected here as well.
- There is an 'missing semicolon' issue with Shopify's inline Admin Panel script, which gets corrected here as well.
{% endcomment %}{% assign _content = _content | replace: '<script >', '<script>' | replace: '<script ', '<script ' | replace: 'analytics.onload = onload', ';analytics.onload = onload' | replace: 'analytics.async = true;', ';analytics.async = true;' | replace: 'if (window.addEventListener){ addEventListener("message", ', ';if (window.addEventListener){ addEventListener("message", ' %}{% comment %}
Compress whitespace outside of <pre>
- We have to ensure a space after every </pre> otherwise Liquid won't match, and blow up everything if two elements comes straight after eachother: <pre></pre><div></div>
{% endcomment %}{% assign _content = _content | replace: '</pre>', '</pre><!-- [SPACE] -->' | replace: '<!-- [SPACE] -->', " " %}{% assign _pre_befores = _content | split: "<pre" %}{% assign _content = "" %}{% for _pre_before in _pre_befores %}
{% assign _pres = _pre_before | split: "</pre>" %}
{% case _pres.size %}
{% when 2 %}
{% capture _content %}{{ _content }}<pre{{ _pres.first }}</pre>{{ _pres.last | split: " " | join: " " }}{% endcapture %}
{% when 1 %}
{% capture _content %}{{ _content }}{{ _pres.last | split: " " | join: " " }}{% endcapture %}
{% endcase %}
{% endfor %}{% comment %}
Remove html comments
- Matching just "<!--" and "-->" will whipe out IE Conditional Comments, which you probably don't want
{% endcomment %}{% assign _comment_befores = _content | split: "<!-- " %}{% for _comment_before in _comment_befores %}
{% assign _comment_content = _comment_before | split: " -->" | first %}
{% if _comment_content %}
{% capture _comment %}{{ "<!-- " }}{{ _comment_content }}{{ " -->" }}{% endcapture %}
{% assign _content = _content | remove: _comment %}
{% endif %}
{% endfor %}{% comment %}
Clip whitespace around elements
{% endcomment %}{% assign _clippings = "html head title base link meta style body article section nav aside h1 h2 h3 h4 h5 h6 hgroup header footer address p hr blockquote ol ul li dl dt dd figure figcaption main div table caption colgroup col tbody thead tfoot tr td th option img script" | split: " " %}{% for _element in _clippings %}
{% assign _edges = " <e;<e; </e>;</e>;</e> ;</e>" | replace: "e", _element | split: ";" %}
{% assign _content = _content | replace: _edges[0], _edges[1] | replace: _edges[2], _edges[3] | replace: _edges[4], _edges[5] %}
{% endfor %}{% comment %}
Output
{% endcomment %}{{ _content }}
@mib32

This comment has been minimized.

Copy link

mib32 commented Sep 1, 2017

Hello Jimmy! Very nice one. Works really great.

Can i use it?

@ccharneca

This comment has been minimized.

Copy link

ccharneca commented Sep 11, 2017

Hi. how do I use this on my store?

@n2q

This comment has been minimized.

Copy link

n2q commented Jun 11, 2018

Hi @JimmyRittenborg
Can I use this snippet for my store? and how do I use it?

Thank you

@irbrandon

This comment has been minimized.

Copy link

irbrandon commented Aug 17, 2018

This is dope! How can I adapt this to incorporate mini .scss and .js as well?

@ruinyourfun

This comment has been minimized.

Copy link

ruinyourfun commented Sep 19, 2018

Hi Jimmy! Is there any way you can explain how to use it with the Shopify liquid templates architecture? Thanks so much.

@vikramsakariya

This comment has been minimized.

Copy link

vikramsakariya commented Jun 19, 2019

Hello Jimmy! Very nice one. Works really great.

Can i use it?

Hello Mib,
You know how this code will be use in liquid code file?

@voigtnathan

This comment has been minimized.

Copy link

voigtnathan commented Jun 21, 2019

Hi Jimmy!
May I use this? And would I put it in the head or at the top of my theme.liquid?
Cheers,
Nate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.