Sunday Golf

Sunday Golf: Dawn 2.0 Theme Migration with Sub-2s Load Times

Led complex Shopify theme migration implementing bundle builder and mega menu while maintaining sub-2.5s load times for premium golf apparel brand.

Duration: Nov 2024 - Feb 2025
Role: Shopify Developer
Shopify Dawn 2.0LiquidJavaScriptCustom Extensibility AppsCheckout Extensibility
Page Load Time
<2.5s
Conversion Rate
+18%
Mobile Performance
95+ Score
Cart AOV
+25%
Published February 1, 2025
Nov 2024 - Feb 2025

The Challenge

Sunday Golf, a premium golf apparel brand, needed to migrate from a legacy Shopify theme to the modern Dawn 2.0 architecture while implementing advanced features like bundle builders and mega menus. The challenge was maintaining exceptional performance while adding complex functionality.

Key Requirements

  • Performance First: Must maintain sub-2.5s load times
  • Bundle Builder: Custom bundle creation for product combinations
  • Mega Menu: Complex navigation for extensive product catalog
  • Checkout Extensibility: Custom checkout experience with upsells
  • Mobile Excellence: Premium mobile shopping experience
  • Zero Downtime: Seamless migration without business interruption

The Process

Phase 1: Architecture & Planning (Weeks 1-2)

Theme Analysis

  • Audited existing theme structure and custom modifications
  • Identified migration risks and dependencies
  • Created comprehensive migration roadmap
  • Established performance budgets

Dawn 2.0 Customization

  • Evaluated Dawn 2.0 architecture and section rendering
  • Designed custom app blocks for extensibility
  • Planned bundle builder integration
  • Architected mega menu system

Phase 2: Core Migration (Weeks 3-6)

Theme Implementation

{% comment %}
  Custom Bundle Builder Section
  Allows customers to create personalized golf gear bundles
{% endcomment %}

<div class="bundle-builder" data-section-id="{{ section.id }}">
  <div class="bundle-configurator">
    <div class="bundle-steps">
      {% for step in section.settings.bundle_steps %}
        <div class="step" data-step="{{ forloop.index }}">
          <h3>{{ step.title }}</h3>
          <div class="product-grid">
            {% for product in step.products %}
              <div class="product-card" data-product-id="{{ product.id }}">
                <img 
                  src="{{ product.featured_image | image_url: width: 400 }}" 
                  alt="{{ product.title }}"
                  loading="lazy"
                  width="400"
                  height="400"
                >
                <h4>{{ product.title }}</h4>
                <span class="price">{{ product.price | money }}</span>
                <button class="add-to-bundle">Add to Bundle</button>
              </div>
            {% endfor %}
          </div>
        </div>
      {% endfor %}
    </div>
    
    <div class="bundle-summary">
      <h3>Your Bundle</h3>
      <div class="bundle-items"></div>
      <div class="bundle-total">
        <span>Total:</span>
        <span class="total-price">$0.00</span>
        <span class="savings">Save 15%</span>
      </div>
      <button class="complete-bundle">Add Bundle to Cart</button>
    </div>
  </div>
</div>

<script>
class BundleBuilder {
  constructor(sectionId) {
    this.section = document.querySelector(`[data-section-id="${sectionId}"]`);
    this.selectedItems = new Map();
    this.init();
  }
  
  init() {
    this.attachEventListeners();
    this.loadPersistedBundle();
  }
  
  attachEventListeners() {
    this.section.querySelectorAll('.add-to-bundle').forEach(btn => {
      btn.addEventListener('click', (e) => this.handleAddItem(e));
    });
    
    this.section.querySelector('.complete-bundle').addEventListener('click', () => {
      this.addBundleToCart();
    });
  }
  
  async addBundleToCart() {
    const items = Array.from(this.selectedItems.values());
    
    try {
      const response = await fetch('/cart/add.js', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ items })
      });
      
      if (response.ok) {
        // Track conversion
        window.dataLayer = window.dataLayer || [];
        window.dataLayer.push({
          event: 'bundle_purchase',
          bundle_value: this.calculateTotal(),
          items: items.length
        });
        
        window.location.href = '/cart';
      }
    } catch (error) {
      console.error('Bundle add failed:', error);
    }
  }
  
  calculateTotal() {
    let total = 0;
    this.selectedItems.forEach(item => {
      total += item.price * item.quantity;
    });
    return total * 0.85; // 15% bundle discount
  }
}

new BundleBuilder('{{ section.id }}');
</script>

{% schema %}
{
  "name": "Bundle Builder",
  "settings": [
    {
      "type": "text",
      "id": "title",
      "label": "Section Title"
    }
  ],
  "blocks": [
    {
      "type": "bundle_step",
      "name": "Bundle Step",
      "settings": [
        {
          "type": "text",
          "id": "step_title",
          "label": "Step Title"
        },
        {
          "type": "product_list",
          "id": "products",
          "label": "Products"
        }
      ]
    }
  ]
}
{% endschema %}

Mega Menu System

{% comment %}
  Intelligent Mega Menu with Category Previews
{% endcomment %}

