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 { DashboardMobileNav } from "@/components/dashboard-mobile-nav";
|
||||
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 = [
|
||||
["Ads", "/dashboard/ads"],
|
||||
|
||||
+19
-7
@@ -1,18 +1,20 @@
|
||||
import type { Metadata } from "next";
|
||||
import "./globals.css";
|
||||
|
||||
const appUrl = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000";
|
||||
import { SITE_DESCRIPTION, SITE_NAME, SITE_URL } from "@/lib/seo";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL(appUrl),
|
||||
applicationName: "AdSeeQ",
|
||||
metadataBase: new URL(SITE_URL),
|
||||
applicationName: SITE_NAME,
|
||||
title: {
|
||||
default: "AdSeeQ — Reklam ve Trend Zekâsı",
|
||||
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ı"],
|
||||
alternates: { canonical: "/" },
|
||||
alternates: {
|
||||
canonical: "/",
|
||||
languages: { "tr-TR": "/" }
|
||||
},
|
||||
openGraph: {
|
||||
title: "AdSeeQ — Kazanan reklamları ve trendleri keşfedin",
|
||||
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ı",
|
||||
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 }) {
|
||||
|
||||
@@ -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 { BrandLogo } from "@/components/brand-logo";
|
||||
import { homeFaq, homeStructuredData, serializeJsonLd } from "@/lib/seo";
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<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">
|
||||
<BrandLogo />
|
||||
<div className="flex gap-3">
|
||||
@@ -20,7 +25,7 @@ export default function LandingPage() {
|
||||
Kazanan reklamları ve mağazaları dakikalar içinde keşfet.
|
||||
</h1>
|
||||
<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>
|
||||
<div className="mt-8 flex flex-wrap gap-3">
|
||||
<LinkButton href="/register" className="px-6 py-3">Ücretsiz başla</LinkButton>
|
||||
@@ -45,6 +50,54 @@ export default function LandingPage() {
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,18 @@ import { LinkButton } from "@/components/ui/button";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import { CheckoutButton } from "@/components/checkout-button";
|
||||
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() {
|
||||
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");
|
||||
}
|
||||
Reference in New Issue
Block a user