Chris & Marie talk about a big long project that we’ve finished at CodePen: our new Admin Tools. Any web app is gonna need ’em. They do stuff that is unique to customer service on your app. Say you need to manually trigger a password reset email or hand-verify an account. You look them up in an Admin Tool, and perform those specialized actions. Our Admin Tools are heavily focused on users and content. We’ve totally re-built them to focus on the UX of actually doing customer support, as well as to make a clean UI that users the same componentry that the main CodePen app does. We do a lot of spam cleanup in our Admin Tools as well, so getting a chance to re-think those experiences was satisfying.

We dove into this project not just to make customer support better, but because of an alignment of concerns. We got to use a whole new development stack to do this, using technology we wanted to prove out for more of CodePen. We used Next.js on the front end and for server side rendering, and a Go-powered GraphQL API for the data. We made it all work in our monorepo. We build tools for deployment, so in a cool twist of fate, this app can deploy itself.

  • 01:06 Working on internal tools
  • 02:50 How do we pick things to work on?
  • 08:16 Admin tools specific to CodePen support
  • 12:33 Sponsor: Mailpoet
  • 14:31 Benefits of mono repo development
  • 20:27 Figuring the perfect UX with a team
  • 25:25 Early detection of spam users
  • 29:00 Multiple CMS built in

Sponsor: Mailpoet

If you build your website and business around WordPress, you’re in good hands for a lot of reasons. One of which is that you own your site, you own your own data, you own all aspects of what powers your business, and the rug can’t get pulled out from under you entirely. Check out this article and video on how to make a paid subscription newsletter with WordPress + WooCommerce + Mailpoet. That is a business model right there, from which you can grow forever entirely under your control.


[Radio channel adjustment]

Announcer: Today, on CodePen Radio.

Chris Coyier: Hey, everybody. CodePen Radio #330, we're going to be talking about admin tools. We've finished up what ended up being a pretty long project to rebuild some admin tools. Let's get into why we would do that and what the deal is. I've got Marie with me. Hey, Marie.

Marie Mosley: Hey, everybody.

Chris: Hey. Marie does a lot of support at CodePen. We split the load a little bit, but Marie is head of support and does most of it. This tool was, in a way, for you - if it's for anybody.

Marie: Yeah.

Chris: Yeah.

Marie: I think I was the main customer here.

Chris: Yeah, right, so you could help kind of guide us in what we're going to do and stuff. I'll tell you what we didn't -- we knew that we would have liked to get rid of our old admin and rebuilt it because, of course, doesn't every company in the world want to do that? You know, like, "Oh, yeah. Of course, we want better tools for ourselves." A little hard to prioritize.

Marie: Mm-hmm. Yeah.

Chris: Because it's -- what's the thing? The cobbler's son?

Marie: Oh, yeah. The cobbler's children have no shoes. Yeah.

Chris: Yeah. No shoes at all?!

Marie: Yeah.

Chris: Poor cobbler's children.

Marie: [Laughter]

Chris: To me, it's almost like a badge of pride or something. I don't want any poor cobbler's children without shoes, but I also want companies to focus on the thing that they do. You know? Not the internally facing, like, "Oh, we need a button to clear some cache. So, can somebody put together a dashboard in the thing?"

I almost want that dashboard to be as cheap and dirty as possible, right? Please move on to something that actually affects your customers and stuff. Support affects customers.

Marie: Exactly. Yes. Support does affect customers, and the things that you do on the admin of your site oftentimes actually does affect the customers in the end.

In this case, we've done things to speed things up and make things work faster, so we could just handle tickets faster now. We've also brought some things in that I would have to wait for someone else to do. Now I can just do them inside the admin. I understand the desire to really want to ship things that are customer-facing and that improve the external product, but you can also improve the internal product and, by extension, help your customers. So, it has its worth.


Chris: Yeah. That's exactly what happened here. The story is even more complicated than that. And this is answering the question if this podcast is about (and it is), what is it like to run a software company. What's up with that on the Web?

