*/ (function() { 'use strict'; const CONFIG = { storageKey: 'aos_utm_data', storageDuration: 30, // days utmParams: ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'], // Shopify attribution mapping shopifyFields: { utm_source: 'source', utm_medium: 'medium', utm_campaign: 'campaign', utm_content: 'content', utm_term: 'term', landing_page: 'landing_site', referrer: 'referring_site' } }; // ============================================ // STEP 1: CAPTURE & STORE UTM PARAMETERS // ============================================ function captureUTMFromURL() { const params = new URLSearchParams(window.location.search); const utmData = {}; let hasUTM = false; CONFIG.utmParams.forEach(param => { if (params.has(param)) { utmData[param] = params.get(param); hasUTM = true; } }); return hasUTM ? utmData : null; } function getStoredUTMData() { try { const stored = localStorage.getItem(CONFIG.storageKey); if (stored) { const data = JSON.parse(stored); // Check if data is still valid (within duration) const timestamp = data.timestamp || 0; const now = Date.now(); const maxAge = CONFIG.storageDuration * 24 * 60 * 60 * 1000; if (now - timestamp < maxAge) { return data; } } } catch (e) { console.error('Error reading UTM data:', e); } return null; } function saveUTMData(utmData) { try { const dataToStore = { ...utmData, timestamp: Date.now(), landing_page: utmData.landing_page || window.location.href, referrer: utmData.referrer || document.referrer || 'direct' }; localStorage.setItem(CONFIG.storageKey, JSON.stringify(dataToStore)); // Also set as cookie for server-side access setCookie(CONFIG.storageKey, JSON.stringify(dataToStore), CONFIG.storageDuration); console.log('UTM data saved:', dataToStore); return dataToStore; } catch (e) { console.error('Error saving UTM data:', e); return null; } } function setCookie(name, value, days) { const date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); const expires = "expires=" + date.toUTCString(); document.cookie = name + "=" + encodeURIComponent(value) + ";" + expires + ";path=/;SameSite=Lax"; } // ============================================ // STEP 2: MANAGE UTM DATA (NEW OR STORED) // ============================================ function initializeUTMTracking() { // Check for new UTM parameters in current URL const newUTM = captureUTMFromURL(); if (newUTM) { // New UTM found - overwrite stored data console.log('New UTM parameters detected, updating storage'); return saveUTMData({ ...newUTM, landing_page: window.location.href, referrer: document.referrer || 'direct' }); } else { // No new UTM - get stored data const storedUTM = getStoredUTMData(); if (!storedUTM) { // First visit, no UTM - save as direct traffic console.log('First visit without UTM, marking as direct'); return saveUTMData({ utm_source: 'direct', utm_medium: 'none', landing_page: window.location.href, referrer: document.referrer || 'direct' }); } console.log('Using stored UTM data:', storedUTM); return storedUTM; } } // ============================================ // STEP 3: AUTO-APPEND UTM TO INTERNAL LINKS // ============================================ function appendUTMToURL(url, utmData) { try { const urlObj = new URL(url, window.location.origin); // Only add UTM if not already present CONFIG.utmParams.forEach(param => { if (utmData[param] && !urlObj.searchParams.has(param)) { urlObj.searchParams.set(param, utmData[param]); } }); return urlObj.toString(); } catch (e) { return url; // Return original if parsing fails } } function isInternalLink(url) { try { const urlObj = new URL(url, window.location.origin); return urlObj.hostname === window.location.hostname; } catch (e) { // Relative URLs are internal return !url.startsWith('http://') && !url.startsWith('https://'); } } function hasUTMParameters(url) { try { const urlObj = new URL(url, window.location.origin); return CONFIG.utmParams.some(param => urlObj.searchParams.has(param)); } catch (e) { return false; } } function addUTMToInternalLinks(utmData) { if (!utmData) return; // Function to update a single link function updateLink(link) { const href = link.getAttribute('href'); if (!href || href === '#' || href.startsWith('javascript:') || href.startsWith('mailto:') || href.startsWith('tel:')) { return; } // Only update internal links without UTM if (isInternalLink(href) && !hasUTMParameters(href)) { const newHref = appendUTMToURL(href, utmData); link.setAttribute('href', newHref); } } // Update all existing links document.querySelectorAll('a[href]').forEach(updateLink); // Watch for dynamically added links const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { // Element node if (node.tagName === 'A' && node.hasAttribute('href')) { updateLink(node); } // Also check children node.querySelectorAll && node.querySelectorAll('a[href]').forEach(updateLink); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); } // ============================================ // STEP 4: SEND TO SHOPIFY ATTRIBUTION // ============================================ function sendToShopifyAttribution(utmData) { if (!utmData) return; // Method 1: Use Shopify's analytics tracking if (window.ShopifyAnalytics && window.ShopifyAnalytics.lib) { try { const attributionData = {}; Object.keys(CONFIG.shopifyFields).forEach(key => { const shopifyField = CONFIG.shopifyFields[key]; if (utmData[key]) { attributionData[shopifyField] = utmData[key]; } }); // Set landing site if (utmData.landing_page) { attributionData.landing_site = utmData.landing_page; } // Set referring site if (utmData.referrer && utmData.referrer !== 'direct') { attributionData.referring_site = utmData.referrer; } console.log('Sending to Shopify Analytics:', attributionData); // This sets the attribution data for the session if (window.ShopifyAnalytics.lib.config) { window.ShopifyAnalytics.lib.config.Attribution = attributionData; } } catch (e) { console.error('Error setting Shopify attribution:', e); } } // Method 2: Add to checkout attributes (for order-level tracking) addToCheckoutAttributes(utmData); // Method 3: Add to cart note attributes addToCartAttributes(utmData); } function addToCheckoutAttributes(utmData) { // This will be picked up during checkout window._shopifyCheckoutAttributes = window._shopifyCheckoutAttributes || {}; CONFIG.utmParams.forEach(param => { if (utmData[param]) { window._shopifyCheckoutAttributes[param] = utmData[param]; } }); if (utmData.landing_page) { window._shopifyCheckoutAttributes['landing_page'] = utmData.landing_page; } if (utmData.referrer) { window._shopifyCheckoutAttributes['referrer'] = utmData.referrer; } } function addToCartAttributes(utmData) { // Hook into cart form submissions document.addEventListener('submit', function(e) { const form = e.target; // Check if it's a cart form if (form.action && (form.action.includes('/cart/add') || form.action.includes('/cart'))) { // Add hidden fields for UTM data CONFIG.utmParams.forEach(param => { if (utmData[param]) { addHiddenField(form, `attributes[${param}]`, utmData[param]); } }); if (utmData.landing_page) { addHiddenField(form, 'attributes[landing_page]', utmData.landing_page); } if (utmData.referrer) { addHiddenField(form, 'attributes[referrer]', utmData.referrer); } } }); } function addHiddenField(form, name, value) { // Check if field already exists let field = form.querySelector(`input[name="${name}"]`); if (!field) { field = document.createElement('input'); field.type = 'hidden'; field.name = name; form.appendChild(field); } field.value = value; } // ============================================ // STEP 5: AJAX CART HANDLING // ============================================ function interceptAjaxCalls(utmData) { // Intercept fetch calls const originalFetch = window.fetch; window.fetch = function(...args) { let [url, options] = args; if (typeof url === 'string' && url.includes('/cart/add')) { options = options || {}; // Add UTM data to body if it's a POST request if (options.method === 'POST' || !options.method) { try { const body = options.body ? JSON.parse(options.body) : {}; body.attributes = body.attributes || {}; CONFIG.utmParams.forEach(param => { if (utmData[param]) { body.attributes[param] = utmData[param]; } }); if (utmData.landing_page) body.attributes.landing_page = utmData.landing_page; if (utmData.referrer) body.attributes.referrer = utmData.referrer; options.body = JSON.stringify(body); } catch (e) { console.error('Error adding UTM to fetch:', e); } } } return originalFetch.apply(this, [url, options]); }; // Intercept jQuery AJAX if jQuery is loaded if (window.jQuery) { const originalAjax = jQuery.ajax; jQuery.ajax = function(url, options) { if (typeof url === 'object') { options = url; url = options.url; } if (url && url.includes('/cart/add')) { options.data = options.data || {}; if (typeof options.data === 'object') { options.data.attributes = options.data.attributes || {}; CONFIG.utmParams.forEach(param => { if (utmData[param]) { options.data.attributes[param] = utmData[param]; } }); if (utmData.landing_page) options.data.attributes.landing_page = utmData.landing_page; if (utmData.referrer) options.data.attributes.referrer = utmData.referrer; } } return originalAjax.call(this, url, options); }; } } // ============================================ // STEP 6: INITIALIZE EVERYTHING // ============================================ function init() { console.log('Initializing UTM Tracking System...'); // Initialize UTM tracking (capture new or get stored) const utmData = initializeUTMTracking(); if (utmData) { // Add UTM to all internal links if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => addUTMToInternalLinks(utmData)); } else { addUTMToInternalLinks(utmData); } // Send to Shopify attribution sendToShopifyAttribution(utmData); // Intercept AJAX cart calls interceptAjaxCalls(utmData); console.log('UTM Tracking System initialized successfully'); } } // Start the tracking system init(); // Expose utility function to get current UTM data window.getUTMData = function() { return getStoredUTMData(); }; // Expose function to manually clear UTM data window.clearUTMData = function() { localStorage.removeItem(CONFIG.storageKey); console.log('UTM data cleared'); }; })(); Skip to Main Content
TUXEDOS WITH A TWIST

TUXEDOS WITH A TWIST

Every year around the holidays menswear brands, magazines and blogs show-off their most elegant formalwear…although I’m not sure how many people actually wear black-tie for New Year’s anymore.

Here’s the thing about formalwear: it should be the opposite of an impulse purchase. As a gentleman with style, you should never be in this position; “oh shit, I have an event coming up, I need a tux, quick!”.

Even though you won’t wear it often, your wardrobe should always be prepared with a sharply tailored tuxedo. And not just be prepared to dress appropriately, but prepared to look and feel your absolute best.

It doesn’t have to be boring, either. Formal occasions are a time to have a little fun, take a little risk and enjoy the pleasures of classic menswear.

Here, our friend and client Tyrone Naraine – a stock broker born and raised in NYC – gives us some ideas on how to shut the party down, no matter what year it is.


CRUSH IT IN VELVET

Man in a burgundy velvet tuxedo sitting on a bar, pouring a drink in a playful pose, showcasing modern formalwear style

Anyone can do a velvet jacket, but it takes a certain level of panache to pull-off the full crushed velvet tuxedo, especially in Bordeaux.

Velvet is specifically designed for the winter – it’s warm and cozy like wearing a soft blanket and it looks absolutely magnificent against winter light and snowy landscapes.

Close-up of a man smiling in a burgundy velvet tuxedo with black satin lapels and bow tie, highlighting luxurious menswear fashion.

Of course, this is a power move designed for the more experienced dresser.

If you’re more of a novice when it comes to formalwear, make sure you get the basics down first.

Man posing in a serious expression wearing a burgundy velvet tuxedo and black bow tie, perfect for unique formal menswear styling

GO THREE-DIMENSIONAL

Man in a black patterned tuxedo and bow tie sitting on a red leather bench, embodying luxury formal menswear

The dinner jacket has become something of an icon in menswear, often times becoming the go-to option for stylish men on formal occasions.

Dinner jacket fabrics typically have unique textures (that wouldn’t work for pants) which allows you to get a little more expressive.

Portrait of a man wearing a black patterned tuxedo with a white pocket square and black bow tie, ideal for modern tuxedo styling

This dinner jacket, for example, is cut from an extremely rare wool & cashmere fabric embroidered with a circular tonal pattern that creates a 3-dimensional texture unlike any other.

 

Close-up of a man’s hands and tuxedo jacket sleeve, featuring patterned black fabric and gold cufflinks, highlighting formal details

CLASSIC NEVER FAILS

Man lounging on a red leather couch in a black tuxedo with a drink, showcasing a relaxed yet elegant formalwear style.

If you’re thinking about a classic 4-season tuxedo that you can wear any time of year, for any formal occasion, again and again…than think about a midnight shawl.

It’s still very classic, but not boring. Your average Jo Smo is going to have a black tuxedo, probably with peak (or worse, notch) lapels. The midnight shawl gives you a chance to separate yourself subtly with the color and the style.

Of course, as with all things menswear, nailing the fit is essential.

Close-up of a man sitting on a red leather couch, holding a drink while wearing a black tuxedo and white bow tie, exuding sophisticated style.

FORMAL SEPARATES

Man in a burgundy blazer and black bow tie sitting on a leather chair, holding a drink with a decorated Christmas tree in the background, showcasing holiday formalwear

Another way to stretch a dollar and get the most out of your wardrobe; a dinner jacket/sportcoat combo.

It’s sort of a blurry line; the difference between a dinner jacket and a sportcoat. It usually comes down to the color, the fabric and the styling.

Close-up of a man wearing a burgundy textured blazer, white dress shirt, and black bow tie, ideal for elegant holiday menswear styling.

We designed our silk rose jacket to float right in the middle; you can wear it formally with a tux shirt, bowtie and cummerbund.

Or you can wear it with a turtleneck and flannel trousers for a more casual setting.

Side profile of a man in a burgundy blazer with a patterned bow tie, highlighting sophisticated formal holiday menswear.

UNTOUCHABLE PATTERN

Man sitting on a stool in a black tuxedo with a cigar, posing against a brick wall for a refined and modern menswear look.

If you’re really trying to absolutely shut the party down, look no further than our Jacquard Tuxedo.

We took all the elements that make a formal garment more badass (midnight blue, double-breasted, subtle pattern, grosgrain trim) and designed this beauty to reach a whole other level of formal style.

Close-up of a man lighting a cigar while wearing a textured black tuxedo and bow tie, embodying luxury formal menswear

A few words come to mind: smooth, confident, rakish, unforgettable.

Close-up of a man’s textured black tuxedo jacket, featuring sharp lapels, bow tie, and a white pocket square, perfect for formal style enthusiasts

Thanks, as always, for reading.

Yours in style,

Dan Trepanier

SHOP THIS ARTICLE


NEED HELP WITH YOUR WARDROBE?


MORE FROM ARTICLES OF STYLE