Files
novalon-website/src/app/layout.tsx
T
张翔 2f45818724 feat(analytics): enhance Google Analytics with privacy compliance and comprehensive tracking
- Add automatic route change tracking for SPA navigation
- Implement Cookie consent banner for GDPR compliance
- Add performance tracking (LCP, FID, CLS Web Vitals)
- Add outbound link click tracking
- Integrate contact form submission tracking with conversion events
- Add CTA button click tracking in hero section
- Integrate error tracking in ErrorBoundary component
- Extend analytics utility library with 15+ tracking functions
- Configure IP anonymization and privacy settings
- Remove unused test files and deployment scripts
- Update case studies to include only specified cases
- Fix mobile navigation active state issues
- Fix lint errors in test files and components

BREAKING CHANGE: Google Analytics now requires user consent before tracking
2026-04-22 07:19:29 +08:00

173 lines
5.6 KiB
TypeScript

import type { Metadata, Viewport } from "next";
import { Geist, Geist_Mono, Noto_Sans_SC, Ma_Shan_Zheng, Long_Cang } from "next/font/google";
import localFont from "next/font/local";
import "./globals.css";
import { Suspense } from "react";
import { ThemeProvider } from "@/contexts/theme-context";
import { GoogleAnalytics } from "@/components/analytics/GoogleAnalytics";
import { CookieConsent } from "@/components/analytics/CookieConsent";
import { PerformanceTracker } from "@/components/analytics/PerformanceTracker";
import { OutboundLinkTracker } from "@/components/analytics/OutboundLinkTracker";
import { OrganizationSchema, WebsiteSchema } from "@/components/seo/structured-data";
import { MobileTabBar } from "@/components/layout/mobile-tab-bar";
import { ErrorBoundary } from "@/components/ui/error-boundary";
import { ScrollProgress } from "@/components/ui/scroll-progress";
import { BackToTop } from "@/components/ui/back-to-top";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
display: "swap",
preload: false,
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
display: "swap",
preload: false,
});
const notoSansSC = Noto_Sans_SC({
weight: ["400", "500", "700"],
variable: "--font-noto-sans-sc",
subsets: ["latin"],
display: "swap",
preload: true,
});
const maShanZheng = Ma_Shan_Zheng({
weight: "400",
variable: "--font-ma-shan-zheng",
subsets: ["latin"],
display: "swap",
preload: false,
});
const longCang = Long_Cang({
weight: "400",
variable: "--font-long-cang",
subsets: ["latin"],
display: "swap",
preload: false,
});
const aoyagiReisho = localFont({
src: "./fonts/AoyagiReisho.ttf",
variable: "--font-aoyagi-reisho",
display: "swap",
preload: true,
});
export const metadata: Metadata = {
metadataBase: new URL("https://www.novalon.cn"),
title: {
default: "四川睿新致远科技有限公司 - 企业数字化转型服务商",
template: "%s | 四川睿新致远科技有限公司",
},
description: "四川睿新致远科技有限公司成立于2026年,专注于企业数字化转型服务,提供软件开发、云计算、数据分析、信息安全等一站式解决方案。",
keywords: ["数字化转型", "企业软件", "ERP系统", "CRM系统", "云计算", "数据分析", "软件开发", "成都科技公司", "金融科技", "诺瓦隆"],
authors: [{ name: "四川睿新致远科技有限公司" }],
creator: "四川睿新致远科技有限公司",
publisher: "四川睿新致远科技有限公司",
robots: {
index: true,
follow: true,
googleBot: {
index: true,
follow: true,
"max-video-preview": -1,
"max-image-preview": "large",
"max-snippet": -1,
},
},
openGraph: {
type: "website",
locale: "zh_CN",
url: "https://www.novalon.cn",
siteName: "四川睿新致远科技有限公司",
title: "四川睿新致远科技有限公司 - 企业数字化转型服务商",
description: "专注于企业数字化转型服务,提供软件开发、云计算、数据分析、信息安全等一站式解决方案",
images: [
{
url: "/og-image.jpg",
width: 1200,
height: 630,
alt: "四川睿新致远科技有限公司",
},
],
},
twitter: {
card: "summary_large_image",
title: "四川睿新致远科技有限公司 - 企业数字化转型服务商",
description: "专注于企业数字化转型服务,提供软件开发、云计算、数据分析、信息安全等一站式解决方案",
images: ["/og-image.jpg"],
},
alternates: {
canonical: "https://www.novalon.cn",
},
verification: {
google: "your-google-verification-code",
},
};
export const viewport: Viewport = {
width: "device-width",
initialScale: 1,
maximumScale: 5,
themeColor: [
{ media: "(prefers-color-scheme: light)", color: "#FFFFFF" },
{ media: "(prefers-color-scheme: dark)", color: "#0A0A0A" },
],
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="zh-CN" className="scroll-smooth" suppressHydrationWarning>
<head>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="apple-touch-icon" href="/favicon.svg" />
{/* 字体预加载优化 */}
<link
rel="preload"
href="/fonts/AoyagiReisho.ttf"
as="font"
type="font/ttf"
crossOrigin="anonymous"
/>
<OrganizationSchema />
<WebsiteSchema />
</head>
<body
className={`${geistSans.variable} ${geistMono.variable} ${notoSansSC.variable} ${maShanZheng.variable} ${longCang.variable} ${aoyagiReisho.variable} font-sans antialiased`}
style={{ fontFamily: "'Noto Sans SC', 'Geist', -apple-system, BlinkMacSystemFont, sans-serif" }}
>
<a
href="#main-content"
className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-[9999] focus:px-4 focus:py-2 focus:bg-[#C41E3A] focus:text-white focus:rounded-md focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-[#C41E3A]"
>
</a>
<ScrollProgress />
<GoogleAnalytics />
<PerformanceTracker />
<OutboundLinkTracker />
<ThemeProvider>
<ErrorBoundary>
{children}
</ErrorBoundary>
</ThemeProvider>
<Suspense fallback={null}>
<MobileTabBar />
</Suspense>
<CookieConsent />
<BackToTop />
</body>
</html>
);
}