A question that I get asked anyway is, how do you pick things to work on then? How do you prioritize stuff? The answer to that is always, "It's very complicated, actually."

When it's simple, you're screwing up. When it's just like, "Oh, it's because we saw a tweet." That's our internal joke for Twitter-driven development. That's what we don't do because that's too easy then. That means you haven't thought about it enough. You're just being reactionary, and you're just building whatever you want. That's not how we pick features.

How we ended up on this admin tools is that, is that, okay, we can do better customer support if we improve this tool. Great. We have all kinds of things that we can identify and that Marie can help us identify of ways that this tool sucks and, if we could reimagine it from scratch, we'd do it like this. Great.

Another one is we can pick some technology that we want to try to build this thing in because we're thinking of building future things in it that are user-facing in it but we have no experience with. So, in a way, it's a little bit of a playground for seeing if that technology really actually works for us or if it doesn't. That was big.

Marie: Mm-hmm.

Chris: That was a big part of this. You can just play with tech and just see, but that's not the same as building something really, really honestly for real. That's what we did. We built something really for real that we need to deploy, that we need to protect, that we need new APIs for, that we need the whole ball of wax.

In a way, some of the stuff (APIs and stuff) we had to build are almost more complicated than what we need for the public-facing version of whatever this ends up being--

Marie: Right.

Chris: --because of how much sensitivity there is in the data in an admin tool.

Marie: Right. Yeah.

Chris: You know you have to be really extra careful.

Marie: Yeah, of course.

Chris: Yeah, so there's that. So, that gets another checkmark. Why did we build this? Oh, because we can play out some stuff.

And we've been on this forever march -- literally forever because I don't think it will ever end -- of where you're at the back of the line. You're trying to rip out old technology and replace it with new technology. For us, for a long time, the old technology has been Ruby on Rails, jQuery, and things like that, which are not bad tools. The goal in life isn't just to replace them. It's just that we have some better options. We have a fresher stack. It's kind of like if we can remove some of that, we're just getting rid of a lot of old code that's just sitting there and modernizing it with stuff that everybody feels better about. It feels more future-forward. It feels easier to work on that kind of stuff.

We get to prove out new technology, rip out old technology, build a better tool, and all that stuff. Hopefully, at the end of it, we have this thing that's supporting customers better. It just checked a lot of boxes is the point.


Marie: Yeah, and it was a big success. It took us a while to do it. I think everyone was a little frustrated with the time that it took to do it, but I really do feel like it was worthwhile. The finished product is fantastic. It's so much faster. It's so much nicer to use.

One thing that I think it's almost kind of funny when you think about admin tools because a lot of the time they just are tacked on in the moment. And so, you'll just get whatever button style we were using at the time or no button. [Laughter] Just a link that you've got to click - or whatever. The appearance of admin tools is almost like it shows you a history of the site because it's so weirdly tacked together. But we actually took the time to apply some actual UI/UX design to the admin tools this time.

Chris: Right.

Marie: It's a much more unified experience, which is great because, as we grow and as we bring new people into the team, it's a lot easier to acclimate someone to an admin that has a sensible UI. When you're going to different sections and they all look different from each other and buttons that do the exact same thing have different labels (stuff like that), that can be super confusing. To just kind of unify the appearance of it, give it a sensible look and good UX, it really does a lot.

Chris: Mm-hmm.

Marie: I really appreciate the time that the team put into the design of it. And I talked with the team about what tasks take the longest, what tasks really need some additional options, like we would have certain things, for example, we used to have a UI for handling spam comments.

We do get quite a few spam comments. The options there were to delete the comment and then delete the account, and that was it. Those were the only options. [Laughter] You had to separately clear the status on the comment if it was actually okay to keep it. Just silly things like that in the old admin, we've sorted that out. Now everything is sensible. It makes sense how this all works, so it's a huge improvement and it's important for growth as we go, like I said. We need to have something that makes sense that we can train people on.


