Coworking Session with Jason Lengstorf
with Jason Lengstorf
Grab your current project and work along with Jason as he tackles his todo list. This is a casual session, so bring questions!
Resources & Links
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
JASON: Hello, everyone. And welcome to another episode of Learn With Jason. And watch, I can do this now. (Cheers and applause) All right. That's absurd. Hi. Hello. How are you? I see Ben, Kelvin, Tristan. First-time chatter. What's up? And Chris, thank you for the sub. Very much appreciated.
Yeah, having a great time with this new setup. I just got it all running. I've got independent source recording and new lights and camera angles and all of this fun stuff going on, and I am absolutely thrilled. I just realized, crap, I didn't even start my new captions. So these will be -- oh, okay. So captions will start streaming through now. That closed caption button will be on. I got to put that on a checklist. All right. New stream. All new buttons. I only know what some of them do.
So how is everybody? What's everybody up to today? What I wanted to do in this stream is work on the learnwithjason.dev suite of sites. So as some of you know, I run a lot of different things off of learnwithjason.dev. So I've gotten a API. I've got some web hooks for things like -- you know, I use a service for scheduling episodes, and I need web hooks to kind of move the scheduled episodes between different things. I've got a blog. I've got the episode listings themselves. I have -- what else is in there? The scenes, what you're looking at right now.
This overlay down here, this is all a website that I run off of the Learn With Jason system. So as you can imagine, there's a lot of overlap. Like, there's shared colors. There's shared -- some shared components like the logo, the sponsor information. All that kind of stuff is very easy to get out of sync if you're running it across multiple repos. I didn't really want to get into the game of trying to, like -- I don't want to have to maintain a package that's my design system, and every time I need to update a color, I have to open a pull request to the design system and then merge that and then publish a new package and go to every website I own and bump the version of the package and re-deploy those sites.
That process is great if you're a big company. I'm not a big company. I'm a small company. And I want to be able to do this more easily. And I think even for big companies, it's kind of preferable to not have to do those sort of hoop jumps every time you want to roll something out. So I really like monorepos for that reason. Because they give you the ability to have, like, private packages.
But you don't have to publish those packages. They're just other things that are in the repo with you. That allows you to then do all the things you would do if you did have external packages. So you can share them. You can import them just like you would, you know, you import logo from LWJ design system. If I update the design system, it updates everywhere. But when I push to the repo, because I'm using Nx, the sites all build if the thing they needed to build is affected.
So Nx has this command called affected. It also has an X cloud, which will cache the output of a response. So if nothing in the code base changed, it just pulls the previously cached build. All of that makes my life easier, and it means I don't have to do manual steps to deploy, which is a big win as far as I'm concerned. Because I really -- I always miss manual steps. As you noticed, when I started the stream, I was supposed to start the caption, and I didn't for the first few seconds because I forgot. I don't realizing that, hey, I'm going to do this thing before I head out. Then I'm out at dinner and realize I broke everything because I forgot to do that one manual step. I want to take all that away.
So that's why I've been thinking about moving to a monorepo. The other reason is because I have different tools for different purposes. I really like writing blog posts in MDX, and I want to be able to do that. I also really like the dev experience of Remix as it allows me to pull in lots of different data sources, and it's got good form handling and stuff that I like. I want to keep using that.
But remix does not like markdown. It's just not built for it. And you can wrestle it into working with MDX, but it's kind of a big manual slog. Whereas Astro just loves MDX. It works perfectly with it. And I want to be able to kind of that my cake and eat it too here. So why not just have a blog in Astro and the episodes in Remix and use proxies to make it all feel like one big website. And because I have a monorepo and because I'm using Netlify, that's pretty straightforward to do.
So that's what I've been working on for a little bit. Let me do some quick shouts here. Sorry, I'm just reading the chat here. No, you're absurd. Yes. This hat is a Jason Santa Maria recommendation. It makes me very happy. I hope that everybody figures out how to get one of these. I don't know. I don't remember where I got it. I will have to look this up. Let me see if I can find it. It was something -- there's no way I'm going to find this. It was like some kind of not great website where everything was listed without a URL, and you just had to scroll down a little ways.
Don't know. I linked it somewhere else, if anybody remembers where I posted that weeks ago. Otherwise, you're just going to have to Google it for yourself. All right. Let's see. Oh, good. We got some spammers in the chat. Always fun. Let's just get you out of here. Good-bye. All right. Need to get some moderation tools in these chats so I can do this stuff faster. A few hearts in the chat. (Laughter)
Yes, Ben. Hey, Jacob. How you doing? Okay. So yeah, what I was going to do before and what I will do now is I'm going to switch over to this view here, where I will first and foremost -- let me pull across this tab where we will go to lwj.dev where I'm live right now. Let's see. Why is that so small? There it is.
This episode, like every episode, is being live captioned. You can hit that little CC button on your Twitch video player to get those closed captions. That is being done by White Coat Captioning. I have Rachel here with me today. Thank you very much, Rachel. And that's made possible through the support of our sponsors. Netlify, Nx, and New Relic all kicking in to make this show more accessible to more people, which I very much appreciate.
And today we're going to be looking at Nx, who is a sponsor of the show and is the monorepo tool that I like. And we're also going to be using Netlify. So let me drop a couple quick links here to Nx, if you want to give this a shot. And also to Netlify. If you've never tried it, it is also kind of magical. We'll look at how both of those things go. Coops45, excellent.
I'm happy to see you're learning Nx. Hopefully I can do something useful here. So, all right. Let's do a quick walk through of what's going on. I'm going to close down everything that's in here and let's just take a look at the guts of what's in this repo.
So the first thing that you'll notice is that I have an Nx.json at the root of this package. I also in my package JSON these workspaces. So in the workspaces, I'm saying that anything in the sites folder or the packages folder should be considered a deployable thing. And in the Nx.json, I'm actually kind of just using their defaults here.
I'm saying that if I run a build on something, it depends on the build of any of the repos it's including. So if I have my design system, for example, if that had a build step, which in my case it doesn't, but if it did have a build step, if it was depended on by the blog -- what's everybody doing? Go away. You're going into do not disturb mode. How do I do that? Do not disturb. Yeah.
Okay. So if I build my website, like the blog, which depends on the design system, then Nx will automatically run the build or whatever other commands. You could set this up to have testing or any kind of pre-build hooks, anything you wanted to do to make sure that this all happens in the way that you would do it if you were doing it manually. But now the robot does it.
Then down here, this Nx Cloud is just me saying, like, cache my builds if you can. This is a public token. So we're not leaking anything here. And you know, just some magic here. Jacob, yeah, there's some really cool things you can do with this, but I'm not using it for any of that. All I really want to be able to do is I want to have these shared pieces here.
So I've got my design system that has a few things that I reuse, like my header and the logo and a few pieces like that. I then have my shared CSS, like my color system. I've got a really, really basic reset. I have a few things about what colors things should be and all that. Then a couple utilities, like a visually hidden so we can do accessible hints for screen readers.
I've got my web fonts in here, a couple other things I need. And the same for Notion and Sanity and Socket Studio is what I use to run the chat. So the chat component on the screen right now -- this one down here -- that is from this package. So that is the kind of shared components. The reason I have Socket Studio shared is eventually, some day, I want to build this into a thing that other people can use. I had intentions a long time ago of making that into an call business. I don't really want to start another company.
Also, did you notice my enormous water bottle? I promised myself I was going to drink more water. If I have a small cup, I drink my small cup and forget about it for four days. So with this, at least I'm drinking 40 ounces of water.
So, okay. Then in the sites, we have a few things. We've got the API. So this is my API end points. I've got -- you know, I'm loading the episodes, featured episodes, the poster. That's a work in progress. Schedule, sponsors. If I want to get a topic, all of those good things. Then I just use redirect so there are some functionality there where I can hit /API and all of that.
Then it looks like I have a weird bug there. We're just going to delete that and pretend it doesn't exist. Then I've got my blog. So this blog, this is an Astro site. This is the new home of my blog because I want to write in MDX. This is just a little more friendly for me in terms of how I like to work. So I specify a layout, and then just use my standard metadata and I'm off to the races.
Then I've got a couple other things. Code of conduct, newsletter, the about page, stuff like that, that doesn't really need any special functionality. I just want it to be plain old CSS and HTML at the end of the day. Those all live in here. Then I've also got my -- what is all of this? This is very weird. Whatever I did here is weird. I created bonus folders and I'm not sure why. Then I have a Discord bot.
I don't use this right now. It's a thing I want to use more of. I'll get more into it later, but for now, it's all good. Then I have my scenes and more ghost folders for reasons I don't understand. These are what you're looking at now. This is the lower third, the name overlay, you know, all the pieces you need to make the stuff function. And then we've got Sanity Studio, which I need to talk to Cap over there about upgrading to v3 because I haven't done that yet. I have web hooks so I can handle Calendly. Then this is my -- whoops. This is my remix site. So this is kind of the original all in one.
It's got a bunch of things in here, like my old API that I've since extracted out into separate sites. So this is the one I'm kind of pulling things out of. So instead of trying to jam the whole ecosystem into this one project, I want to instead make this into a component of the ecosystem. And so the way that I'm doing that, and this is the tricky part here.
So first, let's look at how each of these work. I'll go into GitHub, Learn With Jason. Then I can Nx run blog dev. All right. So this is the part that I find really magical. In the blog, I have created in my package JSON the name of blog.
Then I've got a script of dev. Since I have Nx running here and I have the Nx CLI, I can just run any command out of any of my sites. So you do the site name and the command you want to run. Note as we're looking in here, there's no -- there's nothing Nx specific going on.
There's no actually reference to Nx in this site at all. I haven't used their generators. There's a bunch of power stuff that you can do with Nx that I'm not using. I eventually, I'm sure, will get deeper into this. But for the moment, what I really wanted was my sites to be in one repo in a way that I could deploy. That's it. That's all I want. That gives me the ability to then set this up.
So now that I have that done, I can go over here, and we can go to local host 8888. This is my placeholder homepage I haven't actually deployed. I hit the blog. Now, this is in dev mode, so it's a little slower because it's hitting different queries and stuff as it goes. But I get my list of blog posts. Okay. Good. Happy about that.
Click in here. Get my blog posts. There's a bug -- there's probably like an "I'm holding it wrong" happening here that I need to fix. Oh, wait. I'm not reading chat. Oh, what's up. Thank you for the raid. Welcome, everybody. It's good to see you. What were y'all working on over there? Akawr, I don't know you. So here's a shout out. That's not how these commands work. It's like this. There we go. One of these days I'm going to learn how all this works.
What are we looking at right now? This is Arc browser. I've started using it because it's a little cleaner for me. The whole thing runs off a command bar sort of deal. So you just sort of hit command L and it brings this thing up. If I want it to open a thing, you just kind of get all of these different options. Anyway, it's dope. I think it's Arc browser. Arc.net. It's worth checking out for sure. And welcome, everybody. First-time chatters, what's up, y'all? Thank you, thank you.
So yeah, what I want to do is I've got my blog here, and then if I want to go to the episodes, it's not set up on Astro. So what I want instead is I want to hit the other site, which is the old Remix site. So I'm going to hit that with run dev. Then the way Remix is set up, it's set to use port 3000. So I'm going to come over here, and I'm going to change this over to 3000. So this is then my homepage. And if I go to all episodes, it's there. But if I go to blog, blog doesn't work because it's not defined. So this is sort of the setup of how I want this to function.
I want it all to work where, you know, the episodes, the schedule, the store all live on the Remix site. Then the blog, the newsletter signup, about pages, miscellaneous confirmation, legal pages, like stuff that's just static I want to be on Astro because I want to edit it and publish it in Markdown. So to do that, that brings me into Netlify. So the piece I'm going to be using here is redirects. If I look in my blog, which I'm going to set the blog as being the root because it has fewer -- there's less going on with an Astro site. So we're going to use Redirects. Then I'll talk about why I switched to the Astro site. This is everything that happens behind the scenes on the Learn With Jason site. So I'm making sure my other domains or old domains all go to the main URL. I have my web hooks. This is where it starts to get interesting. So I've got this site deployed that's my web hooks.
And I can have the main site, any time you go to /webhooks, just redirect to this web hook. And then the API v2 goes out to my new API I'm publishing. And that just redirects to the splat there. Then we've got stuff for the sponsors. We have stuff for DOS keyboard. I've gotten a affiliate link for them. I have booking links and stuff like that. Then a bunch of moved stuff.
So this is kind of the magic of all these things. Then here's the real big piece. Anything that doesn't exist on this site is going to redirect to the old site, which I'm going to host at LWJ Remix. So that means that I can put whatever pages I want on the Astro site, and the Astro site will take precedent.
If I were to publish an episodes page on the Astro site, it would take precedence over the Remix site. But if there's a 404, it's going to few through to the Remix site. That means I can do an incremental migration, which is great. Or in my case, a partial migration. I'm not intending to get rid of the Remix site or get rid of the Astro site. I want both of them to work together because I need them for different things. And it's kind of fun to hack on two different frameworks.
So I can be my own chaos agent, and therefore, I choose to do so. So what I want to do here is then do this. The reason I set this one up like this as in Astro is going to be the root, the first site we hit, is because if we go over and look at the same set of rules in remix, I've got some things like RSS feeds set up. I've got some old redirects for the v1 API. I've got a site map. Then down here, this is so that Remix can function. You have to redirect every single request to the server, to this serverless function. And that's just how Remix runs.
So I can't do a fall through on Remix. I have to make Remix the last stop in the chain, or else I'm going to -- everything there get caught by this Remix catch-all. So that means that this becomes the end of the chain instead of the start of the chain. Okay. So all of that means that when I come in here -- oh, we got some gift codes to Arc. That's dope. Yes, Ben Holmes, exactly. You can slowly migrate all the pages. And that is the thing. And Muescha, no, you don't need to set up a redirect. That's the real power here.
This is the Remix redirect. Then let's go back to the blog and look at the blog redirects. Down here at the bottom, anything that 404s -- so if I go to my Astro site/something fake, I won't get a 404 from the Astro site. I will instead go to the Remix site and request /something fake, and Remix will deliver that 404. So basically, Astro, if it exists, it will show up from the Astro site. If not, try to show it from the Remix site. If it doesn't exist, then Remix does the error handling. So I've created this sort of chain.
When I figured out how this worked, when this lightbulb kind of clicked on for me with Netlify, it was a really, really big revelation because one of the biggest problems that I've had is I want to do something, and it requires me to use a new tool. I do not have time or interest to rebuild the whole project, you know, re- implement all the functionality that's already there, just to enable this one thing that I want.
So using these reverse proxies, I can go in and say, I'm going to use this tool to build the thing that I need. Then I'm going to reverse proxy it in at the path that I want. So my whole website is on Remix. Except for maybe I want to send -- I don't know. Here's a good example. I want to send all of my requests to GraphQL to Hasura. So I can just proxy that in. It just does the thing. So now when you go to learnwithjason.dev/GraphQL, you hit Hasura, which I think is broken right now. I'm phasing it out. It served its purpose. I've thanked it for its time, and I'm going to set it aside. But I was able to do that.
I was like, I want to use Hasura for something. So I proxied it in. I didn't have to rebuild my whole site. I didn't have to change anything else. I just set up this reverse proxy, and lo and behold, it works. So to me, that is very, very cool and very, very helpful. So Mykal, I'm not moving. I'm augmenting. I want to use Astro for MDX and Remix for the stuff using databases. And I know that I could use Astro for the stuff with databases.
I actually think if I wanted to, I could migrate my whole site to Astro, and it would work. But I like the development flow of the actions and loaders that come with Remix. So I don't want to throw that out. I actually kind of dig that. So for the episodes, for the scheduling, for some of the other things this I do on the Learn With Jason site, I want to keep that Remix stuff. Then for the blog, I want to have a faster workflow with MDX. It's just so much less painful to write MDX on Astro. So that's my plan, to just kind of put one foot in both camps and use the tools for the things that I like best about them in the places where I need them.
So, okay. I have -- oh, Astro form handling. All right, all right. For anybody who doesn't know, Ben Holmes is one of the Astro core members. Also, Ben is the white board to web guy. Let's do a little shout out to Ben. What up, Ben?
But yeah, so this is my Netlify dashboard. On it, you can see I've got a bunch of different things. I've starred the ones I use all the time. I've been building in this monorepo branch for a long time. You may have, if you watch me on the tweeter, seen me complaining about my own hubris in thinking I could do a long-live feature branch. And that's kind of what I want to work on today, trying to untangle this.
So this is the site as it stands today, if anybody wants to go and mess with it. You won't be able to build it locally because I have a bunch of tokens and stuff and environment variables that you would need. But you can at least see how it works and sort of make your own thing. Benjamin, I do not work at Netlify any longer. I have now gone independent. I'm full time on Learn With Jason. But I did work at Netlify up until like November. So I've been on my own for less than a month. Three Bens. Thrice the power. (Laughter)
Okay. So I've been working on this branch, and what I would like to do is I want to take this live today. I've actually got it running. So if we look at -- is this the one? No. If I go to here, deploy previews. That's not it. I want -- somewhere in here. Yeah, branch deploys. I've got my monorepo, and I want to open this. Ah, crap. I committed that index folder. I need to undo that.
So this branch deploy works. You can see this in action. So this is the blog, right. Ben, do you see this? Ben Holmes, you're now captive audience. Why does this happen? Do you see that flash? It is driving me up a wall. So I actually opened a question on the support Astro forum about this. Look what's happening. I know what's happening, I just don't know how to fix it. If I open this up and I look at my header, right, my header is here. The header has CSS module styles that I would expect would appear up here somewhere.
But they actually get put where the slot is, when is in the main down here. Let me close this up. They're in here, and it's killing me because that means my header loads before the styles for the header load. Now I get this very irritating flash of unstyled content. So Ben, please fix that and do it for me so I don't have to do it myself. Okay, Ben? Huh? Okay. (Laughter)
What version of Astro? That's a great question. I think it's right. Let me see. What am I using? I'm using Astro 1.6.8. How out of date is that? It shouldn't do that Jason-cam-2. (Laughter)
Am I outdated? I thought I was up to date. Hold on. Let's check. I'm going to go into sites, blog, and we're going to do an npm outdated. It says Astro 1.7.2. That should all be okay. You know what, doing it live. Let's upgrade. Link you to the support forum. All right. Let me figure out how to link to the support forum.
Yeah, if y'all aren't in the Astro, this is a good place to be. So let's see. Here's the link. This is the link to that Discord. And I tried to include all the details on what I think is going on. But yeah, I'm not 100% sure what's going on there. Did something weird. And I want it to stop.
Oh, yeah. Good call. Let me actually also send that Astro.build/chat. If I put it into the chat, it goes into a list. Oh, yeah. Get on that wait listen if Arc. Somebody up the chat, if you scroll up, has some invites. Brandon, if you want to grab one, you should hit them up and ask.
Let's see. Okay. So we've updated. Watch, this is going to take the whole site down. I did something and now it's going to break. Okay. So that's good. Come over here. Wait. I need to go to 8888. Then we're going to go here. Okay. So we're in dev mode. So it's still happening in dev mode, but I don't know what it'll do in the other mode. We're going to git commit for this package lock. Then I need to git remove -- oh, wait. We want to go with -- where am I? Source, pages, index. Because I don't actually want that one, right. I want that out.
So did that delete it entirely, though? I just get mystery -- it did delete it entirely. That's okay. You know what, we're going to let it be okay. I'm going to git commit, remove place holder homepage and off we go. Now, watch. Here we go. I have now pushed a change to my repo. So what we're going to see is we'll get a bunch of builds all kicking off at once. This is my whole monorepo suite all running. So these are my scenes. These are my web hooks, my API, the Remix site, the blog, and this is my main site, which I want to switch over to be the blog. So this one will actually go away once I get that done. Okay.
Okay. Oh, nice. People dropping Arc invites. That's wonderful. Wonderful. And let's see. That Remix site is failing. So I better go look at that. Or no, wait. Failed yesterday. Worked today. Good. Okay. So that's working. That one is working. Let's go try this out. I'm going to open this branch deploy. Okay. So now look.
Look, here's what's cool. I'm in the feature monorepo. If I go and look at what I'm actually deploying here, let's go to the deploy settings. And I'm deploying from this repository, but I'm running npx run blog build. That's the Astro site. And I'm publishing the built Astro files from the feature monorepo. So now I'm looking at my -- this is not it. Let's see. Let's close that one. Here? Yeah. So here's the branch build.
This is Remix stuff. If I click around, still looking at Remix stuff. Everything is doing what I want. As soon as I click over here, I'm now looking at my blog. Pretty magical stuff. I now have a fully stitched site all running on the same thing.
So there are a couple things I could do. The first thing I could do, if I wanted, is I can go back to my deploys. I've got my branch deploy. And I could do something like publish this. So I've published this. Now if we go to learnwithjason.dev, we are looking at -- so here's the live site. If I go to my blog, we're now looking at the Astro blog on the live site. So that's fine. That's good. But I haven't actually fixed my public branch. Like, I need this to be what happens by default.
So now what I need to do is I need to merge my long-live branch with main. Oh, it's going to suck so bad. Okay. Everybody ready? Let's do this. I'm going to do a PR create. What are you going to do? Let's see. For a body, we'll do just a quick one of these. So this is a big ol' PR to merge in a monorepo migration that introduces Nx, an Astro-powered blog, a v2 of the API, and a few other sites that share LWJ resources. Then to get done, I hit what? Control X. Nope. I want to save. Oh, man. Nano confuses the heck out of me. And submit. You're going to explode so hard. So I'm going to go to this pull request. Here's the pull request. You're doing it, Peter! (Laughter) oh, boy. All right.
So this is everything that I've done. Look at this. This has been the labor of weeks, I think. When did I do the first commit here? Does it show? 30 commits last week. Oh, boy. Four days ago. I don't know. I don't know when I did my last thing, but this is going to explode.
All right. So where's the actual main site building? Let's go over here and look at this one. Here's our deploys. The deploy preview. It should -- should, theoretically -- work. Nx run blog build. Yeah, do the thing. Come on, come on, come on. Holy crap, did that work on the first try? No way. Is it going to let me -- no. There's no way. There's no way this is just going to work. Okay.
So we're going to go look at this. Here's the deploy preview. Okay. So here's the deploy preview. We can click around. There's the blog, right. Right? Okay. So everything is doing what we want. We can get in here. Get to the episodes. Get to the schedule. Uh-oh. Unexpected token in -- what is that? Hold on. This was working. Oh, no. Oh, goodness. That's not good. It was fine, and now it's not fine.
Crap. What are you -- oh, you know what I bet it is. I bet this is trying to load from the -- let's see. I bet it's trying to load from the Learn With Jason hosted API, which just went down because I pushed the other thing. So I probably need to move this. So let's go to routes, look at store. API products. That's hosted on this site, which I just changed. That means that it's not going to work anymore, which means I need to move this end point into my new API before this will all work.
So episode moved. Episodes moved. Schedule moved. Sponsors moved. Tag moved. Then I'm going to need to move all of these Shopify ones. Okay. All right. How we doing on time? We got nothing but time. All right. So let's do this. We're going to move all of these -- how should I do this? Should I move API products -- where is -- retrieving product list. So this is the Shopify API. So I'm going off, I'm getting these bits here. It doesn't like any of this because it's all TypeScript. And that -- this looks like I can just copy/paste it, I think. Yeah, I'm going to just do it.
So let's copy. Then I'll need this post to Shopify as well. And we're going to come up to my API end points. Going to drop this one in. You're going to complain about not having that, but that's okay because we can get that for you. Don't worry, little buddy. And I'm going to do that by getting post to Shopify.
We're going to come up here, and we're just going to see how well this works if I do a util. So you should be up one then. Okay. And do you depend on anything? Process end. Yeah, we expected that. We are on Node 18. So I think I can get rid of -- I think I can get rid of this. Just go with a built-in fetch now. Let's test it. Now I can test my API. Nx run API dev. Okay. Then if I go to -- let's go over here. 8888. And we're going to hit API products. Crashed because of what? Failed to parse URL from undefined. Okay. That's fair. Is it not getting -- LWJ Sanity token.
Oh, I need to move this key over to the API. Fine, fine, fine. So to do that, I can go into here. I'm going to go to my environment variable. So I'm going to use the command K here, which lets me do a search, and I'm just going to go to environment variables. I've got all of these keys in here. The one I need is the Shopify API end point, I believe. Here's the end point. I need the storefront API token. Okay.
So this one is not actually secret. So I'm going to see if it's shown by default. It's not. Oh, beautiful. Okay. Then I can copy this, right. Then I can go -- let's open a new -- I'm going to paste this off screen, actually, so I can use this later. Just give me one second. There we go. Okay. So that's over there.
Then I'm going to copy the other one as well, which was the storefront API token. And that one goes down here. Okay. So now I'm going to head over to my LWJ API. This command bar stuff is so freaking cool. Makes my life much easier. Then I'm going to go to environment variables again. And in here, I can create another variable. So I'm going to create one that is called Shopify API end point. And this is now hidden.
So I can go in and grab this that will have a I copied off screen. Drop it in here. Then I actually only need this to be available in functions. So I can turn it off for everything else. Then that way it stays nice and secure. If I wanted to, I could do different values for each deploy. So staging environment and production environment, so on and so forth. But in my case, I'm got doing that. I don't have the deployment requirements to have separate environments. I just kind of YOLO deploy everything. It is what it is.
So then the other thing that I need is let's do this storefront API token. We're going to give it specific scopes. I want it only in functions. And make sure this is hidden. There we go. So then I can go and get this. Right. So I'm going to create that variable.
All right. Now that I got these, I'm going to run this again. They should show up for me. There they are. Okay. So now if I come back out here and I reload, it works. There are all of our products. Okay, great. So that then means that if I save this and I git add API, then I can say git commit, move products end point to new API site. Okay. Then what I need to do is I need to change this site to call that instead. So I'm going to go into routes and store. Then I have just proxied this in under v2. So I can hit the v2 products end point now, and it should all just work. So I'm going to -- we're going to say update to the v2 API.
Going to push all of that. Then we're going to watch it build. Here's the other thing that's kind of cool about all this. If I go to my deploys, and actually, we can just look at all deploys here, the thing I find really cool about this is each one of these things, like the blog deploys in 22 seconds. Here's the API in 24 seconds. The main repo in a minute. The scenes in a few seconds. Where's the Remix? Remix in 30 seconds.
So each of the pieces of the site deploys really fast because I'm kind of using them for what they're ideal for. So the API is just a bundle of serverless functions. There's no build step at all. So they deploy super fast. The Remix site is just a remix side. I'm not making it read the file system and include a bunch of stuff so it can handle MDX anymore. Now it's super fast. It used to be slow because I was doing slow stuff with it.
Astro is real fast at reading those MDX files. So it's just a few seconds. So the whole suite of builds goes live in, you know, about 30 seconds total. Even when I'm going all of these different things. Why did you just fail? This is the weird thing. This Remix one is giving me intermittent failures, and that worries me a little bit. See, I don't know about that.
This is one of the things that concerns me a little bit about the way that remix is configured. It has to get all of this stuff copied over, and that is -- like, this build just sometimes doesn't go and I don't know why. If I clear cache and re-deploy. Mykal, yes, all of these deploys share the same repo.
Each is set up as a distinct project. I run Npx Nx. So it will look for a local version of Nx. If there isn't one, it'll install it. This runs the build for the remix side. Then it publishes the public files for the Remix site. If I go back and look at, say, the web hooks. So the web hooks site is failing right now, and I don't know why. Oh, you know what, this one is set up for the wrong thing. This one needs to be npx run web hooks.
Is there even a build step for the web hooks? There might not be. Yeah, there's not. So there's actually no end here. Then the public is just a placeholder. Then I need to make sure it's deploying the right thing. So I can save that. Then I go to functions here. And I need to make sure the functions directory is also set to sites, web hooks, source. Right, okay. So that's the right thing as well. Then if I come back out to my deploys, we will deploy the site. So I was doing a few different things and had different tools set up, but landed on Nx and forgot to update this one. Jacob, when you say deploy previews, what do you mean?
Okay. So this is all building. And this should only take a couple seconds. I'm building from scratch here because this has clearly been failing since I switched over to the Nx setup. And I just didn't notice. Honestly, it's one web hook that I don't use very often, and the last deployed version worked. So I haven't really been -- I haven't needed to work on this. But what I was hoping this would show, and maybe I have something else that'll show it, is when there's no change -- so like the API, there's no change. So theoretically, Nx should have pulled from the cloud. Let's see. Did it do it? Yeah, read the output from cache instead of running the command.
So it takes, like -- the build command completed in 1.1 seconds instead of 13. As a site gets bigger, this is a really big deal, actually. Because this site -- like, the change I made in the API didn't make any difference to the blog. It just reads the cached output of the blog. That means this whole build gets done in 17 seconds.
So yes, I could probably go through and set up Nx affected and find ways to short circuit, but I don't care. 17 seconds doesn't matter to me. It's so straightforward to set this up. Like, I literally -- all I did was this piece here with the access token. I went to the Nx cloud stuff, which you can find here. They've got docs on how to set this up. But it is surprisingly straightforward. Highly, highly recommend that. It was very nice.
Jacob, if you click on a link that takes you to Astro's deploy preview, does every link there point to the same deploy preview, such as a link? No, absolutely not. There might be a way for me to set that up, but that is not -- I've definitely not done that.
Probably the way to do that would be to have some kind of -- how would you do that? Are these hooked up to a commit? Because that would be interesting. Because if I go to, like -- let's go to my sites, and let's look at this site here. Let's look at the main build on here. And the permalink.
Is this URL -- does that match the commit hash? Because that would be -- it can't. That would be too convenient. No. It doesn't. So, I don't know how you would do it. There's probably a way this could be done, but I'm not sure.
Yeah, you can get the context env, but the way I've set this up -- and this is something that I think -- I don't know that anybody's got a good solution to this, right. This is sort of the challenge. Each of these sites is an independent Netlify site.
So the proxying is the only thing that ties them together. And that actually kind of brings up a good point. I am very rarely going to need to change, like, all of the sites at once, where I would need them to be deployed preview together. Instead, I'm most likely going to be changing one thing at a time. The proxy is almost never what I'm testing.
So that -- like, I probably could find out some way to connect these together, but I don't -- I mean, I'm open to be proven wrong, but I'm having a hard time imagining why those things proxied together would make a big impact on my ability to test the change that I made. Because the changes are typically going to be pretty contained. The change I made on the site worked. And very few things are -- like, I'm architecting these so that there's very little that reaches across the line between progress sis. That's kind of my intention here. So, okay. I want to go back and look at my builds here. The Remix site failed again. Why did you fail? Using Node restoring cache. I'm a little worried that there's something going on with remix where it doesn't want to keep this build directory between caches, and I need something. It read the output from the cache. Oh, no. I know what the problem is.
When you read the output from the cache, it doesn't trigger the part where the build folder would get copied over into the server. Here. And so I need Nx to not read from the cache on Remix. Okay. That's a later problem. Because honestly, if I'm not deploying Remix, I don't really care if the build doesn't go live because it's going to be exactly the same as the one before it. Nothing really breaks if this one doesn't deploy. And a new change would not trigger the Nx cache. So that doesn't matter.
You know what, it's not actually a problem. It's going to be annoying, but it's not actually anything wrong. The web hooks are now building. Good. The blog is building. The API is building. And when I change Remix, Remix will build. My Discord bot is not building. And we can change that because, yep, it's on the old settings. So my Discord bot is, I believe, only serverless functions. So let's go fix it. Here's my web hooks, Discord bot is functions. That's all good.
Okay. So I'm just going to -- yep. Just going to change this out, make sure it doesn't have a build command. The build command is no build. Cool. We'll skip the build command altogether. Keep that there. Then I'm going to go to functions, make sure it's got the right functions directory. It does. Good. Okay. So we can go out here, trigger another deploy, and that should get all of my sites building the way that I want them build. So these ones are all doing their thing. Scenes are building. Yes. All right. We're ready.
So nothing up my sleeve here, but if this'll let me commit -- blog worked. Web hooks failed. That's fine. Remix failed. We know why. API failed. Okay. Will you let me just do this? I'm just doing it. Here we go. Is this all going to work? It's all going to work. It's just going to work. Bot is now building properly. You doing the thing? There's no way that just worked. I actually can't believe it let me merge that. I can't believe there were no merge conflicts. Oh, god. Uh, what did I do? (Laughter)
Okay. Great. So now I have my monorepo at the root here. This is all inaccurate. Son of a biscuit. Okay. Cool. I need to go fix that. Let's see. The slow motion press of the enter button. Yes. (Laughter) Need some, like, really tense music. I don't have any tense music. I only have -- I guess we could -- oh, we're live. So, unrelated. Trying to make a site on Netlify, use Netlify forms. Solid start. Forms don't work. I don't know enough about Solid Start to answer that question, unfortunately. But I know the Solid team is super helpful. Check out their Discord and other spots they hang out. I'm sure they can get that set for you. Oh, yeah. And Mykal has an answer. Look at that. Okay. Did this work? Are we live? Okay. Just double checking everything did what I want. We're going to the builds. We've got successful Learn With Jason. Successful API. Successful Discord bot. Successful web hooks. And then we're missing the Remix, but the Remix is clearly working because -- let's see. Close this. Got a lot of tabs open. So this one works. That's all doing what I want. Let's get into the schedule. Good. Get into the episodes themselves. They're all doing their thing. Click in, yep. Got transcripts. All right. Go to the store. Store works again because we're on the v2 API now. Head over to the blog. Blog is working. Great. Go to the newsletter. We got ourselves -- I think we got ourselves a working site here. Let's try -- yep, command K works to open up the search. I'm feeling pretty okay here, y'all. This seems good. How do y'all feel?
So now, the nice thing about this is that when I want to work on something, I don't have to -- wow, this is magical. I'm going to git checkout main, git pull. Please just work. Oh, my goodness. That is amazing. I can't tell you how -- okay. Let's take a beat here. I love git with my entire heart. I really do. And every single time that I try to do something ambitious with git, I forget that I love git. Because the re-basing stuff, I've been doing this long enough that I get it. I can do a re-base. But it still barely make sense to me. The challenge of -- okay. So if I revert a commit and then that reverted commit is now in the commit history, then when you go to, like, re-base, you get these conflicts. You can work through it every time, but it just doesn't feel easy, you know. All that to say this two-week-old -- maybe more -- monorepo migration that I've been working on is -- I cannot believe that that just merged. Okay. So let's talk about -- I don't even know what we talk about. Are we done? (Laughter)
Actually, let's go fix this. Because I got a bunch of these sites running on the monorepo branch. If I go to my sites here and go to the API, we need to go to the deploy settings and make sure it's using the main branch. Then I don't really need it to follow that one anymore. So we'll just deploy the production branch. Okay. So the API is done. One. Discord bot, same deal. Deploy settings. Oh, build settings is what I was looking for. So, same thing here. We want the -- oh, I had an old branch called Nx. So this is even longer. I was like, December 11th doesn't seem like long enough. But I had an old branch called Nx that I was working on. Lots happening. So the Discord bot is good. We need to go to the web hooks. We need to go to the build settings. And we're going to make this one main. Okay. Let's go to remix. Build settings. And make this one main. We're going to go to the blog. This one I'm actually going to delete. I'm not using it anywhere anymore. I've now consolidated this into the LWJ site. So that one goes away. What else is left? We've updated Remix. We've updated -- let's go back to sites. Updated Remix. Updated web hooks, Discord bot, API. Let's go to the build settings. We don't need to build either of these branches anymore. Actually, I'll just go to none. Okay. Okay. So then if I go in here, let's take this, and we're going to -- what do I need to do? I need to update this readme a little bit. All right. It's built with Remix. Let's see. This whole section is now incorrect. Hmm. How do I want to do this? Let's do it's an Nx monorepo housing multiple sites built with -- we'll do one of these. And one of those. I don't need UTM campaigns. Then we can do one of -- we need Astro. And what else? What else am I doing in here? For data, it uses -- so I use Sanity. Do I use Hasura anymore? I don't think I do. I'm going to take this out, actually. Then Shopify. What else? We're loading data from -- let's do a little tour here.
I've got my -- this is coming out of just a Netlify function now. We've got this coming out of Sanity. All of this comes out of Sanity. The topic information comes out of Sanity. That's hard coded. The store comes out of Shopify. Blog is MDX. Newsletter is Convert Kit. Am I using any other data? We'll say -- we'll give Algolia a shout out. Hooked me up with an Algolia search that is just dope. All right. So the API is now at v2. Just check that actually works. Yes. Look at this highlighter plug-in I got. This is great. The only complaint I have about this highlighter plug-in is it doesn't have the night owl theme, and this just feels wrong to me. But otherwise, this is great. Okay. So that one works. We want episodes. I did not paginate the episodes. So we're going to skip pagination. Maybe I'll put that back later. Details about a single episode. You can get the transcript, but it's -- transcript equals true. The poster doesn't work that way anymore. So we're going to leave that off for now. Schedule here. We're just running Node 18 now. This is not really runnable. There's so many environment variables now that I don't know that you can do -- I don't know that you can actually do anything with this. I don't know. We'll npx nx run. That one should run at least. That should work. Just going to use -- port 8888 now. Environment variables are not set so things won't set. Yeah, yeah, yeah. And I have my all contributors, which I love that tool. All right.
So let's git commit. I need to get back to the directory here. Did this just freeze? Whoa. That was super weird. All right. We push, and now comes the test. Everything should build now. We're going to go to sites. Actually the, I'm going to go to builds. It should show me remix, web hooks, API, bot, and this is the main blog. So, collapsing all the sites. Oh, we don't do the scenes. We've got -- I'll do one of these over here. Do one of these over here. What are you? Get out of here. We've got the blog Discord bot, the API, the web hooks, and the Remix site building. We don't have the scenes. So I got to go to the scenes. That's the right one. I'm going to go to build settings. And I need to change this over to main. Save. Okay. So theoretically speaking, this is all now running and just working. If we go to learnwithjason.dev, reload, it's all doing the thing. All right. I got a little inconsistency. This is part of the Remix stuff. I have to move this to the common header I build because I did some touch-ups on this to make it a little easier for me to manage and style, and I actually added -- this will be nice on mobile. I added an easier search and a better menu. Previously if we go to the homepage, it's kind of like this, which is fine. But it makes it pretty hard to see what's going on, on the page. Whereas now you can see a little bit more on a phone. So I'm excited about that. And we'll slowly roll out that design system consistency across all of the Remix stuff as I kind of back things out and figure them out. Episode without v2? Oh, did I screw that up? Let's go back to the readme. I'll just include the v2 right here. Then we can hit one, two, three -- ah, yes. Good call. Okay. Update the link in readme. Push. Then, watch. I'll show you why this stuff is so cool. So if I go in here and I say -- watch, I can "at" one of these. So I'll go into the monorepo, and you should just help. So I'm going to say -- I did that backwards.
All right. So watch. Now I do an all contributors. I think this is how this works. Then it will respond, if I tag the right bot. Yeah, so check this out. Now it has opened up a pull request for me. And added the -- it like updates the number of contributors and adds another thing there. Like, this is dope. It's just such a nice thing to have. Then I can probably go and configure some of this stuff to get less noise happening here. Probably don't need a full deploy preview. Although, they are so fast that maybe it doesn't matter. I don't know. Yeah, then this Remix one is going to fail because it's going to use the cache. That's okay. Yeah, there's the Remix one failing. Whatever. So I need to fix that. That part is annoying, that it makes it look like the PR failed, when I know that it didn't. So I'll probably need to go fix that part. Maybe I'll just unhook the Remix part of things. But then the other piece I can do here is if I go into -- what are we doing on time? We're almost out of time here. So let's do one quick test to make sure that the Remix site is actually building the way I want it to. So I'm going to go to the root here. We've got the head. Meta links, all that stuff is in here. Good. Good, good. All right. Let's actually do a quick check to see, do I have any instances of API that aren't v2? So the subscribe is fine. These are all v2. The store I'm going to have to fix, but I've got a different redirect in place for that, that I think will work. I might have to port that redirect over. We'll see. That's actually a great question. Let's go check. Can I, in my store, add something to a cart? No. We're getting a 502. API store add to cart. So let's go check what is happening here. I need to go in here. Let's update this redirect where we want API v2. That's fine. But what I really want is I want API store. I have this configured on the other side. Let's get into the app. Store goes into Netlify functions, Shopify splat. So I can grab this and come over here. What I want it to be is the Remix site. We'll do one of these.
I'm just going to line these up because it pleases me. Looks like I got a straggler out there. So now instead of trying to redirect it to the root of the site, we'll redirect it specifically to the Remix site, which should theoretically make it work. Let's test it and find out. I'm going to git commit, say fix use Remix store API, and we push. Oh, we didn't do the -- did that all contributors merge. This should cause the site to rebuild. And here they all go. Now we can see we have our happy little army of sites all building. And they all build nice and fast, which makes me very happy. The push notifications are always kind of nice. I had to turn my off because I was getting -- I'm in a lot of orgs on GitHub. I couldn't figure out how to only give myself notifications when it was my stuff and not org stuff. So they've basically become completely useless to me. All right. So we're almost built. We are built. So now, theoretically speaking, nothing up my sleeve here, let's see what happens. Oh, no. See, that one is failing. 502. Why would it 502, though? It's 502'ing because I bet the Remix site doesn't have the -- crap. I bet the Remix site doesn't have the keys, which let's verify that. Then I probably won't have time to re-deploy.
Let's go to Remix. Then let's go to build settings. And I actually want environment variables. Opt into the new experience. No environment variables set. Okay. So that's the problem. I need to go and grab the environment variables from the other site and bring them in. So I'll have to do a little bit of digging into -- let's see here. No. Not the blog. This one. In the store, for example, I'm going to have all of my Shopify stuff. I'm going to have to get these details and then probably in here there are going to be potentially other ones. Yeah, so I just need to move those details in so that I've got the post to Shopify stuff there. The good news is that I'll be able to migrate this into the API, or maybe I'll get real wild and build out the store as its own little microservice so I can do more with it. I want to do more with it, I just haven't gotten around. But yeah, so I think I have a path forward to fixing this. I'll go and fix that as soon as we get done here. Because it's not going to happen in two minutes. And then we'll have an actually migrated, fully functional, like, running as a monorepo Nx, Netlify, Astro, Remix, Netlify functions site, right. So pretty exciting in how all of that works, and I need to probably go and set up a couple web hooks so the Remix site rebuilds when you update Sanity and a couple other pieces like that. But the big thing, the thing that I thought was going to be the hardest, which was getting that repo merged, that big PR merge, went so painlessly that I'm kind of astonished. And that -- now it's just the admin cleanup to go and do. So let's call that one a success, y'all. I think this was a lot of fun. Oh, Ben. Whole Microsoft? Woof. All right.
So back to the homepage, where this episode, like every episode, has been live captioned. We have had Rachel from White Coat Captioning here. That is made possible through the support of our sponsors, Netlify, Nx, and New Relic all kicking in to make this show more accessible to more people, which I appreciate so very much.
We have so many good things coming on this show. I really hope y'all go and mark your calendars. I'm starting something new in January, actually, where I'm going to do solo streams on Tuesdays. They're going to be a little longer. So we're going to do three hours, which will give me an opportunity to build stuff that's a little more ambitious. I feel like I'm always in a sprint in a 90-minute co-working session. Then Thursdays will be for guests.
So you can see here these are the Thursday guest streams. I'll get the Tuesday ones listed so they show up in the calendar. But yeah, this will hopefully be an opportunity for folks to hang out a little bit more. It'll give me more of an opportunity to talk to y'all in the chat without feeling like I'm ignoring the guest or vice versa. And we'll see what we can build. I'm going to try to build a bunch of stuff over the next year, and my intention is to build as much of it as I can just here. We'll see what that turns into.
So with that, y'all, this has been great. Anybody have recommendation on who we should raid? I am looking, and I see coding garden, bash bunny, code it live. If anybody has recommendations, toss them out now. Joshua K. Goldberg. All right, Ben, let's do it. We're going to go raid -- wait. Is that spelled wrong?
Oh, weird. Okay. I spelled it wrong. So let me go back over here. And we're going to raid. Raid has been created. Here we go. All right, everybody. Thank you so much for hanging out. We will see you all next time.