feat: add SEO and GEO discovery metadata
This commit is contained in:
@@ -2,6 +2,12 @@ import Link from "next/link";
|
|||||||
import { requireUser } from "@/lib/auth/current-user";
|
import { requireUser } from "@/lib/auth/current-user";
|
||||||
import { DashboardMobileNav } from "@/components/dashboard-mobile-nav";
|
import { DashboardMobileNav } from "@/components/dashboard-mobile-nav";
|
||||||
import { BrandLogo } from "@/components/brand-logo";
|
import { BrandLogo } from "@/components/brand-logo";
|
||||||
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Dashboard",
|
||||||
|
robots: { index: false, follow: false, nocache: true }
|
||||||
|
};
|
||||||
|
|
||||||
const nav = [
|
const nav = [
|
||||||
["Ads", "/dashboard/ads"],
|
["Ads", "/dashboard/ads"],
|
||||||
|
|||||||
+19
-7
@@ -1,18 +1,20 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
import { SITE_DESCRIPTION, SITE_NAME, SITE_URL } from "@/lib/seo";
|
||||||
const appUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
metadataBase: new URL(appUrl),
|
metadataBase: new URL(SITE_URL),
|
||||||
applicationName: "AdSeeQ",
|
applicationName: SITE_NAME,
|
||||||
title: {
|
title: {
|
||||||
default: "AdSeeQ — Reklam ve Trend Zekâsı",
|
default: "AdSeeQ — Reklam ve Trend Zekâsı",
|
||||||
template: "%s | AdSeeQ"
|
template: "%s | AdSeeQ"
|
||||||
},
|
},
|
||||||
description: "Meta reklamlarını, TikTok Shop ürünlerini, yükselen trendleri ve rakip markaları yapay zekâ ile tek panelden keşfedin.",
|
description: SITE_DESCRIPTION,
|
||||||
keywords: ["reklam kütüphanesi", "Meta Ads", "TikTok Shop", "trend analizi", "marka takibi", "reklam zekâsı"],
|
keywords: ["reklam kütüphanesi", "Meta Ads", "TikTok Shop", "trend analizi", "marka takibi", "reklam zekâsı"],
|
||||||
alternates: { canonical: "/" },
|
alternates: {
|
||||||
|
canonical: "/",
|
||||||
|
languages: { "tr-TR": "/" }
|
||||||
|
},
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: "AdSeeQ — Kazanan reklamları ve trendleri keşfedin",
|
title: "AdSeeQ — Kazanan reklamları ve trendleri keşfedin",
|
||||||
description: "Meta Ads, TikTok Shop, Magic AI Trends ve Brand Tracker tek panelde.",
|
description: "Meta Ads, TikTok Shop, Magic AI Trends ve Brand Tracker tek panelde.",
|
||||||
@@ -26,7 +28,17 @@ export const metadata: Metadata = {
|
|||||||
title: "AdSeeQ — Reklam ve Trend Zekâsı",
|
title: "AdSeeQ — Reklam ve Trend Zekâsı",
|
||||||
description: "Kazanan reklamları, ürünleri ve rakip marka hareketlerini keşfedin."
|
description: "Kazanan reklamları, ürünleri ve rakip marka hareketlerini keşfedin."
|
||||||
},
|
},
|
||||||
robots: { index: true, follow: true }
|
robots: {
|
||||||
|
index: true,
|
||||||
|
follow: true,
|
||||||
|
googleBot: {
|
||||||
|
index: true,
|
||||||
|
follow: true,
|
||||||
|
"max-image-preview": "large",
|
||||||
|
"max-snippet": -1,
|
||||||
|
"max-video-preview": -1
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { SITE_DESCRIPTION, SITE_URL } from "@/lib/seo";
|
||||||
|
|
||||||
|
const content = `# AdSeeQ
|
||||||
|
|
||||||
|
> ${SITE_DESCRIPTION}
|
||||||
|
|
||||||
|
AdSeeQ, reklam araştırması ve e-ticaret trend keşfi yapan ekipler için web tabanlı bir platformdur.
|
||||||
|
|
||||||
|
## Temel özellikler
|
||||||
|
|
||||||
|
- Meta Ads Library reklamlarını anahtar kelime ve ülkeye göre araştırma
|
||||||
|
- Medya içeren reklam kreatiflerini inceleme ve kaydetme
|
||||||
|
- TikTok Shop ürün keşfi
|
||||||
|
- Magic AI ile reklam ve ürün sinyallerini analiz etme
|
||||||
|
- Trends ile yükselen sinyalleri takip etme
|
||||||
|
- Brand Tracker ve Store Tracker ile marka ve mağaza takibi
|
||||||
|
|
||||||
|
## Resmî sayfalar
|
||||||
|
|
||||||
|
- Ana sayfa: ${SITE_URL}
|
||||||
|
- Fiyatlandırma: ${SITE_URL}/pricing
|
||||||
|
- Hesap oluşturma: ${SITE_URL}/register
|
||||||
|
- Giriş: ${SITE_URL}/login
|
||||||
|
|
||||||
|
## Ürün bilgisi
|
||||||
|
|
||||||
|
AdSeeQ ücretsiz ve ücretli planlar sunar. Güncel plan limitleri ve fiyatlar için resmî fiyatlandırma sayfasını kullanın. Özel dashboard ve API rotaları herkese açık içerik değildir.
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function GET() {
|
||||||
|
return new Response(content, {
|
||||||
|
headers: {
|
||||||
|
"content-type": "text/plain; charset=utf-8",
|
||||||
|
"cache-control": "public, max-age=3600, s-maxage=86400"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Giriş",
|
||||||
|
description: "AdSeeQ hesabınıza giriş yapın.",
|
||||||
|
alternates: { canonical: "/login" },
|
||||||
|
robots: { index: false, follow: false, nocache: true }
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function LoginLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import { ImageResponse } from "next/og";
|
||||||
|
|
||||||
|
export const alt = "AdSeeQ — Reklam ve trend zekâsı";
|
||||||
|
export const size = { width: 1200, height: 630 };
|
||||||
|
export const contentType = "image/png";
|
||||||
|
|
||||||
|
export default function OpenGraphImage() {
|
||||||
|
return new ImageResponse(
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
alignItems: "center",
|
||||||
|
background: "linear-gradient(135deg, #0f172a 0%, #4c1d95 58%, #7c3aed 100%)",
|
||||||
|
color: "white",
|
||||||
|
display: "flex",
|
||||||
|
height: "100%",
|
||||||
|
justifyContent: "center",
|
||||||
|
padding: "72px",
|
||||||
|
width: "100%"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", maxWidth: "980px" }}>
|
||||||
|
<div style={{ alignItems: "center", display: "flex", fontSize: 46, fontWeight: 800 }}>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
alignItems: "center",
|
||||||
|
background: "white",
|
||||||
|
borderRadius: 24,
|
||||||
|
color: "#6d28d9",
|
||||||
|
display: "flex",
|
||||||
|
height: 82,
|
||||||
|
justifyContent: "center",
|
||||||
|
marginRight: 24,
|
||||||
|
width: 82
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Q
|
||||||
|
</span>
|
||||||
|
AdSeeQ
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: 72, fontWeight: 900, letterSpacing: "-3px", lineHeight: 1.06, marginTop: 48 }}>
|
||||||
|
Kazanan reklamları ve trendleri keşfedin
|
||||||
|
</div>
|
||||||
|
<div style={{ color: "#ddd6fe", fontSize: 30, lineHeight: 1.35, marginTop: 30 }}>
|
||||||
|
Meta Ads · TikTok Shop · Magic AI · Trends · Brand Tracker
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>,
|
||||||
|
size
|
||||||
|
);
|
||||||
|
}
|
||||||
+54
-1
@@ -1,9 +1,14 @@
|
|||||||
import { LinkButton } from "@/components/ui/button";
|
import { LinkButton } from "@/components/ui/button";
|
||||||
import { BrandLogo } from "@/components/brand-logo";
|
import { BrandLogo } from "@/components/brand-logo";
|
||||||
|
import { homeFaq, homeStructuredData, serializeJsonLd } from "@/lib/seo";
|
||||||
|
|
||||||
export default function LandingPage() {
|
export default function LandingPage() {
|
||||||
return (
|
return (
|
||||||
<main className="min-h-screen overflow-hidden bg-[radial-gradient(circle_at_top_left,#ddd6fe,transparent_35%),#f8fafc]">
|
<main className="min-h-screen overflow-hidden bg-[radial-gradient(circle_at_top_left,#ddd6fe,transparent_35%),#f8fafc]">
|
||||||
|
<script
|
||||||
|
type="application/ld+json"
|
||||||
|
dangerouslySetInnerHTML={{ __html: serializeJsonLd(homeStructuredData) }}
|
||||||
|
/>
|
||||||
<nav className="mx-auto flex max-w-7xl items-center justify-between px-6 py-6">
|
<nav className="mx-auto flex max-w-7xl items-center justify-between px-6 py-6">
|
||||||
<BrandLogo />
|
<BrandLogo />
|
||||||
<div className="flex gap-3">
|
<div className="flex gap-3">
|
||||||
@@ -20,7 +25,7 @@ export default function LandingPage() {
|
|||||||
Kazanan reklamları ve mağazaları dakikalar içinde keşfet.
|
Kazanan reklamları ve mağazaları dakikalar içinde keşfet.
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mt-6 max-w-2xl text-lg leading-8 text-slate-600">
|
<p className="mt-6 max-w-2xl text-lg leading-8 text-slate-600">
|
||||||
Meta reklam kütüphanesi, TikTok Shop ürün keşfi, Magic AI trend analizi ve rakip marka takibi tek panelde.
|
AdSeeQ, reklam ve e-ticaret araştırmalarını tek panelde birleştiren reklam zekâsı platformudur. Meta Ads Library reklamlarını araştırın, TikTok Shop ürünlerini keşfedin, Magic AI ile trend sinyallerini analiz edin ve rakip markaları takip edin.
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-8 flex flex-wrap gap-3">
|
<div className="mt-8 flex flex-wrap gap-3">
|
||||||
<LinkButton href="/register" className="px-6 py-3">Ücretsiz başla</LinkButton>
|
<LinkButton href="/register" className="px-6 py-3">Ücretsiz başla</LinkButton>
|
||||||
@@ -45,6 +50,54 @@ export default function LandingPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<section className="mx-auto max-w-7xl px-6 py-16" aria-labelledby="features-heading">
|
||||||
|
<div className="max-w-3xl">
|
||||||
|
<p className="text-sm font-black uppercase tracking-[0.2em] text-violet-700">Tek panel, altı araştırma aracı</p>
|
||||||
|
<h2 id="features-heading" className="mt-3 text-3xl font-black tracking-tight text-slate-950 md:text-4xl">
|
||||||
|
Reklamdan trende, araştırma akışınız tek yerde
|
||||||
|
</h2>
|
||||||
|
<p className="mt-4 leading-7 text-slate-600">
|
||||||
|
Kreatifleri bulun, sinyalleri karşılaştırın ve incelemek istediğiniz reklam, mağaza ve markaları kaydedin.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="mt-9 grid gap-5 md:grid-cols-2 lg:grid-cols-3">
|
||||||
|
{[
|
||||||
|
["Meta reklam araştırması", "Anahtar kelime ve ülkeye göre medya içeren reklam kreatiflerini araştırın."],
|
||||||
|
["TikTok Shop keşfi", "Ürünleri ve mağaza sinyallerini aynı araştırma akışında inceleyin."],
|
||||||
|
["Magic AI", "Kreatif açıları, hedef kitle fikirleri ve test edilebilir yaklaşımlar üretin."],
|
||||||
|
["Trends", "Yükselen reklam ve ürün sinyallerini düzenli bir görünümde takip edin."],
|
||||||
|
["Brand Tracker", "Rakip markaları kaydedin ve yeni hareketlerini tek listeden izleyin."],
|
||||||
|
["Store Tracker", "Mağazaları takip edin, benzer mağazaları ve ürün sinyallerini keşfedin."]
|
||||||
|
].map(([title, description]) => (
|
||||||
|
<article key={title} className="rounded-3xl border border-slate-200 bg-white/80 p-6 shadow-sm">
|
||||||
|
<h3 className="text-lg font-black text-slate-950">{title}</h3>
|
||||||
|
<p className="mt-2 leading-7 text-slate-600">{description}</p>
|
||||||
|
</article>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section className="border-y border-slate-200 bg-white/70" aria-labelledby="faq-heading">
|
||||||
|
<div className="mx-auto max-w-4xl px-6 py-16">
|
||||||
|
<p className="text-sm font-black uppercase tracking-[0.2em] text-violet-700">Sık sorulan sorular</p>
|
||||||
|
<h2 id="faq-heading" className="mt-3 text-3xl font-black tracking-tight text-slate-950">AdSeeQ hakkında</h2>
|
||||||
|
<div className="mt-8 space-y-4">
|
||||||
|
{homeFaq.map(({ question, answer }) => (
|
||||||
|
<details key={question} className="group rounded-2xl border border-slate-200 bg-white p-5">
|
||||||
|
<summary className="cursor-pointer list-none pr-6 font-black text-slate-950">{question}</summary>
|
||||||
|
<p className="mt-3 leading-7 text-slate-600">{answer}</p>
|
||||||
|
</details>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<footer className="mx-auto flex max-w-7xl flex-col gap-4 px-6 py-10 text-sm text-slate-500 sm:flex-row sm:items-center sm:justify-between">
|
||||||
|
<BrandLogo markClassName="h-8 w-8" />
|
||||||
|
<div className="flex gap-5">
|
||||||
|
<a href="/pricing" className="hover:text-slate-950">Fiyatlandırma</a>
|
||||||
|
<a href="/register" className="hover:text-slate-950">Ücretsiz başla</a>
|
||||||
|
<a href="/login" className="hover:text-slate-950">Giriş</a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,18 @@ import { LinkButton } from "@/components/ui/button";
|
|||||||
import { Card } from "@/components/ui/card";
|
import { Card } from "@/components/ui/card";
|
||||||
import { CheckoutButton } from "@/components/checkout-button";
|
import { CheckoutButton } from "@/components/checkout-button";
|
||||||
import { BrandLogo } from "@/components/brand-logo";
|
import { BrandLogo } from "@/components/brand-logo";
|
||||||
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Fiyatlandırma",
|
||||||
|
description: "AdSeeQ Free, Basic, Standard ve Premium planlarının reklam arama, mağaza takip ve kayıt limitlerini karşılaştırın.",
|
||||||
|
alternates: { canonical: "/pricing", languages: { "tr-TR": "/pricing" } },
|
||||||
|
openGraph: {
|
||||||
|
title: "AdSeeQ Fiyatlandırma",
|
||||||
|
description: "İhtiyacınıza uygun reklam ve trend araştırma planını seçin.",
|
||||||
|
url: "/pricing"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default async function PricingPage() {
|
export default async function PricingPage() {
|
||||||
const plans = await prisma.plan.findMany({ orderBy: { sortOrder: "asc" } }).catch(() => []);
|
const plans = await prisma.plan.findMany({ orderBy: { sortOrder: "asc" } }).catch(() => []);
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import type { Metadata } from "next";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Ücretsiz Hesap Oluştur",
|
||||||
|
description: "AdSeeQ ücretsiz hesabınızı oluşturun ve reklam araştırmasına başlayın.",
|
||||||
|
alternates: { canonical: "/register" },
|
||||||
|
robots: { index: false, follow: false, nocache: true }
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RegisterLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import type { MetadataRoute } from "next";
|
||||||
|
import { SITE_URL } from "@/lib/seo";
|
||||||
|
|
||||||
|
export default function robots(): MetadataRoute.Robots {
|
||||||
|
return {
|
||||||
|
rules: {
|
||||||
|
userAgent: "*",
|
||||||
|
allow: ["/", "/pricing", "/llms.txt"],
|
||||||
|
disallow: ["/api/", "/dashboard/", "/login", "/register"]
|
||||||
|
},
|
||||||
|
sitemap: `${SITE_URL}/sitemap.xml`,
|
||||||
|
host: SITE_URL
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import type { MetadataRoute } from "next";
|
||||||
|
import { SITE_URL } from "@/lib/seo";
|
||||||
|
|
||||||
|
export default function sitemap(): MetadataRoute.Sitemap {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
url: SITE_URL,
|
||||||
|
changeFrequency: "weekly",
|
||||||
|
priority: 1,
|
||||||
|
alternates: { languages: { "tr-TR": SITE_URL } }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: `${SITE_URL}/pricing`,
|
||||||
|
changeFrequency: "monthly",
|
||||||
|
priority: 0.8,
|
||||||
|
alternates: { languages: { "tr-TR": `${SITE_URL}/pricing` } }
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
export const SITE_URL = "https://adseeq.com";
|
||||||
|
|
||||||
|
export const SITE_NAME = "AdSeeQ";
|
||||||
|
|
||||||
|
export const SITE_DESCRIPTION =
|
||||||
|
"Meta reklamlarını, TikTok Shop ürünlerini, yükselen trendleri ve rakip markaları yapay zekâ destekli tek panelden araştırın.";
|
||||||
|
|
||||||
|
export const homeFaq = [
|
||||||
|
{
|
||||||
|
question: "AdSeeQ nedir?",
|
||||||
|
answer:
|
||||||
|
"AdSeeQ; Meta reklamlarını, TikTok Shop ürünlerini, yükselen trendleri ve rakip markaları tek panelde araştırmaya yardımcı olan reklam ve trend zekâsı platformudur."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "AdSeeQ ile hangi reklamlar araştırılabilir?",
|
||||||
|
answer:
|
||||||
|
"Meta Ads Library kaynaklı reklamlar anahtar kelime ve ülke ölçütleriyle aranabilir; medya içeren kreatifler incelenebilir ve uygun reklamlar daha sonra değerlendirmek üzere kaydedilebilir."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "Magic AI ne işe yarar?",
|
||||||
|
answer:
|
||||||
|
"Magic AI, reklam ve ürün sinyallerini özetleyerek kreatif açıları, hedef kitle fikirleri ve test edilebilecek pazarlama yaklaşımları üretmeye yardımcı olur."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
question: "AdSeeQ ücretsiz kullanılabilir mi?",
|
||||||
|
answer:
|
||||||
|
"Evet. Ücretsiz plan günlük sınırlı reklam araması sunar; daha yüksek arama ve takip limitleri için ücretli planlar bulunur."
|
||||||
|
}
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export const homeStructuredData = {
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@graph": [
|
||||||
|
{
|
||||||
|
"@type": "Organization",
|
||||||
|
"@id": `${SITE_URL}/#organization`,
|
||||||
|
name: SITE_NAME,
|
||||||
|
url: SITE_URL,
|
||||||
|
logo: `${SITE_URL}/icon.svg`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "WebSite",
|
||||||
|
"@id": `${SITE_URL}/#website`,
|
||||||
|
url: SITE_URL,
|
||||||
|
name: SITE_NAME,
|
||||||
|
description: SITE_DESCRIPTION,
|
||||||
|
inLanguage: "tr-TR",
|
||||||
|
publisher: { "@id": `${SITE_URL}/#organization` }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "SoftwareApplication",
|
||||||
|
"@id": `${SITE_URL}/#software`,
|
||||||
|
name: SITE_NAME,
|
||||||
|
applicationCategory: "BusinessApplication",
|
||||||
|
applicationSubCategory: "Advertising Intelligence",
|
||||||
|
operatingSystem: "Web",
|
||||||
|
url: SITE_URL,
|
||||||
|
description: SITE_DESCRIPTION,
|
||||||
|
inLanguage: "tr-TR",
|
||||||
|
offers: {
|
||||||
|
"@type": "Offer",
|
||||||
|
price: "0",
|
||||||
|
priceCurrency: "EUR",
|
||||||
|
description: "Günlük sınırlı reklam araması içeren ücretsiz plan"
|
||||||
|
},
|
||||||
|
publisher: { "@id": `${SITE_URL}/#organization` }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "FAQPage",
|
||||||
|
"@id": `${SITE_URL}/#faq`,
|
||||||
|
mainEntity: homeFaq.map(({ question, answer }) => ({
|
||||||
|
"@type": "Question",
|
||||||
|
name: question,
|
||||||
|
acceptedAnswer: {
|
||||||
|
"@type": "Answer",
|
||||||
|
text: answer
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export function serializeJsonLd(value: unknown) {
|
||||||
|
return JSON.stringify(value).replace(/</g, "\\u003c");
|
||||||
|
}
|
||||||
@@ -8,6 +8,10 @@ import { stripePriceFor } from "../src/lib/stripe";
|
|||||||
import { tikTokActorInput } from "../src/lib/apify-tiktok";
|
import { tikTokActorInput } from "../src/lib/apify-tiktok";
|
||||||
import { NextRequest } from "next/server";
|
import { NextRequest } from "next/server";
|
||||||
import { proxy } from "../src/proxy";
|
import { proxy } from "../src/proxy";
|
||||||
|
import sitemap from "../src/app/sitemap";
|
||||||
|
import robots from "../src/app/robots";
|
||||||
|
import { GET as llmsTxt } from "../src/app/llms.txt/route";
|
||||||
|
import { homeStructuredData, serializeJsonLd } from "../src/lib/seo";
|
||||||
|
|
||||||
test("Apify reklamı metin, medya ve ülke alanlarıyla normalize edilir", () => {
|
test("Apify reklamı metin, medya ve ülke alanlarıyla normalize edilir", () => {
|
||||||
const ad = normalizeApifyAd({
|
const ad = normalizeApifyAd({
|
||||||
@@ -76,3 +80,34 @@ test("AdSeeQ ana alan adı yönlendirilmez", () => {
|
|||||||
assert.equal(response.status, 200);
|
assert.equal(response.status, 200);
|
||||||
assert.equal(response.headers.get("location"), null);
|
assert.equal(response.headers.get("location"), null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("sitemap yalnızca indekslenebilir herkese açık sayfaları içerir", () => {
|
||||||
|
const urls = sitemap().map((entry) => entry.url);
|
||||||
|
assert.deepEqual(urls, ["https://adseeq.com", "https://adseeq.com/pricing"]);
|
||||||
|
assert.equal(new Set(urls).size, urls.length);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("robots özel alanları engeller ve sitemap adresini bildirir", () => {
|
||||||
|
const value = robots();
|
||||||
|
assert.equal(value.sitemap, "https://adseeq.com/sitemap.xml");
|
||||||
|
assert.deepEqual(value.rules, {
|
||||||
|
userAgent: "*",
|
||||||
|
allow: ["/", "/pricing", "/llms.txt"],
|
||||||
|
disallow: ["/api/", "/dashboard/", "/login", "/register"]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("llms.txt ürün kapsamını düz metin olarak açıklar", async () => {
|
||||||
|
const response = llmsTxt();
|
||||||
|
const body = await response.text();
|
||||||
|
assert.match(response.headers.get("content-type") || "", /^text\/plain/);
|
||||||
|
assert.match(body, /Meta Ads Library/);
|
||||||
|
assert.match(body, /https:\/\/adseeq\.com\/pricing/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("ana sayfa JSON-LD verisi yazılım ve SSS şemalarını içerir", () => {
|
||||||
|
const value = serializeJsonLd(homeStructuredData);
|
||||||
|
assert.match(value, /SoftwareApplication/);
|
||||||
|
assert.match(value, /FAQPage/);
|
||||||
|
assert.equal(value.includes("<"), false);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user