diff --git a/public/llms.txt b/public/llms.txt new file mode 100644 index 0000000..3832651 --- /dev/null +++ b/public/llms.txt @@ -0,0 +1,34 @@ +# YS Lootah Robotics + +> YS Lootah Robotics is the United Arab Emirates destination for selected Unitree and Pudu robotics. We sell, configure, demonstrate and deploy humanoid, quadruped, delivery, hospitality and cleaning robots for businesses across Dubai and the UAE. Part of the Yousuf Saeed Lootah Investment Group. + +## Important Pages +- [Home](https://yslootahrobotics.com/) +- [All robots](https://yslootahrobotics.com/robots/) +- [Configure your robot (3D)](https://yslootahrobotics.com/configure/) +- [Brands](https://yslootahrobotics.com/brands/) +- [Industries](https://yslootahrobotics.com/industries/) +- [Accessories](https://yslootahrobotics.com/accessories/) +- [Book a demo](https://yslootahrobotics.com/book-demo/) +- [Contact](https://yslootahrobotics.com/contact/) +- [About](https://yslootahrobotics.com/about/) + +## What we offer +- Robot sales in the UAE: humanoids (Unitree G1, H1), quadrupeds (Unitree Go2, B2), and Pudu delivery, reception and cleaning robots. +- 3D configurator: choose persona, attire, colours and accessories, preview live, then request a UAE quotation. +- Live demonstrations and showroom visits in Dubai. +- On-site deployment, integration and support across the UAE. +- Accessories and add-ons for Unitree and Pudu platforms. + +## Brands +- [Unitree Robotics](https://yslootahrobotics.com/robots/): humanoid and quadruped robots. +- [Pudu Robotics](https://yslootahrobotics.com/robots/): service, delivery and cleaning robots. + +## Industries served +Hospitality, restaurants and cafes, hotels and resorts, shopping malls, healthcare, education, security and surveillance. + +## Contact +- Email: info@yslootahrobotics.com +- Phone: +971 55 948 2728, +971 4 349 9319 +- WhatsApp: https://wa.me/971559482728 +- Location: Office 408, City Bay Business Center, Dubai, United Arab Emirates diff --git a/public/og.jpg b/public/og.jpg new file mode 100644 index 0000000..358b108 Binary files /dev/null and b/public/og.jpg differ diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..1fa36e7 --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1,16 @@ +{ + "name": "YS Lootah Robotics", + "short_name": "Lootah Robotics", + "description": "The UAE destination for selected Unitree and Pudu robotics. Explore, configure and book a demo in Dubai.", + "start_url": "/", + "display": "standalone", + "background_color": "#0b0b0b", + "theme_color": "#0b0b0b", + "lang": "en", + "icons": [ + { "src": "/icon-192.webp", "sizes": "192x192", "type": "image/webp", "purpose": "any" }, + { "src": "/icon-512.webp", "sizes": "512x512", "type": "image/webp", "purpose": "any" }, + { "src": "/icon-192-maskable.webp", "sizes": "192x192", "type": "image/webp", "purpose": "maskable" }, + { "src": "/icon-512-maskable.webp", "sizes": "512x512", "type": "image/webp", "purpose": "maskable" } + ] +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 856bdd2..c640176 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,6 +1,8 @@ import type { Metadata, Viewport } from "next"; import { ErrorBoundary } from "@/components/ErrorBoundary"; import { I18nProvider } from "@/components/I18nProvider"; +import JsonLd from "@/components/JsonLd"; +import { OG_IMAGE, siteName, organizationJsonLd, websiteJsonLd } from "@/lib/seo"; import "./globals.css"; export const metadata: Metadata = { @@ -28,17 +30,32 @@ export const metadata: Metadata = { ], openGraph: { type: 'website', + url: '/', title: 'YS Lootah Robotics UAE Destination for Unitree & Pudu Robotics', description: 'Advanced robotics. UAE access. Selected Unitree and Pudu solutions available through YS Lootah Robotics in Dubai.', locale: 'en_AE', siteName: 'YS Lootah Robotics', + images: [{ url: OG_IMAGE, width: 1200, height: 630, alt: siteName }], }, twitter: { card: 'summary_large_image', title: 'YS Lootah Robotics UAE Destination for Unitree & Pudu Robotics', description: 'The UAE’s dedicated destination for Unitree and Pudu Robotics sales, demo inquiries, and business deployment.', + images: [OG_IMAGE], + }, + manifest: '/site.webmanifest', + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + 'max-image-preview': 'large', + 'max-snippet': -1, + 'max-video-preview': -1, + }, }, }; @@ -63,6 +80,7 @@ export default function RootLayout({ + {children} diff --git a/src/app/page.tsx b/src/app/page.tsx index 309b9b0..07b5985 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -35,6 +35,7 @@ export const metadata: Metadata = { 'robotics configuration UAE', 'robot sales and demo UAE', ], + alternates: { canonical: '/' }, }; export default function HomePage() { diff --git a/src/app/robots.ts b/src/app/robots.ts new file mode 100644 index 0000000..e148f68 --- /dev/null +++ b/src/app/robots.ts @@ -0,0 +1,16 @@ +import type { MetadataRoute } from 'next'; +import { SITE_URL } from '@/lib/seo'; + +export default function robots(): MetadataRoute.Robots { + return { + rules: [ + { + userAgent: '*', + allow: '/', + disallow: ['/admin', '/admin/', '/api/'], + }, + ], + sitemap: `${SITE_URL}/sitemap.xml`, + host: SITE_URL, + }; +} diff --git a/src/app/robots/[slug]/page.tsx b/src/app/robots/[slug]/page.tsx index 7ea61e8..23fbc33 100644 --- a/src/app/robots/[slug]/page.tsx +++ b/src/app/robots/[slug]/page.tsx @@ -11,6 +11,8 @@ import { ProductSpecTable } from '@/components/robotics/ProductSpecTable'; import { ProductGallery } from '@/components/robotics/ProductGallery'; import { MotionSection } from '@/components/ui/MotionSection'; import { ROBOTS, getRobotBySlug, BRANDS, CATEGORY_LABELS } from '@/data/robots'; +import JsonLd from '@/components/JsonLd'; +import { canonical, abs, productJsonLd, breadcrumbJsonLd } from '@/lib/seo'; type Params = { slug: string }; @@ -22,10 +24,17 @@ export async function generateMetadata({ params }: { params: Promise }): const { slug } = await params; const robot = getRobotBySlug(slug); if (!robot) return { title: 'Robot not found YS Lootah Robotics' }; + const url = canonical(`/robots/${robot.slug}`); + const img = abs(robot.image); + const title = `${robot.brandLabel} ${robot.name} Available in Dubai | YS Lootah Robotics`; + const description = `${robot.shortDescription} Available through YS Lootah Robotics in Dubai request a price or book a live demo.`; return { - title: `${robot.brandLabel} ${robot.name} Available in Dubai | YS Lootah Robotics`, - description: `${robot.shortDescription} Available through YS Lootah Robotics in Dubai request a price or book a live demo.`, + title, + description, keywords: [robot.brandLabel, robot.name, 'Dubai', 'UAE', CATEGORY_LABELS[robot.category], 'robotics'], + alternates: { canonical: url }, + openGraph: { type: 'website', url, title, description, images: [{ url: img, alt: `${robot.brandLabel} ${robot.name}` }] }, + twitter: { card: 'summary_large_image', title, description, images: [img] }, }; } @@ -37,8 +46,23 @@ export default async function RobotDetailPage({ params }: { params: Promise r.id !== robot.id && (r.brand === robot.brand || r.category === robot.category)).slice(0, 3); + const productLd = productJsonLd({ + name: `${robot.brandLabel} ${robot.name}`, + description: robot.shortDescription, + image: robot.image, + brandName: brand.name, + path: `/robots/${robot.slug}`, + category: CATEGORY_LABELS[robot.category], + }); + const crumbLd = breadcrumbJsonLd([ + { name: 'Home', path: '/' }, + { name: 'Robots', path: '/robots' }, + { name: robot.name, path: `/robots/${robot.slug}` }, + ]); + return ( <> +
diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts index 53073f1..fbd2782 100644 --- a/src/app/sitemap.ts +++ b/src/app/sitemap.ts @@ -1,29 +1,48 @@ import { MetadataRoute } from 'next'; import { ROBOTS } from '@/data/robots'; - -const baseUrl = 'https://yslootahrobotics.com'; +import { INDUSTRIES } from '@/data/industries'; +import { ACCESSORIES } from '@/data/accessories'; +import { SITE_URL } from '@/lib/seo'; export default function sitemap(): MetadataRoute.Sitemap { const now = new Date(); + const u = (path: string) => `${SITE_URL}${path}`; + const staticRoutes: MetadataRoute.Sitemap = [ - { url: `${baseUrl}/`, lastModified: now, changeFrequency: 'weekly', priority: 1 }, - { url: `${baseUrl}/robots/`, lastModified: now, changeFrequency: 'weekly', priority: 0.9 }, - { url: `${baseUrl}/brands/`, lastModified: now, changeFrequency: 'weekly', priority: 0.8 }, - { url: `${baseUrl}/industries/`, lastModified: now, changeFrequency: 'weekly', priority: 0.8 }, - { url: `${baseUrl}/about/`, lastModified: now, changeFrequency: 'monthly', priority: 0.6 }, - { url: `${baseUrl}/contact/`, lastModified: now, changeFrequency: 'monthly', priority: 0.7 }, - { url: `${baseUrl}/book-demo/`, lastModified: now, changeFrequency: 'monthly', priority: 0.8 }, - { url: `${baseUrl}/configure/`, lastModified: now, changeFrequency: 'monthly', priority: 0.8 }, - { url: `${baseUrl}/privacy-policy/`, lastModified: now, changeFrequency: 'yearly', priority: 0.3 }, - { url: `${baseUrl}/terms-of-service/`, lastModified: now, changeFrequency: 'yearly', priority: 0.3 }, + { url: u('/'), lastModified: now, changeFrequency: 'weekly', priority: 1 }, + { url: u('/robots/'), lastModified: now, changeFrequency: 'weekly', priority: 0.9 }, + { url: u('/configure/'), lastModified: now, changeFrequency: 'weekly', priority: 0.9 }, + { url: u('/brands/'), lastModified: now, changeFrequency: 'weekly', priority: 0.8 }, + { url: u('/industries/'), lastModified: now, changeFrequency: 'weekly', priority: 0.8 }, + { url: u('/accessories/'), lastModified: now, changeFrequency: 'weekly', priority: 0.7 }, + { url: u('/book-demo/'), lastModified: now, changeFrequency: 'monthly', priority: 0.8 }, + { url: u('/contact/'), lastModified: now, changeFrequency: 'monthly', priority: 0.7 }, + { url: u('/about/'), lastModified: now, changeFrequency: 'monthly', priority: 0.6 }, + { url: u('/bu-sunaidah/'), lastModified: now, changeFrequency: 'monthly', priority: 0.5 }, + { url: u('/privacy-policy/'), lastModified: now, changeFrequency: 'yearly', priority: 0.3 }, + { url: u('/terms-of-service/'), lastModified: now, changeFrequency: 'yearly', priority: 0.3 }, ]; const robotRoutes: MetadataRoute.Sitemap = ROBOTS.map((r) => ({ - url: `${baseUrl}/robots/${r.slug}/`, + url: u(`/robots/${r.slug}/`), lastModified: now, changeFrequency: 'monthly', priority: 0.7, })); - return [...staticRoutes, ...robotRoutes]; + const industryRoutes: MetadataRoute.Sitemap = INDUSTRIES.map((i) => ({ + url: u(`/industries/${i.slug}/`), + lastModified: now, + changeFrequency: 'monthly', + priority: 0.6, + })); + + const accessoryRoutes: MetadataRoute.Sitemap = ACCESSORIES.map((a) => ({ + url: u(`/accessories/${a.slug}/`), + lastModified: now, + changeFrequency: 'monthly', + priority: 0.5, + })); + + return [...staticRoutes, ...robotRoutes, ...industryRoutes, ...accessoryRoutes]; } diff --git a/src/components/JsonLd.tsx b/src/components/JsonLd.tsx new file mode 100644 index 0000000..878cd43 --- /dev/null +++ b/src/components/JsonLd.tsx @@ -0,0 +1,10 @@ +// Renders a JSON-LD structured-data script tag. +export default function JsonLd({ data }: { data: object | object[] }) { + return ( +