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 propertiessubdomain(string | null): The subdomain partdomain(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
Related Utilities
- String Utilities - For URL string manipulation
- Object & Array Utilities - For configuration object handling
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