This commit is contained in:
@@ -27,6 +27,32 @@ import { signIn } from "next-auth/react";
|
||||
import { toaster } from "@/components/ui/feedback/toaster";
|
||||
import { useState } from "react";
|
||||
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "signin";
|
||||
|
||||
return {
|
||||
title: t("signin.title"),
|
||||
description: t("signin.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const schema = yup.object({
|
||||
email: yup.string().email().required(),
|
||||
password: yup.string().required(),
|
||||
|
||||
@@ -27,6 +27,32 @@ import { useState } from "react";
|
||||
import { signIn } from "next-auth/react";
|
||||
import { toaster } from "@/components/ui/feedback/toaster";
|
||||
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "signup";
|
||||
|
||||
return {
|
||||
title: t("signup.title"),
|
||||
description: t("signup.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const schema = yup.object({
|
||||
name: yup.string().required(),
|
||||
email: yup.string().email().required(),
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "about";
|
||||
|
||||
return {
|
||||
title: t("about.title"),
|
||||
description: t("about.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function AboutPage() {
|
||||
return <div>AboutPage</div>;
|
||||
}
|
||||
|
||||
@@ -5,12 +5,29 @@ import { isAdminRole } from "@/lib/auth/roles";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "admin";
|
||||
|
||||
return {
|
||||
title: `${t("admin.title")} | Suggest Bet`,
|
||||
description:
|
||||
"Admin panel for managing users, monitoring predictions, and system overview.",
|
||||
title: t("admin.title"),
|
||||
description: t("admin.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import AnalysisContent from "@/components/analysis/analysis-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "analysis";
|
||||
|
||||
return {
|
||||
title: `${t("analysis.title")} | Suggest Bet`,
|
||||
description: "AI-powered multi-match analysis for coupon generation.",
|
||||
title: t("analysis.title"),
|
||||
description: t("analysis.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import CouponBuilderContent from "@/components/coupons/coupon-builder-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "coupon-builder";
|
||||
|
||||
return {
|
||||
title: `${t("coupons.builder-title")} | Suggest Bet`,
|
||||
description:
|
||||
"Build your coupon with AI-powered suggestions. Choose your strategy and let AI optimize your bets.",
|
||||
title: t("coupon-builder.title"),
|
||||
description: t("coupon-builder.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import CouponHistoryContent from "@/components/coupons/coupon-history-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "coupon-history";
|
||||
|
||||
return {
|
||||
title: `${t("coupons.history-title")} | Suggest Bet`,
|
||||
description:
|
||||
"View your coupon history, track wins and losses, and analyze your betting performance.",
|
||||
title: t("coupon-history.title"),
|
||||
description: t("coupon-history.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import DashboardContent from "@/components/dashboard/dashboard-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "dashboard";
|
||||
|
||||
return {
|
||||
title: `${t("dashboard.title")} | Suggest Bet`,
|
||||
description:
|
||||
"Your personalized betting dashboard with predictions, value bets, and match insights.",
|
||||
title: t("dashboard.title"),
|
||||
description: t("dashboard.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import H2HContent from "@/components/h2h/h2h-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "h2h";
|
||||
|
||||
return {
|
||||
title: `${t("matches.head-to-head")} | Suggest Bet`,
|
||||
description: "Compare two teams and view their head-to-head match history.",
|
||||
title: t("h2h.title"),
|
||||
description: t("h2h.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import HomeContent from "@/components/home/home-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "home";
|
||||
|
||||
return {
|
||||
title: `${t("home")} | Suggest Bet`,
|
||||
description:
|
||||
"AI-powered betting predictions. Analyze matches, discover value bets, and build winning coupons.",
|
||||
title: t("home.title"),
|
||||
description: t("home.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import LeagueDetailContent from "@/components/leagues/league-detail-content";
|
||||
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string; id: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale, id } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
const pathSegment = `leagues/${id}`;
|
||||
|
||||
return {
|
||||
title: `${t("leagues.title")} - Detay`,
|
||||
description: t("leagues.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default async function LeagueDetailPage(props: { params: Promise<{ id: string }> }) {
|
||||
const { id } = await props.params;
|
||||
return <LeagueDetailContent leagueId={id} />;
|
||||
}
|
||||
@@ -1,11 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import LeaguesContent from "@/components/leagues/leagues-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "leagues";
|
||||
|
||||
return {
|
||||
title: `${t("leagues.title")} | Suggest Bet`,
|
||||
description: "Browse football and basketball leagues, countries, and teams.",
|
||||
title: t("leagues.title"),
|
||||
description: t("leagues.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import MatchDetailContent from "@/components/matches/match-detail-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "matches/[id]";
|
||||
|
||||
return {
|
||||
title: `${t("matches.match-details")} | Suggest Bet`,
|
||||
title: t("matches.title"),
|
||||
description: t("matches.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import MatchesContent from "@/components/matches/matches-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "matches";
|
||||
|
||||
return {
|
||||
title: `${t("matches.title")} | Suggest Bet`,
|
||||
description:
|
||||
"Browse and analyze upcoming football and basketball matches with AI predictions.",
|
||||
title: t("matches.title"),
|
||||
description: t("matches.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import PredictionsContent from "@/components/predictions/predictions-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "predictions";
|
||||
|
||||
return {
|
||||
title: `${t("predictions.title")} | Suggest Bet`,
|
||||
description:
|
||||
"AI-powered match predictions with confidence scores, value bets, and prediction history.",
|
||||
title: t("predictions.title"),
|
||||
description: t("predictions.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import ProfileContent from "@/components/profile/profile-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "profile";
|
||||
|
||||
return {
|
||||
title: `${t("profile.title")} | Suggest Bet`,
|
||||
description:
|
||||
"Manage your profile, view account info, and track your betting statistics.",
|
||||
title: t("profile.title"),
|
||||
description: t("profile.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import SporTotoContent from "@/components/spor-toto/spor-toto-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "spor-toto";
|
||||
|
||||
return {
|
||||
title: `${t("spor-toto.title")} | Suggest Bet`,
|
||||
description:
|
||||
"Spor Toto predictions with AI-powered analysis. Generate optimized system coupons with contrarian parimutuel strategy.",
|
||||
title: t("spor-toto.title"),
|
||||
description: t("spor-toto.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import TeamDetailContent from "@/components/teams/team-detail-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "teams/[id]";
|
||||
|
||||
return {
|
||||
title: `${t("nav.teams")} | Suggest Bet`,
|
||||
title: t("teams.title"),
|
||||
description: t("teams.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,29 @@
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import TeamsContent from "@/components/teams/teams-content";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getTranslations();
|
||||
import { Metadata } from "next";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const { locale } = params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
// Next.js parses route variables automatically, but for canonical we'll just use a clean relative base if available,
|
||||
// or let next.js construct it implicitly from metadataBase if not explicitly specified.
|
||||
// We'll set alternates just for languages based on current path segment as a best effort
|
||||
const pathSegment = "teams";
|
||||
|
||||
return {
|
||||
title: `${t("nav.teams")} | Suggest Bet`,
|
||||
description: "Search and explore football teams, view match history and stats.",
|
||||
title: t("teams.title"),
|
||||
description: t("teams.description"),
|
||||
alternates: {
|
||||
canonical: `${siteUrl}/${locale}/${pathSegment}`,
|
||||
languages: {
|
||||
en: `${siteUrl}/en/${pathSegment}`,
|
||||
tr: `${siteUrl}/tr/${pathSegment}`,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,38 @@ import { hasLocale, NextIntlClientProvider } from "next-intl";
|
||||
import { notFound } from "next/navigation";
|
||||
import { routing } from "@/i18n/routing";
|
||||
import { dir } from "i18next";
|
||||
import { Metadata } from "next";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import "./global.css";
|
||||
|
||||
export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }): Promise<Metadata> {
|
||||
const { locale } = await params;
|
||||
const t = await getTranslations({ locale, namespace: "seo" });
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
|
||||
return {
|
||||
metadataBase: new URL(siteUrl),
|
||||
title: {
|
||||
template: `%s | ${t("global.title").split(" | ")[0]}`,
|
||||
default: t("global.title"),
|
||||
},
|
||||
description: t("global.description"),
|
||||
keywords: t("global.keywords"),
|
||||
openGraph: {
|
||||
title: t("global.title"),
|
||||
description: t("global.description"),
|
||||
siteName: t("global.title").split(" | ")[0],
|
||||
locale: locale,
|
||||
type: "website",
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: t("global.title"),
|
||||
description: t("global.description"),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const bricolage = Bricolage_Grotesque({
|
||||
variable: "--font-bricolage",
|
||||
subsets: ["latin"],
|
||||
@@ -23,6 +53,27 @@ export default async function RootLayout({
|
||||
notFound();
|
||||
}
|
||||
|
||||
const siteUrl = process.env.NEXT_PUBLIC_APP_URL || "https://iddaai.com";
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
"name": "iddaai.com",
|
||||
"url": siteUrl,
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": `${siteUrl}/search?q={search_term_string}`,
|
||||
"query-input": "required name=search_term_string"
|
||||
}
|
||||
};
|
||||
|
||||
const orgJsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "iddaai.com",
|
||||
"url": siteUrl,
|
||||
"logo": `${siteUrl}/favicon/android-chrome-512x512.png`,
|
||||
};
|
||||
|
||||
return (
|
||||
<html
|
||||
lang={locale}
|
||||
@@ -35,6 +86,14 @@ export default async function RootLayout({
|
||||
<link rel='icon' type='image/png' sizes='32x32' href='/favicon/favicon-32x32.png' />
|
||||
<link rel='icon' type='image/png' sizes='16x16' href='/favicon/favicon-16x16.png' /> */}
|
||||
<link rel="manifest" href="/favicon/site.webmanifest" />
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(orgJsonLd) }}
|
||||
/>
|
||||
</head>
|
||||
<body className={bricolage.variable}>
|
||||
<NextIntlClientProvider>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 193 KiB |
@@ -0,0 +1,13 @@
|
||||
import { MetadataRoute } from 'next';
|
||||
|
||||
export default function robots(): MetadataRoute.Robots {
|
||||
const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'https://iddaai.com';
|
||||
return {
|
||||
rules: {
|
||||
userAgent: '*',
|
||||
allow: '/',
|
||||
disallow: ['/admin', '/*/dashboard', '/*/profile', '/*/coupon-history'],
|
||||
},
|
||||
sitemap: `${baseUrl}/sitemap.xml`,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { MetadataRoute } from 'next';
|
||||
import { routing } from '@/i18n/routing';
|
||||
|
||||
const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'https://iddaai.com';
|
||||
|
||||
const staticPages = [
|
||||
'',
|
||||
'/home',
|
||||
'/about',
|
||||
'/analysis',
|
||||
'/leagues',
|
||||
'/matches',
|
||||
'/teams',
|
||||
'/predictions',
|
||||
'/spor-toto',
|
||||
'/coupon-builder',
|
||||
'/h2h'
|
||||
];
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
const sitemapEntries: MetadataRoute.Sitemap = [];
|
||||
|
||||
staticPages.forEach((page) => {
|
||||
routing.locales.forEach((locale) => {
|
||||
sitemapEntries.push({
|
||||
url: `${baseUrl}/${locale}${page}`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: 'daily',
|
||||
priority: page === '' || page === '/home' ? 1.0 : 0.8,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return sitemapEntries;
|
||||
}
|
||||
Reference in New Issue
Block a user