Roots Theme Customization
The Baits.com site uses the Roots Theme v1.7.14 by Weizen Young, built on top of BigCommerce's Cornerstone v6.1.1. This theme provides extensive customization options and modern e-commerce features.
Theme Information
- Theme Name: Roots Theme
- Version: 1.7.14
- Based On: Cornerstone v6.1.1
- Author: Weizen Young
- License: MIT
- Support: [email protected]
- Documentation: https://themesupport.weizenyoung.com/help/roots-theme-manual
Theme Features
Core Features
From config.json metadata:
- Fully Responsive - Mobile-first design
- Mega Navigation - Multi-column dropdown menus
- Multi-Tiered Sidebar Menu - Collapsible category navigation
- Frontpage Slideshow - Hero carousel with custom content
- Quick Add to Cart - Add products without page reload
- Product Comparison Table - Side-by-side product comparison
- Complex Search Filtering - Faceted search and filtering
- Customizable Product Selector - Variant selection with options
- Cart Suggested Products - Related product recommendations
- Free Theme Upgrades - Lifetime updates from Weizen Young
- High-Res Product Images - Zoom and gallery support
- Product Filtering - Category page filters
- Advanced Quick View - Enhanced product preview modal
- Product Showcase - Featured product sections
- Persistent Cart - Cart saved across sessions
- One Page Checkout - Streamlined checkout process
- Product Videos - Video embeds on product pages
- Google AMP - Accelerated Mobile Pages support
- Customized Checkout - Branded checkout experience
- Enhanced E-commerce - GA4 tracking integration
- CSRF Protection - Security against cross-site attacks
- Account Payment Methods V2 - Stored payment methods
Theme Settings
The theme exposes hundreds of customization options via schema.json. Settings are organized into sections:
Colors
Global color scheme with extensive control:
{
"type": "color",
"label": "Header Background",
"id": "header-backgroundColor"
}
Color Settings:
- Header background
- Primary navigation background and borders
- Body background
- Product grid background
- Footer background and separators
- Text colors (base, headings, links)
- Link hover states
- Button colors (primary, secondary, tertiary)
- Price colors (default, sale, MSRP)
- Badge colors (sale, new, featured)
- Alert colors (success, info, warning, error)
- Form element colors
Typography
Font customization with Google Fonts integration:
// Font families
$fontFamily-sans: "Source Sans Pro", Arial, Helvetica, sans-serif;
$fontFamily-serif: Georgia, serif;
// Font sizes
$fontSize-root: 16px;
$fontSize-base: 1rem;
$fontSize-hero: 3rem;
$fontSize-h1: 2.5rem;
$fontSize-h2: 2rem;
// ... etc
Typography Controls:
- Font families (sans-serif, serif, display)
- Font sizes per element type
- Font weights (light, regular, semibold, bold)
- Line heights
- Letter spacing
- Text transforms
Layout
Grid and container settings:
$container-width: 1280px;
$container-max-width: 1440px;
// Grid columns
$grid-columns: 12;
$grid-gutter: 20px;
Layout Options:
- Container max-width
- Grid gutter size
- Sidebar widths
- Product grid columns (desktop, tablet, mobile)
- Navigation alignment
- Header layout (sticky, static, overlay)
- Footer layout (multi-column, centered)
Navigation
Primary navigation customization:
{
"type": "select",
"label": "Primary Navigation Link Alignment",
"id": "navPages-grow",
"options": [
{ "value": 1, "label": "Justify" },
{ "value": 0, "label": "Left" }
]
}
Navigation Settings:
- Link alignment (left, center, justify)
- Number of links per dropdown column (5, 10, 15, 20)
- Mega menu column count
- Dropdown behavior (hover, click)
- Mobile menu style (overlay, slide-out)
- Breadcrumb visibility
- Search bar position
Product Display
Product card and detail page settings:
{
"label": "Homepage Featured Products",
"id": "homepage_featured_products_count",
"type": "input"
}
Product Settings:
- Card hover effects
- Image aspect ratios
- Badge positions (sale, new, featured)
- Price display format
- Rating display
- Quick view button
- Add to cart button style
- Product per page (category)
- Related product count
- Thumbnail gallery style
- Image zoom behavior
Homepage
Homepage section configuration:
{
"name": "Homepage",
"settings": [
{
"type": "checkbox",
"label": "Show Carousel",
"id": "homepage_show_carousel"
},
{
"type": "input",
"label": "Featured Products Count",
"id": "homepage_featured_products_count"
}
]
}
Homepage Sections:
- Hero carousel (enable/disable, autoplay, arrows, pause button)
- Featured products (count, heading, description)
- New products (count, heading)
- Top products (count, heading)
- Brand showcase (heading, description)
- Blog posts (heading, description)
- Custom highlight section (image, heading, CTA)
- Our story section (image, text)
- Newsletter signup
Responsive Design
Breakpoint System
The theme uses a mobile-first approach with four breakpoints:
// Small devices (landscape phones, 551px and up)
@media (min-width: 551px) { }
// Medium devices (tablets, 801px and up)
@media (min-width: 801px) { }
// Large devices (desktops, 1261px and up)
@media (min-width: 1261px) { }
// Extra large devices (large desktops, 1441px and up)
@media (min-width: 1441px) { }
Responsive Grid
Foundation 5 grid with custom extensions:
<div class="row">
<div class="column small-12 medium-6 large-4">
<!-- Full width mobile, half tablet, third desktop -->
</div>
</div>
Grid Classes:
small-{1-12}- Mobile sizesmedium-{1-12}- Tablet sizeslarge-{1-12}- Desktop sizessmall-centered- Center columnsmall-offset-{1-11}- Column offset
Mobile Optimizations
- Touch-friendly buttons (min 44px height)
- Simplified navigation (hamburger menu)
- Stacked layouts on mobile
- Swipeable product galleries
- Bottom-fixed add to cart on mobile
- Collapsible filters and facets
- Mobile-optimized forms
Swiper Carousel Integration
The theme extensively uses Swiper v11.1.15 for carousels.
Brand/Promotions Swiper
Located in assets/js/theme/baits/swiper.js:
const swiper = new Swiper('.promos-swiper', {
breakpoints: {
551: {
grid: { fill: 'row', rows: 3 },
slidesPerView: 2.3,
},
801: {
grid: { fill: 'row', rows: 5 },
enabled: false,
slidesPerView: 3,
}
},
grid: {
fill: 'row',
rows: 5,
},
loop: false,
pagination: {
clickable: true,
el: '.promos-swiper__pagination',
type: 'bullets',
},
slidesPerView: 1.3,
});
Features:
- Responsive grid layout
- Multiple rows on larger screens
- Bullet pagination
- Disabled on desktop (shows grid instead)
Product Carousels
Featured and related products use shared configuration:
const swiper = new Swiper(selector, {
breakpoints: {
551: {
slidesPerView: 2.2,
},
801: {
spaceBetween: 10,
slidesPerView: 3.2,
},
1261: {
slidesOffsetAfter: 0,
slidesPerView: 4,
},
1441: {
slidesPerView: 5,
},
},
loop: false,
navigation: {
nextEl: '.product-swiper__button--next',
prevEl: '.product-swiper__button--prev',
},
pagination: {
clickable: true,
el: '.product-swiper__pagination',
type: 'bullets',
},
slidesOffsetAfter: 20,
slidesPerView: 1.2,
spaceBetween: 25,
});
Responsive Behavior:
- Mobile (< 551px): 1.2 slides visible
- Small (551-800px): 2.2 slides visible
- Medium (801-1260px): 3.2 slides visible
- Large (1261-1440px): 4 slides visible
- XLarge (1441px+): 5 slides visible
Carousel State Management
Visual indicators for navigation:
on: {
slideChange: () => {
if (swiper.isBeginning) {
container.classList.add('swiper-beginning');
} else {
container.classList.remove('swiper-beginning');
}
if (swiper.isEnd) {
container.classList.add('swiper-end');
} else {
container.classList.remove('swiper-end');
}
},
}
Used to disable/hide navigation buttons when at start/end.
Custom SCSS Structure
Baits-Specific Styles
Located in assets/scss/baits/:
// Import order in theme.scss
@import "baits/brand-page";
@import "baits/product-page";
@import "baits/swiper";
@import "baits/variant-selector";
Custom SCSS Modules:
- _brand-page.scss - Brand listing page styles
- _product-page.scss - Product detail page overrides
- _swiper.scss - Swiper carousel custom styling
- _variant-selector.scss - Slideout modal styles
Example Custom Styles
// assets/scss/baits/_swiper.scss
.product-swiper-container {
position: relative;
&.swiper-beginning .product-swiper__button--prev {
opacity: 0.3;
pointer-events: none;
}
&.swiper-end .product-swiper__button--next {
opacity: 0.3;
pointer-events: none;
}
}
.product-swiper__button {
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 10;
&--prev {
left: 0;
}
&--next {
right: 0;
}
}
Image Handling
Lazy Loading
Using Lazysizes library for performance:
{{> components/common/responsive-img
image=product.image
class="lazyload"
lazyload=theme_settings.lazyload_mode
}}
Generated output:
<img
class="lazyload"
data-sizes="auto"
src="/img/loading.svg"
data-src="https://cdn.bcapp.dev/product-image-500w.jpg"
data-srcset="
https://cdn.bcapp.dev/product-image-500w.jpg 500w,
https://cdn.bcapp.dev/product-image-800w.jpg 800w,
https://cdn.bcapp.dev/product-image-1200w.jpg 1200w
"
alt="Product Name"
/>
Image Sizes
Defined in theme settings:
{
logo_size: '250x100',
product_size: '500x500',
product_thumbnail_size: '100x100',
zoom_size: '1280x1280',
cart_item_size: '100x100',
gallery_size: '300x300'
}
Zoom Functionality
Product images support zoom on hover/click:
<figure
data-image-gallery-main
data-zoom-image="{{getImageSrcset product.main_image 1x=theme_settings.zoom_size}}"
>
<!-- Image -->
</figure>
Uses EasyZoom library for zoom behavior.
Forms & Validation
Form Styling
Foundation form styles with custom overrides:
.form-field {
margin-bottom: 1.5rem;
label {
display: block;
margin-bottom: 0.5rem;
font-weight: 600;
}
input[type="text"],
input[type="email"],
select,
textarea {
width: 100%;
padding: 0.75rem;
border: 1px solid $input-borderColor;
border-radius: 4px;
&:focus {
border-color: $input-borderColor-focus;
outline: none;
box-shadow: 0 0 0 3px rgba($color-primary, 0.1);
}
}
}
Client-Side Validation
Using nod-validate library:
import nod from 'nod-validate';
nod.configure({
delay: 300,
submit: '.form[data-validate]'
});
Validation Rules:
- Required fields
- Email format
- Password strength
- Phone number format
- Zip/postal code format
- Credit card format (via
creditcardslibrary)
Cart & Checkout
Cart Preview
Dropdown cart in header:
Add to Cart
AJAX add to cart via Stencil Utils:
import utils from '@bigcommerce/stencil-utils';
$('[data-cart-item-add]').on('submit', (event) => {
event.preventDefault();
const $form = $(event.currentTarget);
const formData = new FormData($form[0]);
utils.api.cart.itemAdd(formData, (err, response) => {
if (err) {
// Show error
return;
}
// Update cart counter
// Show success message
// Update cart preview
});
});
Persistent Cart
Enabled in theme features. Cart contents saved across:
- Browser sessions
- Device switches
- Login/logout
Accessibility
ARIA Labels
Proper ARIA attributes throughout:
<button
aria-label="Add {{product.title}} to cart"
data-cart-item-add
>
Add to Cart
</button>
<nav aria-label="Main navigation">
<!-- Navigation links -->
</nav>
<div role="alert" aria-live="polite">
<!-- Dynamic messages -->
</div>
Keyboard Navigation
- Tab order follows visual flow
- Skip to content link
- Focus indicators on all interactive elements
- Escape key closes modals and dropdowns
- Arrow keys navigate carousels
Screen Reader Support
- Semantic HTML5 elements (
<header>,<nav>,<main>,<footer>) - Hidden labels for icon-only buttons
- Alt text on all images
- Form labels associated with inputs
- Loading states announced
Color Contrast
Theme settings enforce WCAG AA contrast ratios:
- Text on background: 4.5:1 minimum
- Large text: 3:1 minimum
- UI components: 3:1 minimum
Performance Features
Critical CSS
Font loading CSS inlined in head:
<script>
WebFont.load({
google: {
families: ['Source Sans Pro:400,600,700']
}
});
</script>
Async Script Loading
Non-critical scripts deferred:
<script src="{{cdn 'assets/dist/theme-bundle.head_async.js'}}" async></script>
Resource Hints
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://cdn.bcapp.dev">
Service Worker
Not currently implemented, but theme is PWA-ready with manifest.json support.
Customization Best Practices
Override Pattern
Don't modify core Roots files. Use custom overrides:
// assets/scss/baits/_custom.scss
.productView {
// Custom overrides
.productView-title {
font-size: 2rem;
color: $brand-primary;
}
}
Import after base styles:
// theme.scss
@import "roots/all";
@import "baits/custom";
Template Inheritance
Create custom templates in baits/ subdirectory:
templates/components/products/
├── product-view.html # Base template
└── baits/
└── product-main.html # Custom override
Use in page template:
JavaScript Modules
Extend functionality without modifying core:
// assets/js/theme/baits/custom-feature.js
export default class CustomFeature {
constructor() {
this.init();
}
init() {
// Custom initialization
}
}
Import in page class:
import CustomFeature from './baits/custom-feature';
export default class Product extends PageManager {
onReady() {
new CustomFeature();
}
}
Theme Updates
Staying Current
Check for theme updates:
- Visit https://themesupport.weizenyoung.com
- Check CHANGELOG.md for new versions
- Download updated theme package
- Merge custom changes carefully
Version History
From CHANGELOG.md, recent updates include:
- v5.1.0: Wallet payment buttons, variant pricing fixes
- v5.0.0: Node 18 upgrade, Webpack config updates
- v4.2.1: Grid CSS fixes, sale badge customization
- v4.2.0: Cornerstone v6.3.0 merge, thumbnail alignment
- v4.1.2: Newsletter styling, navigation borders
- v4.1.1: MSRP display, brand thumbnail settings
- v4.1.0: Compare page fixes, quantity box option, mobile filters
Migration Strategy
When updating:
- Backup: Save current theme files
- Review: Check CHANGELOG for breaking changes
- Test: Apply updates in development environment
- Verify: Test custom features still work
- Deploy: Upload to production after testing