Files
aigrowthtech/src/app/[lang]/layout.tsx
T
Alejandro Veras 2d7e7f2fe1 Apply website QA: light theme, clearer contact form, office emails
- Add a light theme with a header toggle; the choice is remembered and applied before paint
- Make the globe, product visuals and footer logo follow the theme
- Give the message field a full outline, strengthen the captcha box border and keep autofilled fields readable
- Accept website addresses without https://
- List the info email under every office
- Keep the phone header on one row: languages move into the menu below 480px
2026-10-16 11:56:10 -04:00

99 lines
2.9 KiB
TypeScript

import { Suspense } from "react";
import type { Metadata, Viewport } from "next";
import { Inter, Noto_Sans_Arabic } from "next/font/google";
import "../globals.css";
import SiteHeader from "@/components/site-header";
import SiteFooter from "@/components/site-footer";
import Analytics, { AnalyticsNoScript } from "@/components/analytics";
import { themeScript } from "@/components/theme-toggle";
import { dirOf, locales, localize, ogLocale } from "@/i18n/config";
import { mainNav } from "@/i18n/nav";
import { getUI } from "@/i18n/server";
import { localeAlternates } from "@/lib/metadata";
import { SITE_URL } from "@/lib/routes";
const inter = Inter({
variable: "--font-inter",
subsets: ["latin"],
display: "swap",
});
// Only Arabic pages use it, so it isn't preloaded everywhere.
const arabic = Noto_Sans_Arabic({
variable: "--font-arabic",
subsets: ["arabic"],
display: "swap",
preload: false,
});
export function generateStaticParams() {
return locales.map((lang) => ({ lang }));
}
export async function generateMetadata(): Promise<Metadata> {
const { locale, t } = await getUI();
return {
metadataBase: new URL(SITE_URL),
title: { default: t.meta.title, template: "%s" },
description: t.meta.description,
alternates: localeAlternates("/", locale),
// Google Search Console ownership.
verification: { google: "LnRawiMDpDtTVBC2X34We70f8OHBLMVC6e9IWoHCZLs" },
openGraph: {
type: "website",
url: localize("/", locale),
siteName: "AI Growth Technologies",
locale: ogLocale[locale],
title: t.meta.title,
description: t.meta.description,
},
};
}
export const viewport: Viewport = {
themeColor: "#000000",
colorScheme: "dark light",
};
export default async function RootLayout({ children }: LayoutProps<"/[lang]">) {
const { locale, t } = await getUI();
const headerLabels = {
primary: t.nav.primary,
bookCall: t.bookCall,
openMenu: t.nav.openMenu,
closeMenu: t.nav.closeMenu,
language: t.nav.language,
logoHome: t.logoHome,
lightTheme: t.nav.lightTheme,
darkTheme: t.nav.darkTheme,
};
return (
<html
lang={locale}
dir={dirOf(locale)}
className={`${inter.variable} ${arabic.variable}`}
data-scroll-behavior="smooth"
// The theme script sets data-theme before React hydrates.
suppressHydrationWarning
>
<head>
<script dangerouslySetInnerHTML={{ __html: themeScript }} />
</head>
<body>
<AnalyticsNoScript />
<a href="#main" className="skip-link">
{t.skip}
</a>
{/* The header reads the pathname, which is request data on dynamic routes. */}
<Suspense>
<SiteHeader locale={locale} nav={mainNav(t, locale)} t={headerLabels} />
</Suspense>
<main id="main">{children}</main>
<SiteFooter />
<Analytics />
</body>
</html>
);
}