From 0b8527c1366c998bdd703529c0dba941053c0154 Mon Sep 17 00:00:00 2001 From: Alireza Hassani Date: Sat, 5 Sep 2026 19:48:59 +0330 Subject: [PATCH] Add page metadata and generated SEO sitemap configuration --- CONTEXT.md | 3 +++ app/about-us/page.tsx | 2 +- app/blog/page.tsx | 2 +- app/layout.tsx | 14 +++++++++++++- app/page.tsx | 5 +++++ app/tmas-bama/page.tsx | 2 +- public/meshkee/sitemap-config.json | 8 ++++++-- scripts/sitemap-config.mjs | 8 +++++++- 8 files changed, 37 insertions(+), 7 deletions(-) diff --git a/CONTEXT.md b/CONTEXT.md index 05e7967..8943e8d 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -47,4 +47,7 @@ User confirmed parent-domain cookies meshkee_customer_access_token and meshkee_c ## Backend access rules confirmed (2026-09-05) Profile URL: https://customer.sgemed.com/profile. Website management URL: https://business.sgemed.com/website. The account endpoint treats a user as eligible for the management link only if they are a super-admin (`isSuperAdmin` or `roles` includes `super_admin`) or hold a membership for the resolved SGE tenant (`businessId`/`id` matches tenant ID) with `isOwner: true` or `teamRole` `admin`, `editor`, or `viewer`. This decision is made server-side from the verified `/auth/me` response; it is never inferred from client data. +## SEO update (2026-09-05) +Source brief: https://api.meshkee.com/api/v1/public/ai-prompts/sge-medical-group/seo/700d7980abbb7920d7a95085. Added page-specific titles, descriptions and canonical URLs for home, about, contact and blog; root metadata now includes Persian Open Graph defaults and `metadataBase` for sgemed.com. Blog detail already uses CMS title/content summary and canonical `/blog/{id}/{titleSlug}`. The build-time sitemap generator now publishes `public/meshkee/sitemap-config.json` with change frequencies and priorities for public static routes only. Do not add `robots.txt` or `sitemap.xml`: production nginx proxies Meshkee’s generated versions. After deployment, run Website → Settings → Sync sitemap config in the Meshkee business dashboard to include the static routes. + Build-generated public/meshkee/sitemap-config.json lists public static pages. Do not ship sitemap.xml or robots.txt because production nginx delegates them to Meshkee. Test commands: node --experimental-strip-types --test tests/contact.test.mjs; node --test tests/backend.test.cjs. diff --git a/app/about-us/page.tsx b/app/about-us/page.tsx index dff925e..a4a6052 100644 --- a/app/about-us/page.tsx +++ b/app/about-us/page.tsx @@ -1,3 +1,3 @@ import Link from 'next/link'; -export const metadata={title:'درباره ما'}; +export const metadata={title:'درباره سلامت گستر اعتماد',description:'با شرکت مهندسی سلامت گستر اعتماد، مشاور و مجری استریل و کنترل عفونت، مأموریت و رویکرد ما آشنا شوید.',alternates:{canonical:'/about-us'}}; export default function About(){return <>
ABOUT SGE MEDICAL GROUP

آنچه درباره ما باید بدانید

شرکت مهندسی سلامت گستر اعتماد

از یک ایده در سال ۱۳۸۵

هر روز، بهتر از دیروز.

اولین ایده تشکیل شرکت در سال ۱۳۸۵، با هدف نوآوری، خلاقیت، ایجاد اشتغال و تولید ارزش افزوده شکل گرفت. تجربه کار در حوزه خدمات سلامت، بهداشت، کنترل عفونت و استریلیزاسیون، نگاه ما را تکامل داد.

باور داریم هدف غایی این است که کاری را که بر عهده می‌گیریم، هر روز بهتر از دیروز انجام دهیم و مشکلی از مشکلات مشتریانمان کم کنیم.

مهندس اویسیمدیرعامل
تجهیزات و فعالیت در آزمایشگاه

دانش و تجربه، در خدمت سلامت

اکنون پس از تجربه‌های فراوان، سبدی از محصولات دارای استانداردها و تأییدیه‌های جهانی و مناسب اقتصاد ایران را در زمینه استریلیزاسیون و کنترل عفونت ارائه می‌دهیم. هدف ما بهبود مستمر در سایه دانش و تجربه است.

بهبود مستمر، کلید ماندگاری است.

اعتقادی به تبلیغات غلوآمیز «بهترین» و «بزرگترین» نداریم. معتقدیم هر روز کاری، روزی برای بهتر شدن و بزرگتر شدن است. دنیای امروز، دنیای تغییرات سریع است و نبوغ و تلاش آدمی مرز ندارد.

ما خانواده کوچکی هستیم که با تمرکز بر توسعه دانش و آموزش مهارت‌ها، در کنار همکاران، رقبا و به‌ویژه شما مشتریان عزیز بهتر می‌شویم. تمام تلاشمان را انجام می‌دهیم تا کاری را که بر عهده می‌گیریم به بهترین شکل ممکن به انجام برسانیم و پذیرای نظرات و پیشنهادات شما هستیم.

