[dyad] Added headline extraction and display - wrote 4 file(s)

This commit is contained in:
[dyad]
2026-01-20 13:56:24 +01:00
parent cbd7f55d92
commit dd690eba2e
4 changed files with 86 additions and 1 deletions

View File

@@ -7,6 +7,12 @@ interface FaqItem {
answer: string; answer: string;
} }
interface HeadlineItem {
tag: string;
text: string;
length: number;
}
export async function extractMetaData(url: string) { export async function extractMetaData(url: string) {
if (!url) { if (!url) {
return { error: "URL is required." }; return { error: "URL is required." };
@@ -73,12 +79,26 @@ export async function extractMetaData(url: string) {
} }
}); });
const headlines: HeadlineItem[] = [];
$("h1, h2, h3, h4, h5, h6").each((i, el) => {
const tag = $(el).prop("tagName").toLowerCase();
const text = $(el).text().trim();
if (text) {
headlines.push({
tag,
text,
length: text.length,
});
}
});
return { return {
data: { data: {
title, title,
description, description,
image, image,
faq: faqData.length > 0 ? faqData : null, faq: faqData.length > 0 ? faqData : null,
headlines: headlines.length > 0 ? headlines : null,
}, },
}; };
} catch (error) { } catch (error) {

View File

@@ -0,0 +1,51 @@
"use client";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
interface HeadlinesDisplayProps {
headlines: {
tag: string;
text: string;
length: number;
}[];
}
export function HeadlinesDisplay({ headlines }: HeadlinesDisplayProps) {
return (
<div>
<h3 className="font-semibold text-card-foreground mb-2">Headlines</h3>
<div className="border rounded-lg max-h-80 overflow-y-auto relative">
<Table>
<TableHeader className="sticky top-0 bg-muted/95 backdrop-blur-sm">
<TableRow>
<TableHead className="w-[80px]">Tag</TableHead>
<TableHead>Text</TableHead>
<TableHead className="text-right w-[100px]">Length</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{headlines.map((headline, index) => (
<TableRow key={index}>
<TableCell>
<Badge variant="secondary" className="uppercase">
{headline.tag}
</Badge>
</TableCell>
<TableCell className="font-medium">{headline.text}</TableCell>
<TableCell className="text-right">{headline.length}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
);
}

View File

@@ -12,12 +12,14 @@ import { CopyButton } from "./copy-button";
import { SerpPreview } from "./serp-preview"; import { SerpPreview } from "./serp-preview";
import { ResultsSkeleton } from "./results-skeleton"; import { ResultsSkeleton } from "./results-skeleton";
import { FaqDisplay } from "./faq-display"; import { FaqDisplay } from "./faq-display";
import { HeadlinesDisplay } from "./headlines-display";
interface MetaData { interface MetaData {
title: string; title: string;
description: string; description: string;
image?: string | null; image?: string | null;
faq?: { question: string; answer: string }[] | null; faq?: { question: string; answer: string }[] | null;
headlines?: { tag: string; text: string; length: number }[] | null;
} }
export function MetaForm() { export function MetaForm() {
@@ -161,7 +163,7 @@ export function MetaForm() {
</div> </div>
</div> </div>
)} )}
{metaData.faq && metaData.faq.length > 0 && ( {metaData.faq && metaData.faq.length > 0 && (
<FaqDisplay faqs={metaData.faq} /> <FaqDisplay faqs={metaData.faq} />
)} )}
@@ -271,6 +273,9 @@ export function MetaForm() {
</p> </p>
)} )}
</div> </div>
{metaData.headlines && metaData.headlines.length > 0 && (
<HeadlinesDisplay headlines={metaData.headlines} />
)}
</div> </div>
</div> </div>
</CardContent> </CardContent>

View File

@@ -63,6 +63,15 @@ export function ResultsSkeleton() {
<Skeleton className="h-4 w-full mb-2" /> <Skeleton className="h-4 w-full mb-2" />
<Skeleton className="h-24 w-full" /> <Skeleton className="h-24 w-full" />
</div> </div>
<div>
<Skeleton className="h-5 w-24 mb-2" />
<div className="border rounded-lg p-2 space-y-2">
<Skeleton className="h-8 w-full" />
<Skeleton className="h-8 w-full" />
<Skeleton className="h-8 w-full" />
<Skeleton className="h-8 w-full" />
</div>
</div>
</div> </div>
</div> </div>
</CardContent> </CardContent>