324 lines
12 KiB
TypeScript
324 lines
12 KiB
TypeScript
import './globals.css'
|
|
import type { Metadata, Viewport } from 'next'
|
|
import { Inter, Poppins } from 'next/font/google'
|
|
import Providers from './providers'
|
|
import { Toaster } from '@/components/ui/sonner'
|
|
import { auth } from '@/auth';
|
|
import StructuredData from '@/components/StructuredData'
|
|
import { generateOrganizationJsonLd } from '@/lib/structured-data'
|
|
import PWAInstallPrompt, { IOSInstallPrompt } from '@/components/PWAInstallPrompt'
|
|
import ClientFloatingWhatsApp from '@/components/ClientFloatingWhatsApp'
|
|
|
|
// Optimize font loading
|
|
const inter = Inter({
|
|
subsets: ['latin'],
|
|
display: 'swap',
|
|
preload: true,
|
|
variable: '--font-inter'
|
|
})
|
|
|
|
const poppins = Poppins({
|
|
subsets: ['latin'],
|
|
weight: ['400', '500', '600', '700'],
|
|
display: 'swap',
|
|
preload: true,
|
|
variable: '--font-poppins'
|
|
})
|
|
|
|
export const metadata: Metadata = {
|
|
title: 'Padmaaja Rasooi - Premium Rice Products & Quality Grains',
|
|
description: 'Experience the finest quality rice with Padmaaja Rasooi. Premium rice varieties sourced from the best farms for exceptional taste and nutrition.',
|
|
keywords: ['padmaaja rasooi', 'premium rice', 'quality rice', 'organic rice', 'basmati rice', 'rice products', 'agriculture', 'quality grains', 'healthy food'],
|
|
authors: [{ name: 'Padmaaja Rasooi Team' }],
|
|
creator: 'Padmaaja Rasooi',
|
|
publisher: 'Padmaaja Rasooi',
|
|
formatDetection: {
|
|
email: false,
|
|
address: false,
|
|
telephone: false,
|
|
},
|
|
other: {
|
|
charset: 'utf-8',
|
|
},
|
|
metadataBase: new URL(process.env.NEXTAUTH_URL || 'http://localhost:3000'),
|
|
alternates: {
|
|
canonical: '/',
|
|
},
|
|
openGraph: {
|
|
title: 'Padmaaja Rasooi - Premium Rice Products & Quality Grains',
|
|
description: 'Experience the finest quality rice with Padmaaja Rasooi. Premium rice varieties sourced from the best farms for exceptional taste and nutrition.',
|
|
url: '/',
|
|
siteName: 'Padmaaja Rasooi',
|
|
locale: 'en_US',
|
|
type: 'website',
|
|
images: [
|
|
{
|
|
url: '/android-chrome-512x512.png',
|
|
width: 512,
|
|
height: 512,
|
|
alt: 'Padmaaja Rasooi - Premium Rice Products',
|
|
type: 'image/png'
|
|
},
|
|
{
|
|
url: '/android-chrome-192x192.png',
|
|
width: 192,
|
|
height: 192,
|
|
alt: 'Padmaaja Rasooi Logo',
|
|
type: 'image/png'
|
|
}
|
|
]
|
|
},
|
|
twitter: {
|
|
card: 'summary_large_image',
|
|
title: 'Padmaaja Rasooi - Premium Rice Products & Quality Grains',
|
|
description: 'Experience the finest quality rice with Padmaaja Rasooi. Premium rice varieties sourced from the best farms for exceptional taste and nutrition.',
|
|
images: ['/android-chrome-512x512.png'],
|
|
creator: '@padmaajarasooi',
|
|
site: '@padmaajarasooi'
|
|
},
|
|
robots: {
|
|
index: true,
|
|
follow: true,
|
|
googleBot: {
|
|
index: true,
|
|
follow: true,
|
|
'max-video-preview': -1,
|
|
'max-image-preview': 'large',
|
|
'max-snippet': -1,
|
|
},
|
|
},
|
|
manifest: '/manifest.json',
|
|
icons: {
|
|
icon: [
|
|
{ url: '/favicon.ico', sizes: 'any' },
|
|
{ url: '/favicon-16x16.png', sizes: '16x16', type: 'image/png' },
|
|
{ url: '/favicon-32x32.png', sizes: '32x32', type: 'image/png' },
|
|
{ url: '/favicon-96x96.png', sizes: '96x96', type: 'image/png' }
|
|
],
|
|
shortcut: '/favicon.ico',
|
|
apple: [
|
|
{ url: '/apple-touch-icon.png', sizes: '180x180', type: 'image/png' }
|
|
],
|
|
other: [
|
|
{
|
|
rel: 'icon',
|
|
url: '/android-chrome-192x192.png',
|
|
sizes: '192x192',
|
|
type: 'image/png'
|
|
},
|
|
{
|
|
rel: 'icon',
|
|
url: '/android-chrome-512x512.png',
|
|
sizes: '512x512',
|
|
type: 'image/png'
|
|
}
|
|
]
|
|
},
|
|
appleWebApp: {
|
|
capable: true,
|
|
statusBarStyle: 'default',
|
|
title: 'Padmaaja Rasooi',
|
|
startupImage: [
|
|
{
|
|
url: '/images/apple-splash-2048-2732.png',
|
|
media: '(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
|
|
},
|
|
{
|
|
url: '/images/apple-splash-1668-2224.png',
|
|
media: '(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
export const viewport: Viewport = {
|
|
themeColor: [
|
|
{ media: '(prefers-color-scheme: light)', color: '#3B82F6' },
|
|
{ media: '(prefers-color-scheme: dark)', color: '#1E40AF' }
|
|
],
|
|
width: 'device-width',
|
|
initialScale: 1,
|
|
maximumScale: 1,
|
|
userScalable: false,
|
|
colorScheme: 'light'
|
|
}
|
|
|
|
export default async function PublicRootLayout({
|
|
children,
|
|
}: {
|
|
children: React.ReactNode
|
|
}) {
|
|
const session = await auth();
|
|
|
|
// Generate base URL for structured data
|
|
const baseUrl = process.env.NEXTAUTH_URL || 'https://padmaajarasooi.com'
|
|
const organizationData = generateOrganizationJsonLd(baseUrl)
|
|
|
|
return (
|
|
<html lang="en">
|
|
<head>
|
|
{/* DNS prefetch for external domains */}
|
|
<link rel="dns-prefetch" href="//images.unsplash.com" />
|
|
<link rel="dns-prefetch" href="//4m5m4tx28rtva30c.public.blob.vercel-storage.com" />
|
|
<link rel="dns-prefetch" href="//fonts.googleapis.com" />
|
|
|
|
{/* Preconnect to critical resources */}
|
|
<link rel="preconnect" href="https://images.unsplash.com" crossOrigin="anonymous" />
|
|
<link rel="preconnect" href="https://4m5m4tx28rtva30c.public.blob.vercel-storage.com" crossOrigin="anonymous" />
|
|
|
|
{/* Favicon and app icons */}
|
|
<link rel="icon" href="/favicon.ico" sizes="32x32" />
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
|
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png" />
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
|
<link rel="manifest" href="/manifest.json" />
|
|
<meta name="msapplication-TileColor" content="#10B981" />
|
|
<meta name="msapplication-config" content="/browserconfig.xml" />
|
|
<meta name="theme-color" content="#10B981" />
|
|
<meta property="og:image" content="/android-chrome-512x512.png" />
|
|
<meta property="og:image:type" content="image/png" />
|
|
<meta property="og:image:width" content="512" />
|
|
<meta property="og:image:height" content="512" />
|
|
<meta name="twitter:image" content="/android-chrome-512x512.png" />
|
|
</head>
|
|
<body className={`${inter.variable} ${poppins.variable} font-sans antialiased`}>
|
|
{/* Skip to main content link for accessibility */}
|
|
<a href="#main-content" className="sr-only focus:not-sr-only focus:absolute focus:top-0 focus:left-0 bg-blue-600 text-white p-2 z-50 rounded">
|
|
Skip to main content
|
|
</a>
|
|
|
|
{/* Organization Structured Data */}
|
|
<StructuredData data={organizationData} id="organization-data" />
|
|
|
|
<div
|
|
itemScope
|
|
itemType="https://schema.org/WebSite"
|
|
className="min-h-screen flex flex-col"
|
|
>
|
|
<meta itemProp="url" content={baseUrl} />
|
|
<meta itemProp="name" content="Padmaaja Rasooi" />
|
|
|
|
<Providers session={session}>
|
|
{/* Enhanced semantic structure for better SEO */}
|
|
<div className="flex-1 min-h-screen">
|
|
<main
|
|
id="main-content"
|
|
className="flex-1 min-h-screen"
|
|
role="main"
|
|
aria-label="Main content"
|
|
itemScope
|
|
itemType="https://schema.org/WebPage"
|
|
>
|
|
<article className="min-h-screen">
|
|
{children}
|
|
</article>
|
|
</main>
|
|
</div>
|
|
|
|
{/* Footer for semantic completeness */}
|
|
<footer
|
|
role="contentinfo"
|
|
aria-label="Site footer"
|
|
className="hidden"
|
|
itemScope
|
|
itemType="https://schema.org/WPFooter"
|
|
>
|
|
<div itemProp="copyrightHolder" itemScope itemType="https://schema.org/Organization">
|
|
<meta itemProp="name" content="Padmaaja Rasooi" />
|
|
</div>
|
|
</footer>
|
|
|
|
<Toaster />
|
|
<PWAInstallPrompt />
|
|
<IOSInstallPrompt />
|
|
<ClientFloatingWhatsApp
|
|
phoneNumber="+919475758817"
|
|
message="Hello! I'm interested in Padmaaja Rasooi products. Can you help me?"
|
|
position="bottom-right"
|
|
showTooltip={true}
|
|
/>
|
|
</Providers>
|
|
</div>
|
|
|
|
{/* PWA Cache Manager and Update Notification - Deferred for mobile performance */}
|
|
<script
|
|
dangerouslySetInnerHTML={{
|
|
__html: `
|
|
// Deferred Service Worker Registration for mobile performance
|
|
if ('serviceWorker' in navigator && 'requestIdleCallback' in window) {
|
|
// Use requestIdleCallback to register SW when main thread is idle
|
|
requestIdleCallback(function() {
|
|
navigator.serviceWorker.register('/sw.js', {
|
|
scope: '/',
|
|
updateViaCache: 'none'
|
|
})
|
|
.then(function(registration) {
|
|
console.log('SW registered: ', registration);
|
|
|
|
// Check for updates less frequently on mobile
|
|
const isMobile = window.innerWidth <= 768;
|
|
if (!isMobile) {
|
|
setInterval(() => registration.update(), 30000);
|
|
}
|
|
|
|
// Listen for updates
|
|
registration.addEventListener('updatefound', () => {
|
|
const newWorker = registration.installing;
|
|
if (newWorker) {
|
|
newWorker.addEventListener('statechange', () => {
|
|
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
|
// New version available - show less intrusive notification on mobile
|
|
if (isMobile) {
|
|
console.log('New version available - will update on next visit');
|
|
} else if (confirm('New version available! Refresh to update?')) {
|
|
window.location.reload();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
})
|
|
.catch(function(registrationError) {
|
|
console.log('SW registration failed: ', registrationError);
|
|
});
|
|
});
|
|
} else if ('serviceWorker' in navigator) {
|
|
// Fallback for browsers without requestIdleCallback
|
|
window.addEventListener('load', function() {
|
|
setTimeout(() => {
|
|
navigator.serviceWorker.register('/sw.js', {
|
|
scope: '/',
|
|
updateViaCache: 'none'
|
|
});
|
|
}, 2000); // Delay registration on mobile
|
|
});
|
|
}
|
|
|
|
// Development cache bypass
|
|
if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
|
|
if ('caches' in window) {
|
|
caches.keys().then(names => {
|
|
names.forEach(name => caches.delete(name));
|
|
});
|
|
}
|
|
}
|
|
|
|
// Deferred component preloading with mobile detection
|
|
if ('requestIdleCallback' in window) {
|
|
requestIdleCallback(() => {
|
|
const isMobile = window.innerWidth <= 768;
|
|
if (!isMobile) {
|
|
// Only preload on desktop to save mobile bandwidth/processing
|
|
import('/components/ProductCard').catch(() => {});
|
|
import('/components/FloatingWhatsApp').catch(() => {});
|
|
}
|
|
}, { timeout: 5000 });
|
|
}
|
|
`,
|
|
}}
|
|
/>
|
|
</body>
|
|
</html>
|
|
)
|
|
} |