Theater Review: Harry Potter and the Broadway Spectacle
BySara Holdren,
a theater director and a critic at New York magazine and Vulture.
Wands at the Lyric.
Photo: Matthew Murphy
“My geekness is a-quiverin’!” a teenage wizard named Scorpius yelps in excitement somewhere around hour five. He’s not the only one. If you’ve ever wanted to experience the feeling of 1,626 people’s geekness quivering in unison, you might try apparating into the Lyric Theater during a performance of the two-part, almost-six-hour-long, record-breakingly extravagant, and extravagantly entertaining Harry Potter and the Cursed Child.
It’s not a cheap time to be a Harry Potter fan, but it is an exciting one. Jam-packed with breakneck plot twists, charming performances, mind-bending spectacle, and, perhaps more surprisingly, moments of theatrical whimsy that feel, amid the high-tech sorcery, delightfully simple, The Cursed Child is a remarkable and fitting addition to the Potter canon. By “fitting” I mean: It effectively weaves serious themes with bouncy adventure narrative, it’s heartfelt and sometimes a touch hokey, it could have used a more rigorous editor, and, if you have even a beginner’s taste for this kind of thing, you’re pretty much willing to forgive its shortcomings as it sweeps you along in a rush of rip-roaring, good-natured imagination.
J. K. Rowling — whose progress from single parent on welfare scribbling in Edinburgh coffee shops to world’s first billionaire author is almost as well known as her tale of a boy wizard — conceived the original story for this eighth installment in the Potter saga along with the show’s director, John Tiffany, and Jack Thorne, who wrote the script (a best seller virtually as soon as it appeared in hardback, which … doesn’t happen to plays). Thorne has a definite feel for Rowling’s wordy, waggish, plot-happy sensibility, and Tiffany, along with his longtime collaborator, movement director Steven Hoggett, keeps the stage magic wheeling along at an often breathless pace. He needs to: Rowling devoted a full novel to each year her teenage hero spent at Hogwarts School of Witchcraft and Wizardry, whereas in The Cursed Child, that hero’s son speeds through the first three years at his dad’s alma mater within 15 minutes.
Harry’s boy is named Albus Severus Potter, and fast-forwarding him from 12 to 15 years old in a matter of moments is only the first of the tricks the show plays with time. Mounted in the arched buttresses of Christine Jones’s shadowy, evocative set — which calls to mind a gothicized Kings Cross, the train station where young British wizards head to school — are a number of large clocks. A massive, ornate clock-face also dominated Alfonso Cuarón’s 2004 film of the third Harry Potter novel, The Prisoner of Azkaban (in my mind the first Potter movie worth paying attention to), and the parallel is no coincidence. The central device of that novel, a self-explanatory magical object called a Time-Turner, also plays a key role in The Cursed Child. We’re in for a time-hopping tale, full of butterfly effects and temporal twists. Think of it as Back to the Wizarding Future, or It’s a Wonderful Wizarding Life.
But before we go any further, I should say that a few minor spoilers lie ahead. Nothing too shocking — after all, when you exit the theater, ushers hand you a pin exhorting you to #KEEPTHESECRETS. The show’s program even encourages you not to read the cast list until after the performance, if you don’t want to know which characters you’ll be encountering along the way. Well, I’ll have to name a few names below, so don’t hex me. Or you could always try obliviating yourself afterward.
Rowling, Thorne, and Tiffany have done something rather brilliant in hanging their story on the ability to jump through time. The Time-Turner allows them to capitalize upon and revisit the world of the novels, the familiar terrain that fans know and love, while also crafting a new present-day narrative that’s affected by the characters’ dalliance with history. (As we’ve been taught by everyone from Bill and Ted to the X-Men, messing with the past is a tricky business.) The creators of The Cursed Child aren’t just attaching another sequel — they’re going back into the canon and making mischief in the margins, which feels deliciously naughty.
Most of the play takes place 22 years after the events at the end of the final Harry Potter novel, which makes the Boy Who Lived not quite a boy anymore. You could call him Harried Potter now: The 40-something wizard is an overworked Ministry of Magic official with three kids. His boss, the Minister of Magic — his eternally type-A buddy, Hermione Granger, who else? — wants him to clear his desk of paperwork. His former rival — the still supercilious, short-fused, silver-blond Draco Malfoy — wants Harry to help quell the nasty rumors that his (Draco’s) son is actually the bastard child of the Dark Lord, Voldemort. And Harry’s wife, Ginny Weasley, wants him to try to connect with his middle child, the brooding, frustrated Albus.
Poor Albus Severus seems to be the ill-starred child of the play’s title (or is he?). At any rate, he’s a classic misfit, struggling to live up to his father’s fame. Like any teenager, underneath the antisocial angst, he wants to be special, to be seen, to make his parents proud. But Albus isn’t particularly quick with spells, he hates Quidditch, his best (and only) friend is Scorpius Malfoy — Draco’s kid, the one surrounded by ominous rumors — and, worst of all, he’s a Slytherin. “What would you like me to do?” he snaps at his beleaguered father at one point, “Magic myself popular? Conjure myself into a new House? Transfigure myself into a better student? Just cast a spell, Dad, and change me into what you want me to be, okay?”
Anyone who’s read The Order of the Phoenix knows that Harry himself was the reigning king of teenage angst, but age and anxiety have made it hard for the famous wizard to see just how like him his son is. He’s concerned but quick to anger, and in their clumsy efforts to connect, he and his boy end up lashing out. The Cursed Child is, at its heart, all about fathers and sons — the particular emotional blockages experienced by wizards (and muggles) of the dude persuasion — and the engine of its plot is Albus’s increasingly reckless quest both to win his father’s approval and (the essential teenage paradox) to defy/outshine him. The Time-Turner is the dangerous tool he employs in that conflicted attempt.
“Everyone talks about all the brave things Dad did,” Albus tells Scorpius in a flush of stubborn conviction, “But he made some mistakes too. Some big mistakes, in fact. I want to set one of those mistakes right.” Sam Clemmett is an affecting Albus, believably teenager-ish with his tensed-up shoulders, furrowed brow, and coiled, simmering energy. Like the young Harry, Albus isn’t necessarily the most vivid character — he’s got to be average in certain ways, an audience cypher who triumphs not through extraordinary ability as much as through extraordinary will, loyalty, and courage. It’s a standard setup, but it works — due in part, as these setups often are, to the exceptional supporting work of a quirkier sidekick.
As that sidekick — the homework-loving, candy-hoarding crown prince of nerds, Scorpius Malfoy — the tremendously talented Anthony Boyle carries a huge portion of the show on his skinny shoulders. Boyle, who won an Olivier for his performance in London, is channelling a young Rowan Atkinson in a chlorine-blond wig: He’s all gangly, awkward gestures, bursts of enthusiasm that come out somewhere between a snort and a shriek, and expert comic timing of the hopelessly-uncool-guy variety. He’s also — and this is critical if you’re an actor in a Rowling-based universe — incredibly skilled at converting large passages of exposition into dramatic action through the sheer energy of his delivery. He brings potentially moribund dialogue to life. Coming out of Boyle, lines like “We did it! We beat the library!” (uttered after a fight with a magical bookcase and, let’s face it, not the most compelling exclamation on the page) provoke riotous laughter.
Scorpius is also compelling because he’s a genuinely new character. In Albus we’ve got a kind of Harry 2.0; in Hermione and Ron’s daughter Rose Granger-Weasley we get another, slightly snootier Hermione (though really, we have so little of Rose that the impression isn’t fully formed); in the upbeat, punky Delphi Diggory we have (at least for a while) a rebooted Tonks; and of course in the play’s adults we have, if we’re readers of the books, our old friends — with a few more gray hairs. Scorpius, however, is no reboot or variation on a theme but his own animal, and the writers know what they’re doing when, for a significant chunk of Part Two, they implement a plot twist that keeps Clemmett in the greenroom for a spell and moves Boyle to center stage.
Without venturing into spoiler territory, it’s fair to say that the climax of The Cursed Child’s first part and the opening sequence of its second offer the hungry audience a generous helping of theatrical candy. Jamie Harrison — who’s first among the team credited for the show’s illusions and magic effects — is consistently working at full blast, and at the end of Part One, his visual sorcery spills out of the proscenium and takes over the room. (Great credit is also due to Neil Austin’s sharply articulated lighting design, whose deep swaths of shadow and streaks of blinding brightness facilitate much of the show’s misdirection.) Is the sudden immersive effect borderline Las Vegas–y? For sure. But it’s also pretty thrilling. And what makes The Cursed Child a continuous delight is that for every million-dollar effect (and there are plenty), there’s a piece of lo-fi stage magic that feels equally beloved by its creators. Watching the towering Brian Abraham — a human embodiment of the Sorting Hat — pluck his bowler out of the air where it seems to be floating unsupported; or seeing him sprinkle a handful of paper snow in anticipation of a flurry falling from the flies; or watching the cast ingeniously enact the effects of a transmogrifying potion: Moments like these keep the show’s makers, and we its watchers, honest. So does Tiffany’s multipurposing of objects like suitcases and steamer trunks, or his realization that actor-controlled rolling staircases offer a perfect dramatization of Hogwarts’ magically shifting internal architecture. Tiffany and Hoggett have done their share of scrappy, actor-driven theater, and they know that simple things — suitcases, stairs, an ensemble moving in unison, a well-timed cape swish — are where the real enchantment of their medium lies.
But the additional — and perhaps the most powerful — enchantment of this particular trip to the theater is actually on our side of the footlights. Looking around me, I saw Hogwarts house colors, black robes, and wands filling the seats. When Jamie Parker made his first entrance as Harry Potter, and when Noma Dumezweni and Paul Thornley first appeared as Hermione and Ron, the already crackling energy in the dark auditorium erupted. (Later, I heard a woman actually scream in delight when a silhouette resembling that of Severus Snape began to glide forward, back to us, on the set’s big central turntable.) This isn’t normal entrance applause: The audience is cheering not for celebrities but for characters. Not that the actors aren’t doing cheer-worthy work. On the contrary, they’re turning in effective, endearing performances, from Parker’s stubborn, struggling, still emotionally stunted Harry, to Thornley’s dad-jokey Ron, to Dumezweni’s restrained (but comically adept) Hermione and Poppy Miller’s patient, not-to-be-messed-with Ginny.
The truth, though, is that we haven’t come to see Parker: We’ve come to see Harry. And even after a star-studded movie series, our imaginary friends still remain more powerful, more solidly alive in our minds, than the famous figures who’ve erstwhile donned their robes. Though the experience we’re all engaged in is massively, knowingly commercial, it’s also a startlingly moving affirmation of the human appetite for story, and — because we’re now in a theater instead of nestled in our beds with a book — the bodily power of sharing that story with 1,000 other breathing, quivering souls in real time. Sitting in the Lyric today is like standing on the New York docks in 1841 where, legend has it, avid American readers of Dickens’ serialized novels flocked in passionate crowds, crying out to the sailors whose boats were bringing the latest installment of The Old Curiosity Shop: “Is Little Nell dead?”
Harry Potter and the Cursed Child is at the Lyric Theatre.
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,"12":12,"35":35,"40":40}];
window.modules["global-nav.client"] = [function(require,module,exports){"use strict";const dom=require(3),auth=require(12),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(136),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 o=t.querySelector(".dropdown");!n||t.contains(e.target)&&27!==e.keyCode||o.classList.remove("open")})}function gtmSendReport(e,n,t){let o={eventCategory:"ecommerce",eventAction:"componentClick",brand:e,dimension23:"global-nav",list:pageUri,pageZone:"header",variant:"nav-link"};"global-nav-link"===t&&(o.eventLabel=n.href),gtm.reportNow(o)}function updateElementTargetUrlsIfQueryStrings(e){if(searchString){const n=new URLSearchParams(searchString);let t=e.href;if(t.includes("?")){const o=t.split("?"),i=new URLSearchParams(o[1]);for(let e of n.entries())i.set(e[0],e[1]);t=`${o[0]}?${i.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()&&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,"3":3,"12":12,"124":124,"136":136}];
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","aaa-module-mounting.legacy":"aaa-module-mounting.legacy","ads.legacy":"ads.legacy","facebook.legacy":"facebook.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();
// ]]