Chris: This is an interesting exercise in what's UI and what's UX. But before we get too far, I'd like to say these are admin tools that you'll never see. They're just internal to CodePen.

Marie: Mm-hmm.

Chris: The whole point of them existing is to do things that are specific to CodePen support in that we know what kind of support questions come in. It might be something like, "I'm trying to verify my account and I just cannot get the email from you. You say you send me an email, but I don't get it," or something.

Then one of the things that we have the ability to do (because we're admins of the account) is just click a button and verify you. So, that would be one of the things that we would just do. There are other avenues to that. We can also look into our email records and see if we really did send the email, just to make sure that our system is working and that the reason you didn't get the email is somehow your fault, right? It's in your spam folder your firewall blocked it, or something.

Marie: Mm-hmm.

Chris: That's an example of a task that needs to be done in the admin. We build tools to make sure that we can answer that question for users quickly, for example. But there are - what - 50 of those things.

Marie: Oh, yeah. Easily. Yeah.

Chris: [Laughter] Yeah. There's lots of stuff, and so, okay, that's what the admin tools are. There are a bunch of pages. It's not just one big dashboard with stuff all over it. It's more like the main UX of the thing is, "Look something up," and so we made this unified search for it where you can basically paste in a URL to anything on CodePen and it'll try to basically guess what you mean and bring up that thing. That's pretty cool. We based that on some URL trickery and stuff, too. You can do a special thing on CodePen and get right to what you need to look at in the admin.

That's a big deal, like, "Oh, I want to look up a user." It just tries to help you every which way to do that.

Marie: Right.

Chris: Then the result of that is this mega dashboard that has all kinds of information about them, like billing information. We can't see your credit card number because that's not something we store at all, but you know what I mean.

Marie: Mm-hmm.

Chris: Like when they signed up, what plan they're currently on, and were they ever on other plans. Just all kinds of stuff like that. We just can see a little bit more about you. [Laughter]

Marie: Right. It's all unified to the user card.

Chris: Yeah.

Marie: Before, like you said, I would have to jump through multiple different sections of the admin to get all the information I needed about one user, and that's crazy when you think about it. [Laughter] It's nice that we've pulled it all together.

Chris: Yeah, it kind of is. Conceptually, it's kind of like, "Oh, go to the billing area if you want to have billing questions."

Marie: Mm-hmm.

Chris: You're like, "Why?"


Marie: Right. Yeah. Yeah, because we would also have situations where things would somewhat get disconnected from the actual user if there was a change in the account, so that could create a situation where I'm having to dig through multiple different admins. Not just the admin of our own, but the admin of payment processors. So, this really unifies everything and makes it much, much faster to just get right to it. It's nice. It's going to help. As we have it out, I think we are going to see a reduction in support ticket turnaround time just because these things are faster.

Chris: Yeah.

Marie: Just shaving a couple of minutes off here and there, they reduce the average numbers.

Chris: Plus it's so fresh that if you're like, "Oh, you know what actually would be sweet at this part, this little piece of data, or this little functionality?" It's going to be a lot easier for us to just slide that in quick.

Marie: Right.

Chris: Because everyone is so familiar with how this was built and what we can do with it.

Marie: I think also having a unified system for the UI helps in this way, too, because I can say -- I don't even remember what I asked for at first, but I asked for something recently. Oh! On The Spark, I wanted some of the fields to clear when I submitted them. I asked for that, and I had it the same day. Before, when it was an admin tool when I had something that I wanted to have changed, it would be like, "Hmm. Well, let's look into the ancient records and see if we know how to change this admin page." You know?


[Guitar music starts]

Chris: This episode of CodePen Radio is brought to you by Automattic, who has, WooCommerce, Jetpack. There's a plugin called MailPoet I'm going to tell you about.

I want to talk about a little cocktail of technology that can allow you to build and send out a paid subscription newsletter. You know how those are all hot right now? I think they're super cool and get a bunch of them myself.

Now, you'll hear tech news once in a while where you're like, "Oh, this big company where people built up a following and ran their business around, oh, they changed everything." They might even disallow you one day from the content that you want to send on the site. Those are scary, big moments in tech that get people questioning everything.

That's one of the reasons I like this is because, for example, WordPress is open-source. You can host it yourself. You can operate your website on your own technology. Now nobody can rip that away from you. WooCommerce, the same way; it's an open-source plugin. You can host it on your WordPress site and now you've got e-commerce going. It's your e-commerce.

MailPoet is a plugin for WordPress that allows you to build fancy emails, essentially, with a visual builder and get it all ready. You can do all kinds of cool stuff with it with your e-commerce emails and whatever. But you could also just craft a newsletter in it and send out a newsletter. It doesn't even have to be paid. It can just be a free newsletter. That's how you craft and send your newsletter and manage it all through your own website that nobody can take from you. Great!

With WooCommerce, you tie it in. Then you say, "Oh, you've got to have an active subscription to get this newsletter." It's really easy to wire those two things together, WooCommerce and MailPoet. Now, boom, done. You sell a product in your store that's a subscription product. As long as somebody has an active subscription, they get the newsletter. Now you've built your own paid newsletter product that nobody can, again, take from you. How cool is that?

It's an affordable way to do it, and it's a powerful way to do it. It's built on your own technology. Just great. WordPress, WooCommerce, MailPoet, thanks for the support.

[Guitar music ends]


Chris: A lot of that is UX, right? That's thinking about what you need and let's build that thing. Then there is UI as well. This ends up being a nice little demonstration of the difference between UX and UI.

UI-wise, it's a lot cleaner as well. But in the old admin, we didn't use Bootstrap or foundation. We just used nothing.

Marie: Mm-hmm.

Chris: We just wrote our own CSS on every page for what we needed. It just was dirty and who cares, you know? It wasn't that bad, but there was no consistency to it. It didn't even really look like CodePen (in a lot of ways).

Marie: No. Yeah.

Chris: What was cool about this is another part of the story that's kind of part of the tech story that I didn't mention yet is that, on this podcast we've talked a lot about mono-repo stuff. It meant a lot of things to CodePen. I don't want to be too reductive because that mono-repo thing was big in a lot of ways. But this is, for example, one of the things that probably would have been a different repo that's now just in our main thing.

This thing is totally different than It's deployed a different place. It has a different URL. It uses different tech. It's different, right? But it's all within the same kind of parent folder. It's all one big repo on CodePen. This was a driver of why do the mono-repo at all.

Marie: Mm-hmm.

Chris: Even though it's different technology, we can still use the same componentry, which was a hill to climb technologically. We have button components, table components, tabs, modals, and all the stuff. We did a whole show on components. There are a lot of them. We just use those.

This admin is built entirely from all the same componentry that is. It's 100% the same as far as visual stuff. If there's anything bespoke, it's bespoke because it truly is just for the admin.

Marie: Mm-hmm.

Chris: But I don't think there's visually a drop of UI that's not just available in our design system library.

Marie: I don't think so. I think that was a smart choice because, like I said, everything looks the same. Then also, it is easier to make adjustments and add new things in because you already know what you're working in.


Chris: Yeah. Everything looks consistent because it's just the same exact design pattern library. How satisfying is that? Once this thing rolled out, and it has, then all that old UI, all those old templates, all those old Rails controllers, all that is just gone.

Marie: Mm-hmm.

Chris: We just got to delete it all, which feels great. I don't know. It's technology. We should do another show on just the technical stuff there.

Then what else is an example of straight-up why it's better? I know spam is certainly something we think about here. I guess if I'm guessing, that seemed like the biggest improvement, perhaps.

Marie: Oh, yeah. Yeah, the spam detection and removal tools are a lot easier to use, must faster to get through and check out the previews of things. I think it was Stephen who came up with the idea of using the embeds there so we can actually use the same concept as the pop-out preview on the homepage. We can pop out previews of items that have been grabbed by the spam filter, and we can actually (on that popped out embed) make the content moderation decisions right from there, which really speeds things up. It used to be that you'd have to open it in another tab, take a look at it over there, come back to the original tab, hit the button over there. This is much faster. It's just right up on the actual piece of content.

Chris: Yeah.

Marie: And you can look through each of the individual tabs because it's exactly the same as an embed.

Chris: Yeah. It's quite literally the embed. Yeah, this is such a cool idea. Isn't it? Now I'm looking at it for the first time in a minute, and it seems like when you choose a choice, though, you know, make one of the choices, that it should close too. You know?

Marie: Yeah. That might be.

Chris: But now it doesn't.

Marie: That might be cool.

Chris: Maybe. We're just playing around because that would be so easy to do now. You know?

Marie: Yeah, but just this -- it's funny because [laughter] -- it's kind of funny. When we were planning this out, I was being asked, "What do you want? What do you need here?"

I was just like, "Uh, I don't know. It's fine. Just keep it how it is."

Chris: Yeah.

Marie: Because I'm just so used to it, and so it actually kind of took the team bringing ideas in, like these embeds and things like that, for me to even say, "Oh, yeah. That would be better," because I was just so used to it and kind of just built workflows around all of it that I didn't really even think out. I didn't have the imagination for how this could be better. [Laughter]

Chris: Yeah, that is tricky if you're too close.

Marie: Exactly. Yeah. I think that Claire and Stephen kind of realized this about how I was reacting to the suggestions, so they just started to bring stuff to me and say, "What do you think of this? What do you think of this?" That's where I started to see these great ideas like bringing in the embeds and things like that. It really shows an understanding of our product and also the understanding of what I need to do that they kind of drew out of me because I wasn't really forthcoming with what I needed because I didn't know.

Chris: Yeah.

Marie: That's an interesting thing when you think about it. People who are really good at design, people who are really good at UI and UX, sometimes they know better than you do what you need even when you think you know what you know and what you need. It's an interesting experience to have.

Chris: It is a lot on you to be like, "Marie, describe the perfect UX for it."

Marie: [Laughter] Right. Yeah.

Chris: Sometimes, that takes a team. It takes multiple people thinking about it. Some ideas can come from all around.

Marie: Yeah, definitely, and I do see everyone's influence in this one. I see everyone's efforts here.

The Omnibar search concept is fantastic. I never would have even thought to ask for, "Hey, can I just have one bar where I could type in whatever and it'll pull it up for me?"

Like you said, being able to paste in a URL for an account, a Pen, or whatever that just brings up the account or item card, that's super helpful. These things are just really clever ideas that I would never have even thought to ask for because they wouldn't have occurred to me.


Chris: Very cool. God, there's so much too this. I remember trying to improve how we're able to delete users because that's kind of a big deal, right? If you're a spammer, you need to get deleted right away.

Marie: Mm-hmm.

Chris: Which is fine and that's what happens 99% of the time, at least. But then rare time where you misclicked or you misinterpreted or something, and it turns out that that person's account shouldn't have been deleted, right?

Marie: Right. Yeah. Yeah.

Chris: I've got to tell you it happens once in a while. Part of that was why this took so long were little opportunities like that. We were like, "You know what? Let's actually improve how we handle user deletion, record more data, and make it easy to recover them."

Marie: Right. Yeah, one thing that was missing in the past was the context of how an account got deleted. We would know who deleted it and what date. Although, for a while, we actually didn't even have that. But we knew who and when, but that was all we would know. We didn't know the context, and the context is very helpful because if we know it was in a bulk cleanout, which is when we get many, many, many registrations that are basically identical content, we just remove those. Or if it was from another type of admin action like they were posting spam content, just anything like that, we get the detailed context of what the reason was for the deletion. That saves us time because, in the past, we would have a situation where something would get deleted and the person would write in. It could have been a couple of days before.

Chris: Right.

Marie: We didn't know how was this done. Now, we know who did it, we know what the context was, and that can help us put together, like, is this even worth reviewing? Then we know what to do from there.

Luckily, we do have the ability to reverse when there is an admin delete. We cannot reverse when someone deletes their own account. But if there is an admin delete, we have a little bit of time where we can bring it back.


Chris: Yeah. It's an interesting call. You look at a spam comment and it'll be like somebody saying, "Ooh..." or something.

Marie: [Laughter]

Chris: For some reason, our spam thing has intelligently learned that that might be spam.

Marie: Right.

Chris: It's not automatically spam. We can come in here and click it as not spam if we determine that you're not spam. But that's a weird little judgment call for us, right? We've got to look at your account and just kind of make a guess on how you're doing.

Marie: Yeah, and there's a difference between spam and harassment and things like that. That's when the code of conduct comes in. None of this could ever be fully automated. I don't think we could ever reach a point where moderation is completely automated. Someone has to look at things and understand what they're looking at to make the appropriate choice. But we have made it easier for us to make faster choices. If for some reason that choice needs to be reverted, we can.

Chris: Right.

Marie: It's much safer now.

Chris: It makes you feel a little bit better because you do have to make a call. If you're thinking about just spam comments, which is one of the kinds of things that we deal with, you have to make this call. "Is what I'm looking at totally just not spam, like it's a mistake? It shouldn't be on this list," which hopefully will then kind of train the world that you're learning a little bit. Or is it the rarest one, but it's still possible, is that I'm not going to delete your entire world, but this comment is not good.

Marie: Right.

Chris: We can just reverse the right to just delete the comment. Probably the rarest one, right? I would think it's either not spam or you, your entire account, you have signaled to us that you're a spam account and we just get rid of the whole account, which is probably the most common thing.

Marie: Yeah. It's uncommon, but it does happen. You do get into a situation where someone is just being really egregiously rude to someone else. It's like, there is no reason for this comment to remain. But the rest of their account is classwork or something, so there's nothing wrong with the account itself.

Chris: Yeah.

Marie: People make mistakes, and we do reach out in those cases and just say, "Hey, we removed this. Do not do this again. Check out the code of conduct. This is how we expect you to behave."

Chris: All right. That's just spam. That's an example of us thinking out the UI and UX of what spam handling is like. It's just so interesting, isn't it? The more I use this, the more I'm like, I still have more ideas.

Marie: Yeah. [Laughter]

Chris: It's getting context about what happened is the most important thing.

Marie: Mm-hmm.


Chris: I think there's room for improvement here. I do really like -- my favorite one is our detection, our early detection of spam users.

Marie: Mm-hmm.

Chris: You're actually treated a little differently in the first few days you sign up for CodePen because there are a lot of people that just sign up for spam reasons, and so we kind of catch you a little early with stuff, and we can kind of keep it even out of our own database.

If you send some nasty stuff in there, we don't even save it. It's just like, "N. Screw you. We can tell," because this is 100% effective. If you match these keywords, you're super gone.

Marie: Right. Yeah.

Chris: But just in case, they go into the review pile kind of thing because you're in a state of limbo when you're caught like this.

Marie: Right. What happens there is that their content is not actually saved, but we do take a snapshot of what they tried to save.

Chris: Right.

Marie: We have text that we can review, but we actually don't even let them post the piece of content at all, which has been very helpful in preventing very specific categories of spam from getting through. I think it's also even discouraged some of it.

Chris: In this case, though, we can see what you tried to post -- this is kind of a new concept for us -- and kind of highlight what the problems were in it.

Marie: Mm-hmm.

Chris: I think that's one of my favorite bits of UI that I hope make it to other areas of that. For example, you're looking at spam items we just described. It's a lot nicer now. You can see the code and stuff, but it doesn't go so far as to point exactly to the line of text that's a problem. [Laughter]

Marie: Mm-hmm.

Chris: Which I think would be kind of neat.

Marie: That would be.

Chris: Like, "Show me what triggered it." A lot of times it's really easy if it's one of the really egregious words. Use your imagination - but also don't use your imagination.

Marie: Yeah, and don't try.

Chris: [Laughter] Yeah. You're done.

Marie: We'll find you.

Chris: You see that in there, and I don't have to think very hard about this one. Goodbye.

Marie: Yeah, there are certain ones where you don't have to put any thought into it.

Chris: Yeah.

Marie: That's nice, and it is useful when that's highlighted because then also you don't necessarily have to see the rest of it because you don't want to.

Chris: Yeah. Exactly. That's what's kind of cool is it's a pop-up. Yet another little piece of UX here is that you don't have to open that pop-up if you don't want to.

Marie: Right. Yeah.


Chris: Okay, so that's kind of cool. As far as just an admin tool, because CodePen exists and we're working on this on the side, it's tempting to think, "Oh, this is just a little side project," or whatever. But in the grand scheme of things, this is a full-blown application that was created.

Marie: Mm-hmm.

Chris: That to some degree is probably a lot more complicated than some startups out there. I'll tell you what.


Marie: Yeah. I would think so. There's a lot going on in here.

Chris: CRUD is one of those things. That's kind of a classic way of saying create, replicate, update, delete, which is a lot of what apps on the Web or apps, in general, are. They're just like, "Oh, I have an idea to make an app. It's going to be a recipe app. You can save your favorite recipes in there." Great.

Then you can edit them, of course, too, and delete them. Basically, it's this app where it saves data and you can manage that data. It's like most of what programming is.

Marie: Mm-hmm.

Chris: It's like a CMS, yeah?

Marie: Yeah.

Chris: Are you familiar with that? There's a bespoke CMS just as a part of this. Multiple of them, really.

Marie: Yeah. Two. Yeah. There are a couple, yeah.

Chris: That was really easy in Rails. I mean that's what kind of started this Web revolution, in a way, is that Rails was famous for, like, "Oh, you need a little bespoke CMS kind of thing? We're totally built for that. We'll help you build that." Not that we were unhappy with that but, when we ripped that out, now we're on our own.

Marie: Mm-hmm.

Chris: We've got to build this ourselves, and that's okay because our data model is already solidified. We know how we build APIs. This wasn't much of a challenge for us, necessarily, but it did mean doing it.

These CMSs are for two things. One of them is the CodePen Spark goes out every single Monday. Check your inbox, people. It's a wonderful newsletter that Marie puts together. And the challenges, which is an opt-in deal where, every week, we give you basically a prompt. We've talked about all these things on CodePen before.

The way of creating this, it's not like we're like, "Marie, just use Mailchimp. Just handcraft the email every week." It's like, "No."

This has gone through changes over the years, but we make sure that the data that powers The Spark and the challenges is really clean. It's just database data. Then when we take that data, and we template it because we use it in different ways. We use it on the website, and we use it in the email. Those are so different that having a data core to that is fundamental to what we do. We can't just make an email and then somebody else turns that email into HTML or something.

Marie: Right.

Chris: That's just not how we roll. [Laughter]

Marie: Yeah.

Chris: We had to make a CMS, and the CMS is like, "So, what is a challenge?" Well, it has all these bits of data. There are not just challenges. There's a month of challenges. Then there are weeks of challenges. These are all concepts that we just invented.

Marie: Mm-hmm. Yeah. [Laughter]

Chris: Yeah, so we had to build the CMS around that. This gives us crucially an ability to make the CMS aspects of this thing whatever you want.


Marie: Right. Yeah, and that's been really great. I mean it's funny. There are episodes of this podcast going back I think probably all the way back to 2016 or maybe 2017 talking about how The Spark worked and how we did it and how we sent it. I mean it went from we literally used to code it up in a Pen and then send it out to now we have this very sophisticated CMS with sending controls.

We have to have two people approve each one before it can be sent, and that's really nice because we don't have situations where we're sending out things with typos or we're sending out things more than once. That's the other thing. It also removes things we've already sent, so you can't accidentally send the wrong email. I couldn't send a Spark from three months ago - or something - by mistake just by clicking the wrong thing.

Chris: Yeah.

Marie: We've built a lot of safeguards in place here to make sure that we are sending a correct thing and the thing that we're supposed to be sending to the right people. And so, it's been a real journey from the very beginning where it was just hilariously slapdash compared to how it is now.

Chris: Yep. That's funny. There's the CMS in place for managing challenges and Sparks. That's been going pretty good, I think. Then there's that whole separate vibe, which is the send station concept, which is not really a CMS. It's like a workflow that we created for previewing, approving, and sending emails that's a fricken' beast.

Marie: Yeah, it is.

Chris: That thing is a startup, too. Like, "Wow!"

Marie: It is, actually. I think about that sometimes, especially the things we've learned about making and sending email since we started the Spark is just -- [laughter] yeah, it could be its own whole thing.

Chris: Right. It has this way of just being fine for a year or two, and then being like, "We need to rewrite the whole world."

Marie: There's a big problem. [Laughter] Yeah.

Chris: A lot of times it's based on scale.

Marie: Yes, absolutely.

Chris: We'll see. That's a whole -- we're talking about everything under the sun here, but we'll just wrap it up by saying--

Marie: Well, that's what admin is about.

Chris: Yeah.

Marie: That's everything under the sun. [Laughter]

Chris: Yeah, it really is, so that's why god dang it, it took so long to get this right is because all those little aspects of it were like, "It should work like this. It should work like this." We tried to not scope creep it too bad.

Marie: Yeah.


Chris: Fortunately, the final product is really neat. There are a couple of other things tucked in here that I think are interesting and worth mentioning is that this gives us kind of a playground that we know only admins at CodePen have access to and, thus, it's kind of like a URL that you can link somebody to look at stuff.

Here's one thing that's in there. You all know -- maybe a lot of people have heard of storybook, which is kind of like a way to explore a design system, all the patterns and stuff available to your company. We could have chucked that in here, but we actually just didn't even go that far. We kind of hand-rolled our own. It feels silly to say but, believe me, it was actually almost simpler to do it this way. Shaw put this together, a little component explorer, so you can explore our design library internally and make sure that they're all working, see a usage example, and stuff like that. That's been really useful.

Then he just kept going. He made an icon library, every single icon available to you and how you use it with a preview and a one-click to copy the stuff that you need to use that icon in our codebase and stuff. How cool is that? And then some other things.

He wrote a thing that parses all of our CSS, finds all the CSS custom properties, and makes a thing. It's kind of like a glossary of what kind of CSS variables are available to us in our app. It's just been super useful for auditing, like, "Why is that there? What do we use this for? Let's clean that up," kind of thing.

He even made one that we were having this heated discussion on what kind of technology to use to most efficiently re-render a complex tree of objects. It was like, "Well, if we do it this way, it has to re-render the parent. This one has to re-render four objects, but they're much smaller in the DOM." We could battle test these things against each other. That could have been done anywhere, but because this is so easy to work with in here, he just made it a part of the little admin.

Marie: Yeah.

Chris: It doesn't have to stay there forever, but it gives us a place where we have access to all our componentry - yadda-yadda. It's become a little bit of a playground without becoming a mess.

Marie: Yeah. That's nice. We're keeping it tidy.

Chris: Mm-hmm. Well, we can talk about this a little bit more. We can dig into the tech of it. We can talk about how it evolves. Please let us know if you have any questions about it. I know you can't see it, so it's probably a little not satisfying. [Laughter]

Marie: Yeah, but everybody with an app has got admin tools.

Chris: Yeah.

Marie: We sure know a lot about them now. [Laughter]

Chris: Yeah. Yeah. It was satisfying to get done. Now that we've moved on, we're like, "Yes!" It was very satisfying as a release, I would say.

Marie: Yes. Yes, satisfying in a lot of ways. It was something that we wanted to complete before we moved forward with other things. And it's also just awesome to have it out and to be able to use it myself. It is a significantly better experience. I'm very proud of the team on this one.

Chris: Cheers. All right. See you later, Marie.

Marie: Bye.

[Radio channel adjustment]