Replace global FontAwesome with icon snippet - #39
Conversation
There was a problem hiding this comment.
Pull request overview
This PR replaces the global Font Awesome kit-based icon usage with a self-hosted inline-SVG approach via a new snippets/icon.liquid, and updates Liquid templates + CSS selectors accordingly so the theme no longer depends on loading Font Awesome in the page header.
Changes:
- Removed the Font Awesome kit
<script>includes from all layouts. - Added
snippets/icon.liquidand replaced<i class="fa...">usages with{% render 'icon' %}calls across snippets/sections. - Updated CSS to style
.iconSVGs (including spin animation) and to target the new markup.
Reviewed changes
Copilot reviewed 23 out of 24 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| snippets/icon.liquid | Introduces the inline SVG icon renderer and the icon subset mapping. |
| snippets/socials.liquid | Replaces social <i> icons with render 'icon' calls. |
| snippets/sidebar-navigation.liquid | Replaces navigation icons and caret icons with the icon snippet. |
| snippets/collection-navigation.liquid | Replaces navigation icons/carets with the icon snippet. |
| snippets/product-page-preview.liquid | Replaces carousel control icons with the icon snippet. |
| snippets/pagination.liquid | Replaces pagination chevrons with the icon snippet. |
| snippets/form.liquid | Replaces success/error icons with the icon snippet. |
| sections/header.liquid | Replaces header search/menu/cart spinner icons with the icon snippet and updates class hooks. |
| sections/footer.liquid | Replaces payment method icons with the icon snippet (with accessible titles). |
| sections/search.liquid | Replaces breadcrumb chevron icon with the icon snippet. |
| sections/product-page.liquid | Replaces breadcrumb chevron icon with the icon snippet. |
| sections/reset-password-form.liquid | Replaces breadcrumb chevron icon with the icon snippet. |
| sections/activate-account.liquid | Replaces badge icon with the icon snippet. |
| layout/theme.liquid | Removes Font Awesome kit script include. |
| layout/session.liquid | Removes Font Awesome kit script include. |
| layout/minimal.liquid | Removes Font Awesome kit script include. |
| layout/checkout.liquid | Removes Font Awesome kit script include. |
| assets/base.css | Adds base .icon / .icon--spin styles and keyframes. |
| assets/core.min.css | Adds .icon / .icon--spin styles and keyframes to the minified bundle. |
| assets/header.css | Updates spinner selectors and replaces external SVG URL with data URI. |
| assets/footer.css | Updates payment icon styling to target .icon SVGs. |
| assets/form.css | Updates form info icon styling to target .icon SVGs. |
| assets/pagination.css | Updates pagination icon styling to target .icon SVGs. |
| assets/sidebar-navigation.css | Updates sidebar icon selectors to target .icon SVGs. |
Files not reviewed (1)
- assets/core.min.css: Generated file
Comments suppressed due to low confidence (12)
sections/header.liquid:103
- The search close control is icon-only, and the rendered icon is
aria-hiddenby default, leaving the control without an accessible name for screen readers. Add an explicitaria-labelto the label.
<label class="header-search__trigger" for="floating-search">
{% render 'icon', name: 'xmark', style: 'light', class: 'header-search__icon close' %}
snippets/socials.liquid:12
- This social link is icon-only; without an accessible label, screen readers will announce it as an unlabeled link. Add
aria-label(andrelfor target=_blank safety).
<a href="{{ settings.social_facebook_link }}" target="_blank" class="footer__social-item">
{% render 'icon', name: 'facebook', style: 'brands' %}
snippets/socials.liquid:19
- This social link is icon-only; without an accessible label, screen readers will announce it as an unlabeled link. Add
aria-label(andrelfor target=_blank safety).
<a href="{{ settings.social_pinterest_link }}" target="_blank" class="footer__social-item">
{% render 'icon', name: 'pinterest', style: 'brands' %}
snippets/socials.liquid:26
- This social link is icon-only; without an accessible label, screen readers will announce it as an unlabeled link. Add
aria-label(andrelfor target=_blank safety).
<a href="{{ settings.social_instagram_link }}" target="_blank" class="footer__social-item">
{% render 'icon', name: 'instagram', style: 'brands' %}
snippets/socials.liquid:33
- This social link is icon-only; without an accessible label, screen readers will announce it as an unlabeled link. Add
aria-label(andrelfor target=_blank safety).
<a href="{{ settings.social_tiktok_link }}" target="_blank" class="footer__social-item">
{% render 'icon', name: 'tiktok', style: 'brands' %}
snippets/socials.liquid:40
- This social link is icon-only; without an accessible label, screen readers will announce it as an unlabeled link. Add
aria-label(andrelfor target=_blank safety).
<a href="{{ settings.social_tumblr_link }}" target="_blank" class="footer__social-item">
{% render 'icon', name: 'tumblr', style: 'brands' %}
snippets/socials.liquid:47
- This social link is icon-only; without an accessible label, screen readers will announce it as an unlabeled link. Add
aria-label(andrelfor target=_blank safety).
<a href="{{ settings.social_snapchat_link }}" target="_blank" class="footer__social-item">
{% render 'icon', name: 'snapchat', style: 'brands' %}
snippets/socials.liquid:54
- This social link is icon-only; without an accessible label, screen readers will announce it as an unlabeled link. Add
aria-label(andrelfor target=_blank safety).
<a href="{{ settings.social_youtube_link }}" target="_blank" class="footer__social-item">
{% render 'icon', name: 'youtube', style: 'brands' %}
snippets/socials.liquid:61
- This social link is icon-only; without an accessible label, screen readers will announce it as an unlabeled link. Add
aria-label(andrelfor target=_blank safety).
<a href="{{ settings.social_vimeo_link }}" target="_blank" class="footer__social-item">
{% render 'icon', name: 'vimeo', style: 'brands' %}
snippets/sidebar-navigation.liquid:52
- These submenu toggle labels are icon-only; because the icon snippet defaults to
aria-hidden, the associated checkbox controls are effectively unlabeled for screen readers. Add anaria-labelto the label.
<label for="sidebar-navigation-menu-grandchild-{{ menu_index }}-{{ forloop.index }}{% if mode == "mobile" %}-mobile{% endif %}">
{% render 'icon', name: 'angle-down', style: 'regular', class: 'list-menu__item-caret' %}
snippets/collection-navigation.liquid:45
- These submenu toggle labels are icon-only; because the icon snippet defaults to
aria-hidden, the associated checkbox controls are effectively unlabeled for screen readers. Add anaria-labelto the label.
<label for="sidebar-navigation-menu-grandchild-{{child_collection.id}}{% if mode == "mobile" %}-mobile{% endif %}">
{% if current_url == url %}{% render 'icon', name: 'angle-down', style: 'solid', class: 'list-menu__item-caret' %}{% else %}{% render 'icon', name: 'angle-down', style: 'regular', class: 'list-menu__item-caret' %}{% endif %}
snippets/pagination.liquid:34
- This next-page link is icon-only; since the icon snippet is
aria-hiddenby default, the link ends up without an accessible name. Add anaria-labelto the .
href="{% if paginate.next != blank %}{{
paginate.next.url
}}{% else %}#{% endif %}"
>
{% render 'icon', name: 'chevron-right', style: 'solid' %}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Previously we were using classic FontAwesome embedding approach. We added the whole FontAwesome font in the header and then used
<i class="fa fa-chevron-left"></i>throughout the codebase.In this PR we remove the font awesome embedding, and instead create a
snippets/icon.liquidwhich has inlined SVGs for icons we actually used. This snippet was generated out of SVG icons we downloaded directly from FontAwesome so they should be an exact match.The rest of the PR is replacing the direct FontAwsome embedding with the new
render 'icon'snippet.Note: There were quite a few icons replaced in footer, I don't think we ever use these but I didn't want to remove them as part of this effort. We can remove more dead code in a follow-up PR.
Media
Before
After