import { Suspense } from 'react'; import { Caveat, Inter } from 'next/font/google'; import { cookies, headers } from 'next/headers'; import { AxiomWebVitals } from 'next-axiom'; import { PublicEnvScript } from 'next-runtime-env'; import { FeatureFlagProvider } from '@documenso/lib/client-only/providers/feature-flag'; import { I18nClientProvider } from '@documenso/lib/client-only/providers/i18n.client'; import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server'; import { NEXT_PUBLIC_MARKETING_URL } from '@documenso/lib/constants/app'; import type { SUPPORTED_LANGUAGE_CODES } from '@documenso/lib/constants/i18n'; import { ZSupportedLanguageCodeSchema } from '@documenso/lib/constants/i18n'; import { getAllAnonymousFlags } from '@documenso/lib/universal/get-feature-flag'; import { TrpcProvider } from '@documenso/trpc/react'; import { cn } from '@documenso/ui/lib/utils'; import { Toaster } from '@documenso/ui/primitives/toaster'; import { ThemeProvider } from '~/providers/next-theme'; import { PlausibleProvider } from '~/providers/plausible'; import { PostHogPageview } from '~/providers/posthog'; import './globals.css'; const fontInter = Inter({ subsets: ['latin'], variable: '--font-sans' }); const fontCaveat = Caveat({ subsets: ['latin'], variable: '--font-signature' }); export function generateMetadata() { return { title: { template: '%s - Documenso', default: 'Documenso', }, description: 'Join Documenso, the open signing infrastructure, and get a 10x better signing experience. Pricing starts at $30/mo. forever! Sign in now and enjoy a faster, smarter, and more beautiful document signing process. Integrates with your favorite tools, customizable, and expandable. Support our mission and become a part of our open-source community.', keywords: 'Documenso, open source, DocuSign alternative, document signing, open signing infrastructure, open-source community, fast signing, beautiful signing, smart templates', authors: { name: 'Documenso, Inc.' }, robots: 'index, follow', metadataBase: new URL(NEXT_PUBLIC_MARKETING_URL() ?? 'http://localhost:3000'), openGraph: { title: 'Documenso - The Open Source DocuSign Alternative', description: 'Join Documenso, the open signing infrastructure, and get a 10x better signing experience. Pricing starts at $30/mo. forever! Sign in now and enjoy a faster, smarter, and more beautiful document signing process. Integrates with your favorite tools, customizable, and expandable. Support our mission and become a part of our open-source community.', type: 'website', images: ['/opengraph-image.jpg'], }, twitter: { site: '@documenso', card: 'summary_large_image', images: ['/opengraph-image.jpg'], description: 'Join Documenso, the open signing infrastructure, and get a 10x better signing experience. Pricing starts at $30/mo. forever! Sign in now and enjoy a faster, smarter, and more beautiful document signing process. Integrates with your favorite tools, customizable, and expandable. Support our mission and become a part of our open-source community.', }, }; } export default async function RootLayout({ children }: { children: React.ReactNode }) { const flags = await getAllAnonymousFlags(); let overrideLang: (typeof SUPPORTED_LANGUAGE_CODES)[number] | undefined; // Should be safe to remove when we upgrade NextJS. // https://github.com/vercel/next.js/pull/65008 // Currently if the middleware sets the cookie, it's not accessible in the cookies // during the same render. // So we go the roundabout way of checking the header for the set-cookie value. if (!cookies().get('i18n')) { const setCookieValue = headers().get('set-cookie'); const i18nCookie = setCookieValue?.split(';').find((cookie) => cookie.startsWith('i18n=')); if (i18nCookie) { const i18n = i18nCookie.split('=')[1]; overrideLang = ZSupportedLanguageCodeSchema.parse(i18n); } } const { lang, i18n } = setupI18nSSR(overrideLang); return ( {children} ); }