Development Guide: Customizing and Working with the Flex Theme
We've built Flex not only for merchants who love tinkering with a myriad of settings and want full control over their theme and customization options, but for developers and agencies looking to use the Flex theme to build something truly unique and one-of-a-kind for clients.
With that said, we're going to provide an overview of the code within the Flex theme, take a look under the hood so to say, and point out some key features and best practices that'll make customizing your theme that much easier with this handy Development Guide!
In This Article
- Flex Template Overview
- Notable Code Blocks
- Theme Kit Considerations
- Development Best Practices
- Adding Custom Icons
- Hide Sections on Desktop/Mobile
Flex Template Overview
Taking a closer look into some of the template structure within Flex. To follow along and locate files, open up the Flex theme within a code editor of your choice (Visual Code Studio, Sublime Text, Atom etc).
assets
folder
All the functionality (JavaScript) and style (CSS/SCSS) files will be located within the assets
folder.
scripts
folder
In many Shopify themes, you'll normally find a theme.js
or an app.js
that contains all of the JavaScript for the theme. In our other themes, we have an app.js.liquid
.
While Flex still contains an app.js.liquid
file within the assets
folder, if you view the theme in a code editor, you'll see that the JavaScript has been divided into folders, and then into additional files.
Within the assets
folder, there is a scripts
folder that contains: currencyConversion
(for the currency converter), sections
, utilities
, and vendors
.
sections
Folder
Each section has it's own JavaScript file that is found within the sections
folder, for example: jsFeaturedCollection.js
for the Featured Collection section, jsSlideshow.js
for the Slideshow section etc. We've done this to be more performance and resource friendly, instead of having all of the JavaScript in one large file. Here's what the structure looks like inside the sections
folder:
Each JavaScript file within sections
folder will only be called when that respective object is loaded in the theme editor. The JavaScript files are named using the same class names assigned in their respective sections schema. Flex then looks for the class in the schema, finds the JavaScript file with the same name and then loads it in.
Example
jsVideo
for example, if you search for jsVideo
in the theme
It’s present in the schema class portion of index__video
(homepage), page-details__main
(page.details).
So it will run when that section is loaded:
Throughout the JavaScript files, sometimes we will refer to properties of the object that don’t exist in the file. But that’s what this line is doing, (adding settings from schema to current object).
So for video JavaScript we are adding these variables from the settings via the schema:
These then become variables in the JavaScript files we can access by writing: this.autoplay
for example.
utilities
folder
The utilities
folder includes all the global functions for the theme. If you open up the Flex theme in your code editor, you'll see that within the utilities
folder, all the global functions are separated into a JavaScript file per global function:
So here, you'd have all the functionalities related to theme wide elements. For example, there is an animation.js
since the animation JavaScript gets used in all sorts of places across the theme (pages, sections), thumbnail.js
since thumbnails appear in multiple areas (product page, collection, featured collections).
If you view the Flex theme in the Shopify Admin > Edit Code view, you'll see that all of these separate utilities
files all get compiled into one utilities.js
file.
vendors
folder
The vendors folder includes all of the JavaScript for any third-party code (external libraries, plugins, dependencies). If you open up the Flex theme in your code editor, you'll see that within the vendors
folder, there is a JavaScript file for each third party library:
If you view the Flex theme in the Shopify Admin > Edit Code view, you'll see that all of these separate vendors
files all get compiled into one vendors.js
file.
app.js.liquid
file
As mentioned above, the app.js.liquid
file is still included within the Flex theme code. Instead of containing all functionailty, app.js.liquid
includes:
- Theme editor events (
reorder
,load
,unload
,select
, anddeselect
): during each event, for example, load, we’re loading the respective JavaScript for that section, but we’re also loading any required utility functions (global functions). - Document ready: where we initialize everything for the first time in terms of logic.
- Window resize function: triggers events whenever the window changes from mobile to desktop.
styles
folder
When the Flex theme is opened in your code editor, you'll see within the assets
folder, there is a styles
folder. Within the styles
folder, there will be an additional folder structure that contains SCSS (a.k.a SASS) files: components
, elements
, layout
, product
, sections
, templates
, vendors
. As well as additional SCSS files that are for the base of the theme.
All sections have their own SCSS files. If you're looking to edit or customize code for a specific section, you can do so directly in its SCSS file. Code from all of the SCSS files will then get compiled into styles.scss.liquid
.
What may also be worth pointing out here, classes from the SCSS files can brought over to the Custom CSS feature in Flex to make use of existing styles and apply them to sections directly in the theme editor.
Gulp and Using a Build Tool
Gulp
Gulp is a build tool that we've used for developing the Flex theme. However, you can use whatever build tool you'd like. You don't have to use Gulp, but it is already built into the theme! Since all of the scripts and styles files are split up, if you make any edits to these files or create new ones, they will need to get compiled by running a build tool.
Breakdown of Gulp:
- Combines all of the
SCSS
into one file,styles.scss.liquid
- Combines all of the vendor (external JavaScript) into
vendors.js
- Combines all of the utility functions into
utilities.js
- Combines all of the currency logic into
currencyConversion.js
- Runs our JavaScript through Babel
- Babel is a JavaScript transpiler that converts + downgrades ES6 JavaScript into plain old ES5 JavaScript that can run in any browser (even the old ones).
- Example:
const
andlet
(keywords from ES6) get converted intovar
for older browsers.
- Babel is a JavaScript transpiler that converts + downgrades ES6 JavaScript into plain old ES5 JavaScript that can run in any browser (even the old ones).
All of the tasks are outlined in gulp/watch.js
. All of the scripts and styles files are added here so they can get compiled. If you were to create a new SCSS
file or add a new scripts
file, they need to get added to gulp/watch.js
as well in order to get compiled.
Setting up your Flex project to use Gulp
In order to use Gulp, you'll need to open up your terminal. When actively working on the theme, you'll need to make sure you're running Gulp.
Step 1: In one terminal window, run npm install
.
Step 2: In one terminal window, navigate to your theme folder and run the gulp watch
command.
Step 3: If you're using Theme Kit, in a separate terminal window, navigate to your theme folder and run the theme watch
command.
sections, templates, snippets
folders
All the liquid code for the Flex theme (except for theme.liquid
and password.liquid
in the layouts
folder) can be found in the sections
, templates
and snippets
folders.
The main markup for sections and pages will be within its section
file. The template
file for the section or page will pull in the content from the section
file, and otherwise, just have some code for structure such as container
or section
elements.
For example, the article.liquid
template file pulls in all the code from the section files that relate to the article template: article__banner
, article__sidebar
and article__main
.
Snippet
files contain small blocks of reusable code (ex. image-element
or header-divider
). Many snippets also take in variables that can change how the block of code is displayed. Each snippet will have it’s variables described in the top of the file.
Product Templates
Another key difference in Flex's code structure, compared to other themes, are the product template files.
In a lot of Shopify themes, and in instructions for app integrations, you'll hear of a product-template.liquid
file. This is normally where all the code for the product template lives, and where you can add third-party app code for your products.
However, the Flex theme has a different file and code structure for its product templates as there are 3 of them to choose from!
There is no product-template.liquid
file in the theme.
Instead, under templates
, there are: product.liquid
, product.classic.liquid
, product.scrolling.liquid
, product.sections.liquid
files. In each template
file, the corresponding section
will get pulled in:product__main.liquid
, product-image-scroll__main.liquid
, product-sections__main.liquid
.
The template
files also pull in the product__sidebar.liquid
and product__recommendations.liquid
section
files for the sidebar and product recommendations which are both product page features.
Within the section
files: product__main.liquid
, product-image-scroll__main.liquid
, product-sections__main.liquid
, product__form.liquid
and product__images.liquid
are two key snippet
files that get pulled in.
The product__form.liquid
file contains the code relating to the product form (add to cart, quantity box, price etc.) while the product__images.liquid
file contains the code relating to the product gallery and thumbnail images.
Notable Code Blocks
js-variables.liquid
file
Located within the snippets
folder, the js-variables.liquid
file is where you can store any liquid variables that you want to reference in your JavaScript on global namespaced objects - allows you to run linters on your JavaScript!
Within this file, you'll find variables for breakpoints for screensizes, translations, currency, and some theme settings.
For example, if you can adjust translations here:
Shopify.translation = Shopify.translation || {};
Shopify.translation.product_savings = "{{ 'products.product.savings' | t | strip_newlines | escape }}";
Shopify.translation.free_price_text = "{{ settings.free_price_text }}";
{% comment %} Notify form {% endcomment %}
Shopify.translation.notify_form_success = "{{ 'products.notify_form.post_success' | t | strip_newlines | escape }}";
Shopify.translation.notify_form_email = "{{ 'products.notify_form.email' | t | strip_newlines | escape }}";
Shopify.translation.contact_email = "{{ contact.fields.email }}";
Shopify.translation.customer_email = "{{ customer.email }}";
Shopify.translation.notify_form_send = "{{ 'products.notify_form.send' | t | strip_newlines | escape }}";
Shopify.translation.message_content = "{{ 'products.notify_form.message_content' | t | strip_newlines | escape }}"
{% comment %} Cart {% endcomment %}
Shopify.translation.cartItemsOne = "{{ 'layout.counts.items.one' | t | strip_newlines | escape }}";
Shopify.translation.cartItemsOther = "{{ 'layout.counts.items.other' | t | strip_newlines | escape }}";
Shopify.translation.addToCart = "{{ 'products.product.add_to_cart' | t | strip_newlines | escape }}";
Shopify.translation.soldOut = "{{ 'products.product.sold_out' | t | strip_newlines | escape }}";
Shopify.translation.unavailable = "{{ 'products.product.unavailable' | t | strip_newlines | escape }}";
{% comment %} Product {% endcomment %}
Shopify.translation.product_count_one = "{{ 'products.product.items_left_count.one' | t | strip_newlines | escape }}";
Shopify.translation.product_count_other = "{{ 'products.product.items_left_count.other' | t | strip_newlines | escape }}";
Shopify.translation.sold_out = "{{ 'products.product.sold_out' | t | strip_newlines | escape }}";
Shopify.translation.savings = "{{ 'products.product.savings' | t | strip_newlines | escape }}";
Shopify.translation.best_seller = "{{ 'collections.general.best_seller' | t | strip_newlines | escape }}"
Shopify.translation.coming_soon = "{{ 'collections.general.coming_soon' | t | strip_newlines | escape }}"
Shopify.translation.new = "{{ 'collections.general.new' | t | strip_newlines | escape }}"
Shopify.translation.pre_order = "{{ 'collections.general.pre_order' | t | strip_newlines | escape }}"
Shopify.translation.sale = "{{ 'collections.general.sale' | t | strip_newlines | escape }}"
Shopify.translation.staff_pick = "{{ 'collections.general.staff_pick' | t | strip_newlines | escape }}"
Shopify.translation.free = "{{ settings.free_price_text | t | strip_newlines | escape }}"
{% comment %} Newsletter form {% endcomment %}
Shopify.translation.newsletter_form_success = "{{ 'general.newsletter_form.success_text' | t | strip_newlines | escape }}";
{% comment %} Contact form {% endcomment %}
Shopify.translation.contact_form_success = "{{ 'contact.form.post_success' | strip_html | t | strip_newlines | escape }}";
heading.liquid
file
Located within the snippets
folder, the heading.liquid
file features an easy to use snippet for including a heading and takes care of whether a heading divider should be added or not. Then, this whole heading snippet file gets pulled in elsewhere with this line of code, for example in the Collection List:
{% include 'heading', title: 'this is a heading', heading_tag: 'h1', context: 'list-collection', text_alignment: 'left' %}
Required/Optional Values
There are required and optional values at the top of the heading.liquid
file that point out which variables can be added when including this snippet within the code:
{% comment %} Required values title: heading_tag: context: ______________ Optional values url: text_alignment: {% endcomment %}
image-element.liquid
file
Located within the snippets
folder, the image-element.liquid
file is used across the theme to display images. This snippet has some useful features such as lazy loading and object cropping:
{% include ‘image-element’, image: section.settings.image, alt: section.settings.image.alt, stretch_width: true %}
Required/Optional Values
There are required and optional values at the top of the image-element.liquid
file that point out which variables can be added when including this snippet within the code:
{% comment %} Required values image: <image object> alt: <image alt property> ______________ Optional values progressive: <boolean> stretch_width: <boolean> additional_classes: <string> inline_style: <string> back_to_basics: <boolean> object_fit: <boolean> image_crop: <boolean> max_height: <number>
{% endcomment %}
button.liquid
file
Located within the snippets
folder, the button.liquid
file is used to create a button. Like the image-element
snippet, it offers some useful features such as the button style:
{% include ‘button’, label: block.settings.button_1, href: block.settings.button_1_link, type: “link”, style: block.settings.button_1_style %}
Required/Optional Values
There are required and optional values at the top of the button.liquid
file that point out which variables can be added when including this snippet within the code:
{% comment %} Required values label: ______________ Optional values href: type: style: class: attribute: {% endcomment %}
column-width
file
Located within the snippets
folder, the column-width.liquid
file is used to determine what column class gets added based on the number value:
{% assign value = value | plus: 0 %} {% if value == 1 %} one-whole {% elsif value == 2 %} one-half {% elsif value == 3 %} one-third {% elsif value == 4 %} one-fourth {% elsif value == 5 %} one-fifth {% elsif value == 6 %} one-sixth {% elsif value == 7 %} one-seventh {% elsif value == 8 %} one-eighth {% else %} {{ value }} {% endif %}
Required Values
There is a required value at the top of the column-width.liquid
file that points out what variable can be added when including this snippet within the code:
{% comment %} Required values value: {% endcomment %}
Theme Kit Considerations
Theme Kit is a command line tool for Shopify themes. If you're using Theme Kit, you'll need to set up a config.yml
file to ignore scripts
, styles
folders and the settings_data.json
file.
If you have the Flex theme opened in a code editor, you will see a config-sample.yml
file as an example. You can use this to create your config.yml
file as it has the certain files ignored already. You will just need to populate it for your environment.
Shopify's Theme Kit Setup Documentation
Development Best Practices
JavaScript
- Any of the sections JavaScript files should only include JavaScript related to
sections
- If it’s more of a global method then it should be in
utilities
- If its an external plugin that you’re using, then add it in
vendors
CSS/SCSS
- Avoid adding styles to column classes - if you need to target a column element, apply a new class.
Adding Custom Icons
Please view our developer doc on adding custom icons to the Flex theme
Hide Sections on Desktop/Mobile
Please view our article on hiding sections on desktop or mobile