 It's a long walk. Good morning. As Hannah informed you, my name is Libby Barker. I'm a senior project manager at Human Made. And I'm Mike Sealander. I'm a senior engineer at Human Made. And incidentally, Mike and I met for the first time at WordCamp Europe in Vienna two years ago. So we're really excited to be back for this presentation. So thanks to you all for being here. Over the next 30 minutes or so, Mike and I are going to be sharing with you an experience of a project that we recently delivered, which was a collaboration with Tech Crunch to build a decoupled WordPress application with a React front-end. This seems to be, may I use yours? Thank you. So over the course of our talk here, we're going to touch on a few key aspects of the project. First, we're going to do a little bit of an introduction about the partners who are involved. We're going to talk at a high level about the business opportunity that Tech Crunch had and why our approach, which we'll then follow that with, was specifically chosen for this project. We're then going to look at some of the features that we built out specifically for Tech Crunch to meet those business needs and to work within the context of the architecture that we determined as a team. And then finally, we're going to be sharing with you some of the technical solutions and open-source libraries that we've developed as a result of this project. So to get started, let's look at who all was involved. HumeMade's relationship with Tech Crunch actually also began in 2016 when Nicole Wilkie, Tech Crunch's head of product, approached us with an exciting redesign opportunity that they wanted to pursue. For those of you or anyone who is unfamiliar with Tech Crunch, they are a leading publisher of startup and venture capital news based in Silicon Valley. And not only are they reporting on this space, but they're important influencers in it as well. They run a series of events. The flagship one is called The Swrupt that are held all over the world. And they are an important opportunity for startups that are already established or just starting out to create networks and identify funding opportunities. Tech Crunch has been a longstanding user of WordPress. And actually to that end, they're hosted on WordPress VIP, which is a great hosting solution for enterprise clients that need to be able to host at scale. For this particular project, Tech Crunch wanted to do something that would be innovative, cutting edge. They loved their work with WordPress, felt it was the foundation of their editorial workflow and the product that was supporting their business. But they wanted to do something that was going to really embody that philosophy of innovation that's such a core part of their mission. So we're obviously very excited to get involved in anything innovative and cutting edge. So we were eager to get started. When we begin any project, it's important for us not just to come in with a technical understanding, but a business understanding of our clients' needs as well. We want to, at the end of a project, deliver something that's not just a great code base, but something that's going to embrace longevity and help our clients to pivot and grow as their markets change. So as senior PM, I was brought in pretty early to work through these with Nicole. And we wanted to just touch on a few of them to hopefully help clarify some of the choices that we would make later. So in Nicole's own words, TechCrunch wanted this redesign to be ambitious. As we touched on at the beginning, for this project, they chose to pursue a decoupled WordPress application. TechCrunch wanted to leverage the inclusion of the WordPress REST API into core to use this as a platform for exploring WordPress as a foundation with JavaScript front end. This would do two things. It would allow them to continue using the CMS that they felt most comfortable with, and that was that foundation of their product. But it would also give them the flexibility through the JavaScript front end of being able to pivot and incorporate new features in a quickly changing environment, such as venture capital. It also was a great opportunity for us in collaboration with TechCrunch and their development team to look at how we could refactor their existing code base, which had grown over the years, to best support this type of product and create a really lean, powerful solution. For any publication considering a redesign, or really any product considering a redesign, considering how you will improve user engagement through your changes is one of the most critical questions. To accomplish this, TechCrunch worked with a design agency called Work&Co to deliver a design that was focused on fluid interactions that would apply well over a JavaScript front end. The hope was that this approach would embrace a native app experience that would deliver to the end readers a continuous flow of content, a really immersive reading experience that would keep them on the site longer. And while, of course, the end user is the one who's seeing the final product, user engagement of the people building and delivering the product to the end user are just as important. So as part of our reconsideration of how the CMS would be used in relation to this approach, we wanted to take an opportunity to also think about how this would impact the editorial team as well as the other business teams operating on the product as well. So with that approach in mind, it was time for our team to really dig into the technical approach that we were going to pursue with this project. And to speak to that, I'm actually past the conversation to Mike. Thanks. So as Libby mentioned, the client wanted something that was extremely interactive, extremely engaging, and they wanted this website to feel like it was a mobile application, even if you were on your desktop. So basically, they wanted the user to never feel like they had left the website, even if they're doing full page navigations. So for example, you're popping in and out of an article. They don't want the whole site to disappear as you're transitioning between those pages. They want everything to feel fluid. They want to be able to replace small parts of the component, small parts of the application in time as we're going. So we knew from the get-go that we wouldn't be able to use a typical traditional WordPress templating approach. So there's just too much page transitions. There's too much jank. There's too much going on between those pages, and you're really pulled out of that experience. It doesn't feel fluid. It doesn't feel like you're a part of the application the whole time. So we wanted to go with a JavaScript framework to handle the front end of the website. And at this point, it should be unsurprising that we use React.js for this. React.js is a JavaScript library that is built specifically to create engaging and interactive UIs. So it's a component-based model that allows us to swap out small parts of an application really fast, really performantly, and the user sees almost no transition in most cases. So it gives us a lot of power and a lot of flexibility on the front end. Now, WordPress is still a first-class citizen in this architecture. It still handles all of the administrative side. We're still handling all the data through it. Editorial sees it. We're still using the REST API and such, because TechCrunch had used WordPress for almost 10 years. So it was always going to be a really strong part of this. However, when you're building a React or View or Angular application on top of WordPress, usually what you would go with is a fully decoupled or headless approach. And what this means is that WordPress is stored on one stack, or it's served up from one stack. So you have PHP and Apache. That's all served on separate servers. And then React or View or another, your front end of the site would be served on a completely different stack. And they only talk to each other over the REST API. And this architecture has a lot of benefits. But for us, we wanted to go with a slightly different approach. And we chose what we like to call a semi-decoupled React application. And what this means at the base, at its core, is that WordPress still handles some of the templating. So we're not just handling the data in WordPress, handling the administration there, and then handing it off to React and saying, React, go do your thing, do whatever. But we're using WordPress to preload and hydrate some of this data and preload some of the templates so that the user sees something almost instantly. And we have a lot of advantages in the simplicity of the stack, because everything is served from the same servers. So our React bundle is served from the same servers that WordPress is handled on. We're not having to deal with and handle a completely different stack to serve that up. So to give you an example of what this looks like in practice, because all this series is great, but you kind of want to actually see how this works, this is what you would see if you went to techcrunch.com today without JavaScript enabled in your browser, or if your browser is just really slow, like if it's really throttled. And this is a very Spartan, simplistic view of the website. All we have here is a couple of posts. You can actually click through all of this so it's fully navigable, you can use it like you would a normal website. But it's very simple, it's very Spartan. And this is all served using WordPress templating. So we haven't gotten to React, we haven't gotten any JavaScript at this point. And this has two advantages, this really simple view here. The first is that we're not duplicating too much effort in recreating what we've created in React and all the templating and the views in JSX on that side. So we're not duplicating that too much in WordPress templates, so there's low duplication of effort. But even more importantly, this very small return allows us to get this to the user almost instantly. This is very aggressively page cached and VIP does an excellent job of serving this out via their edge nodes and they have a CDN to serve this out very quickly. So as a user, you're gonna see this view almost instantly, so the perceived performance of this page is going to be very, very quick even if it's not the full experience. And while this is loading, while WordPress is serving this, it's also giving React a little bit of time to load in the background. Because our React bundle ended up being really big, this is a very complex website with a lot of components in it. So we're serving almost 300 kilobytes just for the React bundle and the routing and the componentry and such. And that can take one to two seconds to load. And when that actually loads up, what you get is a view similar to this. Now you have all these extra things on here, you have navigation, you have a feature island and you have advertisements and these extra pieces that you get with any functional website. What's important to note here is that this view here, this river, the posts, is almost identical to the view that we had before. So as a user, this feels like React is progressively loading up more into the website, even though it's actually going in and wiping out everything that WordPress has handled. So it feels very smooth, it feels very fluid and from this point on, React handles all of the routing, all of the animations, the transitions, all the content and it only goes through the REST API to get what it needs. So to look at this architecture a little bit again, just a tiny bit closer, we have WordPress and this serves as a base of our application. It's hosted on WordPress VIP and that serves data into React. We hydrate or preload some data in there when we handle all these templates or when we're loading up the page. And then React takes over and as long as you stay in that tab in your browser even though you're navigating through several pages, React is the only part of this application that you see from now on and that's where it becomes effectively decoupled because it only goes through the REST API for the rest of its data. We also use Redux for our state management and React Router for our animation routing needs and then we also use Webpack to build it. And so with all this architecture in mind, I'm gonna hand this back to Libby and she's gonna talk to you a little bit about some of the features that we were able to build using this architecture. Thanks. Right, so once the architecture was in place and this is the key delivery for the first part of the project or deliverable, I should say, it was time for us to start considering the kind of features we were going to build out for TechCrunch in this environment to make sure we were meeting those business goals that we talked about earlier. The first one I wanna talk about is the River experience which I'll get to in a moment but is that kind of core reading experience for anyone landing on this site. And this is the experience that is the underpinning of that native app experience that TechCrunch wanted to create. As Mike mentioned, in order to do this, the experience needed to be consistent across the site, needed to make the user feel that they were never off a single page. So the River is termed such as the idea that when a reader enters TechCrunch.com, they should feel that they're immersed in a current of content or a river of content and they're being propelled very fluidly from one piece of content to the next. I'm just gonna demonstrate what this looks like here. So you scroll through, this is the home page, driving the user through all the latest posts but as you'll notice, we click into startups which is a section page, that experience is exactly the same. Only it's targeted to readers who wanna know specifically about startups and funding or in this case, for a topic page, readers who wanna know about the WWDC last week. This information is all targeted but the experience is consistent regardless of where you are on the site. This kind of continuous flow of content and consistency so heavily rooted as part of the experience also led to some other considerations that we needed to take as a development team. The first was how we would develop wayfinding for readers. While it's great for them to be in this river of content, they also needed some ways to navigate it. So there are a couple of little details that I just wanted to point out as part of this experience. I'm entering a single article here and at the top right, it's a little subtle but you can see the progress indicator demonstrating exactly where you are on the read. The check mark, a subtle change of background which may be too late to see before the article snaps shut. I actually wanna just point out that snapping shut behavior because it is, again, very understated but it's actually really important in terms of the reading experience. You'll notice when the article closed it actually dropped me right back to where I was before. Right back in the river, at the top of the content that I haven't yet read. There's a change in the title color, it's grayed out, kind of encouraging me onto the next piece which I have now a clear indication that I haven't read but that maybe I should. There's also posts of interesting challenges for the editorial team as well. For editorial teams working within very specific strategies, they need ways to distinguish content. Whether it's featured stories or sponsored posts, how can they differentiate or highlight certain pieces? One example that I wanted to, where we wanted to talk about, is developing stories. Developing stories was very interesting. It was unique to the redesign, actually. It had not existed as a feature before the redesign and it was an opportunity for the editorial team to really leverage the river experience and the native app experience of the new product to better tell a story, a more engaging story for the reader. So I'm just gonna pull up another little video here. The idea behind developing stories is that TechCrunch's editorial team is remote. They're not working in the same office or co-located though. But they found they were often reporting on stories about the same topic across a number of days or weeks, but they're all referring to the same subject. So using that river continuous flow of content experience to guide them, we came up with a solution to help them target these stories to readers more effectively. The developing story groups related but autonomous articles under a single heading and a teaser text on the homepage. And as an administrator or an editor, when you go and create new posts, you can very easily assign these to this group or unassign them as you need. Play a little video. So as I click into the story here, you'll notice, again, that river experience is persistent. The articles are in reverse chronological order. So for someone who's dying to know about the electric scooter saga in San Francisco, they can turn to their trusted reporter, TechCrunch, for the latest information that's always up to date. Even go back further, learn the genesis of this problem. However, you also have the ability to enter a story individually. And the story retains its autonomy. This was an important piece to get right because TechCrunch generates a lot of brand loyalty through their social presence. In order for users to share stories within a developing story, they needed this individuality of the story to create entry points for other people through social networks to enjoy the content as well. So when we're talking about user engagement, it's kind of impossible to have that conversation without also talking about ads and analytics. Ads are obviously an important revenue stream for any product. But we couldn't deliver this in the way that we would have done with a traditional WordPress website. We faced a couple of constraints as a result of the architecture and business needs of this project. The first is that React is not compatible with that traditional method of delivering ads. So we needed to find a solution for how we would approach that. Additionally, we were requested by the client to use their proprietary ad system, which is part of a larger network of sites. And that in itself presented some parameters we needed to work around. So actually, to talk about the specifics of how exactly we did that, I'm going to once again. To Mike. All right. So like Libby mentioned, ads and analytics rely on basically a very traditional model of web pages and web applications. So usually, when you integrate most ad and analytics platforms, they expect a consistent and stable set of DOM elements of contextual information, such as that. So basically what they expect is you have an element with this ID on the page. You put some information in the window object. You tell the ad script where to put an ad similar with analytics. You load up a page. You give it some information. It sends off info. And you load another page. Does the same thing. Loading the page does the same thing. So this relies on stability. This relies on everything staying the same. But when you're building a single page application, everything is always changing. The contextual aspect of it is not going like the contextual aspect of a page is not going to change when you go into a post. Because the entire page is still there, all the DOM elements have potentially changed. And you have to control how that context flows, how it runs, where the elements go, where you want it, et cetera. So React and View and Angular and all of these, they completely blow those typical expectations out of the water. And you have to do a lot of custom work to actually make them make analytics and ads work as they're supposed to work as they're expected. So what we did for this project is we decided to hook into Redux, which I mentioned earlier was our state flow management tool for React. And Redux has a singular data flow, which allows us to hook in at very specific points and know that when an action in Redux has fired, and an action in Redux is somewhat actually very similar to actions in WordPress, when a certain action is fired, we know we have the data that we need, we know we have the elements that we need, and we know where those elements are. So we had to write a lot of wrappers around the ads and analytics scripts that we received, and when an action is run. So for example, when a user pops open a post, that entire page is still there. We just have extra elements. But when that's done loading and when it's all there, we know we have the information we need. So we send off analytics, and we load ads in very specific spots using wrapper components in React. So the big takeaway for us with this was the fact that you really have to evaluate what your traditional legacy tools are going to do in this kind of situation, because they're probably not gonna work as you expect. There's gonna be subtle issues, subtle changes, and subtle differences that you have to evaluate. The next feature that we wanna talk about is events. And Libby mentioned earlier that TechCrunch does not just have an editorial team. If you've used TechCrunch before, you've probably been reading their articles, looking at what they've shared on social media, reading through the news on startups, but they have a whole other side that's incredibly important to their business, because they're not just about journalism. They're about increasing the overall startup space, increasing venture capital, connecting people together, and they do this with events. And events have a very different editorial need and a very different visual need, because when you're looking at news on the TechCrunch site, you're interested in the most recent, most ongoing articles. Like you're probably just gonna read that homepage or maybe search for something very specific. So it's gonna be an ordered list. It's gonna be relatively static the way that it's set up. But events need to be customized for each and every single one. So we had to build a view that kept the branding and kept the same kind of componentry, the same feel that we have with the rest of the website, but GiveEditor is a lot of control over how this works. So you can see here, this is an event that is coming up, I believe. And we have this navigation on the left-hand side. So the branding stays consistent. We still know you're on this TechCrunch site. But everything else about this site is gonna look slightly off or slightly different. So all of these blocks on here are controlled by a customized page builder in the backend. And editors can go in and change out any of these. They can add, remove, delete, change out the content of them, customize any single aspect of this. So they have full editorial control over this on a very, very granular level. And every event is gonna end up a little different because everyone has different needs, different locations, et cetera. And in this same vein of needing a lot of customizability, these events also need different information depending on what stage you're in because they're very time-focused, very time-based. If you're in this view, which is the pre-event view, you need to have information about what's upcoming on the event. But if the event is ongoing, alternatively, we want users to be able to go on and feel like they're a part of this event. So we display a live screencast of what's going on. You can see what sessions are coming up so you know when to tune in, what to see, et cetera. And you can see the news actually rolling in. And the beauty of using React for this was that we were able to use the same components across the board, across all these different views, just in slightly different orders with a little bit different control. So the reusability and extensibility was really, really solid with this. And then similarly on the back end, you'll recognize the feature island that we have from the home page. And this just shows different news and different screencasts and different views of the event. So you can keep engaged with the brand as you're going. So we're able to use React to create really reusable and really interesting interfaces, even though we have completely different needs for different editorial sides of the company. So it was obviously really exciting to watch these and a number of other features take shape in the weeks leading up to launch. And when we did deliver the project this past March, we celebrated first. And then we took a step back and started to assess what actually the lessons we learned from this project were. What were we going to take forward with us to our next project, to our colleagues, and back to the community as well. As a result of this project, there are a number of open sourced or now open sourced libraries that we developed. And we wanted to share those with you today for anyone who's interested in pursuing a project of this nature. And to speak to those, I'm actually going to ask you. So like Libby mentioned, these are kind of the epilogue to our project. This is our gift back to the community with some of the things that we've learned. And I'm only going to share three of these, but there's quite a few... There's a couple more that we can also talk about. So if you want to come up and talk to us about these projects or any other further ones that came out of this, feel free because we'd love to tell you more about them. We're only going to talk about three of these today. All of these are going to be available on GitHub and we'll have links to the resources at the end. And we're just going to talk quickly through some of the challenges that we encountered and how we solved them through these open source tools. So the first issue that we encountered or for one of the first and biggest challenges we encountered was there's a large disparity between the way that WordPress expects a development environment to function and how Webpack, which powers React and Vue and these other single-page applications, expect a development to... expect a local development environment to behave. So WordPress expects a very static set of resources. So you give it a URL of a script you want to serve. It looks for that script and tries to load it and that's the end of the story. It's very simple. It's very static. But Webpack is going to serve all of its resources from its own development server on your local machine and the name of those are going to change. The context is what's going to change. It allows you to do things like hot reloading the page so you don't have to manually refresh it, do component swapping, change out styles granularly and very quickly. So you need some kind of bridge between these two different systems. And so we built a small drop-in tool called ReactWPScripts. And ReactWPScripts is built to expect a Create React application. Yeah, Create React. Yeah, Create React. So it's built very specifically for this setup but you can modify it to use in almost any Webpack situation. You drop in this tool, so it's library, you put it in your Moop plugins or your plugins and instead of on-queuing in your local, you use our own on-queue function which looks for a Webpack manifest file and then it feeds those resources in and allows you to really smooth out and speed up your development environment and make sure everything is working quickly and as it should. And it really will improve developer happiness when you're working on the single-page applications on WordPress. So the next challenge that we wanted to address was actually a pretty universal challenge and that is the issue of documenting API data when you're writing it and the friction between wanting to actually write that data and spend time on building the website versus documenting it. Because documentation and API data is extremely important because you have to have some form of contract between your backend and your friend and developers so that when they're working jointly because that's usually how this situation works, they know what data to expect, how it's supposed to be formatted and everything but it takes a lot of time to write this documentation. It's very frustrating as a developer to not be writing something and have to go into some Word doc or something completely separate and write that. So we wanted to create a tool that automatically created this documentation for you and we created a tool called Restplane and it's available to be included as a plugin. You install this plugin and you get a UI that looks something like this and this hasn't been customized. This was just installed on our website and automatically scraped all of our endpoints and you can see here that this has all of the endpoints available to us on the left and we can click into one and we can get context about each of these endpoints and extra information and all of this happens really automatically so all you have to do is install this plugin and your product owners, your developers, anyone who needs access to this information has it and you can easily use it. So the last challenge that we wanted to talk about was the issue of pulling Rest API data into Redux. Now, when you're doing this, what happens frequently is that every time you have to add a new piece of data, a new endpoint, something new that you want to put into Redux, there's a lot of replication of effort. So you have to call out to Rest API, you have to normalize this data, you have to create actions to hook into it, you have to reduce this data into the appropriate formats and such and it's a lot of work, there's a lot of steps here and it's not hard work, but you don't want to replicate this every single time you're doing it and it also creates an opportunity for slight inconsistencies to sneak into the system. So we created a small tool called Repress and what this does is it takes over a small piece of your Redux store and you tell it what your Rest API URL is, which should be in your application already, you tell it what kind of data you want to fetch if it's a custom post-hyperterm, et cetera and it goes out to WordPress, it fetches that data and then it will put it in your store in a consistent manner and it just reduces the amount of work that you have to do when you're pulling all this data in to manage all of this. So next I'm gonna hand it over to Libby and she's gonna finish this off with some resources for you guys and information about the team. Right, so I know we're very close to the end but before we go I do just wanna acknowledge the full team that was part of this project, Mike and I are merely representatives. Leading this was Frank Klein, Senior Engineers Robert O'Rourke and Catam White were an integral part of this project as well and we of course had the help and consultation of Joe Hoyle, our CTO and Ryan McHugh, our Director of Engineering. Incidentally Rob, Catam and Ryan are all here this weekend so if you have questions for them about this project I encourage you to pull them aside, especially Ryan. And as Mike mentioned, these are the links to the open source libraries we discussed today. If you have questions about these or anything else as he also mentioned there are a few other pieces that we couldn't include but would love to talk to you about. You can find here I after the presentation and of course on Twitter. So that does bring us to the conclusion of our presentation and we thank you all very much for your time this morning. Fantastic. So we have some time for questions. I should imagine that you are burgeoning with questions in the audience there, desperate to get them in. So first of all, can we find our mic runners? Where are you there and there? So who's got questions for us please? Awesome, in the middle there, thank you. So switching to this approach from the WordPress classic approach, what sort of SEO challenges did this bring in and is there any tip on how to tackle those challenges? We didn't encounter too many issues because what we found is that Google will load up the website and it will follow links and index those links but it won't necessarily follow those links in JavaScript in most cases. I think there are situations where it does but it didn't end up affecting us at all. So on that preload in WordPress in our situation we're loading up all of the metadata and all of the SEO information available and then in follow on requests as you navigate through the application we're overriding the title and I believe maybe the meta description and a few other small pieces within the application using wrapper components. If you're gonna go server side rendering and node there's a lot of libraries that you can use such as Helmet and some other ones if you're really worried about that but we didn't really see any knock-on effects from Google rankings in this and they're very important to take on so, yeah. Good question, right, who else? More questions in the audience there. Okay, Gentleman in the Green just behind you. Very keen. Hello, thank you for the insightful presentation. I would like to ask you more about your stack on, I understand you're running webpack also on your live machine and server serving. So what are you using as development and also in production? For development tooling, you mean? Yeah, okay, thank you. So what tooling we're using for development? We use a tool called chassis which serves up a WordPress environment with a few additions on there. It's a tool that Ryan McHugh and Bronson, Bronson, can't remember his last name. Bronson Quick. Thank you, Bronson Quick. So a couple of our developers created this local development environment so that handles all of our WordPress and we're using webpack to serve this up on the local level and it creates a development server that we feed in using that React WP scripts. Is not too much more to it? Maybe we should catch up a little later and I can actually show you what we have if you're more interested in seeing what it looks like. But it's actually pretty standard. It's very similar to what you'd get on a live environment just with the addition of webpack. Serving those assets in and everything else is the same React tooling that you'd get in a production bundle and the same code that you would see on the production site, so thank you. Brilliant, thank you. Gentlemen, just next to you, awesome, that's convenient. Thank you, thanks for lining that up. I wanted to ask, because you said you have a semi-decapowed environment. So I'm interested in how such a large site as TechCrunch is scaling. Can you tell us more about the scalability of your architecture? I'm sorry, can you repeat the last part? I'm interested in the scalability of your architecture because you said it's serving the PHP and JavaScript on a single server. So I'm wondering how you scale that for a large website that's serving thousands of requests per second. Yeah, so we had the benefit of being backed up by WordPress VIP and all they do is serve enterprise websites at scale. So we had the advantages there and basically everything is cached really aggressively at the server level. So even the REST API requests are cached for, I believe, 30 minutes and they're served out to edge nodes which means you get the closest response to you and so the React application, even though it's really large, it's all served client-side. So I mean the scalability of that really depends on the user machine but on the server side, it ends up actually being a little bit easier because that initial page render is cached very aggressively. We're doing a lot of things behind the scenes with object caching certain aspects of external resources and things like that and so it scales very well because TechCrunch gets a lot of spikes in traffic. They, a lot of their business model revolves around instantaneous news, the social sharing aspect of that, virality if you will and so they get large spikes in traffic and it handles it really, really well. So really most of it comes down to writing really solid code on the PHP side making sure that you're handling your caching really appropriately and that everything is cached at the object cache level, page caching level and we're cd-ending all the resources out, the images are handled via VIP's file service which is very similar to like Photon or you know, Cloudinary, something like that. Does that answer your question or help provide context? Yeah, yeah, thank you. Okay. Fantastic. Gentlemen at the front here. I'm interested in how much you use the built-in APIs and how, what custom APIs you had to build. Okay, so all of the APIs that we use were customized. So post page response, any of those guys, added some extra data into it. We actually ended up creating a lot of custom endpoints additionally. So there's a lot of third-party data that's feeding into TechCrunch. For example, they had a spinoff company called CrunchBase which provides information about all the companies and all the people that they talk about and we had to pull that in, store it temporarily in WordPress and then serve it out via an API. So all of the API endpoints have been customized and additionally something we didn't talk about is that we had to do some workarounds with authentication and comments. We created menu endpoints for that external information, added information to posts and any custom post types that we had. So our usage of it was extremely customized and we used the core of it. So I mean, we're still using the title you get, we're still using the content you get but we're just providing a lot of ancillary information on top of it. And that was part of why wrestling was so important for us because everything ended up being customized except for the very basic information. Fantastic. I'm gonna take one more, maybe two more questions. You were really enthusiastic then. Can we go for the tap in the front because that was super enthusiasm and then we'll take your question, so in the green and then we'll finish up. Hello, my name's Tom. I imagine on this kind of project, like that's a lot of unknowns, right? We haven't built many sites like this and so as we're coming up with these features we don't really know how we're gonna actually build them. How, I'm wondering like when you're project managing a site like this or when you're talking to a client, how you handle just that amount of unknown. How do you keep kind of a client calm when you don't really know how we're gonna build the site? How do I keep the client calm? I find asking a lot of questions. There are a lot of unknowns, especially if the point of contact or the client that I'm working with has a lot of other stakeholders to report to and they may be facing unknowns themselves about what those stakeholders are all across. But the more you can ask questions and look for those opportunities for that kind of flag or indicated question, it helps them feel heard. I think the most important thing about any kind of client relationship is making sure that they feel heard and that regardless of what happens they're not alone in the project and that they may be unknowns to both of you, but that together you're going to be able to figure it out. We use agile project management and a bit of a variation of agile on this project, but that encourages the kind of breaking down of a feature into very small components and taking them very small steps at a time until those unknowns become a lot more clear. That can be a little challenging because sometimes you get a little in the weeds or can't see the big picture, so making sure that you're able to kind of communicate both of those needs, the minuscule and how that's going to turn into the end project. And keeping the client in the conversation, that's how I approach this project on every other one. Cool, thanks. Good question because I wanted to ask that. So I really miss set expectations there and I'm really sorry but we're out of time, so train me on setting expectations there with the audience. But you are going to be available at the happiness bar and they're really lovely, so do come at the end. I'm so sorry that we didn't go to answer your question. So can we please give it up for Mike and Libby who have done an amazing job. Well done, guys. Thank you. Thank you.