Environment Configuration
The Mina frontend uses JavaScript configuration files to customize behavior for different deployment environments. Each environment file defines specific settings, features, and endpoint configurations.
Configuration File Structure
Environment configuration files are located in
frontend/src/assets/environments/ and follow this general structure:
For the complete, authoritative set of all configuration parameters, see the
TypeScript interface definitions at:
frontend/src/app/shared/types/core/environment/mina-env.type.ts
This file contains the MinaEnv, MinaNode, and FeaturesConfig interfaces
with full JSDoc documentation.
Usage and Integration
This section contains code examples copied directly from the source files. If you modify any of the following files, please update the corresponding documentation:
frontend/src/index.html- Runtime loading logicfrontend/src/app/shared/constants/config.ts- Angular integrationfrontend/src/app/core/services/config.service.ts- Service integration- Environment files in
frontend/src/assets/environments/- Configuration examples
Loading Process
The environment configuration loading happens in multiple stages:
1. Runtime Loading (index.html)
The environment configuration is loaded dynamically at runtime via JavaScript in
frontend/src/index.html:
async function loadEnvironment() {
const possiblePaths = [
"/environments/env.js", // Production/CI path
"../public/environments/env.js", // Development path
];
for (const path of possiblePaths) {
try {
const env = await import(/* @vite-ignore */ path);
if (typeof window !== "undefined") {
window["env"] = window.env || env.default || env;
}
return;
} catch (error) {
continue;
}
}
console.error("Failed to load environment configuration");
}
This script:
- Attempts to load the
env.jsfile from multiple possible paths - Sets the configuration as
window.envfor global access - Handles both production and development paths gracefully
2. Angular Integration (config.ts)
The loaded configuration is integrated into Angular via
frontend/src/app/shared/constants/config.ts:
import { environment } from "@environment/environment";
export const CONFIG: Readonly<MinaEnv> = {
...environment, // Angular build-time environment
globalConfig: {
...environment.globalConfig,
graphQL: getURL(environment.globalConfig?.graphQL),
},
configs: !isBrowser()
? []
: environment.configs.map(config => ({
...config,
url: getURL(config.url),
memoryProfiler: getURL(config.memoryProfiler),
debugger: getURL(config.debugger),
})),
};
// Make config globally available
safelyExecuteInBrowser(() => {
(window as any).config = CONFIG;
});
This creates the final merged configuration by:
- Merging Angular build-time environment with runtime JavaScript config
- Processing and normalizing URLs for different endpoints
- Making the config available globally as
window.config
3. Service Integration
The configuration is consumed throughout the application via Angular services:
ConfigService (frontend/src/app/core/services/config.service.ts):
@Injectable({
providedIn: "root",
})
export class ConfigService {
private node: MinaNode;
constructor(private store: Store<MinaState>) {
this.listenToNodeChanging();
}
get DEBUGGER(): string {
return this.node.debugger;
}
}
Feature Detection Functions:
export function isFeatureEnabled(
config: MinaNode,
feature: FeatureType,
): boolean {
return hasValue(getFeaturesConfig(config)[feature]);
}
export function isSubFeatureEnabled(
config: MinaNode,
feature: FeatureType,
subFeature: string,
): boolean {
const features = getFeaturesConfig(config);
return hasValue(features[feature]) && features[feature].includes(subFeature);
}
Where Configuration is Used
1. Feature Flags
// Check if a feature is enabled
if (isFeatureEnabled(config, "block-production")) {
// Enable block production features
}
// Check if a sub-feature is enabled
if (isSubFeatureEnabled(config, "block-production", "won-slots")) {
// Show won slots information
}
2. Node Connections
// Access configured nodes
CONFIG.configs.forEach(node => {
if (node.isWebNode) {
// Handle WebNode configuration
} else {
// Handle regular node connection to node.url
}
});
3. UI Behavior Control
// Control UI elements based on configuration
if (CONFIG.canAddNodes) {
// Show "Add Node" button
}
if (CONFIG.hidePeersPill) {
// Hide peers status indicator
}
4. Error Tracking
// Configure Sentry with environment-specific DSN
if (CONFIG.sentry) {
Sentry.init({
dsn: CONFIG.sentry.dsn,
tracingOrigins: CONFIG.sentry.tracingOrigins,
});
}
Build-Time vs Runtime Configuration
The system uses a dual-layer configuration approach:
Build-Time Configuration (Angular Environments)
- Located in
frontend/src/environments/environment.*.ts - Processed during Angular build process
- Optimizes bundles and enables/disables features at compile time
- Used for development tooling and build optimization
Runtime Configuration (JavaScript Files)
- Located in
frontend/src/assets/environments/*.js - Loaded dynamically when the application starts
- Allows the same built application to work in different environments
- Used for endpoint URLs, feature flags, and service configurations
This dual approach provides:
- Build optimization through Angular environments
- Deployment flexibility through runtime JavaScript configuration
- Single binary, multiple deployments capability
Environment Variables Integration
Environment configurations work alongside build-time Angular environments. The JavaScript configuration files provide runtime flexibility, while Angular environments control build-time optimizations.