Chris
00:00:05 – 00:00:32
All right.
Welcome back to over engineered the podcast where we ask the very important question, what's the absolute best way to do things that don't particularly matter?
Today, I am excited to have Aaron Francis to talk about personal websites, which I think is, like, what a thing to get a chance to over engineer.
Right?
That's, like, our favorite.
Chris
00:00:33 – 00:00:38
Everyone, there's so many easy ways to build websites, but as developers, we sure don't wanna do it the easy way.
Right?
Aaron
00:00:38 – 00:00:44
Yeah.
They're all always are terrible except the way that I have chosen to do it.
So I'm ready ready to talk about this.
Chris
00:00:45 – 00:00:57
Awesome.
Well, I I can't imagine that my my few hundred listeners don't know who you are, but do you wanna give a a brief intro just to to say hello first?
Aaron
00:00:57 – 00:01:13
Absolutely.
I am, my name's Aaron Francis.
I'm a developer educator at a database company called PlanetScale.
So what that means is I end up making a lot of YouTube videos about databases.
I'm also a Laravel developer, and I make some YouTube videos about that.
Aaron
00:01:14 – 00:01:28
And most importantly, I am dad to 4 children now, which is an insane number of children.
We just had our second set of twins, and they're, like, you know, 3 weeks old.
So I've got a lot of coffee and I'm ready, I'm ready to over engineer.
Chris
00:01:29 – 00:01:55
Nice.
Well, I don't know exactly this is this is one usually, these shows kinda come from a place of this is a thing I've been thinking about a ton and have have sort of a starting point, but for this one, you, you kinda came to me and said, let's talk about this website stuff.
So why don't you instead usually, I'll do the, like, setting the stage, but you wanna set the stage instead?
Like
Aaron
00:01:56 – 00:01:56
Yeah.
Sure.
Chris
00:01:57 – 00:01:58
Yeah.
Aaron
00:01:58 – 00:02:17
Yeah.
So I'm on a you know, I'm I do a podcast with Ian Landsman called Mostly Technical, and it's barely technical, but it's a great name.
And on the show, we were talking about my personal website setup, and he told me I was overcomplicating it.
And I thought, no.
This is perfect, and you just don't understand.
Aaron
00:02:17 – 00:02:31
And so, you know, we had a nice argument about it.
And then I thought, where can I talk about how overcomplicated this isn't?
Bossman Chris has a great show for this.
So here's here's my, like I don't know.
Here's my thesis on personal websites.
Aaron
00:02:31 – 00:03:18
1, I think static site generators are too anemic and they, like, make you learn this whole new thing that is only useful for one particular use case, but it's also not that useful for that particular use case.
And I have made extensive use of, like, jigsaw, Titan's jigsaw, which I loved for a super long time, but I kept running into the boundaries.
And I kept wanting to I I just kept wanting it to be full Laravel, and it's just not.
It's like it uses some of the Laravel components, some of, like, the Illuminate packages, but I just wanted it to be Laravel.
And then I looked at, like, you know, Nuxt because I like Vue JS.
Aaron
00:03:18 – 00:03:37
So I'm not gonna do something like, I don't know, next or whatever.
But I like Nut or I I like Vue.
And so I looked at Nuxt and I was like, am I really gonna learn all of this just to make a personal website?
And so that's when I landed on, just make it Laravel.
And then from there, you know, it kind of evolved into a whole thing.
Aaron
00:03:37 – 00:03:42
But I'll stop and let you let you respond to the static site generators are a waste of time.
Chris
00:03:43 – 00:04:13
Yeah.
I mean, I I agree wholeheartedly.
I think, you know, I I like I'm sure most developers have had many incarnations of my personal website over the years, and I recently moved from a Gatsby site to, which is I was just thinking about, like, remember when Gatsby, no one could stop talking?
Like, no one was everyone was talking about Gatsby, And I haven't heard Gatsby mentioned in in Shocking.
Right?
Aaron
00:04:13 – 00:04:14
Shocking that people have moved on.
Chris
00:04:15 – 00:04:16
It's it Let's You know?
Aaron
00:04:16 – 00:04:22
We'll have to revisit this when Astro when Astro is dead, we can come back and be like, man, you remember Astros?
Chris
00:04:22 – 00:04:42
Yeah.
There you go.
But, yeah, I had I had a Gatsby site and it was fine.
You know, I think I think the fun thing about personal websites is that they're like, you know, a testing ground for new technology that you don't necessarily wanna move into production in, like, your your real job.
So, yeah, it's fun.
Chris
00:04:42 – 00:05:14
Like, all the things that seemed neat about Gatsby, I wanted to play with, but I didn't Mhmm.
You know, I wasn't gonna commit to using it anywhere else.
So I don't I don't regret doing it, but, you know, about, I'd say about 6 months ago, I just, like, ran into a situation where it was gonna be a pain in the ass to upgrade, and I just thought, it's gonna be easier to just rebuild this in Laravel than it is to upgrade Gatsby and, like, fix this bug that I'm running into.
So I'm just gonna do that.
And so I recently kinda made the same switch.
Chris
00:05:14 – 00:05:22
I I will say, and I I decided to hold this until I had you on the podcast to say Uh-oh.
I totally agree with Ian.
Aaron
00:05:22 – 00:05:25
Like That's set up.
Like Oh, no.
Bamboozles.
Chris
00:05:27 – 00:05:43
You are trying to say that you're just building a just Laravel app, but you're you're you're kind of doing just because your static site is SQL.
Like, it doesn't mean that it's not a a statics.
You're basically doing a static site generator.
Aaron
00:05:44 – 00:05:51
What a scam.
What a scam.
I was induced under false pretenses.
Hey.
I've never I've never seen it.
Aaron
00:05:51 – 00:06:04
You made me come on here by planting this idea in my mind.
Okay.
So here we go.
Alright.
Let's talk about my setup for those that don't listen to the mostly technical podcast.
Aaron
00:06:05 – 00:06:18
It's a Laravel.
It's a full on Laravel application.
I make heavy use of markdown.
So, like, all of my it's ataronfrances.com if you wanna see it, but it's it's it's a standard, like, content website.
Right?
Aaron
00:06:19 – 00:06:42
And I make heavy use of mark down to actually, like, write my blog posts and stuff.
I have a few mark down plugins, which I have either written myself or installed, and I think they're, you know, fun and interesting.
But at the end of the day, it's kinda markdown.
Then that gets pushed to GitHub.
And in a GitHub action, I gather a bunch of stuff.
Chris
00:06:43 – 00:06:47
When you start to this this moment right here is when your argument starts to fall apart.
Aaron
00:06:47 – 00:06:49
When you say, oh, so the
Chris
00:06:49 – 00:06:53
GitHub action, I have to do all this this build step to to
Aaron
00:06:53 – 00:06:54
build my screen and
Chris
00:06:54 – 00:06:55
push it to the web.
Aaron
00:06:56 – 00:07:08
This is what I don't understand about the argument that you and Ian are making.
So, like, okay, forget the build step.
Let's say I so we'll we'll take a really concrete example.
I have YouTube videos.
Right?
Aaron
00:07:08 – 00:07:29
And I want the YouTube videos to be on my website Because like, hey, this is this is the central location you can find basically everything I'm up to.
YouTube has a great API that I can just call and like pull it down and put it somewhere.
Okay.
So that's what I do.
I have a command that's called sync colon YouTube.
Aaron
00:07:30 – 00:07:43
So I run PHP artisan sync YouTube.
And it goes out to the API.
It looks at all of, both the PlanetScale channel and my personal channel, looks at all the videos, and then puts them into a database.
Pretty normal so far.
Right?
Chris
00:07:44 – 00:07:44
Sure.
Aaron
00:07:45 – 00:07:55
Right?
It's a standard Laravel app.
It it I run a command, and I write stuff to the database.
That's normal.
I could I could never be accused of that being overcomplicated.
Aaron
00:07:55 – 00:08:02
Right?
That's totally, totally normal.
Okay.
So PHP artisan sync YouTube.
Write stuff to the database.
Aaron
00:08:02 – 00:08:20
Oh, that's super cool.
Let's see.
PHP artisan sync podcasts.
What that does is that goes to, 3, maybe 2 or 3 different RSS feeds and looks for new podcast episodes, and it writes that to the database.
It's like, oh, that's pretty cool.
Aaron
00:08:20 – 00:08:36
So now I'm, like, gathering my digital detritus from all over the Internet and putting it on my site, which is the goal, like, a central place.
So, you know, I'm beefing up my site with all this external content.
Oh, that's really cool.
I agree.
And so now I've got these yes.
Aaron
00:08:36 – 00:08:50
Thank you.
I've got these you know, I've got one table in the database just called content.
And it's like, this is the title.
This is the URL.
Maybe a description, maybe some ancillary data like view count and that sort of stuff.
Aaron
00:08:51 – 00:09:14
Okay.
So I have another I have another command that's just PHP artisan sync articles.
And that sync articles command, it just looks on the disk and it's like, hey.
Let's just grab all the markdown and put that into the content table.
So, like, looks through the articles folder, pulls all the markdown, looks at the front matter, and it's like, what's the title of this post and when was it published?
Aaron
00:09:14 – 00:09:33
Great.
I'll put that in the database.
So now I've got this big table of neat stuff.
Right?
And then the website, like, the actual website just pulls using Eloquent, just pulls from that table and puts it in a giant list, and some things link externally and some things link internally.
Aaron
00:09:33 – 00:09:36
That's it.
Yeah.
I mean Pretty good.
Right?
Chris
00:09:36 – 00:09:40
I think, you know, I I'm most I I'm partially just baiting you.
Aaron
00:09:40 – 00:09:43
I I I do agree.
Not working.
I'm not mad at all.
Chris
00:09:45 – 00:10:02
But, he says as he as he yells into the camera.
But I I do think I do think that I agree with Ian's kind of premise that the fact that this is all happening in, like, a build step
Aaron
00:10:02 – 00:10:08
Well, we haven't gotten there yet.
We haven't gotten there yet.
I'm just setting up I'm setting up the premise.
You don't know where this is going.
You have no idea.
Aaron
00:10:10 – 00:10:10
Okay.
Chris
00:10:10 – 00:10:12
Alright.
Then then
Aaron
00:10:12 – 00:10:15
So that's all reasonable though.
Right?
Pulling all that stuff down That is all
Chris
00:10:15 – 00:10:16
perfectly reasonable.
Yes.
Aaron
00:10:16 – 00:10:18
And writing it to a database.
That's pretty reasonable.
Chris
00:10:19 – 00:10:43
Yes.
I mean, I so I do a similar thing with with markdown, and I think that that's like I think that that's like if I were gonna dig into how to make publishing personal websites with Laravel easier, the thing that I would look into is, like, what I think every developer wants is to just write in markdown.
Aaron
00:10:44 – 00:10:44
Yes.
Chris
00:10:45 – 00:10:56
And, like, how do we make the ergonomics of getting that to be rendered on a site Mhmm.
Better?
I think that'd be an interesting thing to talk about later.
But setting that aside, I mean
Aaron
00:10:56 – 00:10:59
I have lots of thoughts on that, so we should circle back to that.
Chris
00:10:59 – 00:11:05
Okay.
Yeah.
On on my end, I do the same thing, except for I just route directly to the markdown files.
Right?
So I just Yeah.
Chris
00:11:05 – 00:11:12
Yeah.
You know, I I I don't necessarily even bother dumping that into a database.
But, you know, there's nothing wrong with doing that.
Aaron
00:11:12 – 00:11:30
Yeah.
And for for the actual routing, I do the same thing.
I just route to and just, like, it uses the view like, it I think it just uses pulls the view and runs it through Graham Campbell's markdown rendering engine.
That's basically it.
It.
Aaron
00:11:30 – 00:11:50
I just put it in the I put it in the database so I can have a list view.
I mean, it's basically at that point, the database is like a cache layer more or less.
So every request doesn't hit the file system to look for all the markdown.
It just hits the database instead.
I could you know, you could run that once and just do a cache remember for an hour or forever or whatever.
Aaron
00:11:50 – 00:11:53
Right.
So, yeah, totally totally the same there.
Chris
00:11:53 – 00:11:58
Yeah.
And I think that's basically what I do on my end is, like, it's just it's just cached instead.
Aaron
00:11:59 – 00:12:26
Right.
And so that leads us nicely to the next point.
So I wrap up all of these commands into and that that command looks for all commands in the sync namespace that aren't all, and it just runs those commands.
And it's like, great.
Now that's, you know, filling ever filling the database up with all of the content that I could possibly need.
Aaron
00:12:27 – 00:12:45
It's idempotent, so I can just run it over and over and over and anything new will get populated, but nothing old will get duplicated.
So at that point, you know, I'm like, great.
I've got a database full of stuff.
Now the problem is I don't want to set up a database.
So if you guys need a database, go to planetscale.com.
Aaron
00:12:46 – 00:12:52
That's great.
Good databases.
Great databases.
But sometimes you just don't need a database.
Right?
Chris
00:12:52 – 00:12:54
You heard it here, folks.
Aaron
00:12:54 – 00:12:55
No.
No.
No.
No.
No.
Chris
00:12:55 – 00:12:57
Francis says don't need databases.
Aaron
00:12:58 – 00:13:08
Don't clip this.
If Holly ever finds out that I said sometimes you don't need a database, she's gonna be so mad.
That's not true.
Holly never gets mad.
So sometimes you don't need a database.
Aaron
00:13:09 – 00:13:09
Right?
Chris
00:13:09 – 00:13:09
Sure.
Yeah.
Aaron
00:13:09 – 00:13:20
Yeah.
This is an instance where I'm like, you know what I don't want?
I don't want a bunch of services running.
This is my personal freaking website.
I don't want to be maintaining a MySQL database.
Aaron
00:13:20 – 00:13:52
I don't wanna be maintaining some third party API connection.
Like, I just wanna, like, package up a nice little ball of stuff and send it somewhere, which sounds dangerously close to a static site generator.
Right?
So the solution to that is SQLite.
It's just like, it's basically as if I wrote it all to a giant JSON document and then committed the JSON document to the repo and shipped it off and pretended that the JSON document was a database.
Aaron
00:13:52 – 00:14:18
That's what SQLite is.
It's just nothing.
And so what the the the super nice thing that I do is I can sync all that stuff locally and then just commit everything, including the database dot SQLite, and then ship that off.
And I can ship that to any server anywhere.
Now I can't ship it to, like, GitHub pages because it still uses, you know, PHP to like it still uses Eloquent, which I really like.
Chris
00:14:18 – 00:14:19
Sure.
Aaron
00:14:19 – 00:14:39
Still uses Eloquent to inspect the database.
But I can ship that to a $5 digital ocean box.
I can ship that to vapor, which is what I do.
And I just know that, like, I have a unit, which is a standalone basically zip of my website and just kind of send it away.
And then I have all the content out there.
Aaron
00:14:39 – 00:14:47
So that that's the next that's the next step.
It's it's basically like a pre warmed cache just written to the database.
Chris
00:14:48 – 00:14:53
Yeah.
I mean, I think that I don't disagree, or I actually think this is a very elegant
Aaron
00:14:53 – 00:14:56
stop there.
I don't disagree.
Yes.
Yes.
Yes.
Chris
00:14:56 – 00:15:09
Well, I'll even go further to say I think this is a very elegant solution to the problem.
Wow.
I just think that it's it also doesn't feel like just it's just like a regular Laravel app.
This this feels like
Aaron
00:15:09 – 00:15:10
a a
Chris
00:15:10 – 00:15:12
home grown status generator that I
Aaron
00:15:12 – 00:15:16
think this is fine.
I'm fine with that.
Yeah.
I think I'm fine with that.
Chris
00:15:16 – 00:15:19
Yeah.
I mean, that's Yeah.
And I think the
Aaron
00:15:19 – 00:15:27
problem I think the problem I have with, like, let's let's take Jigsaw because it is in the Laravel community.
Right?
Chris
00:15:27 – 00:15:28
Sure.
Aaron
00:15:28 – 00:16:03
And Jigsaw Jigsaw is great, and so I don't wanna disparage it, but the I'm gonna tell you the the problems that I have with it is I have to learn how the jigsaw collections work and, like, how the jigsaw markdown rendering pipeline works, which I have gone super deep on to make syntax highlighting work over there.
And so I've I've really gone deep into Jigsaw and I know it extremely well.
But at the end of the day, when I'm like, great.
Now how do I sync my YouTube feed to it?
It's like, well, I would know I would know immediately how to do that in Laravel.
Aaron
00:16:03 – 00:16:36
Like, it's so so easy.
But with Jigsaw, you gotta figure out, oh, I gotta listen to this after build, before build, and I gotta write my own pages.
And it's kinda Blade, but it's not totally Blade.
And so I don't have a problem, I think, with building static content.
I think I just wanna encourage people to think about using your framework of choice to build that static content instead of relying on some, you know, half half framework implementation of that.
Chris
00:16:37 – 00:17:14
Yeah.
I I think, I mean, I think that this is a perfectly fine choice to make for building, like, building a site of this, like, of this type.
And, you know, I totally get, especially because you're shipping to Vapor, like, you know, dealing with the database consideration is a little bit more complicated there, and just shipping a SQLite file solves that, and I think that's great.
Yeah.
I I do still think that if you were to say, oh, my website is just like a regular old Laravel app, I would expect some of these things to happen just a little differently.
Chris
00:17:14 – 00:17:30
Right?
I'd expect there to be a MySQL database or a persistent SQLite database just sitting next to your app.
Right.
And then, I would expect basically all of these sync commands to just be running on a cron on the server.
Right?
Aaron
00:17:30 – 00:17:31
Right.
And
Chris
00:17:31 – 00:17:45
because you're using Vapor, that complicates a bunch of this, right?
And the same, I mean, I deployed a fly.
Io, and I have to deal with a few of those considerations.
Aaron
00:17:45 – 00:17:46
The memoral stuff, yeah.
Chris
00:17:46 – 00:18:03
Yeah, and so it definitely is.
I mean, in my case, I just don't have a database, you know?
It's just everything is driven directly either by the files or for the API calls that I make.
It's just just a lazy caching situation.
Right.
Chris
00:18:03 – 00:18:08
You know, the first person who hits the site makes the API call, and then everyone else just gets the cached version.
Aaron
00:18:08 – 00:18:08
Totally.
Chris
00:18:10 – 00:18:42
And I would argue that, like, the spirit of what I think Ian was saying and the thing that, like, caught caught me as as sort of like, yeah.
This isn't quite just Laravel is that feels a little bit closer to just, like, just Laravel.
The moment that you have like an extra build step and you're like pushing your, like, built site somewhere, it just feels, you've stepped a little bit outside of the world of this stuff.
Aaron
00:18:42 – 00:18:58
I think the problem I think the problem that most people have with it is the read only it's the read only SQLite database.
That is not a standard that's not a common pattern.
Because, like Yeah.
Chris
00:18:58 – 00:19:06
Using someone came to your site came to your code base, they would it would take them a little while to figure out what was going on there.
Aaron
00:19:07 – 00:19:37
See, I don't even know about that because it's, like, it uses proper eloquent models, it uses artisan commands, You know, it's it's discoverable in the database dot PHP.
It just says, like, the the, you know, the default connection is SQLite.
It uses migrations.
I think the thing that might take them a minute to figure out is why is PHP artisan sync colon all?
Why is that not running every morning?
Aaron
00:19:37 – 00:19:49
Right?
Why is that not running at midnight Right.
In the scheduler?
Like, how do we sync this content if it's never run?
And I think that that's the thing where they would be, like, a little bit confused.
Aaron
00:19:50 – 00:20:02
And I think the other thing that would confuse potentially confuse someone, but the other thing that would potentially confuse someone is that in production, the databases read only.
Chris
00:20:02 – 00:20:02
Right.
Aaron
00:20:02 – 00:20:29
I mean, you can definitely write to it, but it's gonna get blown away.
And I think that might confuse someone, but there are no routes or actions or anything that, like there's no way to, like, you know, leave a comment on aaronfrances.com.
And so there are no places where I'm writing to the database in production.
But if somebody, you know, you know, some intrepid intern came to work for Aaron Francis Incorporated, and they're like, I'm gonna add commenting to your website.
And it's really simple.
Aaron
00:20:29 – 00:20:45
I just post to this route, and it writes to the database.
I would have to be like, oops.
That's gonna disappear on the next deploy.
Or honestly, whenever, you know, AWS Lambda decides this container is toast, then then that comment would go away.
And that that part is weird.
Chris
00:20:46 – 00:20:52
You could you could pretty simply just swap that out for a MySQL connection and Totally.
Know.
Yeah.
Aaron
00:20:52 – 00:21:01
Yeah.
Yeah.
Yeah.
And I I I absolutely I absolutely could.
And at that point, like, it is super standard Laravel.
Aaron
00:21:01 – 00:21:15
Like, all Laravel applications have a deploy step.
Right?
And my deploy step also happens to warm a cache, and that cache happens to be a SQLite database.
Chris
00:21:16 – 00:21:16
Right.
Aaron
00:21:16 – 00:21:41
So it's like, meh, that's kinda weird.
I could, you know, I could get rid of the whole SQLite database and just run these, API calls on the first request and then cache it in whatever vapor's default cache is, like Dynamo DB or something.
And that would be maybe more normal.
It just fills me with immense satisfaction to be like, I'm gonna ship the whole website now.
Here it goes.
Aaron
00:21:41 – 00:21:56
And I don't have to worry about, you know, the scheduler, the cron or anything.
I actually turn those off in vapor, which saves me a number of pennies.
And it's like, yeah.
This is this is kinda nice.
I actually do wanna deploy it to Fly because this is 100% perfect for Fly.
Chris
00:21:56 – 00:21:57
Right.
Aaron
00:21:57 – 00:21:59
And that would be fun that would be fun to try out.
Chris
00:21:59 – 00:22:09
Yeah.
Yeah.
So to okay.
Talk to me about markdown.
What's I have I have some thoughts here, but let me hear what it what's, what's your initial reaction there?
Aaron
00:22:09 – 00:22:17
I have grand plans for I have grand plans for markdown in Laravel in static sites, honestly.
Chris
00:22:18 – 00:22:18
Okay.
Aaron
00:22:19 – 00:22:39
And so I am working I am working on making I I'm working on seeing this thought to completion of Laravel should be your static site generator.
And I have a lot of ancillary things around that, but that is that is the cohesive thesis of what I'm trying to, like, see to fruition.
Chris
00:22:40 – 00:22:40
Yeah.
Aaron
00:22:40 – 00:22:52
And at the core, the heart of that is markdown.
And so let's start with what is it called?
Common mark, I think, is a PHP league package.
Is it a PHP league?
It's by that It is.
Aaron
00:22:52 – 00:23:06
By Colin O'Dell.
Okay.
Commonmark.thephpleague.com.
So that that makes up, like, the main engine.
And then on top of that, I've got Graham Campbell's, basically, Laravel shim.
Aaron
00:23:07 – 00:23:22
Not super necessary, but it, like, you know, gives you some facades and it renders some blade engines and stuff.
Or it I'm sorry.
It registers some blade engines and stuff.
So it's kinda nice.
But the crux of the whole deal is league slash common mark.
Chris
00:23:22 – 00:23:28
And And that that ships with Laravel now.
Like, you can do string markdown and it just will give you HTML.
Aaron
00:23:28 – 00:23:33
I don't know who powers string markdown.
It might be league.
It's God mark.
Chris
00:23:33 – 00:23:35
Same thing.
Yeah.
It's the same God mark engine.
Aaron
00:23:35 – 00:23:44
Yep.
Yeah.
So it's super duper good.
I have a few qualms with it in that they follow all of the best practices, and that annoys me a little bit.
Chris
00:23:44 – 00:23:46
Yes.
It's a pain thing
Aaron
00:23:46 – 00:23:58
as figure.
Figure.
Everything is private.
There aren't, like I've had to break in.
I've had to use that invade thing where you, like, use reflection to change properties, and I felt 0% bad about it.
Aaron
00:23:59 – 00:24:23
But it's very, very good.
It's a great package.
So that makes up, like, the core of the rendering of markdown, like, engine.
But then on top of that, I think there are a lot of things, there are a lot of things that you can add to markdown that meet your specific use cases.
So for example, one is, blade rendering.
Aaron
00:24:23 – 00:24:45
Right?
So when you're writing a markdown file and you want, like, this special blade component that you have.
Like, I have one for a YouTube embed.
I have one for a Twitter embed that, like, makes the tweet look really nice instead of, like, giant the way that the real embeds work.
And when I'm writing markdown, I want to just like, I just wanna use my blade component.
Aaron
00:24:45 – 00:25:00
And there are a couple ways that you could do that.
You could and I think this is dangerous.
You could run blade render over the markdown after it's been turned into HTML.
Right?
So you can write raw HTML in markdown.
Aaron
00:25:00 – 00:25:14
That's not a problem.
But if you run blade render over HTML that you don't control, that possibly includes valid blade inside of a code block.
Yep.
You're gonna be host.
Right?
Aaron
00:25:14 – 00:25:29
So if you're writing an article about scary.
Yeah.
If you're writing an article about Laravel and you have some valid PHP in there and then you run Blade render over it, like, oops.
You're toast.
Especially if you're using that on user generated content, which I would never recommend doing.
Chris
00:25:29 – 00:25:29
Right.
Aaron
00:25:29 – 00:26:10
So I've written a blade a safe blade component parser compiler.
I've written, an extension that, like, looks through the code blocks on my page, and after, you know, some random number of code blocks, it puts a little ad for torchlight underneath the code block.
It's like, hey, this syntax is highlighted by torchlight, a service that I created.
I have a few of those, like I have one that I'm working on right now that'll insert, like, a newsletter sign up, you know, 75% of the way down the page.
And so it just kinda like you can encode some best practices into your rendering engine.
Aaron
00:26:11 – 00:26:52
And then, like, let's say you're launching a course or something.
You can swap out your newsletter sign up for, like, an in house course ad across all of your articles at once by going into this little markdown extension and saying, like, oh, the thing I'm promoting right now is not the newsletter.
It's this thing.
And so there's there's so many things that I think once you understand that you can break into markdown and get access to the abstract syntax tree and just, like, kinda walk around and look at stuff and do stuff, then you can really start to take your, like, your markdown rendered contents.
You still get the authoring experience that you desire, but you still get the outcome of, like, no.
Aaron
00:26:52 – 00:27:04
I'm using it's not just it's not just Tailwind Pros.
I'm using, like, blade components and embeds and Mailchimp sign ups, and that makes your site, like, do the thing that you really want it to do.
Chris
00:27:05 – 00:28:22
Yeah.
I mean, I I definitely feel like the thing about markdown is it gets you 80, 90% of the weight to what you want, and getting that other 10, 20%, there's not a good sort of canonical approach to that yet.
And I, you know, I've seen there are various there have been a bunch of different attempts to do it either, you know, extending the markdown syntax directly or, like you said, just embedding blade components in your markdown or, you know, I've looked at just, like, having sort of a fragment syntax where I can be, like, right here, pull in this other blade file, you know, and just just render the blade, you know, or there's a bunch but all of those I don't know.
I I've never got the ergonomics of that right because it's, like, most of the time, like, I want to just do an inline code block if I'm doing, like, a code example, but every once in a while, an inline code block is not enough, but, like, finding that balance, I don't know, that's always been a pain.
And then have you solved the indentation problem?
Chris
00:28:22 – 00:28:37
Because that's like it's not that hard to solve, but that was the thing that I need like, I needed to do first was, you know, even in Laravel, like, the the markdown renderables where you have to, like, keep everything aligned to the left column.
Aaron
00:28:37 – 00:28:39
You have it left or you're gonna blow it up.
Yeah.
Chris
00:28:39 – 00:28:40
God.
That drives me nuts.
Aaron
00:28:41 – 00:29:00
Yeah.
That drives me nuts too.
And that's one of the frustrations with, trying to write non markdown in a markdown file is, like, you write some pretty HTML that's indented correctly, and it turns the inner part into a code block.
And you're like, f.
Like, I don't want this to be a code block.
Aaron
00:29:00 – 00:29:26
This is actually code.
And so the way the way that I solve that, one of the solutions for rendering markdown in in no.
I'm sorry.
One of the solutions for rendering blade in markdown that I, like, wrote an extension for, I think is kinda neat.
You you open a code block and you say that this code block is, you know, HTML or blade if your, you know, your editor supports blades and text highlighting.
Aaron
00:29:26 – 00:29:45
But I just say that it's HTML.
And then I write all of my fancy HTML, and I get syntax highlighting inside of markdown because markdown knows this is a code block.
I'm gonna I'm gonna highlight it as HTML.
And then so, you know, you do 3 back ticks, and then you write HTML, and that's that's the language identifier.
Chris
00:29:45 – 00:29:46
Okay.
Aaron
00:29:46 – 00:30:22
What I can do after that is do a plus sign and say literal, or I can do a plus sign and say, I think the other one is like blade.
And my markdown rendering engine will either put that HTML literally in there or it will run blade render over that code block and input it.
And so that way I have I have an escape hatch that's like, oh, shoot.
I'm about to write some indented, you know, blade or I I need this blade component to run or whatever.
So I just open a code block and say, this is, like, literally blade or, like, parses maybe the other word.
Aaron
00:30:22 – 00:30:30
Parses this as as blade, and it it does it.
And it doesn't put the code block in, obviously.
It puts the contents of that code block in.
Chris
00:30:30 – 00:31:03
Yeah.
That's a great solution.
I feel like the I've gone the opposite direction where my files are blade files, and then I have, like, an x markdown custom component, and it's it's not it's not perfect.
I like Mhmm.
I like being able to mix, like, a full, like, I I I like being able to just fully hop out of the markdown context
Aaron
00:31:03 – 00:31:03
Yeah.
Chris
00:31:03 – 00:31:20
As many times as I need to and just, like, write full blade views, But, you know, I've been able to sort of trick the IDE into understanding those markdown syntax, but it's not it's not ideal.
Yeah.
You know, I like I I can see the benefit of doing it the other way around.
Aaron
00:31:20 – 00:31:27
Mhmm.
Yeah.
I like I like doing it the other way around because PHP storms markdown editors is pretty good.
Chris
00:31:27 – 00:31:28
Yeah.
It's great.
Aaron
00:31:28 – 00:31:33
And it's code highlighting within a markdown code block is pretty good.
Chris
00:31:33 – 00:31:33
And
Aaron
00:31:33 – 00:32:05
so I feel like I get the best of both worlds there.
And then whenever I render an article, it it renders inside of, like, a proper, you know, blade layout.
And so for the ancillary stuff, I just you know, I throw all of my blade all around, you know, like, the the table of contents I render with, like, alpine and blade and stuff.
But, like, the actual content, it just takes the markdown renders it and plops it in.
And then I do all the framing in, like, real full on blade layout file.
Chris
00:32:06 – 00:32:11
Now do you do much with front matter, or do you just kinda leave the title and that's it?
Aaron
00:32:11 – 00:32:29
A little bit.
Yeah.
So let me open it now so I can tell you which with front matter, I have recently you know, it runs that, sync articles command.
And so if we open yeah.
It's not very much, which is good.
Aaron
00:32:30 – 00:32:47
I have an ID, which is just a UUID that I generate with Raycast.
So I just open Raycast and I type UUID, hit enter, and that becomes unique.
Yeah.
That becomes the the unique, ID for this file.
That's what makes it, you know, this idempotent.
Aaron
00:32:47 – 00:33:04
I don't base it on the path or title or anything like that.
So I have a UUID as the ID.
This is all in the markdown.
Title, date, description, and then an unimplemented tags list.
So, like, I'll I'll tag the articles, but I haven't I haven't actually done anything with that.
Aaron
00:33:04 – 00:33:22
But I do tag it as, like, Laravel or personal or something like that.
Sure.
But that's it.
The path is based on the location on the file system.
So it's, let's see, resources, views, articles, and then the year 2023, and then the name, like, the actual file name.
Aaron
00:33:22 – 00:33:46
And so I don't have to do you know, there's there's an argument to be made that, like, I may wanna generate I don't know.
I may wanna generate URLs differently, but right now it's just straight to the file system for that.
Mhmm.
And I can optionally this one doesn't have it.
I can optionally specify an OG image tag or an OG image path, but the circle doesn't have a OG image.
Chris
00:33:47 – 00:33:52
Yeah.
Yeah.
I worked well, we talked about this ages ago.
It It's still it never went anywhere, but
Aaron
00:33:53 – 00:33:53
Mhmm.
Chris
00:33:53 – 00:33:58
You know, laravel.com is built using a lot of this same Yeah.
These same basic principles.
Aaron
00:33:59 – 00:34:01
Same hodgepodge system, basically.
Chris
00:34:01 – 00:34:02
Yeah.
Aaron
00:34:02 – 00:34:02
Yeah.
And,
Chris
00:34:02 – 00:34:05
the OG images is definitely a trickier
Aaron
00:34:05 – 00:34:06
thing to
Chris
00:34:06 – 00:34:11
figure out.
I feel like I came up with a decent approach to it, but it is it's a big buy in.
Aaron
00:34:12 – 00:34:15
And it requires a service or a server or something.
Yeah.
You need
Chris
00:34:15 – 00:34:17
a node process to build on.
Aaron
00:34:17 – 00:34:28
Yeah.
Yeah.
That's one of the things I'm hoping to solve with this unnamed well, it's named, but I'm not sharing the name.
This unnamed, you know, Laravel static site thing is, like, best practices like OG images, that kind of stuff.
Chris
00:34:28 – 00:34:39
Yeah.
Yeah.
Yeah.
That's cool.
One thing that, we just did so, you know, I I I implemented the, the verb stocks a couple like, a month ago or whatever.
Chris
00:34:39 – 00:35:27
And one thing one thing that I really wanted to see happen was, and I and I basically just shamelessly stole this from Caleb with the LiveWire docs, like, the idea of just having markdown files in the main project that, like, when you're contributing a feature or updating a feature, you can also just, like, include the documentation in your Yes.
Your PR.
I think that's really nice.
And one thing that he did that I I approached a little differently, but I thought it was an interesting decision was instead of having, like, front matter in the individual docs files, Mhmm.
He had, like, a single he has a single, I think, navigation dot MD file Yep.
Chris
00:35:27 – 00:35:35
That is basically just, like, an empty markdown file that's all front matter.
Mhmm.
I opted to just have a navigation.json file.
Aaron
00:35:35 – 00:35:36
Yep.
Chris
00:35:37 – 00:36:06
And I think that maybe the difference is for docs, that feels like a better trade off rather than having to, like, crawl the markdown files and build, like, the navigation from the front matter.
Yeah.
And it gives you a little bit more control over, like, you know, this this, file is gonna be called, you know, quick start or whatever, but, like, the path might be, like, getting started or something like that.
Like, you can change those things.
Aaron
00:36:08 – 00:36:34
Yeah.
For the, I need to actually update all of this.
But for, like, the sidecar and the air drop and all these open source repos that I have worked on, they're all pulled on to the hammerstone.dev website, which is I need to pull that onto my personal website.
But they use a, a system, you know, that I obviously wrote from scratch, like everybody else does.
And it uses a similar idea.
Aaron
00:36:34 – 00:37:01
It uses a manifest dot JSON.
And so all of the docs sit alongside the code, which has been helpful because people do make pull requests and they update both the docs and the code.
But the manifest.json just dictates, like, where the files are, what their pretty names are, how the sidebar should kinda look.
Like, this group has a header of, like, you know, Lambda or, you know, deploying to whatever.
Chris
00:37:01 – 00:37:02
Yep.
Aaron
00:37:02 – 00:37:26
And so there, I can just it's really nice when you've got 50 docs pages to have 1 it's kinda like your routes, you know, your web that PHP routes.
Like, you wanna just go one place and be like, alright, I gotta move some docs around.
Let me do that instead of being like f.
I gotta open all these files and change, you know, this dashed two words to a more clever one word that I came up with and that's a real pain.
So, yeah, I like the navigation.
Aaron
00:37:26 – 00:37:31
Json, manifest.
Json for specifically for docs.
I find that really helpful.
Chris
00:37:31 – 00:37:43
Yeah.
And I mean, even worse would be, like, you have to go in and you have to change the slug, and then you also have to change the, like, group ID and, like, subgroup ID or something like that across 30 files.
Yeah.
Aaron
00:37:43 – 00:37:46
Nah.
I'm not doing that.
Too old for that.
Yeah.
Chris
00:37:46 – 00:37:58
Yeah.
I think I mean so okay.
Here's here's the real question.
Like Uh-oh.
I I I I totally see the, like, oh, I figure out a good way to do this.
Chris
00:37:58 – 00:38:00
I wanna turn it into a nice package for people.
Aaron
00:38:01 – 00:38:03
Yeah.
We've all been bitten by that, haven't we?
Chris
00:38:03 – 00:38:11
Is anybody gonna use it?
Right?
Because the whole point Yeah.
Of a personal website is, well, I'm gonna do it my way.
Right.
Aaron
00:38:11 – 00:38:31
Yeah.
Exactly.
So I hope so.
I think so.
So the the thesis that I'm working with is everyone wants to do it their way, but I can I can give you a skeleton that can let you do it your way a lot faster and a lot better?
Aaron
00:38:31 – 00:39:15
And so then, you know, my my theory is if I if I do a lot of the heavy lifting of alright.
I'm gonna set you up to write markdown extensions, and I'm gonna ship, you know, with a Mailchimp and a ConvertKit embed ready to go, and then you can just kinda tweak it however you want, and you can put it you can put it wherever you want, that kind of stuff.
I'm gonna ship with, OG an OG image generator that you can then you can then muck around with.
Right?
I think that's gonna be compelling enough to people for people to, like, download it, try it, and hopefully hopefully enjoy the authoring experience that they get to authoring faster.
Aaron
00:39:15 – 00:39:35
I think there's always gonna be a subset of people that say they're updating their personal website because they wanna write, but really don't wanna write at all.
And, like, those people, I'm fine.
I'm fine with them tinkering.
Like, if your goal is to tinker, just tinker.
Like, don't don't lie to really this year, 2024, I really wanna start writing.
Aaron
00:39:35 – 00:39:53
Like, I don't know.
I think writing I think publishing obviously is is good for your career, but if you just wanna tinker, just go tinker.
And so I think there will be a subset of if you just wanna tinker, just go tinker.
And so I think there will be a subset, you know, just yeah.
Lots of people use static site generators, so I think there will be a subset of people that are like, I use Laravel.
Aaron
00:39:53 – 00:40:02
I wanna use Laravel, but I wanna have a site that I can deploy to GitHub pages based off of Laravel.
And that that's what I'm hoping this will fill.
Chris
00:40:02 – 00:40:06
Oh, okay.
So you're talking about going full static site generation?
Aaron
00:40:06 – 00:40:07
I think so.
Chris
00:40:07 – 00:40:09
Yeah.
Okay.
Interesting.
Aaron
00:40:09 – 00:40:18
Yeah.
It's gonna be it's gonna be the dealer's choice.
Like, you could do it my way or you could do it full on generated.
Chris
00:40:18 – 00:40:32
There could be a full build.
Yeah.
Interesting.
What have you have you come up with a good approach to, like, images in your articles?
So I feel like that's that's another thing that I keep on finding I wanna
Aaron
00:40:32 – 00:40:33
Yeah.
Chris
00:40:33 – 00:40:43
Like, I wish I wish that I had the authoring experience of, like, a GitHub gist.
Right?
I just wanna drag an image or a video file into my markdown
Aaron
00:40:44 – 00:40:45
and just
Chris
00:40:45 – 00:40:56
have it work.
Yeah.
And, obviously, I can't do that in my IDE.
Right.
And it's not that hard, but it's it definitely is a a point of friction.
Chris
00:40:56 – 00:41:03
Like, I don't include images in these as much as I probably could Yeah.
Just because it's a bit of a pain.
Any thought about that now?
Aaron
00:41:04 – 00:41:36
Yeah.
I have a couple solutions for that, and then I have one that I think I'm aiming for.
So my current solutions are one is I walk the markdown tree looking for images and update the URLs to be, you know, Vapor does this thing where it gives you, like, this cloud front front to distribution URLs.
You kinda have to use their asset helper.
And so I just walk the markdown tree looking for images, and I run the asset helper over it, and it, like, makes it right.
Aaron
00:41:36 – 00:41:42
The other is I have a route in web.php that is /asset/star.
Chris
00:41:44 – 00:41:45
Yep.
Aaron
00:41:45 – 00:41:53
And anything that goes to /asset/star gets redirected to the asset helper with the trailing wildcard.
Chris
00:41:54 – 00:41:54
Mhmm.
Aaron
00:41:54 – 00:42:25
And so that's helpful for me if I'm like let's say I'm linking to somewhere.
So, like, when I set up on Twitter, there's a way that you can set up, like, you have products on on your Twitter profile.
And so I set up screencasting.com as a product and it needed a URL for an image.
And so there, I just link link to, you know, screencasting.com/asset/logo.png.
And then on the server, it redirects to, like, the long uuid.cloudfront.whateverwhatever.
Aaron
00:42:27 – 00:43:09
So those are the 2 solutions to, like, one is you walk the document and you change the URLs.
The other is you just have a really stable URL that actually does a redirect.
I think for this solution that I'm working on, there will be and I think I'm gonna call it airlift because I have air drop, but I think there will be a a corresponding package called airlift that takes your public assets and puts it into s 3 so that you can just, like, you can just reference your images, like, with the root of your website being the root.
And then Yeah.
The markdown on the other side comes out to it references the s 3 bucket.
Aaron
00:43:09 – 00:43:17
Or if you wanna put a vanity name in front of that, you can.
But basically, I'm gonna airlift your assets out and put them on s 3 for you.
Chris
00:43:17 – 00:43:21
Yeah.
That's cool.
I like that.
I like the name too.
Aaron
00:43:21 – 00:43:23
That's a good name.
Right?
Chris
00:43:23 – 00:43:51
Yeah.
Yeah.
I mean, and even, like, you may I don't know if you can pull it off, but you may be able to because, like, at least with PhpStorm, you can you can write one of those helper files that says, like, when you're auto completing this property, like, it's a file name in this path.
So you might even be able to, like, get some ID support if you publish one of those files with the package, which would be kinda cool.
Aaron
00:43:51 – 00:43:54
Interesting.
Yeah.
I didn't know that.
That's cool.
Chris
00:43:54 – 00:44:16
Awesome.
We do that with, like, you know, we do we're we're working on a a Stripe feature that's got a lot of snapshot tests in it.
Mhmm.
And, like, there's just, like, 30, 40 snapshot files.
That not snapshot test is not right, but it's just, like, we've basically snapshotted webhook payloads from a
Aaron
00:44:16 – 00:44:17
Yeah.
Chris
00:44:17 – 00:44:31
Like, a manual test run, and and we build a test around those.
And, yeah.
It's just, like, a nice quality of life thing to just have, like, you know, this arrow stripe snapshot, and then it just auto completes from there.
Aaron
00:44:31 – 00:44:32
Yeah.
That's
Chris
00:44:32 – 00:44:45
cool.
It's a it's definitely a cool little feature.
Okay.
So what, are there any other, like, things that you feel, like, really need to be solved for this Yeah.
To be viable?
Aaron
00:44:46 – 00:45:17
I think I think deploys need to be a single command.
So, like, I think where it breaks down is people are like, oh, I'm gonna build, you know, my Gatsby site, and then I gotta figure out how to get it on Cloudflare pages, how do I get it on GitHub pages, how do I get it on Netlify.
So every one of those is gonna have a first party driver that's like, I just deploy it to, you know, GitHub pages.
So it's just like artisan deploy colon GitHub or whatever.
Chris
00:45:18 – 00:45:18
Sure.
Aaron
00:45:18 – 00:45:36
I think that's 1.
And then based on the providers, it's also going to write it's also going to write Edge, if it has Edge.
It's gonna write Edge middleware to do redirects.
And so that's another one where people are like, alright.
I got my static site.
Aaron
00:45:36 – 00:45:38
Now how do I do a redirect?
And you're like
Chris
00:45:38 – 00:45:39
Right.
Aaron
00:45:39 – 00:45:59
Oh, no.
And, like, you could use meta refresh or whatever on your HTML.
Like, that's a last last resort, but that's kinda grim.
But with, you know, Vercel and Cloudflare and Netlify, you could just write an edge function that looks at the incoming and maps it and redirects to the outgoing.
And so, like, if you go to I think it's aaronfrancis.com.
Aaron
00:45:59 – 00:46:36
Aaronfrancis.com/ twitter, that takes me yep.
That takes you to my Twitter.
And so Right.
There's vanity stuff like that, but there's also, like, I changed some URLs to old blog posts, and I need to redirect those.
And so there will be a way, as you're deploying redirects are just gonna work out of the box, and whether it's fancy with an edge function or lame with an HTML file with a header that says refresh, that kinda depends on the platform, but that's one of those things where it's like the last mile of static sites is kinda, like, figure it out yourself.
Chris
00:46:36 – 00:46:50
Right.
Yeah.
I mean, that's very cool though to be able to just, like, have a a driver based approach that's just like, okay.
For this, we can write just a a edge function that's just a template where you dump it Yeah.
A bunch of the the from and to.
Chris
00:46:51 – 00:47:00
And then if you are on a platform that doesn't support it, you know, we're gonna write an HTML file at least that has a lot of refresh.
Yeah.
Yeah.
Yeah.
That's neat.
Chris
00:47:01 – 00:47:37
I was gonna say, yeah.
You know, I feel like one thing that I don't see talked about a whole lot in the Laravel world or at least the the the world of Laravel that I'm in is SEO.
You know?
Like I don't feel like there are tons of like really established patterns for SEO in Laravel, and I don't know, this is coming I definitely came up in the era of, like, doing stuff for SEO that in hindsight was maybe a questionable.
Aaron
00:47:37 – 00:47:39
You were gray hat.
Chris
00:47:41 – 00:47:44
But back, you know, back in the early 2000,
Aaron
00:47:44 – 00:47:46
like Sure.
Sure.
Sure.
Chris
00:47:46 – 00:47:52
It's constant.
Yeah.
Yeah.
A gray hat was not necessarily even a thing.
It was just like, oh, yeah.
Chris
00:47:53 – 00:47:53
Sure.
We'll buy
Aaron
00:47:54 – 00:47:55
Sure.
I have a private blog network.
Chris
00:47:55 – 00:48:05
1,000.
1,000 Domains and and and also pay for a 1,000 independent IP addresses and then, you know, connect them all together.
Aaron
00:48:05 – 00:48:10
What could be wrong with that?
Yeah.
Exactly.
That seems totally above board.
Chris
00:48:12 – 00:48:14
It worked for a long time.
I mean, I still do.
Aaron
00:48:14 – 00:48:16
That's a different metric though.
Chris
00:48:17 – 00:48:17
Yeah.
Aaron
00:48:17 – 00:48:19
It it worked as a different metric.
Chris
00:48:20 – 00:48:32
My business partner used to put, like, he knew I had yelled at him so many times, but he'd just, like, sneak it in.
He'd, like, put text in white at the bottom of the page.
Brutal.
Aaron
00:48:32 – 00:48:33
It's like Yeah.
Chris
00:48:33 – 00:48:35
Like, you gotta stop this.
Come on.
Yeah.
Aaron
00:48:35 – 00:48:37
That's full on black hat.
Yeah.
Chris
00:48:37 – 00:49:12
Yeah.
But, I feel like SEO and HTTP caching are 2 areas that, like, especially for a static site solution where, you know, the the nature of the content is gonna be, like, a more, like, public facing content website.
Yep.
You know, those things really matter, and I I feel like there are a lot of opportunities for, you know, just better better systems to make it easier to do the right things in those places.
Yep.
Chris
00:49:13 – 00:49:17
How much are you thinking about those two pieces for this this thing you're working on?
Aaron
00:49:18 – 00:49:33
Yeah.
I I mean, a little bit.
I think a huge part of SEO that we don't, you know, all of us don't talk about very much is having it be super duper fast and basically static, you know, you get that for free.
Chris
00:49:34 – 00:49:34
Sure.
Aaron
00:49:34 – 00:50:00
You know, anyone that's running their marketing the marketing side of their website on something like inertia JS, I think is is a little bit, misguided.
If you're using if you're using LiveWire for your marketing site, that's great because, you know, to the search engine, that's just HTML.
But, you know, Google can parse JavaScript now, so it's not, you know, it's not stupid.
I just think Sort of.
Exactly.
Aaron
00:50:01 – 00:50:09
It's not stupid, but it's not very good at it.
Yeah.
Yes.
Even even inertia has its first party server side rendering stuff.
Right.
Aaron
00:50:09 – 00:50:41
And so, yeah, I'm thinking I'm thinking about that a little bit.
I'm not I'm not going down the SEO rabbit hole, but because it is, you know, standard Laravel, you'll have full control over your meta description evolves.
But having it be fast and well structured with the appropriate cache headers, you know, is gonna get a lot of stuff for free.
Chris
00:50:41 – 00:50:49
Yeah.
Exactly.
Yeah.
And, I mean, with static sites, how much control do you have over cache headers?
Like, I don't know that you have a lot.
Aaron
00:50:49 – 00:50:50
Pretty platform specific.
Chris
00:50:50 – 00:50:51
Yeah.
Yeah.
Aaron
00:50:51 – 00:51:01
Yeah.
So for something like that.
Cloudflare, you could say you could say cache everything everywhere all the time.
Mhmm.
And that might be like, that's what I do on my site.
Aaron
00:51:01 – 00:51:13
And then on Deploy, I just tell Cloudflare, hey.
Blow away the cache.
We're gonna start over.
And so there are options there are options like that.
And that's really nice for me because I don't have to think about, what's the etag on this?
Aaron
00:51:13 – 00:51:29
Like, has this when was this content last updated?
It's just like, I mean, with with no cash whatsoever, it's still pretty fast.
And so I don't mind blowing it away every time and telling Cloudflare, alright.
Build it back up.
Mine is still care about that.
Chris
00:51:30 – 00:51:55
Yeah.
I I definitely think that they're I mean, and this is something we have an internal tool that we use for some of this stuff that I you know, one of these days, I wanna open source, but, like yeah, just generating e tags, like, returning, you know, content not changed, responses.
Yeah.
You know, doing caching, stale wall revalidate, like all that stuff.
Yeah.
Chris
00:51:55 – 00:52:16
There's not, I mean, set aside Laravel, there's not I don't feel like there's a single canonical resource for, like, HTTP caching headers anywhere.
You know?
Like, even understanding the difference between, like, the cache control header and, like, the last modified header and, like Yeah.
Which one do you use?
Header and, like, the last modified header and, like Yeah.
Chris
00:52:16 – 00:52:18
Which one do you use?
And Cloudflare doesn't even support
Aaron
00:52:18 – 00:52:18
stale while revalidate.
Chris
00:52:23 – 00:52:23
Okay.
Aaron
00:52:23 – 00:52:31
Yeah.
Which sucks.
Like, they've they've said, you know, for a long time they're gonna support it, but there's no there's no SWR with Cloudflare.
Chris
00:52:32 – 00:52:33
Interesting.
Yeah.
I didn't know that.
Yeah.
Yeah.
Chris
00:52:33 – 00:52:43
We don't use Cloudflare.
I, you know, I use it for some personal stuff, but I Yeah.
I haven't dug very deep into what they what they handle.
Yeah.
Yeah.
Chris
00:52:43 – 00:53:01
That just feels like a thing where, you know, just, like, getting it's it's it really comes down to, like, the DX, like, the ergonomics of it.
Mhmm.
Obviously, there's the there's the education piece of, like, knowing what to do around SEO or knowing what to do around caching.
Mhmm.
Aaron
00:53:01 – 00:53:01
And I
Chris
00:53:01 – 00:53:30
think that's a huge that's a huge piece too, but just like, I don't know, there's not there there are not easy ways right now to do a lot of these things.
And and and, you know, in in our case, like, I know for a while, we would, like, wrap up the response, like, instead of just returning the view, we'd have to, like, grab the view, render it, wrap it in, like, wrap it in a response object, and then set, like, the headers on the response object.
Aaron
00:53:30 – 00:53:30
Yeah.
Chris
00:53:31 – 00:53:41
If you wanted, like, fine grain control over those headers, or else, like, you're doing it at a middleware level, which is fine, but then, you know, it's a little bit more brute force.
Aaron
00:53:41 – 00:53:41
Yep.
Chris
00:53:41 – 00:53:43
Feels like there are a lot of opportunities there.
Aaron
00:53:44 – 00:54:02
Yeah.
Yeah.
And there's one there's one kinda gnarly gotcha with LiveWire the way that it does something related to the back button.
Unless you Oh, yeah.
Unless you disable some Livewire feature, it forces, like, no cache headers on everything.
Chris
00:54:02 – 00:54:03
Oh, interesting.
Aaron
00:54:03 – 00:54:09
Because other otherwise, it, like, the back button remembers the wrong thing or displays the wrong thing or something.
Chris
00:54:10 – 00:54:10
Yeah.
Aaron
00:54:10 – 00:54:28
So I ran I ran into that one at one point too.
So, yeah, there's there's a lot there's a whole lot around caching that we don't super talk about and that frankly, I don't really understand, which is why I really kinda like my my crude blunt force, like, cash it all, blow it all away, cash it all, blow it all away.
Chris
00:54:28 – 00:54:32
Yeah.
And for a static site generator, that's, like, a super appropriate
Aaron
00:54:33 – 00:54:33
Yeah.
Cake.
Chris
00:54:33 – 00:54:47
You know?
That's, like, a really nice that's an that's a nice approach.
Yeah.
Yeah.
I I years ago, I worked on the LiveWire, like, history state stuff.
Chris
00:54:47 – 00:54:50
Oh, yeah.
Here you go.
A dark, dark
Aaron
00:54:51 – 00:54:51
Yeah.
Chris
00:54:51 – 00:54:54
Like, horrible place to be.
Aaron
00:54:54 – 00:55:02
Yeah.
Because it, like, sometimes doesn't contact the server.
It just pulls the page right out of the cache or something.
And yeah.
It's it's a mess.
Aaron
00:55:02 – 00:55:02
Right?
Chris
00:55:03 – 00:56:12
There's I mean, in theory, it's it feels pretty straightforward, but there are so many browser specific gotchas, and there's just a bunch of, like, storage limitations and, like, you need to make sure that you're pushing and popping things on and off the state in a way that feels appropriate.
Because, you know, I I still this is this is the thing that I'd still love to see Livewire do is, like, you know, you can do the query string based routing, but I think that you should be able to do just full URL routing with LiveWire where it actually just changes the URL, but yeah, we spent probably 2 weeks, working on it Each.
And built the whole feature, and it was great, but it was just, like, you know, Caleb was not confident enough in it to be, like, yeah, this is this is good to go.
And it was It's You know, I hate these moments in programming where you're just like, I know this is not good enough, but I don't know what, like, I don't know what would need to happen for me to feel comfortable about it.
You know?
Aaron
00:56:12 – 00:56:14
Yeah.
I know.
I hate that too.
Chris
00:56:15 – 00:56:28
Yeah.
Well, is there we're we're right at an hour.
Is there anything else that, you were thinking about with this, with this secret project of yours?
I'm trying to think if there's anything else.
Any points to talk to you
Aaron
00:56:28 – 00:56:30
if I have any secret projects.
Chris
00:56:33 – 00:57:02
I definitely feel like, you know, when I was setting up my my personal website, just building it in Laravel felt mostly fine, but I bumped into all this stuff.
I definitely Yeah.
I definitely feel like having a really good and and I would love to see this be a, you know, a package that you could pull into anything, like Mhmm.
Really good markdown support that, like Yeah.
Handles a lot of these cases and just has a bunch of, like, really best practices built in.
Chris
00:57:02 – 00:57:07
I love the idea of having those, like, interpreted code blocks.
I think that's pretty neat.
Aaron
00:57:07 – 00:57:08
Mhmm.
Chris
00:57:09 – 00:57:26
Yeah.
That's very cool.
And I mean, I don't know, just getting markdown to output, like, decent tailwind Yeah.
Classes, It's kind of a pain, you know, going back to the the way that the common mark class is configured.
It's like
Aaron
00:57:26 – 00:57:26
Yeah.
Chris
00:57:26 – 00:57:28
Oh, I have to register all these, like,
Aaron
00:57:28 – 00:57:31
custom stuff.
So much freaking crap.
Yeah.
Chris
00:57:31 – 00:57:43
Yeah.
And it's all just, like, an an array with, like, magic keys everywhere.
Yeah.
It's yeah.
So, like, being able to just ship, like, a Tailwind plugin that just Yeah.
Chris
00:57:43 – 00:57:50
Renders everything Exactly.
Is like Tailwind pros, but, like, you know, because you need a little more than just pros.
Aaron
00:57:50 – 00:57:56
Yeah.
You need you need to modify pros a little bit.
Yeah.
Yeah.
So code blocks is gonna be a big one.
Aaron
00:57:57 – 00:58:08
Having tailwind you know, I think there's gonna be, like, a core package, kind of the way that the Laravel framework works.
There's, like, a core Laravel and then there's a starter like, there's the Laravel framework where you start Right.
Chris
00:58:08 – 00:58:08
The
Aaron
00:58:08 – 00:58:09
project.
Right?
Right.
Chris
00:58:09 – 00:58:09
So
Aaron
00:58:09 – 00:58:34
I think that's gonna be how it works is there's gonna be, like, a core package that does a lot of the heavy lifting, and then there's gonna be a composer create, you know, new project that has, like, tailwind already installed and set up and all of the stuff that actually lives in application land, but I wanna get people started on the right foot, that kind of thing.
Chris
00:58:34 – 00:58:48
Right.
Yeah.
That makes sense.
I feel like that you might even be able to, like, tap into the whole, like, composer new, Right?
The the same way that you start a new Laravel project with just Yeah.
Aaron
00:58:48 – 00:58:58
Yeah.
I think you can.
I think you can just register it somewhere with Packagist to say, like, this is a this is a creator starter kit project template, whatever it is.
Chris
00:58:58 – 00:59:02
Yeah.
That's very cool.
Sweet.
Anything else?
Aaron
00:59:02 – 00:59:04
So stay tuned for that.
Chris
00:59:06 – 00:59:12
Anything else fun that you've been up to that just I mean, is is is there anything other than babies?
Aaron
00:59:13 – 00:59:22
Yeah.
That's the tough part is, you know, I am on paternity leave right now, so I do have less planet scale work to do, but I also have 2 newborns, so I have a lot more
Chris
00:59:23 – 00:59:23
Yeah.
Aaron
00:59:24 – 00:59:28
Home life to do.
I've been playing with Pulse quite a bit and Pulse is
Chris
00:59:28 – 00:59:30
very, very good.
Yeah, it seems
Aaron
00:59:30 – 00:59:40
very good.
I started working on a community site and then got just totally pwned by babies and Matt Sauer came along and was like, hey, what if I did some of it?
And he's just done so much of it, which is awesome.
Chris
00:59:41 – 00:59:41
Awesome.
Aaron
00:59:42 – 00:59:55
But yeah.
Doing that, recording some videos.
I wanna record a video on this this markdown rendering stuff, and, I'm building out a Fathom Analytics Pulse card, which I think is gonna be kinda fun.
Chris
00:59:56 – 00:59:56
Yeah.
Aaron
00:59:56 – 01:00:06
So, yeah.
Just doing, like one of the great things about paternity is you can just kinda just do random crap because
Chris
01:00:06 – 01:00:06
Right.
Aaron
01:00:07 – 01:00:22
You don't have to see these long running projects through.
Like at work, I don't have to be like, All right, let me plan my next 6 weeks of content and do my research.
I can just sit down and be like, alright.
I got an hour.
I got an hour and maybe actually I only have 30 minutes and if because someone might wake up here in a second.
Aaron
01:00:23 – 01:00:25
So what do I wanna do?
And that's
Chris
01:00:25 – 01:00:26
kinda funny.
Tinker with something.
Aaron
01:00:27 – 01:00:31
Yeah.
It's a very, it's a very free flowing creativity kinda time.
Chris
01:00:31 – 01:00:41
Yeah.
For sure.
Yeah.
We need to catch up on verbs too.
I I still feel like I need to convince you that, event sourcing is is, a good path for some Hey.
Chris
01:00:41 – 01:00:42
Some things.
Aaron
01:00:42 – 01:00:52
I'm I'm still you give me you give me a you give me, like, a solid, setup and use case.
I'm still willing to give it a honest go.
So yeah.
We we do need to do that.
Chris
01:00:53 – 01:01:00
No.
Daniel and I were talking about we'll we'll follow-up later, but, that's been a fun it's been a fun it's been a fun thing to to been working on.
Aaron
01:01:01 – 01:01:05
It seems, it seems to have been well received.
Do you feel that that's the case?
Chris
01:01:06 – 01:01:24
Yeah.
I mean, I think, you know, we're still we're still very much an alpha, and I think there are a lot of there are a lot of things that are just, like, we're trying to figure out, because, you know, the the the whole vibe of verbs is just, like, the ergonomics have to be perfect.
Right?
Aaron
01:01:24 – 01:01:25
Like Correct.
Chris
01:01:25 – 01:01:31
We'll we'll write some horrible, terrible code so that, like, the the So
Aaron
01:01:31 – 01:01:32
that I don't have to.
Chris
01:01:32 – 01:01:48
API is great.
Yes.
And, you know, there are a few places, especially around testing, where, like, we're, you know, we're very aware that it's not where it needs to be yet.
Mhmm.
So right now, there's just like a handful of, like, true heads in there, and it's that's been really fun though to have, like But
Aaron
01:01:48 – 01:01:53
you you have a few people that are, like Yeah.
We've got to it.
They're little like, a discord or something.
Chris
01:01:54 – 01:02:08
Yeah.
Yeah.
Love it.
And, you know, people are coming in with real questions and working on real little, you know, either, like, test projects or or any you know, I know that Daniel's working on a a production thing in verbs already.
So Cool.
Chris
01:02:08 – 01:02:20
I I think it's it's pretty much good to go.
It's mostly just, like, the main API is there, but all the little things around that, we're still kinda landing on.
You know?
But yeah.
No.
Chris
01:02:20 – 01:02:31
That's been great.
Awesome.
Alright.
Well, thank you for, hanging out.
I feel like, we've I don't know that we've solved the problem of personal websites, but I
Aaron
01:02:31 – 01:02:32
I think that, like,
Chris
01:02:35 – 01:02:38
you know, we've touched on all the major major points at least.
Aaron
01:02:38 – 01:02:43
And we had some fun, which is which is maybe the real journey is the fun we had along the way.
Right?
Chris
01:02:43 – 01:02:45
There you go.
Yeah.
Something like that.
Aaron
01:02:45 – 01:02:46
Something like that.
Chris
01:02:47 – 01:02:49
Alright.
Sweet.
Well, thanks for hanging out.
Aaron
01:02:49 – 01:02:50
Yep.
See you next
Chris
01:02:57 – 01:02:57
time.