feat: conditionally enable recording studio and feedback tool via env vars

This commit is contained in:
2026-02-15 20:59:12 +01:00
parent 9274807427
commit 7a63a418f1
7 changed files with 137 additions and 108 deletions

View File

@@ -51,7 +51,6 @@ export default async function LocaleLayout({
}) {
const { locale } = await params;
// Ensure locale is a valid string, fallback to 'en'
const supportedLocales = ['en', 'de'];
const localeStr = (typeof locale === 'string' ? locale : '').trim();
const safeLocale = supportedLocales.includes(localeStr) ? localeStr : 'en';
@@ -66,12 +65,9 @@ export default async function LocaleLayout({
messages = {};
}
// Track pageview on the server with high-fidelity header context
const { getServerAppServices } = await import('@/lib/services/create-services.server');
const serverServices = getServerAppServices();
// We wrap this in a try-catch to allow static rendering during build
// headers() and cookies() force dynamic rendering in Next.js
try {
const { headers } = await import('next/headers');
const requestHeaders = await headers();
@@ -85,10 +81,8 @@ export default async function LocaleLayout({
});
}
// Track initial server-side pageview
serverServices.analytics.trackPageview();
} catch {
// Falls back to noop or client-side only during static generation
if (process.env.NODE_ENV !== 'production' || !process.env.CI) {
console.warn(
'[Layout] Static generation detected or headers unavailable, skipping server-side analytics context',
@@ -96,38 +90,29 @@ export default async function LocaleLayout({
}
}
// Read directly from process.env — bypasses all abstraction to guarantee correctness
const recordModeEnabled = process.env.NEXT_PUBLIC_RECORD_MODE_ENABLED === 'true';
const feedbackEnabled = process.env.NEXT_PUBLIC_FEEDBACK_ENABLED === 'true';
return (
<html lang={safeLocale} className={`scroll-smooth overflow-x-hidden ${inter.variable}`}>
<head>
<style dangerouslySetInnerHTML={{
__html: `
/* Effectively Invisible Scrollbar */
::-webkit-scrollbar {
width: 2px;
height: 2px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: transparent;
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(130, 237, 32, 0.4);
}
* {
scrollbar-width: none;
}
*:hover {
scrollbar-width: thin;
scrollbar-color: rgba(130, 237, 32, 0.2) transparent;
}
`}} />
<style
dangerouslySetInnerHTML={{
__html: `
::-webkit-scrollbar { width: 2px; height: 2px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: transparent; border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: rgba(130, 237, 32, 0.4); }
* { scrollbar-width: none; }
*:hover { scrollbar-width: thin; scrollbar-color: rgba(130, 237, 32, 0.2) transparent; }
`,
}}
/>
</head>
<body className="flex flex-col min-h-screen font-sans selection:bg-accent selection:text-primary-dark antialiased overflow-x-hidden">
<NextIntlClientProvider messages={messages} locale={safeLocale}>
<RecordModeProvider>
<RecordModeProvider isEnabled={recordModeEnabled}>
<RecordModeVisuals>
<JsonLd />
<Header />
@@ -140,7 +125,7 @@ export default async function LocaleLayout({
<Suspense fallback={null}>
<AnalyticsProvider />
</Suspense>
<ToolCoordinator />
<ToolCoordinator feedbackEnabled={feedbackEnabled} />
</RecordModeProvider>
</NextIntlClientProvider>
</body>