docs/api/configuration.md
qiankun provides flexible configuration options to customize the behavior of micro-frontend applications. This document covers all available configuration options for different use cases.
Configuration for individual micro applications used with loadMicroApp.
type AppConfiguration = {
sandbox?: boolean;
globalContext?: WindowProxy;
fetch?: Function;
streamTransformer?: Function;
nodeTransformer?: Function;
};
Configuration for starting the qiankun framework used with start().
interface StartOpts {
prefetch?: boolean | 'all' | string[] | ((apps: RegistrableApp[]) => { criticalAppNames: string[]; minorAppsName: string[] });
sandbox?: boolean | { strictStyleIsolation?: boolean; experimentalStyleIsolation?: boolean; };
singular?: boolean;
urlRerouteOnly?: boolean;
// ... other single-spa options
}
Type: boolean
Default: true
Description: Enable sandbox isolation for the micro application.
// Enable sandbox (default)
loadMicroApp({
name: 'my-app',
entry: '//localhost:8080',
container: '#container',
}, {
sandbox: true
});
// Disable sandbox (not recommended)
loadMicroApp({
name: 'legacy-app',
entry: '//localhost:8080',
container: '#container',
}, {
sandbox: false
});
// With sandbox enabled, global variables are isolated
loadMicroApp({
name: 'app1',
entry: '//localhost:8001',
container: '#container1',
}, {
sandbox: true // app1 gets its own global scope
});
loadMicroApp({
name: 'app2',
entry: '//localhost:8002',
container: '#container2',
}, {
sandbox: true // app2 gets its own isolated global scope
});
Type: WindowProxy
Default: window
Description: Custom global context for the micro application.
// Create a custom global context
const customGlobal = new Proxy(window, {
get(target, prop) {
// Custom logic for property access
if (prop === 'customAPI') {
return { version: '1.0' };
}
return target[prop];
}
});
loadMicroApp({
name: 'custom-app',
entry: '//localhost:8080',
container: '#container',
}, {
globalContext: customGlobal
});
Type: Function
Default: window.fetch
Description: Custom fetch function for loading application resources.
const customFetch = async (url, options) => {
return fetch(url, {
...options,
headers: {
...options?.headers,
'Authorization': `Bearer ${getToken()}`,
'X-Custom-Header': 'custom-value'
}
});
};
loadMicroApp({
name: 'authenticated-app',
entry: '//localhost:8080',
container: '#container',
}, {
fetch: customFetch
});
const transformFetch = async (url, options) => {
// Transform URLs
const transformedUrl = url.replace('//localhost', '//production-domain');
// Add custom logic
console.log(`Fetching: ${transformedUrl}`);
const response = await fetch(transformedUrl, options);
// Transform response
if (!response.ok) {
throw new Error(`Failed to fetch ${transformedUrl}: ${response.status}`);
}
return response;
};
const cache = new Map();
const cachingFetch = async (url, options) => {
const cacheKey = `${url}${JSON.stringify(options)}`;
if (cache.has(cacheKey)) {
console.log(`Cache hit for ${url}`);
return cache.get(cacheKey);
}
const response = await fetch(url, options);
cache.set(cacheKey, response.clone());
return response;
};
Type: Function
Description: Transform streaming HTML content during loading.
const customStreamTransformer = (stream) => {
return stream.pipeThrough(new TransformStream({
transform(chunk, controller) {
// Transform HTML chunks
const transformedChunk = chunk
.replace(/old-api/g, 'new-api')
.replace(/deprecated-feature/g, 'updated-feature');
controller.enqueue(transformedChunk);
}
}));
};
loadMicroApp({
name: 'streaming-app',
entry: '//localhost:8080',
container: '#container',
}, {
streamTransformer: customStreamTransformer
});
Type: Function
Description: Transform DOM nodes during application loading.
const customNodeTransformer = (node, options) => {
// Transform script tags
if (node.tagName === 'SCRIPT') {
// Add custom attributes
node.setAttribute('data-app', 'my-app');
// Modify script source
if (node.src) {
node.src = node.src.replace('localhost', 'production-domain');
}
}
// Transform style tags
if (node.tagName === 'STYLE') {
// Add CSS scope
node.textContent = `.app-scope { ${node.textContent} }`;
}
return node;
};
loadMicroApp({
name: 'transformed-app',
entry: '//localhost:8080',
container: '#container',
}, {
nodeTransformer: customNodeTransformer
});
Type: boolean | 'all' | string[] | Function
Default: true
Description: Resource prefetching strategy for better performance.
// Disable prefetch
start({ prefetch: false });
// Enable default prefetch
start({ prefetch: true });
// Prefetch all registered micro apps
start({ prefetch: 'all' });
// Prefetch specific apps
start({
prefetch: ['dashboard', 'user-profile', 'analytics']
});
start({
prefetch: (apps) => {
// Business logic to determine prefetch strategy
const currentTime = new Date().getHours();
const isBusinessHours = currentTime >= 9 && currentTime <= 17;
if (isBusinessHours) {
// Prefetch business-critical apps during business hours
return {
criticalAppNames: ['dashboard', 'crm', 'finance'],
minorAppsName: ['reporting', 'settings']
};
} else {
// Minimal prefetch during off-hours
return {
criticalAppNames: ['dashboard'],
minorAppsName: []
};
}
}
});
start({
prefetch: (apps) => {
const userRole = getCurrentUserRole();
switch (userRole) {
case 'admin':
return {
criticalAppNames: ['admin-panel', 'user-management', 'system-monitor'],
minorAppsName: ['reports', 'settings']
};
case 'user':
return {
criticalAppNames: ['dashboard', 'profile'],
minorAppsName: ['help', 'feedback']
};
default:
return {
criticalAppNames: ['dashboard'],
minorAppsName: []
};
}
}
});
Type: boolean | SandboxConfig
Default: true
Description: Global sandbox configuration for all micro applications.
// Enable sandbox for all apps
start({ sandbox: true });
// Disable sandbox for all apps (not recommended)
start({ sandbox: false });
start({
sandbox: {
strictStyleIsolation: true, // Enable Shadow DOM style isolation
experimentalStyleIsolation: true, // Enable scoped CSS style isolation
}
});
strictStyleIsolation: Uses Shadow DOM to completely isolate styles
start({
sandbox: {
strictStyleIsolation: true, // Strongest isolation but may break some UI libraries
}
});
experimentalStyleIsolation: Uses scoped CSS to isolate styles
start({
sandbox: {
experimentalStyleIsolation: true, // Good balance of isolation and compatibility
}
});
start({
sandbox: {
strictStyleIsolation: false, // Disable Shadow DOM
experimentalStyleIsolation: true, // Enable scoped CSS
}
});
Type: boolean
Default: true
Description: Whether only one micro app can be mounted at a time.
// Only one app at a time (default)
start({ singular: true });
// Allow multiple apps simultaneously
start({
singular: false // Useful for dashboard-style applications
});
// Dashboard with multiple widgets
start({
singular: false,
// Other configurations
});
// Register widget-style micro apps
registerMicroApps([
{ name: 'widget-weather', entry: '//localhost:8001', container: '#widget-1', activeRule: '/dashboard' },
{ name: 'widget-stocks', entry: '//localhost:8002', container: '#widget-2', activeRule: '/dashboard' },
{ name: 'widget-news', entry: '//localhost:8003', container: '#widget-3', activeRule: '/dashboard' },
]);
Type: boolean
Default: true
Description: Whether to trigger routing only on URL changes.
// Only route on URL changes (default)
start({ urlRerouteOnly: true });
// Route on both URL and programmatic changes
start({
urlRerouteOnly: false // More responsive but potentially more performance overhead
});
const developmentConfig = {
prefetch: false, // Faster rebuilds
sandbox: {
strictStyleIsolation: false, // Easier debugging
experimentalStyleIsolation: true,
},
singular: false, // More flexible development
urlRerouteOnly: false, // More responsive navigation
};
if (process.env.NODE_ENV === 'development') {
start(developmentConfig);
}
const productionConfig = {
prefetch: 'all', // Better user experience
sandbox: {
strictStyleIsolation: true, // Better isolation
experimentalStyleIsolation: false,
},
singular: true, // Stable performance
urlRerouteOnly: true, // Optimized routing
};
if (process.env.NODE_ENV === 'production') {
start(productionConfig);
}
const mobileConfig = {
prefetch: (apps) => ({
// Conservative prefetch on mobile
criticalAppNames: ['home'],
minorAppsName: []
}),
sandbox: {
// Lighter sandbox for mobile performance
strictStyleIsolation: false,
experimentalStyleIsolation: true,
},
singular: true, // Better for mobile UX
};
const isMobile = window.innerWidth < 768;
if (isMobile) {
start(mobileConfig);
}
const getConfigWithFeatureFlags = async () => {
const featureFlags = await getFeatureFlags();
return {
prefetch: featureFlags.enablePrefetch ? 'all' : false,
sandbox: {
strictStyleIsolation: featureFlags.strictIsolation,
experimentalStyleIsolation: !featureFlags.strictIsolation,
},
singular: featureFlags.allowMultipleApps ? false : true,
};
};
getConfigWithFeatureFlags().then(config => start(config));
const getPerformanceConfig = () => {
const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
const isSlowConnection = connection?.effectiveType === '2g' || connection?.effectiveType === 'slow-2g';
if (isSlowConnection) {
return {
prefetch: false, // No prefetch on slow connections
sandbox: {
strictStyleIsolation: false,
experimentalStyleIsolation: true,
},
singular: true,
};
}
return {
prefetch: 'all',
sandbox: {
strictStyleIsolation: true,
experimentalStyleIsolation: false,
},
singular: false,
};
};
start(getPerformanceConfig());
const getRoleBasedConfig = (userRole) => {
const baseConfig = {
sandbox: true,
singular: true,
};
switch (userRole) {
case 'admin':
return {
...baseConfig,
prefetch: 'all', // Admins get all features
singular: false, // Can use multiple admin tools
};
case 'poweruser':
return {
...baseConfig,
prefetch: ['dashboard', 'analytics', 'reports'],
singular: false,
};
default:
return {
...baseConfig,
prefetch: ['dashboard'], // Basic users get minimal prefetch
singular: true,
};
}
};
const userRole = getCurrentUserRole();
start(getRoleBasedConfig(userRole));
// App-level configuration overrides global configuration
start({
sandbox: true, // Global setting
});
loadMicroApp({
name: 'special-app',
entry: '//localhost:8080',
container: '#container',
}, {
sandbox: false // This overrides the global setting for this app
});
// ❌ Bad: Heavy configuration that impacts performance
start({
prefetch: 'all', // Might slow down initial load
sandbox: {
strictStyleIsolation: true, // More overhead
},
singular: false, // More memory usage
urlRerouteOnly: false, // More frequent route checks
});
// ✅ Good: Balanced configuration
start({
prefetch: ['critical-app'], // Only prefetch what's needed
sandbox: {
experimentalStyleIsolation: true, // Good balance
},
singular: true, // Stable performance
urlRerouteOnly: true, // Optimized routing
});
const debugConfig = {
sandbox: {
strictStyleIsolation: false, // Easier to inspect styles
experimentalStyleIsolation: true,
},
// Custom fetch for logging
fetch: async (url, options) => {
console.log(`[DEBUG] Fetching: ${url}`);
const response = await fetch(url, options);
console.log(`[DEBUG] Response: ${response.status}`);
return response;
},
// Custom node transformer for debugging
nodeTransformer: (node, options) => {
if (node.tagName === 'SCRIPT') {
console.log(`[DEBUG] Processing script: ${node.src || 'inline'}`);
}
return node;
}
};