Files
petfeed/src/app/layout.tsx
T
admin 383817916d perf(landing): scope Clerk provider + fix contrast/landmark on marketing page
Moves ClerkThemeProvider from the root layout into (app)/layout.tsx and
(auth)/layout.tsx — it was previously mounted globally, shipping the
~240 KiB Clerk client SDK to every route including the public marketing
page. Only Sidebar's UserButton and the (auth) sign-in/sign-up forms
actually need client-side Clerk context; server-side auth() calls are
unaffected since they read from proxy.ts's clerkMiddleware, not React
context.

Also fixes two WCAG AA contrast failures on the hero/header CTAs
(orange-500/600 -> orange-700, ~2.8:1/3.6:1 -> ~5.5:1) and adds a
missing <main> landmark around the landing page content.

Source: PageSpeed Insights audit, mobile Performance 70 -> targets >90.
2026-08-20 19:00:35 +02:00

69 lines
2.0 KiB
TypeScript

import type { Metadata, Viewport } from "next";
import { Inter } from "next/font/google";
import { ThemeProvider } from "next-themes";
import { NextIntlClientProvider } from "next-intl";
import { getLocale, getMessages } from "next-intl/server";
import { TRPCReactProvider } from "@/trpc/client";
import { ActivePetProvider } from "@/context/ActivePetContext";
import { Toaster } from "@/components/ui/sonner";
import "./globals.css";
const inter = Inter({
variable: "--font-sans",
subsets: ["latin"],
});
export const metadata: Metadata = {
metadataBase: new URL(process.env.NEXT_PUBLIC_APP_URL ?? "https://pawfeed.org"),
title: { default: "PawFeed", template: "%s · PawFeed" },
description: "The social platform where pets are the stars.",
openGraph: {
title: "PawFeed",
description: "The social platform where pets are the stars.",
url: "/",
siteName: "PawFeed",
type: "website",
},
twitter: {
card: "summary_large_image",
title: "PawFeed",
description: "The social platform where pets are the stars.",
},
};
export const viewport: Viewport = {
width: "device-width",
initialScale: 1,
viewportFit: "cover",
};
export default async function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const locale = await getLocale();
const messages = await getMessages();
return (
<html
lang={locale}
suppressHydrationWarning
className={`${inter.variable} h-full antialiased font-sans`}
>
<body className="min-h-full flex flex-col">
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
<NextIntlClientProvider locale={locale} messages={messages}>
<TRPCReactProvider>
<ActivePetProvider>
{children}
<Toaster />
</ActivePetProvider>
</TRPCReactProvider>
</NextIntlClientProvider>
</ThemeProvider>
</body>
</html>
);
}