Skip to main content

Browser Utils

Browser environment detection and URL manipulation utilities for the WorkPayCore frontend application.

Domain Functions​

getSubdomain()​

Extracts the subdomain and domain from the current window location.

Parameters: None (uses window.location.hostname)

Returns:

  • object: Object containing subdomain and domain properties
    • subdomain (string | null): The subdomain part
    • domain (string | null): The domain part

Example:

// Current URL: https://dashboard.myworkpay.com/users
const { subdomain, domain } = getSubdomain();
// Returns: { subdomain: 'dashboard', domain: 'myworkpay.com' }

// Current URL: https://myworkpay.com/login
const { subdomain, domain } = getSubdomain();
// Returns: { subdomain: null, domain: 'myworkpay.com' }

// Invalid/missing hostname
const { subdomain, domain } = getSubdomain();
// Returns: { subdomain: null, domain: null }

Use Cases:

  • Multi-tenant application routing
  • Subdomain-based feature toggling
  • Environment-specific configurations
  • Analytics and tracking based on subdomain

Environment Detection​

isProd​

Boolean constant indicating if the application is running in production mode.

Type: boolean

Example:

import { isProd } from '@/utils/browser';

if (isProd) {
// Production-specific code
console.log('Running in production mode');
initAnalytics();
} else {
// Development-specific code
console.log('Running in development mode');
}

// Conditional API endpoints
const apiUrl = isProd ? 'https://api.workpay.com' : 'http://localhost:3000';

Use Cases:

  • Environment-specific configurations
  • Conditional logging
  • Feature flags based on environment
  • API endpoint selection

isDev​

Boolean constant indicating if the application is running in development mode.

Type: boolean

Example:

import { isDev } from '@/utils/browser';

if (isDev) {
// Development-only features
window.debugUtils = {
/* debug utilities */
};
console.log('Development mode active');
}

// Development-only debugging
const logApiCall = (url, data) => {
if (isDev) {
console.log('API Call:', url, data);
}
};

Use Cases:

  • Development-only debugging
  • Hot reload configurations
  • Development tools integration
  • Verbose logging

Usage Examples​

Environment-Based Configuration​

import { isProd, isDev } from '@/utils/browser';

const config = {
apiUrl: isProd ? 'https://api.workpay.com' : 'http://localhost:3000',
logLevel: isDev ? 'debug' : 'error',
enableAnalytics: isProd,
enableDevTools: isDev,
timeout: isProd ? 30000 : 5000,
};

Subdomain-Based Routing​

import { getSubdomain } from '@/utils/browser';

const AppRouter = () => {
const { subdomain, domain } = getSubdomain();

// Route based on subdomain
switch (subdomain) {
case 'dashboard':
return <DashboardApp />;
case 'admin':
return <AdminApp />;
case 'api':
return <ApiDocumentation />;
default:
return <PublicSite />;
}
};

Multi-Tenant Configuration​

import { getSubdomain } from '@/utils/browser';

const useTenantConfig = () => {
const { subdomain } = getSubdomain();

const tenantConfigs = {
'company-a': {
theme: 'blue',
features: ['payroll', 'hr', 'analytics'],
logo: '/logos/company-a.png',
},
'company-b': {
theme: 'green',
features: ['payroll', 'hr'],
logo: '/logos/company-b.png',
},
};

return tenantConfigs[subdomain] || tenantConfigs.default;
};

Conditional Feature Loading​

import { isProd, isDev, getSubdomain } from '@/utils/browser';

const FeatureProvider = ({ children }) => {
const { subdomain } = getSubdomain();

const features = {
analytics: isProd && subdomain !== 'demo',
debugTools: isDev,
betaFeatures: subdomain === 'beta' || isDev,
advancedReporting: ['enterprise', 'premium'].includes(subdomain),
};

return (
<FeatureContext.Provider value={features}>
{children}
</FeatureContext.Provider>
);
};

Environment-Specific Error Handling​

import { isProd, isDev } from '@/utils/browser';

const errorHandler = (error, errorInfo) => {
if (isProd) {
// Production error handling
sendToLoggingService(error, errorInfo);
showUserFriendlyMessage();
}

if (isDev) {
// Development error handling
console.error('Error:', error);
console.error('Error Info:', errorInfo);
// Show detailed error in dev mode
}
};

API Configuration Based on Environment​

import { isProd, getSubdomain } from '@/utils/browser';

const createApiClient = () => {
const { subdomain } = getSubdomain();

const baseURL = isProd
? `https://${subdomain}-api.workpay.com`
: 'http://localhost:3001';

return axios.create({
baseURL,
timeout: isProd ? 30000 : 5000,
headers: {
'X-Tenant': subdomain,
},
});
};

Error Handling​

The browser utilities handle edge cases gracefully:

  • Missing hostname: Returns null values instead of throwing errors
  • Invalid URL structure: Safely handles malformed URLs
  • Environment detection: Uses Vite's built-in environment detection

Performance Considerations​

  • getSubdomain(): O(1) - simple string operations
  • isProd/isDev: O(1) - constant values set at build time
  • URL parsing: Minimal overhead using native browser APIs

Security Considerations​

  • Subdomain validation: Consider validating subdomains against allowed values
  • Environment exposure: Be careful not to expose sensitive development information in production
  • Tenant isolation: Ensure proper isolation between different subdomains in multi-tenant setups


TypeScript Definitions​

interface SubdomainInfo {
subdomain: string | null;
domain: string | null;
}

export function getSubdomain(): SubdomainInfo;
export const isProd: boolean;
export const isDev: boolean;

Build-Time Constants​

These utilities depend on Vite's environment variables:

// Set at build time by Vite
import.meta.env.PROD; // Used for isProd
import.meta.env.DEV; // Used for isDev