با ما در ارتباط باشید ←
} diff --git a/app/blog/page.tsx b/app/blog/page.tsx index 0294e2d..8ca89e5 100644 --- a/app/blog/page.tsx +++ b/app/blog/page.tsx @@ -1,7 +1,7 @@ import Link from 'next/link'; import { BookOpen, ArrowUpLeft } from 'lucide-react'; import { getBlogs, blogHref, summary, cover } from '../../lib/meshkee/blog'; -export const metadata = {title:'مجله سلامت گستر',description:'مقالات و تازه‌های سلامت گستر اعتماد در زمینه استریلیزاسیون، تجهیزات پزشکی و کنترل عفونت.'}; +export const metadata = {title:'مجله سلامت گستر',description:'مقالات و تازه‌های سلامت گستر اعتماد در زمینه استریلیزاسیون، تجهیزات پزشکی و کنترل عفونت.',alternates:{canonical:'/blog'}}; export const dynamic = 'force-dynamic'; export default async function BlogPage({searchParams}:{searchParams:Promise<{page?:string}>}) { const query=await searchParams; const page=Math.max(1,Math.min(10000,Number.parseInt(query.page||'1',10)||1)); diff --git a/app/layout.tsx b/app/layout.tsx index 36cb549..d1c6a24 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -4,7 +4,19 @@ import Link from 'next/link'; import './globals.css'; import { getFavicon } from '../lib/meshkee/api'; import ProductMenu from '../components/product-menu'; -const baseMetadata: Metadata = { title: { default: 'سلامت گستر اعتماد | تجهیزات استریل و کنترل عفونت', template: '%s | سلامت گستر اعتماد' }, description: 'شرکت مهندسی سلامت گستر اعتماد؛ مشاور و مجری استریل و کنترل عفونت. محصولات تخصصی، کاتالوگ‌ها و راه‌های ارتباط با ما.' }; +const baseMetadata: Metadata = { + metadataBase: new URL('https://sgemed.com'), + title: { default: 'سلامت گستر اعتماد | تجهیزات استریل و کنترل عفونت', template: '%s | سلامت گستر اعتماد' }, + description: 'شرکت مهندسی سلامت گستر اعتماد؛ مشاور و مجری استریل و کنترل عفونت. محصولات تخصصی، کاتالوگ‌ها و راه‌های ارتباط با ما.', + alternates: { canonical: '/' }, + openGraph: { + type: 'website', + locale: 'fa_IR', + siteName: 'سلامت گستر اعتماد', + title: 'سلامت گستر اعتماد | تجهیزات استریل و کنترل عفونت', + description: 'مشاور و مجری استریل و کنترل عفونت؛ محصولات تخصصی، کاتالوگ‌ها و راه‌های ارتباط با ما.', + }, +}; export async function generateMetadata(): Promise { return { ...baseMetadata, icons: { icon: await getFavicon() } }; } export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) { return
مشاور و مجری استریل و کنترل عفونتدفتر تهران ۰۲۱ − ۶۶۱۵۷۶۰۹
SGE Medical Groupمشاوره و خرید ↖
{children}
diff --git a/app/page.tsx b/app/page.tsx index fe1c4c4..c97a521 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -2,5 +2,10 @@ import HeroSlider from '../components/hero-slider'; import Link from 'next/link'; import { FlaskConical, ShieldCheck, Package, Microscope, ArrowDownLeft, MoveLeft } from 'lucide-react'; import catalog from './catalog.json'; +export const metadata = { + title: 'تجهیزات استریل و کنترل عفونت', + description: 'محصولات تخصصی سلامت گستر اعتماد برای استریلیزاسیون، کنترل عفونت و بسته‌بندی استریل مراکز درمانی.', + alternates: { canonical: '/' }, +}; const groups=[{title:'اندیکاتورهای شیمیایی',en:'Chemical indicators',icon:FlaskConical,start:2,end:15},{title:'اندیکاتورهای بیولوژیکال',en:'Biological indicators',icon:Microscope,start:0,end:2},{title:'بسته‌بندی استریل',en:'Sterile packaging',icon:Package,start:15,end:26},{title:'بهداشت و کنترل عفونت',en:'Infection control',icon:ShieldCheck,start:26,end:30}]; export default function Home(){return <>
{groups.map((g,i)=>
{g.title}{g.en}
)}
محصولات تخصصی ما

دقت در انتخاب؛ اطمینان در عملکرد

معرفی محصولات و دریافت کاتالوگ‌های تخصصی
استریل، بسته‌بندی و کنترل عفونت

{groups.map((g,i)=>
{g.title}{g.en}مشاهده محصولات +
)}
فعالیت متخصصان در محیط پزشکی
دانش، پایهٔ مراقبت بهتر

آموزش، کلید توسعه
و تخصص ما است.

دانش استریل و بازفرآوری ابزار پزشکی، دانشی چندبعدی و تخصصی است. کتاب راهنمای جامع استریلیزاسیون، ترجمه گایدلاین ST79، برای فعالان حوزه استریل و کارشناسان کنترل عفونت معرفی شده است.

برای تهیه کتاب با ما تماس بگیرید
استریل و کنترل عفونت

شناخت بهتر، انتخاب آگاهانه‌تر

۰۱ / CHEMICAL

اندیکاتور شیمیایی چیست؟

این نشانگرها معمولاً جامد و کاغذی‌شکل هستند، داخل پک‌های استریل قرار می‌گیرند و در طول فرایند استریلیزاسیون تغییر رنگ می‌دهند.

۰۲ / BIOLOGICAL

اندیکاتور بیولوژیکال چیست؟

این اندیکاتورها حاوی میکروارگانیسم‌های زنده هستند. نتیجه کشت آن‌ها در محیط مرتبط، برای ارزیابی عملکرد فرایند استریلیزاسیون استفاده می‌شود.

۰۳ / DOCUMENTATION

مستندسازی و ردیابی استریل

نرم‌افزار CSSD-DOC برای مستندسازی و ردیابی استریل؛ گذار از دنیای کاغذی به عصر الکترونیک.

دریافت اطلاعات بیشتر ←

برای انتخاب محصول مناسب، همراه شما هستیم.

مشاوره و خرید محصولات تخصصی کنترل عفونت و استریلیزاسیون

ارتباط با کارشناسان
} diff --git a/app/tmas-bama/page.tsx b/app/tmas-bama/page.tsx index eb55e48..d0c2ec5 100644 --- a/app/tmas-bama/page.tsx +++ b/app/tmas-bama/page.tsx @@ -1,7 +1,7 @@ import ContactForm from '../../components/backend/contact-form'; import { Phone, Headphones, Mail, Send, Printer, ArrowUpLeft } from 'lucide-react'; -export const metadata = { title: 'تماس با ما' }; +export const metadata = { title: 'تماس با سلامت گستر اعتماد', description: 'برای مشاوره و خرید محصولات استریلیزاسیون و کنترل عفونت با کارشناسان سلامت گستر اعتماد تماس بگیرید.', alternates: { canonical: '/tmas-bama' } }; export default function Contact() { return <> diff --git a/public/meshkee/sitemap-config.json b/public/meshkee/sitemap-config.json index 9f9f60b..e37410a 100644 --- a/public/meshkee/sitemap-config.json +++ b/public/meshkee/sitemap-config.json @@ -3,19 +3,23 @@ "staticPages": [ { "path": "/about-us", + "changefreq": "monthly", "priority": 0.6 }, { "path": "/blog", - "priority": 0.6 + "changefreq": "weekly", + "priority": 0.7 }, { "path": "/", + "changefreq": "daily", "priority": 1 }, { "path": "/tmas-bama", - "priority": 0.6 + "changefreq": "monthly", + "priority": 0.5 } ] } diff --git a/scripts/sitemap-config.mjs b/scripts/sitemap-config.mjs index 29bc5c7..902634e 100644 --- a/scripts/sitemap-config.mjs +++ b/scripts/sitemap-config.mjs @@ -1,5 +1,11 @@ import {readdir,mkdir,writeFile} from 'node:fs/promises'; import path from 'node:path'; const staticPages=[]; -async function scan(dir,parts=[]){for(const entry of await readdir(dir,{withFileTypes:true})){if(entry.isDirectory()&&!entry.name.startsWith('[')&&!entry.name.startsWith('_')&&!['api','account','admin','login','cart','checkout'].includes(entry.name))await scan(path.join(dir,entry.name),entry.name.startsWith('(')?parts:[...parts,entry.name]);else if(entry.isFile()&&/^page\.(tsx|jsx|js|ts)$/.test(entry.name))staticPages.push({path:'/'+parts.join('/'),priority:parts.length?0.6:1})}} +const seoByPath={ + '/':{changefreq:'daily',priority:1}, + '/about-us':{changefreq:'monthly',priority:0.6}, + '/tmas-bama':{changefreq:'monthly',priority:0.5}, + '/blog':{changefreq:'weekly',priority:0.7}, +}; +async function scan(dir,parts=[]){for(const entry of await readdir(dir,{withFileTypes:true})){if(entry.isDirectory()&&!entry.name.startsWith('[')&&!entry.name.startsWith('_')&&!['api','account','admin','login','cart','checkout'].includes(entry.name))await scan(path.join(dir,entry.name),entry.name.startsWith('(')?parts:[...parts,entry.name]);else if(entry.isFile()&&/^page\.(tsx|jsx|js|ts)$/.test(entry.name)){const route='/'+parts.join('/');staticPages.push({path:route,...(seoByPath[route]||{changefreq:'monthly',priority:0.6})})}}} await scan('app');await mkdir('public/meshkee',{recursive:true});await writeFile('public/meshkee/sitemap-config.json',JSON.stringify({baseUrl:'https://sgemed.com',staticPages},null,2)+'\n');