All files / src/app layout.tsx

0% Statements 0/16
0% Branches 0/6
0% Functions 0/4
0% Lines 0/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113                                                                                                                                                                                                                                 
import { SpeedInsights } from '@vercel/speed-insights/next';
import type { Metadata, Viewport } from 'next';
import nextDynamic from 'next/dynamic';
import { connection } from 'next/server';
import { getLocaleMessages } from '@/lib/locale/locale';
import { ServerProviders } from '@/providers/server';
import '@mantine/core/styles.css';
import '@mantine/notifications/styles.css';
import '@mantine/carousel/styles.css';
import '@mantine/spotlight/styles.css';
import './globals.css';
import type { PropsWithChildren } from 'react';
import Shell from '@/components/Shell';
import { getLocaleFromCookies } from '@/lib/locale/locale.server';
 
const ClientProviders = nextDynamic(
  () => import('@/providers/client').then((m) => m.ClientProviders),
  {
    ssr: true,
  },
);
 
export const viewport: Viewport = {
  themeColor: [
    { media: '(prefers-color-scheme: light)', color: '#FF00A1' },
    { media: '(prefers-color-scheme: dark)', color: '#FF00A1' },
  ],
};
 
export async function generateMetadata(): Promise<Metadata> {
  await connection();
  const locale = await getLocaleFromCookies();
  const messages = await getLocaleMessages(locale);
 
  const seo = messages.seo as Record<string, string> | undefined;
  const appTitle =
    typeof seo?.appTitle === 'string' ? seo.appTitle : 'Cookbook';
  const appDescription =
    typeof seo?.appDescription === 'string'
      ? seo.appDescription
      : 'Share your recipes';
 
  return {
    metadataBase: new URL(process.env.NEXTAUTH_URL ?? 'http://localhost:3000'),
    title: appTitle,
    description: appDescription,
    manifest: '/site.webmanifest',
    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' },
      ],
      shortcut: [{ url: '/favicon.ico' }],
      apple: [
        { url: '/apple-touch-icon.png', sizes: '180x180', type: 'image/png' },
      ],
    },
    appleWebApp: {
      capable: true,
      statusBarStyle: 'default',
      title: appTitle,
    },
    openGraph: {
      title: appTitle,
      description: appDescription,
      type: 'website',
      siteName: appTitle,
      locale,
    },
    twitter: {
      card: 'summary',
      title: appTitle,
      description: appDescription,
    },
    robots: {
      index: true,
      follow: true,
    },
  };
}
 
export default async function RootLayout(props: Readonly<PropsWithChildren>) {
  await connection();
  const locale = await getLocaleFromCookies();
 
  // Load all language messages for SSR
  const [enMessages, huMessages, deMessages] = await Promise.all([
    getLocaleMessages('en-gb'),
    getLocaleMessages('hu'),
    getLocaleMessages('de'),
  ]);
 
  const allMessages = {
    'en-gb': enMessages,
    hu: huMessages,
    de: deMessages,
  };
 
  return (
    <html lang={locale}>
      <body suppressHydrationWarning>
        <SpeedInsights />
        <ServerProviders>
          <ClientProviders messages={allMessages} locale={locale}>
            <Shell>{props.children}</Shell>
          </ClientProviders>
        </ServerProviders>
      </body>
    </html>
  );
}