Navigation

Famous.ai Config System

Centralized environment-based configuration

๐ŸŽฏ Why Centralized Config?

โœ… No hardcoded URLs - Switch environments instantly

โœ… Type-safe - TypeScript catches config errors

โœ… Single source of truth - Update URLs in one place

โœ… Environment-specific - Dev, staging, prod configs

โœ… Prevents redirect loops - Consistent URL usage

Step 1: Create src/lib/config.ts
Central configuration file
// src/lib/config.ts
// Centralized configuration for all environment-dependent URLs

interface AppConfig {
  GAME_URL: string;
  SNAPPY_LOGIN_URL: string;
  SNAPPY_VERIFY_TOKEN_URL: string;
  MOTHERSHIP_URL: string;
  IS_PRODUCTION: boolean;
  IS_DEVELOPMENT: boolean;
}

function getConfig(): AppConfig {
  const mode = import.meta.env.MODE || 'development';
  const IS_PRODUCTION = mode === 'production';
  const IS_DEVELOPMENT = mode === 'development';

  // Game URL (where this game is hosted)
  const GAME_URL = import.meta.env.VITE_GAME_URL || 
                   (IS_PRODUCTION 
                     ? 'https://play.snappyidioms.com'
                     : 'http://localhost:5173');

  // SnappyIdioms.com URLs
  const SNAPPY_BASE = import.meta.env.VITE_SNAPPY_BASE_URL || 
                      'https://snappyidioms.com';

  return {
    GAME_URL,
    SNAPPY_LOGIN_URL: `${SNAPPY_BASE}/login`,
    SNAPPY_VERIFY_TOKEN_URL: `${SNAPPY_BASE}/api/verifyGameToken`,
    MOTHERSHIP_URL: `${SNAPPY_BASE}/api`,
    IS_PRODUCTION,
    IS_DEVELOPMENT
  };
}

export const config = getConfig();

// Type-safe access
export const { 
  GAME_URL, 
  SNAPPY_LOGIN_URL, 
  SNAPPY_VERIFY_TOKEN_URL,
  MOTHERSHIP_URL,
  IS_PRODUCTION,
  IS_DEVELOPMENT 
} = config;
Step 2: Create .env Files
Environment-specific configuration

.env.example (commit to git)

# .env.example
# Copy this to .env.local and fill in your values

# Game URL (where this Scrabble game is hosted)
VITE_GAME_URL=http://localhost:5173

# SnappyIdioms.com base URL
VITE_SNAPPY_BASE_URL=https://snappyidioms.com

# Environment
VITE_MODE=development

.env.production (for build)

# .env.production
# Production environment variables

VITE_GAME_URL=https://play.snappyidioms.com
VITE_SNAPPY_BASE_URL=https://snappyidioms.com
VITE_MODE=production
Step 3: Update Usage Throughout Codebase
// BEFORE (hardcoded URLs - BAD)
const redirectUrl = 'https://play.snappyidioms.com';
const loginUrl = 'https://snappyidioms.com/login';

// AFTER (using centralized config - GOOD)
import { GAME_URL, SNAPPY_LOGIN_URL } from '@/lib/config';

const redirectUrl = GAME_URL;
const loginUrl = SNAPPY_LOGIN_URL;

// Usage in auth flow
const handleSignIn = () => {
  const url = `${SNAPPY_LOGIN_URL}?redirect=${encodeURIComponent(GAME_URL)}`;
  window.open(url, '_blank');
};

// Usage in token verification
const verifyToken = async (token: string) => {
  const response = await fetch(SNAPPY_VERIFY_TOKEN_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ token })
  });
  return response.json();
};
Update platformAuth.ts
// src/lib/platformAuth.ts
// Update to use centralized config

import { SNAPPY_VERIFY_TOKEN_URL, GAME_URL } from './config';

async function validateTokenAsync(token: string, payload: any) {
  try {
    // Use config instead of hardcoded URL
    const response = await fetch(SNAPPY_VERIFY_TOKEN_URL, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ token })
    });
    
    const result = await response.json();
    // ... rest of validation logic
  } catch (error) {
    console.error('[Auth] Validation failed:', error);
  }
}
Update AuthModal.tsx
// src/components/game/AuthModal.tsx
// Update to use centralized config

import { SNAPPY_LOGIN_URL, GAME_URL } from '@/lib/config';

export function AuthModal() {
  const handleSignIn = () => {
    // Use config URLs
    const redirectUrl = `${SNAPPY_LOGIN_URL}?redirect=${encodeURIComponent(GAME_URL)}`;
    window.open(redirectUrl, '_blank');
  };
  
  // ... rest of component
}
Step 4: Update vite.config.ts
// vite.config.ts
// Ensure environment variables are properly loaded

import { defineConfig, loadEnv } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '');
  
  return {
    plugins: [react()],
    resolve: {
      alias: {
        '@': path.resolve(__dirname, './src'),
      },
    },
    define: {
      // Expose env vars to client
      'import.meta.env.VITE_GAME_URL': JSON.stringify(env.VITE_GAME_URL),
      'import.meta.env.VITE_SNAPPY_BASE_URL': JSON.stringify(env.VITE_SNAPPY_BASE_URL),
    },
  };
});
Step 5: Update .gitignore
# Add to .gitignore
.env
.env.local
.env.production.local
.env.development.local
โœ… Files to Update
  • โ˜ src/lib/config.ts - Create this file
  • โ˜ .env.example - Create this file
  • โ˜ .env.production - Create this file
  • โ˜ .env.local - Create for local dev (not in git)
  • โ˜ src/lib/platformAuth.ts - Replace hardcoded URLs
  • โ˜ src/components/game/AuthModal.tsx - Replace hardcoded URLs
  • โ˜ src/components/game/LinkAccountPrompt.tsx - Replace hardcoded URLs
  • โ˜ src/components/AppLayout.tsx - Replace hardcoded URLs
  • โ˜ src/lib/mothership.ts - Replace hardcoded URLs
  • โ˜ vite.config.ts - Update config loader
  • โ˜ .gitignore - Add .env files
๐Ÿš€ Testing

Local Development:

npm run dev

Should use localhost URLs

Production Build:

npm run build

Should use play.snappyidioms.com

Verify Config:

console.log(config)

Check config values in browser console