feat: add traffic analytics configuration (Umami/GA/Custom)
Add traffic analytics support to the admin panel with three provider options: - Umami (open-source, self-hosted) — script URL + website ID - Google Analytics 4 — Measurement ID (G-XXXXXXXXXX) - Custom — any third-party analytics script (百度统计, Plausible, 51la, etc.) Changes: - admin.types.ts: Add AnalyticsEnabled, AnalyticsProvider, AnalyticsScriptUrl, AnalyticsWebsiteId, AnalyticsCustomScript to SiteConfig interface - config.ts: Add default values in getInitConfig() and configSelfCheck() - api/admin/site/route.ts: Add analytics fields to destructuring, type validation, and SiteConfig update - admin/page.tsx: Add SiteConfig interface fields, state initialization, config sync, and analytics configuration UI with provider-specific input fields - layout.tsx: Inject analytics scripts into <head> based on provider type (Umami: async script with data-website-id; GA: gtag.js + config; Custom: dangerouslySetInnerHTML)
This commit is contained in:
@@ -115,6 +115,11 @@ export default async function RootLayout({
|
||||
let liveEnabled = true;
|
||||
let webLiveEnabled = false;
|
||||
let customAdFilterVersion = 0;
|
||||
let analyticsEnabled = false;
|
||||
let analyticsProvider: 'umami' | 'google' | 'custom' = 'umami';
|
||||
let analyticsScriptUrl = '';
|
||||
let analyticsWebsiteId = '';
|
||||
let analyticsCustomScript = '';
|
||||
let musicFeatureEnabled = false;
|
||||
let suwayomiEnabled = false;
|
||||
let booksEnabled =
|
||||
@@ -202,6 +207,12 @@ export default async function RootLayout({
|
||||
webLiveEnabled = config.WebLiveEnabled ?? false;
|
||||
// 自定义去广告代码版本号
|
||||
customAdFilterVersion = config.SiteConfig?.CustomAdFilterVersion || 0;
|
||||
// 流量统计配置
|
||||
analyticsEnabled = config.SiteConfig?.AnalyticsEnabled || false;
|
||||
analyticsProvider = config.SiteConfig?.AnalyticsProvider || 'umami';
|
||||
analyticsScriptUrl = config.SiteConfig?.AnalyticsScriptUrl || '';
|
||||
analyticsWebsiteId = config.SiteConfig?.AnalyticsWebsiteId || '';
|
||||
analyticsCustomScript = config.SiteConfig?.AnalyticsCustomScript || '';
|
||||
// 音乐功能配置
|
||||
musicFeatureEnabled = config.MusicConfig?.Enabled || false;
|
||||
musicProxyEnabled = config.MusicConfig?.ProxyEnabled ?? true;
|
||||
@@ -335,6 +346,37 @@ export default async function RootLayout({
|
||||
__html: `window.RUNTIME_CONFIG = ${JSON.stringify(runtimeConfig)};`,
|
||||
}}
|
||||
/>
|
||||
{/* 流量统计脚本 */}
|
||||
{analyticsEnabled && analyticsProvider === 'umami' && analyticsScriptUrl && (
|
||||
<>
|
||||
{/* eslint-disable-next-line @next/next/no-sync-scripts */}
|
||||
<script
|
||||
async
|
||||
defer
|
||||
data-website-id={analyticsWebsiteId}
|
||||
src={analyticsScriptUrl}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{analyticsEnabled && analyticsProvider === 'google' && analyticsWebsiteId && (
|
||||
<>
|
||||
{/* eslint-disable-next-line @next/next/no-sync-scripts */}
|
||||
<script
|
||||
async
|
||||
src={`https://www.googletagmanager.com/gtag/js?id=${analyticsWebsiteId}`}
|
||||
/>
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}gtag('js', new Date());gtag('config', '${analyticsWebsiteId}');`,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{analyticsEnabled && analyticsProvider === 'custom' && analyticsCustomScript && (
|
||||
<script
|
||||
dangerouslySetInnerHTML={{ __html: analyticsCustomScript }}
|
||||
/>
|
||||
)}
|
||||
</head>
|
||||
<body
|
||||
className={`${inter.className} min-h-screen bg-white text-gray-900 dark:bg-black dark:text-gray-200`}
|
||||
|
||||
Reference in New Issue
Block a user