Watch Bryant create a system that generates custom landing pages for target companies by scraping their websites and using AI to craft personalized sales pitches. With a mix of Directus hooks, FireCrawl for content scraping, and the Anthropic API for copywriting, he builds a complete workflow that transforms company data into engaging sales pages for his fictional developer seat cushion business.
Speaker 0: Alright. Alright. Welcome back to, yet another episode of 100 apps, one hundred hours. I'm your host, Brian Gillespie. And in this episode, we're reaching back into the AI personalization bucket, and we're gonna build some personalized landing pages.
If this is your first time on 100 apps one hundred hours, there are only two rules to the show. We have sixty minutes to plan and build an application, a clone of one of your favorite apps, or some totally random idea. No more, no less. And then number two is use whatever we have at our disposal. Could be past projects, could be AI, could be all sorts of crazy things that we might get into today.
I've got no idea whether we're actually going to be able to, like, push this one across the finish line or not. So that should be exciting for this episode. Alright. So AI personalized landing pages. You know, there's another episode we've done in this season, like, content personalization.
This time around, I wanna get very, very specific and say, hey, I have a target account or a a company that I wanna do business with. I wanna use AI to generate a landing page for them. So let's dive right in. We're gonna put sixty minutes on the clock, and let's go. Here we are.
Alright. So I always like to start these by just discussing what are the features that we actually want out of this. Right? So as far as our functionality, we'll just make this freaking huge. Oh, not that big.
Alright. So as far as the functionality we want out of this, here's how I'm thinking this is actually going to flow. We're going to add an organization to our back end, which is gonna be powered by Directus. And then a the AI is going to scrape the website. We want to use that content to generate and use content found to shift return.
There we go. That's what I needed to generate a personalized landing page for that specific org. Okay? Display that using a front end. That's it.
I would love to be able to do this on the fly, this part of it. Right? But, unfortunately, like, the LLM models are not super fast or well, if you use something like GROC, maybe. But the this step is gonna have to be done asynchronously. So we'll sort through that.
Let's think through, like, our our actual data model now. So let's throw this up on the board. We're gonna have organization. And, honestly, like, I I could have a separate one for pages. You know, we've got, like, the page builder set up inside Directus, which is really nice.
Something that we've showed in previous episodes where I can build a dynamic page based on predefined blocks. In this case, we might just keep it super simple. We've got an organization that I wanna target. Within that, we're gonna have a name. I need a website URL to scrape.
And then the rest of it would be generated. Right? You know, let's call it blocks, I guess, generated blocks. Maybe we got a hero. I wanna have, like, a feature section.
Call to action. Call to action, CTA. Man, I have outgrown my box here. We'll just add that up there. Alright.
So this seems pretty solid, I guess. I what's our plan of attack? Right? What are we going to sell? What are we going to pitch?
You know, what is our organization that we are setting up? Alright. So, as far as what I've got in the can already, I've got a Nuxt application. I've got a direct instance. So if we load up local host 3,000, I should see my Nuxt instance, my Nuxt application, just the same starter I use in all of these.
And if I go to Logos eight zero five five, I should see a blank directus instance. That is not the one that I wanted to see. Let's control some of these Docker containers here, and then we'll fire this back up to see if we get what we want. Boop boop boop. Should be a blank instance.
Great. Okay. Alright. So now I'm gonna log into this blank Directus instance. Directus is gonna give me all the back end functionality that I want and or need.
And you could see it is totally blank. Right? So let's attack this from the back end perspective first, and then we'll switch to the front end, and then we'll switch to the back end, and we'll switch back and forth and back and forth until we all get confused with how many tabs I have open. Alright. Create a new collection.
So let's create a new collection for our organizations. Right? As far as table names go, I prefer plural. Some people prefer singular. Totally up to you.
We're just gonna add some of these specific default fields that Directus makes available to us. Like, hey. Is this published? Is there a sort order to this? Obviously, date created here will be populated with a timestamp of when this record gets created.
Great. So now we have an organization. I'm gonna make this look very pretty. We will call it we'll search for maybe business. Forget I'm talking to myself here.
I was about to ask you a question of which icon to use, but, still just talking to myself. Alright. So as far as our first field, right, we're going to add a the name of the organization. Pretty simple. Let's keep editing.
I can make this shorter. We'll just go half width. So I am controlling the field, like the the actual form that we'll be interacting with as well as my data model and my APIs. So next, we will save this and let's add a website or URL. Let's just call it website.
And what are we gonna do here? Let's go to advanced field creation. We could see that this is allowing a null value, but let's make sure that we set that to required. So when I fill out this form, it is going to make me input that. Now if I keep this as nullable, that means we could still potentially pass that value into the database as null, using the API.
I could turn that off if I wanted to. I could also make sure this is unique as well, so that we don't generate this a million times. And for the display, we'll just show the raw value. Right? Is that it?
Let's add a little icon just to make this a little fancy. This will be a link. Great. And now we have a website. And let's go ahead and make name required as well.
We're gonna fill both of those things out. Boom. Amazing. I can go in. I can now add a name like Directus and a website, Directus.io.
Save. Great. Notice that perfect little icon right there. It looks great. Right?
I can even oh, no. I was gonna say I could point to it. I can point to it. There it is. Alright.
So now we have this, like, data model. It's amazing. There's two fields here. This is really underwhelming as Bryant. Alright.
So we've got an organization in our back end. Let's switch round to the front end, and let's start, like, fleshing something out. And this is where I will say, like, POC generation, AI has got an incredibly great for this, especially with, like, UI libraries like Shad CN and Tailwind for styling. It's gotten really good at creating components and things like that. So, what are we going to what are we gonna generate here?
Like, what are we pitching? What are we what are we selling? Coffee mugs. Let's do something super developy developer ish. Maybe like a a seat cushion.
Maybe we're gonna sell seat cushions. I'm hopefully, I look younger than I feel, but I've got three little girls. I've got a back that aches every day when I wake up. So maybe that's what we'll do here. We're gonna generate some seat cushions.
Alright. So, when I think of the front end here, let's create a page. So let's create a new route for the org. Organization. I'm gonna wrap this in brackets there.
Great. We'll do v base setup, script setup. Let's change that to length. Yes. And this is giant text, so that's a good thing.
Alright. We got an organization. We're gonna fetch that organizational data. And behind the scenes, I've used this in so many videos. I'd never take the time to explain it.
Basically, I'm using the Directus SDK. I've just got a quick little plug in as far as Nuxt goes. We're gonna pull the direct as URL from the configuration. We're gonna create a really simple direct as client, and we're gonna provide that to the Nuxt application. So the first time this application spins up or, you know, when it loads, it creates that instance for us and makes it globally available through something like this where we could say, Directus use Nuxt app.
The other thing that I'm gonna do here, I'm gonna import read items from the Directus SDK and then we're gonna fetch this data. So we'll say data, that's gonna be organization. No thank you AI. Wait. We're gonna use the async data composable from Nuxt, just a handy little helper for caching.
We're gonna call this organization organization. We're gonna get that organization from our routes, route.params.organization. No. We don't want that. We're going to do it this way, route.params.organization.
We're gonna do direct us dot request. Yes. Direct us request. Read items, and we're just gonna wrap that. And do I have some nice formatting?
Great. We got some formatting. Okay. So what are we doing here? We're looking for a slug.
We don't really have a slug set up yet. So let's just do an ID. And maybe we do wanna set up a slug, maybe we don't. Route dot params ID. You'll notice this filter syntax here.
Directus has a ton of different filter rules that I can use to create deeply nested or crazy queries where I can fetch everything I need in a single API call. And then I'm just gonna go in and log this out on the page. Is this possible? Let's go into Directus and just make this process easy for me as well. There is a button links option here which is just presentational.
And we're gonna say view on website. Give it a label, arrow up link. Do it is there like an external link? Arrow. Let's just go arrow caret ray.
Okay. And we're gonna say HTTP, we want the URL local host 3,000 is what we're running on. And then we're gonna run this at the ID. Great. Well, it's safe.
Now I should get a button on this page where I can view on the website. And lo and behold, it looks amazing. This is the most beautiful page ever. We're just gonna go back in and edit our permissions. So by default, Directus keeps everything secure, keeps a tight lid on everything.
So this public policy that we have doesn't have any access to our data. So let's go in and add read access for organizations and let's let's set files as well in case we decide to upload some pictures of our amazing seat cushions that we're going to sell. And now if I refresh the page, we could see, great, I have a name, I have a website. Alright. That's kinda underwhelming.
Not great. So let's have it design. Let's retray, here. We are going to create I'm gonna use Claude's sonnet, and let's create a landing page. You are let's let's back up a minute.
What do we want our landing page to look like actually? Right? So we probably got like a hero. We've got a features for our seat cushions, seat cushions, hero section. And then we've got like a like a buy button.
Buy button. Buy now. CTA. Alright. So that's gonna be the structure for our page.
Here we go. We are going to flesh this out. You know, we probably want to you are are we gonna, like, one shot this? Let's see. Well, if I do this, you are a expert I I don't think you really need to do this because it's picking up up whatever I have, but create a hero section component for a online store that sells seat cushions to developers.
A beautiful, well designed view three component using alright. So one of the features I've been experimenting with in cursor is this documentation feature. This starter has like the Nuxt UI library built into it. Which version am I actually running? Did I upgrade this to the latest one?
Yeah. I'm running the alpha version. So we're gonna use those docs and tell when CSS. We'll see what we come up with here. Let's create a beautiful new component.
You page hero. I don't know I don't know that I have any of these actually. Just you don't use our Nuxt UI components after all. Okay. So we can see what is coming up with hero section.
We got a feature, ergonomic design. Yeah. I'm kinda curious to see what it comes up with as far as, like, the data model around this as well. We'll just go ahead and flush this out for it here while component section, features. Oh, this is running kinda slow.
New collection, blah blah blah, right column. Yeah. It would probably even be easier just to go into, like, Tailwind UI and find some of these components here. They've got some nice ecommerce components. Let's look at it like a hero section.
Alright. Let's just we'll just see what it came up with first and accept this. We'll go back to our organization. We'll insert this component in here. This is our hero section.
Great. Cushion. JPEG. Is there a cushion dot JPEG? Hero section.
Where is this cushion dot jpeg cushion hero dot jpeg. Alright. Let's bring in one of our first AI big guns here. We'll go to replicate, and I'm just gonna use our flux model here. It will create a product image of a futuristic seat cushion for developers if I could actually spell, that'd be dangerous.
Developer's seat cushion, developer's desk chair. I don't think punctuation is hugely important here. Let's see what we come up with. For 6¢ an image. What are we gonna get out of this?
That looks pretty pretty wicked awesome there. Right? So we're gonna download that. Let's dump this into our assets folder, and we'll call it seat cushion dot JPEG, and we'll just update that here. Alright.
So this should be assets, images slash seat cushion. And oh, what have we got here? Something weird is going on. Better comfort for better code. There we go.
Alright. Now we're getting somewhere, except this looks really odd with our price badge. Something's going on there. Let's just comment that out. There we go.
We got our seat cushion. This is great. Alright. Now let's have it designed something else. Right?
Let me just shrink this down just a little bit. Feature alright. So we want this to be our headline. Right? So let's flush this out a little bit more.
This is gonna be our headline. This will be our description. I'm just trying to think through like our what our props are gonna look like for this. Define props, features as a feature. Great.
Learn more, shop now. Better comfort for better code. This is a new collection. Badge. Alright.
So we'll just stick that in our props. Now we got badge, got features. Do we actually want the icons we can. I think I've got the Nux icon library built into this so we could simplify this, like hero icons. There we go.
I don't know what other hero cons we have here. Shopping bag, check circle. There we go. And then we'll, like, flesh this out. Where is that icon at?
Icon. Feature dot icon. Yeah. So we could ditch all of this and make this a little bit cleaner. We'll keep that.
Right? You icon. Name equals feature dot icon. We'll just ditch this, ditch that, clean this up a bit, and we should still have our icons. Great.
And then we're gonna move out features out of here, we'll put that into this. So for now, we'll just say here's our data, our data. We'll drop our features here. Sometimes it is frustrating as I'll get out to properly just navigate using these AI tools. The tab tab tab is it's nice when it works well.
When you have all these extensions included, it does get a little bit messy. Let's check on time. Where is Figma? Thirty seven minutes. Alright.
Better get to it, g. Alright. If I hit refresh, are we actually going to let's call this data, and then we'll go back into our hero section. We'll just wrap all this up into data. There we go.
There we go. Data dot badge, data dot headline, shop now, learn more, data dot features. Okay. So maybe that is a little long as far as a headline. What do we have previously?
Yeah. Alright. Comfort for better code. There we go. Okay.
Now, this is our data. Right? This is our data structure. Maybe we tell this to generate. Alright.
So how are we gonna generate the actual code here? Like, how are we gonna generate the personalization of this specific page? Let's just ditch the code part. There's our website. Looks great.
How are we gonna personalize this? So for that, let's kick off a Directus extension, basically. Basically. Yeah. Nothing basic about it.
So what I'm thinking we'll do here, we'll set up a custom Directus extension so that whenever I am adding a new organization, it will create that data for us. So let's also do this where we'll go in and we'll call this just page data. Page data. Page content. It doesn't really matter what we call it.
I'm just gonna set it to be JSON. That's what we're gonna ask back from the API. Alright. Let's kick off this extension. So I'm inside my Directus directory.
We're probably gonna go into CD extensions within that. And then I'm gonna go n p x create direct us or create dash direct us dash extension latest. And I am going to create a let's do a custom hook. This is generate personalized page, custom landing page, AI landing page. We use TypeScripts.
We'll go ahead and install the dependencies. And one of the things that I've got set up here inside my Docker Compose for this, obviously, like, I'm I'm I'm creating a volume for the extensions here so we could pull those in. But I'm also somewhere in here. I have extensions auto reload set so that whenever we build this extension, Directus is going to look for that and reload this extension or at least it should. So we'll go into CD AI landing page, npm dev.
Alright. So let's actually open this bad boy up and see what we've got here. Items dot create. Okay. So now I'm just quickly going to cheat a bit and pull up the direct to stocks.
Hooks, custom API hooks. So what we're looking for here is after this item is created, and I think the structure for a collection itself is a collection name dot items dot create. This is what we're gonna do. So our filter will look something like the or our action here will look something like this. We don't necessarily need this.
Alright. So we're gonna say organizations dot items dot create, organization created, and this will be async. And what this is going to receive should be alright. We're gonna get the context here. We can see what that context is gonna look like.
That's how we're gonna initiate some services. What does the action receive? Right? The action receives the event name and a callback function that is executed whenever the thing is submitted. Alright.
Extensions guys. Do we have one on hooks? Use hooks to validate phone numbers. Items that create input collection. So we're gonna get the payload, I'm assuming, and the content, item context.
Let's see just kinda what we get here. Extension's changed. Okay. Test httpstest.co. If I check my Docker logs, I cannot import.
Let's just stop and spin up the Docker container one more time. Make sure we're actually getting that. Okay. I could see that extension being initialized. Oh my gosh.
That gets ugly, doesn't it? Alright. Let's try this one more time. We'll delete testco, test Co. Are we seeing any console log?
I'm not seeing any logs here. Async, define hook. Extensions reloaded. Organization oh, duh. You gotta use the right right syntax, Brian.
Frustrating to be under the clock. Testtest.co. Hit save. Okay. So now we're seeing some stuff here.
Great. Alright. There's our holy moly. Alright. So that is our there's the context that we're getting there.
Organization created. There's the payload that we're receiving. And then we're getting the item context. Okay. Great.
Alright. So what we're gonna do, what do we want to actually happen when this is going to pop off? There's a third party tool that we're gonna use for this called FireCrawl that I've been testing. Right? So let's try this.
We're going to add Firecrawl. Js. Alright. So we're gonna go to our extension that we're running. I'm gonna install this library from FireCrawl.
And we're gonna go ahead and one of the other things that I'm gonna do, we're gonna call this the organization's service. We're going to extract that out of the context. Const request. No. It's gonna be the services out of the context, then the item service through the services.
And we're gonna call new item service. Great. And this is gonna give us the ability to update. Right? So we're gonna initialize that service.
We've got that installed. Now let's copy our code here. I'm hoping this is my live API. New FireCrawl app. We need to import that.
Scrape a single web page. Got it. We'll move that down below our item service, and we're gonna get the scrape result. And for now, let's just oh, I can already see the typo happening here. That's gonna be frustrating for me.
And we're gonna say await updated org equals await organizationservice.update.one. Data, does that need to be wrapped in data? I don't know. Scrape content. Alright.
We're gonna return the updated org, and let's wrap this in a try catch as well. Try catch. Console dot error. See if we get some formatting. Nice.
Okay. Let's fire up the dev server for this and cross our fingers. Right? The other thing I need to update here, we're gonna have to go in and figure out which tab has all of my browsers in it. Maybe we just move that to a single browser for now.
And we're gonna add a new field for this. We're gonna call it, scraped result. Scraped result. I don't know what this is gonna be. I'm assuming scraped content.
I'm assuming this is gonna be JSON data that we're gonna get back. I guess I could look and see. Success data. You know, we could also just store the markdown. That might be easier.
Where do we go? Scrape content. Let's delete that. Where does this store the markdown? Scraped.
Scraped content. Alright. So according to FireCrawl, if we do this correctly, we're gonna get something like this. So with the scrape result dot data dot markdown. Fingers crossed.
That's what we're gonna get. We could also just console log that to verify scrape content, scrape result. Alright. Let's go for it and see one last thing that I wanna do here. This is not, using, like, any of our accountability, so do not do this in production.
But we'll just allow the public to create and update all the content on the underlying instance. Great. Love how secure I am being. I'm sure everybody on my team would be thrilled. Alright.
So let's just go to Directus as the example. HTTPS, Directus.io. That's our website. Oh, I've already got directis.io hard coded in there as well, so we're probably gonna want to pick that up out of the payload as well. Can we still see that payload?
No. Let's do this. We'll see the payload.website URL. We'll see if this actually works. Fingers crossed that it does.
Scrape content. Save. What happens on this side of it? Around URL must be a top level domain or valid path. So I'm getting that error there.
It's fine. Should set this up on update or create. Directus.io. Save and stay. Do we see what we get back?
Is this thing still running in the background? What are we doing here? I got no visibility into what's happening here. Let's try it again. Directus.
Directus. Io. Hit save. Must be a failed to scrape URL. URL must oh, duh, dummy.
This is where it helps to define types so you don't make these same silly mistakes as I have. So I've called this field website. I was calling it website URL here, so not actually passing any website. Cannot read properties of collections. So there's our scrape results.
Do we see the markdown? There's our markdown. Cannot update one. What am I doing wrong here? We're not updating the schema.
We need to extension service, access items. Yes. Here we go. This is what I actually need to see. Alright.
So we got our context. We're gonna do services get schema. We need that schema. And we're also gonna need the accountability schema. So in our item service definition, we don't wanna do this.
We're gonna do this. Equals await. No AI. No. We're gonna await git schema.
So we're gonna get the schema from our context and on the accountability side, accountability. That'll be accountability. If we just destructure that, I think that gives us what we need. Let's go back and try it again. Love hacking this stuff together on the fly.
No pressure. Directus directus dot I o. Hit save and stay. Let's just watch over here and see what happens. Fire crawl seems to take a little bit, so that is forbidden.
I don't know what we're getting over here. Can I just leave off the accountability object? How many times am I gonna create this before I just do update? Directus Directus dot I o. Save.
Probably burning through these fire crawl credits as we speak as well. That that that that that, forbidden. You don't have permission to access this. Why is that not the case? What is the alright.
So let's stop loading that. Let's just say console dot log the payload. Actually, I think it's I goofed up, didn't I? What are we gonna be receiving here? It's not gonna be it'll be payload dot key.
Payload dot let's just log the whole payload again and see. Just comment out this. Comment out. Directus Directus dot I o slash payload key. Okay.
Duh. You're smarter than that, Brian. Alright. So we need this key. That's what we're getting is the key payload dot key.
So here, payload dot key. There's the event. There's the key. There's the organization of the collection we already got. Alright.
Let's keep rolling and maybe try to actually complete this one. Directus. Directus dot I o. Save. Can we actually get the scrape content?
Can we actually complete this on time? Can we do any of these things in any sort of actual working fashion? Is this actually gonna work? Will we know? How do I know?
Console.logupdatedorg. Directus. Directus I o. Save. There's the payload.
Fire crawl really takes a bit. Status code, 200. Updated org. Is this actually gonna see what we want? No.
Of course not. It's not gonna update the right one. Data dot scraped content. I'm sure this is what we need to do here. Right?
Update one. Let's look at the services. Update an item. Yep. It's not inside data.
So I don't need that to wrap. Gosh. I'm just eating up all the time. I wish I spent more time with hook extensions. Super powerful because you're basically just updating the underlying Express app instance anyway.
But alright. So now let's reach for anthropic. If we hit refresh, do we ah, still not getting the data that I want. Right? It's saying that it's updated that org.
Scrape result. Scrape result scrape content. So they tricked me. It's not it's not as it shows. It's actually not there's actually no data attribute there.
It's basically just scrape result dot markdown. Alright. Last freaking time for the scraped content, Directus Directus dot I o. I was not planning on doing this much troubleshooting. Behind the scenes here, I'm gonna go in and just create a API key for anthropic.
Hundred apps. There's my API key. Updated org. Did we actually get what we want? Holy moly.
We got some scraped content in here. Okay. Alright. So now the next step in the puzzle is going to be call the Anthropic API to generate a landing page for the organization with the JSON schema, page data. Alright.
So now this is one of the things where I've been leaning on the Vercel API, or AI SDK. So I'm just gonna install it here, p m p I. This is just AI. And they've got a way. The last time I checked, the Anthropic does really well.
Like, SONNET does really well at copywriting. But it doesn't have the JSON mode that the ones like OpenAI have. So I'm just gonna go in and look for provider management providers. Where are my providers? Providers and models.
Looks for the anthropic provider. I'm gonna add it as well. And let's see what we can get here. Import anthropic. So I'm gonna import this guy.
And then we're also going to do what? Create anthropic. We'll do that here. Now what I would normally do is this context object should have an e and v variables as well. API key.
I'm not gonna do that here because I am worthless, basically. No. We're eating up a lot of time. Base URL, API key, generate text. We want to generate objects.
So there's our anthropic client that we're creating. Don't mind that API key. Now let's define what do we need? We need Zod as well, p m Zod. And we're going to use was it generate object in here?
See if we can find it. Generate object. Alright. Generate object from AI. Okay?
Now what we're trying to do is just basically, we're gonna define a Zod schema of the object that we want, and that's gonna be our hero section. Right? Zod schema. We're gonna lean on the props. There we go.
Okay. So now I'm just gonna copy this wholesale. We're gonna stick this in our custom hook. Again, not being careful at all about separation of concerns or cleanup. So there's our Zod schema.
We want the object to return hero section schema. Alright. So now let's look up what we actually want this to how we're gonna work this. Generate object. We don't want testing.
There's gotta be a better during text, during structured data. Alright. So our model okay. So we want the object equals await generate object. I'm hoping this is right.
Fingers crossed with AI. Generate a landing page for the following organization with the content. Okay. For the organization payload. Name, the following content.
You are an expert copywriter, and your job is to generate amazing landing pages that are personalized for our target clients. We sell the best desk chair cushions in the world for developers. Schema. There's our schema. That's our Zod model.
Okay. When we get that back, what are we gonna do with the object? We are going to update the org, updated org two. It's fancy, fancy, fancy. Okay.
Alright. How we doing on time? We got nine minutes to try and figure this out. Let's just PM, PM, dev this bad boy up and see if this is actually gonna come out at all. We're rebuilding this extension.
Dun dun dun dun dun. I'm gonna nuke this entirely. Let's try it again. Let's see if it works for directus.io. We hit save.
I could check the logs on Docker. Create anthropic is not defined. Anthropic. Response. Anthropic.
Where is that? Providers and models. Anthropic provider. Create anthropic. Import the default provider.
Oh, no. We could just import the what am I doing? Create create anthropic. Organizations. Oh, no.
Directus. Duh. Directus .I o. Hit save. There's the payload.
Obviously, it would be great to have visibility into this. And one tool that I've been using as of late is ingest. Great tool for something like this, generated hero section. This is gonna be nice, doc. Okay.
Alright. So now before we reveal what it generated, let's just try to make sure this is actually gonna work. So instead of the data here, we're just gonna use the organization dot data dot page data. Organization dot page data. Generated hero section.
That looks nice. Organization dot page data. Dun dun dun, the big reveal. Close that guy out. No.
Status message. What is the status message? Did we actually get the page data generated? Okay. We got the page data generated.
It looks like it's coming back with data here as well. So we should probably fix that in our hook. Page data page data is what? Object dot data. But for now, what I'm gonna do, I'm gonna just strip this out.
Right? Great. And we refresh. We refresh. We refresh.
No. What is going on? Organization. I'm excited for this, and I'm hoping we could get this to work. Right?
Why am I not getting any of my data? Organizations. Access policies. We can see that organize oh, that's because it's not the right organization. Alright.
I was using the old organization. We blew that one away like a hundred times. Right? This is probably where you'd wanna slug. Five minutes left.
What do we have on the clock, Johnny? No. It's not working. Boy. Alright.
There's our page data, organization dot page data. There's the scrape content. Why are we not seeing that? Right? Organization.
Let's try it now. Status code. What is the error that we're receiving? V if organization dot page data. I could see the page data, man.
Organization. Oh, duh. Gosh, man. What an idiot. Alright.
So I I've done this on another episode as well. We're gonna transform this to get data. Where is this at? Is it here? Transform data.
I don't know if this is how it functions. Error results, organization. I'm not sure the exact syntax, and I'm not gonna mess around with it. So we're gonna do this. It's gonna be organization.
Boom. Bam. Directus plus Comfy Desk revolutionize your development experience, Seamless integration. Integrate Directus' flexible back end with your favorite front end while sitting comfortably on comfy desk cushions. Tailor your with adjustable cushions.
Perfect. Alright. So now we have landing pages that are personalized for a specific client within, like an AI workflow. Right? So let's try this with some other company.
Let's say OpenAI. I guess just to to pit these guys against each other here is this OpenAI.com. OpenAI Com. We'll hit save. And hopefully, this all runs, works nicely on the back end.
There's the scrape result. You know, if I wanted to get really fancy, obviously, I could take this to the extreme here. But let's look at OpenAI. We'll view this on the website. What is going on?
For noose proper next string, OpenAI. Okay. This one is not super strong. Right? Not sure what the scrape data result was.
It looks like Firecrawl didn't do a great job with their website. Right? Let's try Apple.apple.com. Save. And we'll see what it comes back with.
There's the scrape content. And, again, this is just coming back with markdown. You know, I might have better luck with, like, actual JavaScript parsing or something like that. But boom. Elevate your comfort coding experience with Apple inspired comfort, the iCushion Pro.
Anyway, that's it for this episode. We've achieved this. I'm pushing a stop button on it. One minute left, we have basically fleshed out this personalized landing page where we add an organization, we use AI to scrape it, we then we generate content using LLMs, based on a specific schema, and then boom, we've got a personalized landing page that we could share with them. As far as next steps for me would probably be, like, setting this up on, like, a pretty URL or a slug, you know, adding this to some type of outbound, like, outreach campaign potentially.
That's it though. It's amazing what you can put together in just an hour with tools like Cursor, Directus, Nuxt, Anthropic, all these different things come together to create stuff that's fun to build. I'll catch you on the next episode. Peace.