Files
padmaja/app/layout.tsx
2026-01-17 14:17:42 +05:30

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>
)
}