canonical url changed

This commit is contained in:
Selvi 2026-04-10 16:33:00 +05:30
parent 6363b3996f
commit c21b2c03b2
13 changed files with 99 additions and 48 deletions

View File

@ -8,7 +8,8 @@
"start": "next start", "start": "next start",
"lint": "eslint", "lint": "eslint",
"sitemap": "node scripts/generate-sitemap.cjs", "sitemap": "node scripts/generate-sitemap.cjs",
"optimize-images": "node scripts/optimize-images.mjs" "optimize-images": "node scripts/optimize-images.mjs",
"seo-audit": "node scripts/seo-test-selenium.cjs"
}, },
"dependencies": { "dependencies": {
"axios": "^1.13.2", "axios": "^1.13.2",

View File

@ -1 +1 @@
<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://antalya.metatronnest.com/</loc><changefreq>daily</changefreq><priority>1.0</priority></url><url><loc>https://antalya.metatronnest.com/about-antalya-restaurant/</loc><changefreq>monthly</changefreq><priority>0.5</priority></url><url><loc>https://antalya.metatronnest.com/antalya-restaurant-menu/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://antalya.metatronnest.com/antalya-restaurant-gallery/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://antalya.metatronnest.com/catering-services-ontario/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://antalya.metatronnest.com/book-a-table/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://antalya.metatronnest.com/antalya-turkish-food-blog/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://antalya.metatronnest.com/antalya-turkish-food-blog/the-art-of-turkish-tea/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://antalya.metatronnest.com/antalya-turkish-food-blog/secrets-of-charcoal-grilling/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://antalya.metatronnest.com/antalya-turkish-food-blog/a-taste-of-sweet-legacy/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url></urlset> <?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"><url><loc>https://burlington.antalyarestaurant.ca/</loc><changefreq>daily</changefreq><priority>1.0</priority></url><url><loc>https://burlington.antalyarestaurant.ca/about-antalya-restaurant/</loc><changefreq>monthly</changefreq><priority>0.5</priority></url><url><loc>https://burlington.antalyarestaurant.ca/antalya-restaurant-menu/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://burlington.antalyarestaurant.ca/antalya-restaurant-gallery/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://burlington.antalyarestaurant.ca/catering-services-ontario/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://burlington.antalyarestaurant.ca/book-a-table/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://burlington.antalyarestaurant.ca/antalya-turkish-food-blog/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://burlington.antalyarestaurant.ca/antalya-turkish-food-blog/the-art-of-turkish-tea/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://burlington.antalyarestaurant.ca/antalya-turkish-food-blog/secrets-of-charcoal-grilling/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url><url><loc>https://burlington.antalyarestaurant.ca/antalya-turkish-food-blog/a-taste-of-sweet-legacy/</loc><changefreq>weekly</changefreq><priority>0.6</priority></url></urlset>

View File

@ -3,7 +3,7 @@ const path = require("path");
const { SitemapStream, streamToPromise } = require("sitemap"); const { SitemapStream, streamToPromise } = require("sitemap");
const { pathToFileURL } = require("url"); const { pathToFileURL } = require("url");
const hostname = "https://antalya.metatronnest.com"; // localhost for development const hostname = "https://burlington.antalyarestaurant.ca"; // localhost for development
const addTrailingSlash = true; // ✅ Set this true if your Next.js uses trailingSlash: true const addTrailingSlash = true; // ✅ Set this true if your Next.js uses trailingSlash: true
// Utility to format URLs based on config // Utility to format URLs based on config

View File

@ -15,26 +15,11 @@ import 'swiper/css';
import 'swiper/css/navigation'; import 'swiper/css/navigation';
import { FaStar, FaChevronLeft, FaChevronRight } from 'react-icons/fa'; import { FaStar, FaChevronLeft, FaChevronRight } from 'react-icons/fa';
interface Review { import { Review } from "@/utils/getReviews";
text?: string;
description?: string;
snippet?: string;
review_text?: string;
body?: string;
content?: string;
rating: number;
profile_photo_url?: string;
author_profile_photo_url?: string;
user?: {
thumbnail?: string;
name?: string;
};
author_name?: string;
}
export default function AboutContent() { export default function AboutContent({ initialReviews = [] }: { initialReviews?: Review[] }) {
const [reviews, setReviews] = useState<Review[]>([]); const [reviews, setReviews] = useState<Review[]>(initialReviews);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(initialReviews.length === 0);
const [expandedReview, setExpandedReview] = useState<number | null>(null); const [expandedReview, setExpandedReview] = useState<number | null>(null);
const [swiperInstance, setSwiperInstance] = useState<any>(null); const [swiperInstance, setSwiperInstance] = useState<any>(null);
@ -115,6 +100,8 @@ export default function AboutContent() {
}; };
useEffect(() => { useEffect(() => {
if (initialReviews.length > 0) return;
async function loadReviews() { async function loadReviews() {
try { try {
const res = await fetch("/api/reviews"); const res = await fetch("/api/reviews");
@ -132,7 +119,7 @@ export default function AboutContent() {
} }
} }
loadReviews(); loadReviews();
}, []); }, [initialReviews]);
const displayedReviews = reviews.length > 0 && reviews.length < 3 const displayedReviews = reviews.length > 0 && reviews.length < 3
? [...reviews, ...reviews, ...reviews] ? [...reviews, ...reviews, ...reviews]

View File

@ -1,16 +1,16 @@
import { Metadata } from "next"; import { Metadata } from "next";
import AboutContent from "./AboutContent"; import AboutContent from "./AboutContent";
import ClientOnly from "@/components/ClientOnly"; import { getReviews } from "@/utils/getReviews";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "About Antalya Restaurant | Authentic Turkish Dining", title: "About Antalya Restaurant | Authentic Turkish Dining",
description: "Learn about Antalya Restaurant in Ontario - where authentic Turkish flavours, warm hospitality come together for a memorable dining experience.", description: "Learn about Antalya Restaurant in Ontario - where authentic Turkish flavours, warm hospitality come together for a memorable dining experience.",
}; };
export default function AboutPage() { export default async function AboutPage() {
const reviews = await getReviews();
return ( return (
<ClientOnly> <AboutContent initialReviews={reviews} />
<AboutContent />
</ClientOnly>
); );
} }

View File

@ -20,8 +20,8 @@ export async function generateMetadata({ params }: { params: Promise<{ id: strin
} }
return { return {
title: `${blog.title} | Antalya Restaurant`, title: blog.metatitle || `${blog.title} | Antalya Restaurant`,
description: blog.excerpt, description: blog.metadesc || blog.excerpt,
openGraph: { openGraph: {
title: blog.title, title: blog.title,
description: blog.excerpt, description: blog.excerpt,

View File

@ -25,10 +25,10 @@ const dmSans = DM_Sans({
// We'll use system fonts as fallback in the CSS variables // We'll use system fonts as fallback in the CSS variables
export const metadata: Metadata = { export const metadata: Metadata = {
metadataBase: new URL("https://antalya.metatronnest.com"), metadataBase: new URL("https://burlington.antalyarestaurant.ca"),
title: { title: {
default: "Antalya Restaurant Burlington - Authentic Turkish cuisine", default: "Antalya Restaurant Burlington | Authentic Turkish Cuisine",
template: "%s | Antalya Restaurant Burlington" template: "%s"
}, },
description: "Experience the finest authentic Turkish cuisine at Antalya Restaurant Burlington. Enjoy our delicious kebabs, mezes, and desserts in a warm, inviting atmosphere.", description: "Experience the finest authentic Turkish cuisine at Antalya Restaurant Burlington. Enjoy our delicious kebabs, mezes, and desserts in a warm, inviting atmosphere.",
keywords: ["Turkish restaurant", "Antalya restaurant", "Turkish cuisine", "kebabs", "meze", "dining", "authentic food", "halal food", "middle eastern food"], keywords: ["Turkish restaurant", "Antalya restaurant", "Turkish cuisine", "kebabs", "meze", "dining", "authentic food", "halal food", "middle eastern food"],

View File

@ -11,13 +11,16 @@ import BookTable from "@/components/BookTable/BookTable";
import Footer from "@/components/Footer/Footer"; import Footer from "@/components/Footer/Footer";
import { Metadata } from "next"; import { Metadata } from "next";
import { getReviews } from "@/utils/getReviews";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Best Turkish Restaurant in Ontario | Antalya", title: "Best Turkish Restaurant in Ontario | Antalya",
description: "Enjoy authentic Turkish dining at Antalya with charcoal-grilled kebabs, handcrafted dishes, & warm hospitality for a memorable taste of Turkey.", description: "Enjoy authentic Turkish dining at Antalya with charcoal-grilled kebabs, handcrafted dishes, & warm hospitality for a memorable taste of Turkey.",
}; };
export default function Home() { export default async function Home() {
const reviews = await getReviews();
return ( return (
<main> <main>
<Hero /> <Hero />
@ -26,7 +29,7 @@ export default function Home() {
<Catering /> <Catering />
<Menu /> <Menu />
<Gallery /> <Gallery />
<Testimonials /> <Testimonials initialReviews={reviews} />
<Blogs /> <Blogs />
<BookTable /> <BookTable />
<Footer /> <Footer />

View File

@ -185,9 +185,9 @@ export default function Catering() {
variants={containerVariants} variants={containerVariants}
> >
<motion.div variants={itemVariants} className={styles.smallHeading} style={{ display: 'flex', alignItems: 'center', justifyContent: 'start', gap: '10px' }}> <motion.div variants={itemVariants} className={styles.smallHeading} style={{ display: 'flex', alignItems: 'center', justifyContent: 'start', gap: '10px' }}>
<Image src="/images/dinner.png" alt="Home Gallery Decorative Dinner Icon" width={24} height={24} /> <Image src="/images/dinner.png" alt="Home Gallery Decorative Dinner" width={24} height={24} />
<span>CATERING & EVENTS</span> <span>CATERING & EVENTS</span>
<Image src="/images/eat.png" alt="Home Gallery Decorative Cutlery Icon" width={24} height={24} /> <Image src="/images/eat.png" alt="Home Gallery Decorative Cutlery" width={24} height={24} />
</motion.div> </motion.div>
<motion.h2 variants={itemVariants} className={styles.title}> <motion.h2 variants={itemVariants} className={styles.title}>

View File

@ -1,10 +1,5 @@
"use client";
import dynamic from "next/dynamic"; import Navbar from "@/components/Navbar/Navbar";
const Navbar = dynamic(() => import("@/components/Navbar/Navbar"), {
ssr: false,
});
export default function NavbarClient() { export default function NavbarClient() {
return <Navbar />; return <Navbar />;

View File

@ -29,9 +29,9 @@ interface Review {
author_name?: string; author_name?: string;
} }
export default function Testimonials() { export default function Testimonials({ initialReviews = [] }: { initialReviews?: Review[] }) {
const [reviews, setReviews] = useState<Review[]>([]); const [reviews, setReviews] = useState<Review[]>(initialReviews);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(initialReviews.length === 0);
const [expandedReview, setExpandedReview] = useState<number | null>(null); const [expandedReview, setExpandedReview] = useState<number | null>(null);
const [swiperInstance, setSwiperInstance] = useState<any>(null); const [swiperInstance, setSwiperInstance] = useState<any>(null);
@ -86,6 +86,8 @@ export default function Testimonials() {
}, [expandedReview, swiperInstance]); }, [expandedReview, swiperInstance]);
useEffect(() => { useEffect(() => {
if (initialReviews.length > 0) return;
async function loadReviews() { async function loadReviews() {
try { try {
const res = await fetch("/api/reviews"); const res = await fetch("/api/reviews");
@ -120,7 +122,7 @@ export default function Testimonials() {
} }
} }
loadReviews(); loadReviews();
}, []); }, [initialReviews]);
const displayedReviews = reviews.length > 0 && reviews.length < 3 const displayedReviews = reviews.length > 0 && reviews.length < 3
? [...reviews, ...reviews, ...reviews] ? [...reviews, ...reviews, ...reviews]

View File

@ -4,7 +4,7 @@ export const blogData = [
slug: 'the-art-of-turkish-tea', slug: 'the-art-of-turkish-tea',
title: 'The Art of Turkish Tea', title: 'The Art of Turkish Tea',
metatitle: 'The Art of Turkish Tea Tradition, Taste & Ritual', metatitle: 'The Art of Turkish Tea Tradition, Taste & Ritual',
metadesc: 'Discover the art of Turkish tea its history, brewing traditions, cultural significance, and how this cherished daily ritual reflects Turkish hospitality and heritage.', metadesc: 'Discover the art of Turkish tea—its history, brewing traditions, and cultural significance, reflecting daily rituals, warm hospitality, and rich heritage.',
category: 'Culture', category: 'Culture',
date: 'October 15, 2025', date: 'October 15, 2025',
comments: '12 Comments', comments: '12 Comments',

63
src/utils/getReviews.ts Normal file
View File

@ -0,0 +1,63 @@
export interface Review {
text?: string;
description?: string;
snippet?: string;
review_text?: string;
body?: string;
content?: string;
rating: number;
profile_photo_url?: string;
author_profile_photo_url?: string;
user?: {
thumbnail?: string;
name?: string;
};
author_name?: string;
}
export async function getReviews() {
const apiKey = "37eb7f83988cfd76ffb5c5af9adc25652efe5607e39997fc7d0e054d690ef25e";
const placeId = "ChIJjazCAVJhK4gRUj9RstvmUM0";
let allReviews: Review[] = [];
let nextPageToken: string | null = null;
let pageCount = 0;
try {
while (pageCount < 3) {
pageCount++;
const url: string = `https://serpapi.com/search.json?engine=google_maps_reviews&hl=en&api_key=${apiKey}&place_id=${placeId}${nextPageToken ? `&next_page_token=${nextPageToken}` : ""}`;
const response = await fetch(url, {
next: { revalidate: 3600 } // Cache for 1 hour
});
if (!response.ok) {
break;
}
const data = await response.json();
if (data.error || !data.reviews) {
break;
}
allReviews = [...allReviews, ...data.reviews];
if (!data.serpapi_pagination || !data.serpapi_pagination.next_page_token) {
break;
}
nextPageToken = data.serpapi_pagination.next_page_token;
}
return allReviews.filter((r: Review) =>
(r.text || r.description || r.snippet || r.review_text || r.body || r.content) &&
r.rating >= 4
);
} catch (error) {
console.error("Error fetching reviews:", error);
return [];
}
}