Whether we’re ordering copper pots from Amazon Prime, pho on Caviar, or grenache from any one of those subway-advertised wine-delivery start-ups, New Yorkers are really just a couple of apps away from being complete shut-ins. And yet there’s still so much to do in this town — like sampling garam-masala-spiked lamb chops in Long Island City, trying on leopard-print Alaïa coats in the Seaport, sipping fresh-pressed sake in Industry City, and scrambling up the city’s tallest rock-climbing walls in Bushwick. (You’ll find those and more in our yearly best-of review, rolling out this week. Read the fun, food, and shopping lists now.) This year’s best-of list in the health and self category includes unfussy wedding hair, an energy healer, an acupuncture clinic, and more.
Often compared to a facial, but for your scalp, the popular-in-Japan “head spa” has recently made its way to the U.S. One of its main proselytizers, Ritsuko Borges, has been kneading, cleansing, and steaming happy heads in the back room of an Upper West Side salon since last March. The Ayurveda-influenced massage-slash-cleanse is meant to stimulate blood flow and in turn help balance scalps dealing with dandruff, psoriasis, or hair loss. Borges, who did all this for about a decade in Japan, starts by rubbing her client’s head with a wandlike doodad that projects a magnified image of the scalp onto a computer screen in all its damaged, often yellowed glory. She then creates a cleansing concoction that she’ll use throughout a 60-minute ($140) or 90-minute ($190) session, which takes place in an extremely comfortable recliner, client’s head in sink. Each elaborate treatment involves a steam-therapy bag; a “hydro-dhara” waterfall, wherein an “aromatherapeutic distillate” drip-drops onto the scalp; and lots of shampooing, conditioning, and head massaging. One leaves feeling like a puddle of jelly and possessing an extremely clean scalp and head of hair (a feeling that lasts for days). Although Borges is booked until the end of March, she’s training an assistant to keep up with demand.
This is for the bride who wants her “wedding hair” to look more like an everyday air-dry (but a notch up) than like sausage-y ringlets or a stiff chignon. The references White Rose’s brides bring in are usually laid-back (a loose half-up, half-down; a wispy, elegant bun), but when they’re runway, owner Teddi Cranford knows how to translate them, thanks to her years of working Fashion Weeks on the backstage team of longtime stylist Guido Palau. She regularly gets Rosie Huntington-Whiteley, Laura Harrier, and the sisters Kirke ready for events. And when they get married, those clients (like Domino Kirke for her 2017 upstate wedding to Penn Badgley) tend to want her there for that, too. Given her celebrity clientele, the prices are on the steeper side: Cranford’s associates start at $1,600; working with the owner herself jumps you up to $3,200. Pricey, sure. But no one does a better stretched-out wave.
Sometimes you have a problem — a nonspecific malaise — that you can’t fix, even after consulting your therapist, drug dealer, primary-care physician, tarot-card reader, astrologist, mom, best friend, personal trainer, and/or hairstylist. Healer Jasmine G. has been putting the “fragmented energy of New Yorkers” back together for ten years now. For $200, she will saunter into your apartment (she also offers remote healing) for an hour of energy work to “shift you toward the most optimal flow required for manifesting positive results in your life.” She starts each session by asking for a basic description of what’s bothering you; next, she’ll have you lie down on your bed, where she’ll place her hands next to your head and scan your emotional, physical, and “etheric” fields to figure out how best to treat you. Can’t get over an ex? She’ll break the cosmic tether that keeps you connected. Can’t finish that novel? She’ll figure out what’s blocking your voice. Lost your sense of self? She’ll find your inner child and ask it who you are. She finishes with practical advice on how best to harness your regained energy. It’s vague and mysterious, but you’ll open your eyes refreshed and unblocked.
MetroRock in Brooklyn.
Photo: Courtesy of Metrorock
Rock-Climbing Studio
MetroRock 321 Starr St., nr. Cypress Ave., Bushwick; 929-500-7625
In recent years, multiple climbing gyms have opened in the city, catering to Google programmers and little kids’ weekend birthday parties alike. The latest addition, MetroRock, a longtime Massachusetts chainlet, has the climber community in a tizzy. How is it differentiating itself? By offering the tallest walls in the city, which are ideal for top roping and lead climbing (both require belay partners and harnesses). And unlike competitors Brooklyn Boulders and the Cliffs, MetroRock features top-out bouldering (meaning you can climb onto the top of certain summitlike areas). The gender ratio in climbing tends to skew male, but the club is doing its part to balance things out with a Wednesday ladies’ night for self-identifying women. It’s $30 for a day pass, $125 for a monthly membership; rental equipment (shoes, chalk bag, harness) is $3 to $6 per item.
Although the number of places in the city offering microblading — the process of adding hairlike strokes of semi-permanent pigment to get fuller, more defined brows — has hit critical mass, finding the right one can be difficult if you have Asian ancestry. EverTrue Salon, founded by Harvard Business School graduate Ramon Padilla, however, has a knack for this. With locations in Soho and Flatiron, EverTrue employs a team of technicians who have mastered natural-looking brows for eyes that don’t have conventionally Western dimensions. Whether you have monolids, wide-set eyes, or mismatched lids, a technician will walk you through finding the right shape and degree of darkness beforehand. Allow about 90 minutes for the whole process, which involves drawing on the shape, ten minutes for a numbing cream, and about 15 to 20 minutes to do each side. While it’s not cheap (initial sessions are in the $900 range, and touch-ups are $600), the results will last up to 18 months with minimal maintenance.
As mainstream as it has become, acupuncture hadn’t yet received the wellness-start-up treatment until WTHN arrived in the Flatiron District this past November, providing appointments for a little over half the price of other local practitioners. The place looks more like the Wing — gone is the familiar frayed hippie aesthetic. Acupuncturist and certified Chinese-medicine practitioner Shari Auth’s vision for the airy, 2,200-square-foot space was holistic healing simplified. The pared-down menu has three customizable 45-minute sessions. “Heal” targets everything from headaches to insomnia to PMS, “Prevent” de-stresses and boosts immunity, and “Glow” is facial acupuncture calibrated to reduce wrinkles and inflammation. Intro sessions are $65; return visits are $85. As a bonus, headphones purring binaural beats from Brooklyn sound-bath guru Nate Martinez will put even the most anxious needle-phobe at ease.
HealHaus in Brooklyn.
Photo: Courtesy of Healhaus
Woke Wellness Studio
HealHaus 1082 Fulton St., nr. Classon Ave., Clinton Hill; 347-413-7774
Healhaus — which holds workshops like “Brothers: Men of Color & Mental Health” and Black History Month–themed meditation classes — feels like a direct response to the wellness industry’s lack of diversity. Founders Darian Hall and Elisa Shankle set out to create a POC-friendly space that aims to widen the audience interested in yoga and more holistic types of treatment. The café up front, which serves plant-based elixirs and smoothies that Shankle developed with an herbalist, might be playing D’Angelo, while one of the yoga ($20) or meditation classes ($15), many led by instructors of color, moves along to the healing sounds of Tibetan singing bowls. The burnt-orange studio gets cozy when more than a dozen yoga mats are stacked in it, but the intimate setting often makes for more hands-on adjustments. Other offerings include reiki sound baths ($33), private tarot readings ($85), and CBD facials ($85 for 30 minutes); thriftier patrons can still enjoy a donation-based workshop. In a few months, warmer weather will allow for classes out on the studio’s back deck.
Classic Men’s Cut
Keith Cayea 37 N. 15th St., nr. Wythe Ave., Ste. 203, Greenpoint; keithcayea.com
Eight years ago, Keith Cayea was a graphic designer with a desk job, fine-tuning his haircutting skills on friends after work and on the weekends. But in 2013 he set up at the Stepping Razor in Bushwick and soon converted entire friend groups into return clients. Naturally, they have followed him to his newly opened private Greenpoint studio ($55 for a haircut; $75 to add a beard trim), where he takes around 45 minutes to an hour for clipping and texturizing instead of the usual half-hour. With a little bit of palm-warmed Morris Motley balm, he shows clients how to work their hair into a slick side part or a 1950s quiff. All of this takes place in his centerpiece green Belmont chair. The natural-light-filled sliver of a space has a custom cherrywood mirror and a Galanz mini-fridge stocked with Narragansett, and there’s usually some Motown playing.
Gym
Form Fitness 32 Court St., at Remsen St., Brooklyn Heights; 914-829-8263
Think of all the turnoffs associated with big-box corporate gyms: having to work out in front of incredibly hot people when you feel less than incredibly hot, having to figure out how to use the squat rack in front of impatient weight lifters who need to get their gains in before work, and an unalterable EDM soundtrack. Now imagine working out in a space with none of that, a.k.a. Form Fitness, a small private studio in Brooklyn Heights (around the corner from the Equinox, actually). After spending years training in the same trance-y Skrillex-on-repeat vortex as her clients, Morit “Mo” Summers decided to offer a smaller, more comfortable, less judgmental workout space. Her staff offer one-on-one sessions (starting at $100 each) and specialize in everything from HIIT to boxing to CrossFit to lots of light weights and resistance training. Summers, who worked with Ashley Graham and Danielle Brooks, doesn’t want anybody to feel intimidated by complicated workouts or critical gym patrons. If you don’t want to spend on individual training, there are group classes and small-group workshops (both, $30 to $35). Best of all, your input on the Spotify playlist is welcome.
Claus Porto.
Photo: Eric Petschek
Soap Store
Claus Porto 230 Elizabeth St., nr. Prince St.; 646-609-2922
Claus Porto’s narrow Nolita storefront, the 132-year-old brand’s first boutique outside of Portugal, is not your standard build-out. The 42-foot-long bowed-ceiling space borrows from a famous-in-Portugal landmark, the textured Casa dos Bicos; 1,500 strategically placed Portuguese-cork tiles house the line’s signature hand-wrapped, wax-stamped soaps and create a honeycomb effect. In short, if you’re going to spend $10 on a bar of soap, there is no better place. Larger bars by sister brand Musgo Real are $28. There’s a wide selection of unisex colognes ($130) as well, formulated by British perfumer Lyn Harris. Perhaps most appealing is the Estremoz-marble sink in the middle of the shop. Lathering up is encouraged.
’90s Manicure
Junie Bee Nail Salon 2330 Adam Clayton Powell Jr. Blvd., nr. 137th St.; 917-965-2720
There is no sedate spa music at Junie Bee, Teyana Taylor’s Harlem nail salon. Instead, a giant flat-screen cycles through classic ’90s hip-hop videos. The entire place, in fact, is a tribute to the decade — and neighborhood — that Taylor came up in. Pedicures are done in a structure meant to look like a heavily graffitied A train; the front desk is strewn with archival issues of Ebony. Boom boxes litter the space, as do Polaroids of Taylor’s daughter, the salon’s namesake. The technicians are precise and exacting — on one busy night, the entire staff stayed until 3 a.m. to finish every client’s acrylics. Like the salon itself, the nails are extremely ’90s. From a menu framed in glitter paper, you can choose Swarovskicrystal accents, nail piercings, or, like one recent client, acrylics printed with the fairies from The Fairly Oddparents.
*This article appears in the March 4, 2019, issue of New York Magazine. Subscribe Now!
By submitting your email, you agree to our
Terms and Privacy Notice
and to receive email correspondence from us. This site is protected by reCAPTCHA and the Google
Privacy Policy and
Terms of Service apply.
or
Already a subscriber?
What is your email?
This email will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
Password must be at least 8 characters and contain:
Lower case letters (a-z)
Upper case letters (A-Z)
Numbers (0-9)
Special Characters (!@#$%^&*)
This password will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
You’re in!
As part of your account, you’ll receive occasional updates and offers from New York, which you can opt out of anytime.
or
Already a subscriber?
What is your email?
This email will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
Password must be at least 8 characters and contain:
Lower case letters (a-z)
Upper case letters (A-Z)
Numbers (0-9)
Special Characters (!@#$%^&*)
This password will be used to sign into all New York sites. By submitting your email, you agree to our Terms and Privacy Policy and to receive email correspondence from us.
You’re in!
As part of your account, you’ll receive occasional updates and offers from New York, which you can opt out of anytime.
Already a subscriber?
Already a subscriber?
`;
// integrate Sub(x) scripts and elements
if (hostname !== 'subs.nymag.com') { // do not integrate on this subdomain
document.head.appendChild(trackingScript);
document.body.insertAdjacentHTML('beforeend', subXAnimationElements);
}
There was an error processing the request. Please try again later."}).catch(e=>console.error("Error verifying email: ",e)))(r.querySelector(".content"),o.bannerCTAVerification)})):(l.remove(),s.remove()),o.dismissable||n.remove(),o.useAlertIcon||a.remove(),r.classList.add("show"),n.addEventListener("click",()=>{u(),r.classList.remove("show")})}else r.remove()}});
}, {"1":1,"6":6,"17":17,"35":35,"40":40}];
window.modules["global-nav.client"] = [function(require,module,exports){"use strict";const dom=require(4),auth=require(17),signInButton=dom.find(".user-signin"),signOutButton=dom.find(".user-signout"),globalNav=dom.find('[class^="global-nav"]'),body=dom.find("body"),dropdownItems=dom.findAll(".dropdown-wrap"),gtm=require(1),appendLandingPageParams=require(135),pageUri=require(124).getPageUri(),subscriptionPromoLinks=dom.findAll(".persist-params"),searchString=window.location.search||"";function closeDropdowns(e){let n=globalNav.querySelectorAll(".dropdown.open");dropdownItems.forEach(function(t){let i=t.querySelector(".dropdown");!n||t.contains(e.target)&&27!==e.keyCode||i.classList.remove("open")})}function gtmSendReport(e,n,t){let i={eventCategory:"ecommerce",eventAction:"componentClick",brand:e,dimension23:"global-nav",list:pageUri,pageZone:"header",variant:"nav-link"};"global-nav-link"===t&&(i.eventLabel=n.href),gtm.reportNow(i)}function updateElementTargetUrlsIfQueryStrings(e){if(searchString){const n=new URLSearchParams(searchString);let t=e.href;if(t.includes("?")){const i=t.split("?"),o=new URLSearchParams(i[1]);for(let e of n.entries())o.set(e[0],e[1]);t=`${i[0]}?${o.toString()}`,e.href=t}else e.href=`${t}?${n.toString()}`}}function init(e){const n=e.querySelectorAll(".to-landing-page");window.addEventListener("auth:init",()=>{signInButton.addEventListener("click",function(e){e.preventDefault(),auth.showEmbeddedLoginFlow("top navigation")}),signOutButton.addEventListener("click",function(e){e.preventDefault(),gtmSendReport("Sign Out",e.target,"user-info-link"),auth.logout()}),auth.isAuthenticated()&&e.classList.add("signed-in"),(auth.isSubscriber()||auth.isMobileAppRequest())&&e.classList.add("subscribed"),e.querySelectorAll(".user-link").forEach(e=>{e.classList.add("active")}),subscriptionPromoLinks.forEach(e=>{updateElementTargetUrlsIfQueryStrings(e)}),appendLandingPageParams(n)})}dropdownItems.forEach(function(e){e.addEventListener("click",function(){e.querySelector(".dropdown").classList.toggle("open")})}),body.addEventListener("click",closeDropdowns),document.addEventListener("keydown",closeDropdowns),globalNav.addEventListener("click",function(e){let n=e.target;n.classList.contains("global-nav-track")&>mSendReport(n.text,n,"global-nav-link")}),module.exports=init;
}, {"1":1,"4":4,"17":17,"124":124,"135":135}];
window.modules["aaa-module-mounting.legacy"] = [function(require,module,exports){"use strict";const _pickBy=require(221),_each=require(408),Fingerprint2=require(407),DS=require(406),Eventify=require(246);function registerGlobals(){window.DS=DS,window.Eventify=Eventify,window.Fingerprint2=Fingerprint2,DS.value("Eventify",Eventify),DS.value("Fingerprint2",Fingerprint2),DS.value("$document",window.document),DS.value("$window",window)}function mountDollarSliceComponents(){DS.service("components",["$document","$module",function(e,n){var o=_pickBy(n.definitions,e=>e.providerStrategy===n.providers.controller),r=Object.keys(o);function t(e){return o=>{try{n.get(e,o)}catch(e){logMountError(o,e)}}}_each(r,n=>{var o=e.querySelectorAll('[data-uri*="/_components/'+n+'/"]'),r=e.querySelectorAll('[data-uri$="/_components/'+n+'"]');_each(o,t(n)),_each(r,t(n))}),this.components=r}]),DS.get("components")}function logMountError(e,n){const o=e.outerHTML.slice(0,e.outerHTML.indexOf(e.innerHTML));console.error("Error attaching controller to "+o,n)}registerGlobals(),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>{mountDollarSliceComponents()}):mountDollarSliceComponents();
}, {"221":221,"246":246,"406":406,"407":407,"408":408}];
window.modules["ads.legacy"] = [function(require,module,exports){"use strict";const _map=require(118),_forEach=require(107),_isString=require(268),_intersectionWith=require(409),_isEqual=require(274),_each=require(408),_debounce=require(182),_sortBy=require(205),page=require(124),visit=require(114);DS.service("adService",["Eventify","$cid","$document","$window",function(e,t,a,i){var o,n,s,r,d,c,u,l,g={},p=this,h=[],f=visit.getQueryParamsObject(["utm_campaign"]),m=document.querySelector('script[data-type="ad-a9"]'),b=[],w=!1,v=[],y=document.querySelector('script[data-name="ad-doubleverify"]');document.querySelector('script[data-name="concert-ads"]')||(i.NYM={},i.NYM.analytics={},i.NYM.analytics.adStartTime=i.performance.now(),i.googletag=i.googletag||{},i.googletag.cmd=i.googletag.cmd||[],u=i.googletag,(m||y)&&(i.googletag.cmd=i.googletag.cmd||[],i.googletag.cmd.push(function(){i.googletag.pubads().disableInitialLoad()})),m&&(l=i.setInterval(function(){void 0!==window.apstag&&void 0!==window.apstag.timeout&&(i.clearInterval(l),window.apstag.cleared=!0,l=null)},10),setTimeout(function(){l&&(i.clearInterval(l),i.googletag.pubads().refresh(),window.apstag||console.log("MESSAGE: Timeout for A9 load exceeded, aborting"))},500)),y&&(b.push(new Promise(function(e){w?e():v.push(e)})),c=i.setTimeout(T,2500)),o=function(e){var t,a,o=e.data,n=[];return o.loaded?e:(o.loaded=!0,t=null,(t=o.sizes?u.defineSlot(o.name,o.sizes,o.id).addService(u.pubads()):u.defineOutOfPageSlot(o.name,o.id).addService(u.pubads())).setTargeting("adid",o.id),f.hasOwnProperty("utm_campaign")&&t.setTargeting("utmcamp",f.utm_campaign),a=p.getAdCount(o.label),t.setTargeting("label",o.label+"_"+o.site+"-"+a),u.display(o.id),u.pubads().addEventListener("slotOnload",function(){i.NYM.analytics.firstAdLoadTime||(i.NYM.analytics.firstAdLoadTime=i.performance.now(),i.NYM.analytics.firstAdLoadLabel=e.data.label)}),n=_(o),Promise.all(b).then(function(){n?window.apstag&&window.apstag.cleared?window.apstag.fetchBids({slots:[n],timeout:window.apstag.timeout},function(){u.cmd.push(function(){window.apstag.setDisplayBids(),u.pubads().refresh([t],{changeCorrelator:!1})})}):y&&u.pubads().refresh([t],{changeCorrelator:!1}):u.pubads().refresh([t],{changeCorrelator:!1})}),e.slot=t,e)},n=function(e){var a,i,o,n=t(),s=e.getAttribute("data-name"),r=e.getAttribute("data-sizes"),d=e.getAttribute("data-label"),c=e.getAttribute("data-site");n=e.id,r&&r.length?(r=r.split(","),a=[],_map(r,function(e){e=e.split("x"),i=parseInt(e[0]),o=parseInt(e[1]),a.push([i,o])})):(e.classList.add("oop"),a=!1),this.data={id:n,name:s,sizes:a,loaded:!1,label:d,site:c},g[n]=this},r=function(e){u.cmd.push(function(){var t=o(e);g[e.data.id]=t})},s=function(e){var t=[];e.slot?(t=_(e))&&window.apstag&&window.apstag.cleared&&window.apstag.fetchBids({slots:[t],timeout:window.apstag.timeout},function(){u.cmd.push(function(){window.apstag.setDisplayBids(),u.pubads().refresh([e.slot],{changeCorrelator:!1})})}):e&&r(e)},u.cmd.push(function(){var e,t,o,n=page.getMeta("article:tag"),s=page.getMeta("author"),r=i.location.href,d=(e=a.head.querySelector(".head-gtm"),t=a.body.querySelector(".gtm"),e&&"top"===e.getAttribute("data-gtm")?"gtmtop":t&&"bottom"===t.getAttribute("data-gtm")?"gtmbottom":"");o=[],_forEach([n,s,d],function(e){_forEach(e.split(","),function(e){(e=e.trim().toLowerCase().replace(/\s/g,"-").replace(/\'|\’/g,"")).length&&o.push(e)})}),u.pubads().setTargeting("kw",o),u.pubads().setTargeting("entry_group",o),r=r.slice(r.lastIndexOf("/")+1),u.pubads().setTargeting("pn",r),u.companionAds().setRefreshUnfilledSlots(!0),u.pubads().enableAsyncRendering(),u.enableServices()}),this.load=r,this.create=function(e){return new n(e)},this.refresh=function(e){var t;_isString(e)?(t=this.getById(e),s(t)):s(e)},this.remove=function(e){var t=e.data.id;a.getElementById(t).innerHTML=""},this.getAdCount=function(e){var t,a=0,i=Object.keys(g);return _each(i,function(i){(t=g[i]).data.loaded&&t.data.label===e&&a++}),a},this.getById=function(e){return g[e]},d=_debounce(function(){var e={TopLeaderboard:1,RightColTopMPU:2,outOfPage:99,"homepageTakeover/TopLeaderboard":1},t=_sortBy(h,function(t){return e[t.data.label]||10});_forEach(t,function(e){return e.data.sizes?r(e):i.setTimeout(function(){r(e)},2e3)}),y&&window.PQ.cmd.push(()=>{try{window.PQ.loadSignals(["ids","bsc","vlp"],T)}catch(e){T(),console.error(`There has been an error loading Double Verify signals: ${e}`)}}),h=[]},10),this.addToPageLoadQueue=function(e){h.push(e),d()});function _(e){var t,a=e.sizes;return a=_intersectionWith(a,[[970,250],[970,90],[728,90],[300,600],[300,250],[320,100],[320,50]],_isEqual),e.sizes&&e.sizes.length&&(t={slotID:e.id,sizes:a,slotName:e.label}),t}function T(){i.clearTimeout(c),w=!0,_forEach(v,function(e){e()})}}]);
}, {"107":107,"114":114,"118":118,"124":124,"182":182,"205":205,"268":268,"274":274,"408":408,"409":409}];
window.modules["cid.legacy"] = [function(require,module,exports){"use strict";DS.service("$cid",function(){var r=Math.floor(100*Math.random());return function(){return"cid-"+ ++r}});
}, {}];
window.modules["client.legacy"] = [function(require,module,exports){"use strict";require("cid.legacy"),require("ads.legacy"),require("facebook.legacy"),require("aaa-module-mounting.legacy");
}, {"cid.legacy":"cid.legacy","ads.legacy":"ads.legacy","facebook.legacy":"facebook.legacy","aaa-module-mounting.legacy":"aaa-module-mounting.legacy"}];
window.modules["facebook.legacy"] = [function(require,module,exports){"use strict";DS.service("facebook",[function(){this.fb=function(i){window.FB&&window.FB[i].apply(this,Array.prototype.slice.call(arguments,1))}}]);
}, {}];
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o typeof key === 'string' && key.match(/\.legacy$/)).forEach(key => window.require(key));
}
function tryToMount(fn, el, name) {
try {
fn(el); // init the controller
} catch (e) {
const elementTag = el.outerHTML.slice(0, el.outerHTML.indexOf(el.innerHTML));
console.error(`Error initializing controller for "${name}" on "${elementTag}"`, e);
}
}
/**
* mount client.js component controllers
*/
function mountComponentModules() {
Object.keys(window.modules).filter(key => typeof key === 'string' && key.match(/\.client$/)).forEach(key => {
let controllerFn = window.require(key);
if (typeof controllerFn === 'function') {
const name = key.replace('.client', ''),
instancesSelector = `[data-uri*="_components/${name}/"]`,
defaultSelector = `[data-uri$="_components${name}"]`,
instances = document.querySelectorAll(instancesSelector),
defaults = document.querySelectorAll(defaultSelector);
for (let el of instances) {
tryToMount(controllerFn, el, name);
}
for (let el of defaults) {
tryToMount(controllerFn, el, name);
}
}
});
}
// Make sure that a `window.process.env.NODE_ENV` is available in the client for any dependencies,
// services, or components that could require it
// note: the `` value is swapped for the actual environment variable in /lib/cmd/compile/scripts.js
window.process = window.process || {};
window.process.env = window.process.env || {};
if (!window.process.env.NODE_ENV) {
window.process.env.NODE_ENV = '';
}
// note: legacy controllers that require legacy services (e.g. dollar-slice) must
// wait for DOMContentLoaded to initialize themselves, as the files themselves must be mounted first
mountLegacyServices();
mountComponentModules();
// ]]