Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:

- name: Deploy
env:
GOOGLE_ANALYTICS_ID: ${{ secrets.GOOGLE_ANALYTICS_ID }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
AUTH_EMAIL_RESEND_API_KEY: ${{ secrets.AUTH_EMAIL_RESEND_API_KEY }}
AUTH_SOCIAL_GOOGLE_CLIENT_ID: ${{ secrets.AUTH_SOCIAL_GOOGLE_CLIENT_ID }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/scripts/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const config = {
override: {
vars: {
MODE: "mixed",
GOOGLE_ANALYTICS_ID: process.env.GOOGLE_ANALYTICS_ID,
AUTH_EMAIL_VERIFICATION_ENABLED: "true",
AUTH_EMAIL_RESEND_API_KEY: process.env.AUTH_EMAIL_RESEND_API_KEY,
AUTH_EMAIL_RESEND_FROM: "Typix <[email protected]>",
Expand Down
26 changes: 26 additions & 0 deletions src/app/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,32 @@ function RootComponent() {
// Apply theme and theme color with automatic system theme detection
useThemeManager(theme, themeColor, setTheme);

// Conditionally load Google Analytics when an ID is provided
useEffect(() => {
const gaId = import.meta.env.GOOGLE_ANALYTICS_ID as string | undefined;
if (!gaId || gaId.trim() === "") return;

if (!document.getElementById("ga-gtag")) {
const script = document.createElement("script");
script.id = "ga-gtag";
script.async = true;
script.src = `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(gaId)}`;
document.head.appendChild(script);
}

if (!document.getElementById("ga-inline")) {
const inline = document.createElement("script");
inline.id = "ga-inline";
inline.innerHTML = `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gaId}');
`;
document.head.appendChild(inline);
}
}, []);

// Update loading title when initialization starts
useEffect(() => {
if (hasAuthResolved && !isInitialized && !initError && i18n.isInitialized) {
Expand Down
2 changes: 2 additions & 0 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,14 @@ export default defineConfig(({ mode }) => {
"@": path.resolve(__dirname, "./src"),
},
},
// Only define environment variables that are needed on the client side
define: {
"import.meta.env.RUNTIME": getEnv("RUNTIME"),
"import.meta.env.MODE": getEnv("MODE"),
"import.meta.env.AUTH_EMAIL_VERIFICATION_ENABLED": getEnv("AUTH_EMAIL_VERIFICATION_ENABLED"),
"import.meta.env.AUTH_SOCIAL_GOOGLE_ENABLED": getEnv("AUTH_SOCIAL_GOOGLE_ENABLED"),
"import.meta.env.AUTH_SOCIAL_GITHUB_ENABLED": getEnv("AUTH_SOCIAL_GITHUB_ENABLED"),
"import.meta.env.GOOGLE_ANALYTICS_ID": getEnv("GOOGLE_ANALYTICS_ID"),
"import.meta.env.PROVIDER_CLOUDFLARE_BUILTIN": getEnv("PROVIDER_CLOUDFLARE_BUILTIN"),
},
};
Expand Down
1 change: 1 addition & 0 deletions wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ binding = "AI"
# Authenticated users benefit from cross-device data sync and server-side data persistence.
# Provides the best of both worlds: instant local access with optional cloud features.
MODE = "client"
GOOGLE_ANALYTICS_ID = "G-0T65G1J5DT"

# Authentication configuration, only for mixed mode
#
Expand Down