<nav class="mega-menu">
  <ul class="menu-level-1">
    {% for link in section.settings.menu.links %}
      <li class="menu-item {% if link.links.size > 0 %}has-dropdown{% endif %}">
        <a href="{{ link.url }}">{{ link.title }}</a>
        
        {% if link.links.size > 0 %}
          <div class="mega-dropdown">
            <div class="dropdown-container">
              <div class="menu-categories">
                {% for child_link in link.links %}
                  <div class="category-column">
                    <h4>{{ child_link.title }}</h4>
                    {% if child_link.links.size > 0 %}
                      <ul>
                        {% for sublink in child_link.links %}
                          <li><a href="{{ sublink.url }}">{{ sublink.title }}</a></li>
                        {% endfor %}
                      </ul>
                    {% endif %}
                  </div>
                {% endfor %}
              </div>
              
              <div class="menu-featured">
                <div class="featured-product">
                  {% if section.settings.featured_product %}
                    {% assign product = section.settings.featured_product %}
                    <img 
                      src="{{ product.featured_image | image_url: width: 400 }}" 
                      alt="{{ product.title }}"
                      loading="lazy"
                    >
                    <h5>{{ product.title }}</h5>
                    <a href="{{ product.url }}" class="btn-primary">Shop Now</a>
                  {% endif %}
                </div>
              </div>
            </div>
          </div>
        {% endif %}
      </li>
    {% endfor %}
  </ul>
</nav>

<style>
.mega-menu {
  position: relative;
}

.mega-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  width: 100vw;
  background: white;
  box-shadow: 0 8px 16px rgba(0,0,0,0.1);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-10px);
  transition: all 0.3s ease;
}

.menu-item:hover .mega-dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.dropdown-container {
  max-width: 1200px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 3fr 1fr;
  gap: 2rem;
  padding: 2rem;
}

.menu-categories {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 2rem;
}
</style>

Phase 3: Checkout Extensibility (Weeks 7-8)

Implemented custom checkout experience using Shopify's new extensibility APIs:

  • Upsell Blocks: Contextual product recommendations
  • Trust Badges: Security and shipping guarantees
  • Gift Options: Premium gift wrapping selection
  • Order Tracking: Post-purchase integration

Phase 4: Performance Optimization (Weeks 9-10)

Critical Path Optimization

// Lazy load non-critical sections
const observerOptions = {
  rootMargin: '50px 0px',
  threshold: 0.01
};

const sectionObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const section = entry.target;
      
      // Load section content
      if (section.dataset.lazyLoad === 'true') {
        loadSectionContent(section);
        sectionObserver.unobserve(section);
      }
    }
  });
}, observerOptions);

// Observe all lazy sections
document.querySelectorAll('[data-lazy-load="true"]').forEach(section => {
  sectionObserver.observe(section);
});

Image Optimization

  • Implemented native lazy loading
  • WebP with PNG/JPG fallbacks
  • Responsive images with srcset
  • Optimized above-the-fold images

Phase 5: Testing & Launch (Weeks 11-12)

Comprehensive Testing

  • Cross-browser compatibility testing
  • Mobile device testing (iOS/Android)
  • A/B testing on key pages
  • Load testing with realistic traffic patterns

Staged Rollout

  • Soft launch to 10% of traffic
  • Monitor performance and conversions
  • Gradual increase to 100%
  • Post-launch optimization

The Results

The migration exceeded all performance and business targets:

Performance Achievements

  • Page Load Time: Consistently under 2.5s (avg 1.8s)
  • Lighthouse Score: 95+ on mobile, 98+ on desktop
  • Core Web Vitals: All metrics in "Good" range
  • Bundle Size: Reduced by 60% vs old theme

Business Impact

  • Conversion Rate: +18% increase post-migration
  • Average Order Value: +25% with bundle builder
  • Mobile Conversions: +32% improvement
  • Cart Abandonment: -15% reduction
  • Page Views per Session: +40%

Feature Adoption

  • Bundle Builder: Used by 35% of customers
  • Mega Menu: 60% reduction in header search usage
  • Checkout Upsells: $45k additional monthly revenue
  • Mobile Experience: 50% increase in mobile purchases

Technical Innovations

1. Progressive Bundle Loading

Implemented intelligent loading system that:

  • Loads initial products immediately
  • Lazy loads additional options as user scrolls
  • Prefetches likely selections based on behavior
  • Caches bundle configurations in localStorage

2. Mega Menu Performance

Optimized complex navigation:

  • CSS-only dropdowns (no JavaScript until interaction)
  • Image preloading on hover intent
  • Cached menu structure in service worker
  • Sub-300ms interaction time

3. Checkout Extensibility

Custom checkout enhancements:

  • Dynamic upsell based on cart contents
  • Real-time shipping calculations
  • Gift message customization
  • One-click reorder functionality

Key Takeaways

  1. Dawn 2.0 is Powerful: The new section architecture enables incredible flexibility while maintaining performance

  2. Bundle Builder Drives AOV: Custom bundle experience significantly increased average order value

  3. Performance Budget Works: Strict performance budgets ensured speed wasn't sacrificed for features

  4. Checkout Extensibility ROI: Custom checkout features paid for themselves in first month

  5. Mobile-First Approach: Starting with mobile design led to better overall experience

Client Testimonial

"The migration to Dawn 2.0 was seamless and the results speak for themselves. Our customers love the bundle builder, and our conversion rates have never been higher. Bechara's attention to performance detail while adding complex features is exactly what we needed."

— E-commerce Director, Sunday Golf

Technical Stack

Frontend

  • Shopify Dawn 2.0 theme architecture
  • Vanilla JavaScript (no frameworks for performance)
  • CSS Grid and Flexbox for layouts
  • Intersection Observer API for lazy loading

Shopify Features

  • Theme App Extensions
  • Checkout Extensibility
  • Metafields for custom data
  • Storefront API for dynamic content

Performance

  • Critical CSS extraction
  • JavaScript code splitting
  • Image optimization pipeline
  • Service Worker caching strategy

Tools & Testing

  • Shopify CLI for development
  • GitHub Actions for deployment
  • Lighthouse CI for performance monitoring
  • Google Analytics 4 for tracking

Technologies Used

Shopify Dawn 2.0LiquidJavaScriptCustom Extensibility AppsCheckout Extensibility

Want Similar Results?

Let's discuss how I can help your business achieve growth through strategic development.