-
Notifications
You must be signed in to change notification settings - Fork 0
Advanced Features
This guide covers advanced ModHead features and patterns for power users.
- Complex Response Transformations
- Nested Variable Usage
- Multi-Stage Authentication
- Tab URL Filtering
- Dark Theme
- Advanced URL Matching
- Performance Optimization
For complex API responses, you can navigate deep into the JSON structure.
Example Response:
{
"status": "success",
"metadata": {
"timestamp": "2024-01-15T10:30:00Z",
"version": "2.0"
},
"payload": {
"authentication": {
"credentials": {
"access": {
"token": "deep_nested_token_123",
"expires": 3600
}
}
}
}
}Transform: payload.authentication.credentials.access.token
Result: deep_nested_token_123
{
"tokens": ["primary_token", "secondary_token", "backup_token"]
}Transform: tokens[0]
Result: primary_token
{
"users": [
{
"id": 1,
"tokens": ["user1_token1", "user1_token2"]
}
]
}Transform: users[0].tokens[0]
Result: user1_token1
{
"auth": {
"token": "abc123",
"type": "Bearer",
"version": "v2"
}
}Transform: {{auth.type}} {{auth.token}} ({{auth.version}})
Result: Bearer abc123 (v2)
{
"user_id": "12345",
"session_id": "xyz789",
"timestamp": "1640000000"
}Transform: user={{user_id}}&session={{session_id}}&ts={{timestamp}}
Result: user=12345&session=xyz789&ts=1640000000
{
"key": "my_api_key",
"secret": "my_secret"
}Transform: key={{key}}&secret={{secret}}
Result: key=my_api_key&secret=my_secret
Use in header:
Header: X-Credentials
Value: ${credentialsVar}
If the API returns plain text instead of JSON:
Response: new_token_abc123
Transform: Leave empty or use $response
Result: new_token_abc123
ModHead primarily works with JSON, but you can use the full response for XML:
Response:
<auth>
<token>xml_token_123</token>
</auth>Transform: $response
Result: The entire XML string
Note: You'll need to manually parse XML. Consider converting XML to JSON on the server side if possible.
Variables can reference other variables, enabling powerful composition patterns.
Example: Multi-Tier Authentication
Variables:
refreshToken: long_lived_refresh_token_xyz
Variable: accessToken
Refresh Config:
URL: https://auth.example.com/token
Method: POST
Headers:
Authorization: Bearer ${refreshToken}
Body:
{
"grant_type": "refresh_token"
}
Transform: access_token
Variable: userApiKey
Refresh Config:
URL: https://api.example.com/keys
Method: POST
Headers:
Authorization: Bearer ${accessToken}
Transform: api_key
Usage Chain:
-
accessTokenusesrefreshTokento get a new access token -
userApiKeyusesaccessTokento get an API key - Your rules use
${userApiKey}in headers
Invalid Configuration:
Variable A refresh config uses ${B}
Variable B refresh config uses ${A}
Solution: Ensure variables form a directed acyclic graph (DAG):
refreshToken (no dependencies)
↓
accessToken (depends on refreshToken)
↓
apiKey (depends on accessToken)
Stage 1: Long-Lived Refresh Token
Variable: oauthRefreshToken
Value: (manually obtained refresh token)
Stage 2: Short-Lived Access Token
Variable: oauthAccessToken
Refresh Config:
URL: https://oauth.example.com/token
Method: POST
Headers:
Content-Type: application/x-www-form-urlencoded
Body: "grant_type=refresh_token&refresh_token=${oauthRefreshToken}&client_id=xyz"
Transform: access_token
Stage 3: Service-Specific Token
Variable: serviceToken
Refresh Config:
URL: https://service.example.com/auth
Method: POST
Headers:
Authorization: Bearer ${oauthAccessToken}
Transform: service_access_token
Stage 1: Master JWT
Variable: masterJWT
Value: (manually set)
Stage 2: Session JWT
Variable: sessionJWT
Refresh Config:
URL: https://auth.example.com/session/create
Method: POST
Headers:
Authorization: Bearer ${masterJWT}
Body:
{
"scope": "read write",
"duration": 3600
}
Transform: jwt
Stage 3: Encrypted API Key
Variable: encryptedApiKey
Refresh Config:
URL: https://api.example.com/keys/derive
Method: POST
Headers:
Authorization: Bearer ${sessionJWT}
Transform: encrypted_key
Stage 1: Database Credentials (Static)
Variable: dbUsername
Value: admin
Variable: dbPassword
Value: secret123
Sensitive: ON
Stage 2: Application Token
Variable: appToken
Refresh Config:
URL: https://app.example.com/auth/login
Method: POST
Body:
{
"username": "${dbUsername}",
"password": "${dbPassword}"
}
Transform: token
Stage 3: API Key
Variable: apiKey
Refresh Config:
URL: https://app.example.com/api/keys/generate
Method: POST
Headers:
Authorization: Bearer ${appToken}
Transform: api_key
Tab URL filtering allows you to apply rules only when you're viewing a specific webpage.
Scenario: Only modify API headers when testing from your development dashboard.
Configuration:
Rule: Dev API Headers
Tab URL: localhost:3000/dashboard
Tab URL Match Type: startsWith
Target Domain: api.example.com
Target Domain Match Type: startsWith
Headers:
- Authorization: Bearer ${devToken}
Behavior:
- ✅ Headers are modified when you're on
localhost:3000/dashboardmaking requests toapi.example.com - ❌ Headers are NOT modified when you're on
localhost:3000/profilemaking requests toapi.example.com
Rule 1: Production Testing
Tab URL: app.example.com
Target Domain: api.example.com
Headers:
- Authorization: Bearer ${prodToken}
Rule 2: Staging Testing
Tab URL: staging.app.example.com
Target Domain: staging-api.example.com
Headers:
- Authorization: Bearer ${stagingToken}
Rule 3: Local Development
Tab URL: localhost:3000
Target Domain: localhost:8080
Headers:
- Authorization: Bearer ${devToken}
Good Use Cases:
- Environment-specific configurations
- Preventing accidental production modifications
- Testing from specific admin panels or dashboards
When NOT to Use:
- Most general-purpose rules (leave Tab URL empty)
- When you want headers applied regardless of the current page
- When testing across multiple pages
Note: Currently, tab URL filtering is defined in the UI but not fully implemented in the rule processing logic. This feature may be fully activated in future versions.
ModHead includes a dark theme for reduced eye strain during extended use.
Method 1: Theme Toggle
- Open ModHead options page
- Click the theme toggle button in the top-right corner
- Select "Dark" mode
Method 2: Auto Mode
- Select "Auto" to follow your system theme
- Changes automatically when your OS theme changes
Your theme preference is:
- Saved in Chrome storage
- Synced across Chrome browsers
- Persists across browser restarts
While there's no built-in theme customization, you can:
- Fork the repository
- Edit
src/options/index.css - Modify CSS variables in the dark theme section
- Build and load your custom version
Use multiple target domains with different match types to create complex matching logic.
Example: Match API and CDN
Rule: API & CDN Headers
Target Domains:
1. api.example.com (startsWith)
2. cdn.example.com (startsWith)
3. static.example.com (startsWith)
Headers:
- X-Custom-Header: shared_value
All three domains will receive the same headers.
Example: JSON Files Only
Target Domain: .json
Match Type: endsWith
This matches any URL ending with .json:
-
api.example.com/data.json✅ -
example.com/users.json✅ -
example.com/config.jsonp❌
Example: Exact Login Endpoint
Target Domain: api.example.com/auth/login
Match Type: equals
Only exact matches:
-
api.example.com/auth/login✅ -
api.example.com/auth/login?redirect=/home❌ -
api.example.com/auth/login/callback❌
Note: Query parameters and fragments may affect exact matching depending on Chrome's URL normalization.
Example: All Subdomains
Target Domain: .example.com
Match Type: endsWith
Matches:
-
api.example.com✅ -
www.example.com✅ -
staging.api.example.com✅ -
example.com❌ (no leading subdomain)
Tip 1: Disable Unused Rules
- Disabled rules don't create Chrome declarativeNetRequest rules
- Reduces overhead and improves performance
- Quick toggle for temporary rules
Tip 2: Consolidate Similar Rules
- Combine rules that share the same headers
- Use multiple target domains instead of multiple rules
- Reduces total number of Chrome rules
Before (5 rules):
Rule 1: api1.example.com → Header A
Rule 2: api2.example.com → Header A
Rule 3: api3.example.com → Header A
Rule 4: api4.example.com → Header A
Rule 5: api5.example.com → Header A
After (1 rule):
Rule 1:
Target Domains:
- api1.example.com
- api2.example.com
- api3.example.com
- api4.example.com
- api5.example.com
Headers:
- Header A
Tip 1: Reuse Variables
- Define once, use everywhere
- Reduces duplication and improves maintainability
Tip 2: Minimize Refresh Frequency
- Only refresh when necessary
- Use longer-lived tokens when possible
- Batch token refreshes if possible
Chrome has limits on the number of declarativeNetRequest rules:
- Static rules: 30,000 per extension (not applicable to ModHead)
- Dynamic rules: 5,000 per extension (used by ModHead)
ModHead creates rules as follows:
- Each header modification = 1 Chrome rule
- Rule ID =
RULE_ID_OFFSET + (ruleIndex * 100) + headerIndex
Example:
- Rule 1 with 3 headers = 3 Chrome rules
- Rule 2 with 2 headers = 2 Chrome rules
- Total = 5 Chrome rules
With the 5,000 rule limit, you can have approximately:
- 5,000 rules with 1 header each
- 1,000 rules with 5 headers each
- 500 rules with 10 headers each
In practice: Most users will never hit this limit.
Step 1: Open DevTools
- Navigate to a page that triggers your rules
- Open Chrome DevTools (F12)
- Go to the Network tab
Step 2: Inspect Headers
- Make a request (or reload the page)
- Click on the request in the Network tab
- Go to Headers section
- Verify your headers are present under "Request Headers"
Step 1: Open Extension Management
- Go to
chrome://extensions/ - Find ModHead
- Click "Inspect views: background page"
Step 2: Check Console
- Look for errors or warnings
- Check that rules are being created correctly
Test your refresh configurations manually with curl:
curl -X POST https://auth.example.com/refresh \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_REFRESH_TOKEN" \
-d '{"grant_type": "refresh_token"}'Compare the response with your expected transformation.
Rules:
- Descriptive: "Production API Authentication"
- Environment-prefixed: "DEV - CORS Headers"
- Service-specific: "GitHub API Token"
Variables:
- camelCase:
accessToken,apiKey,userId - Prefixed:
devApiKey,prodJWT,stagingToken
- Use Sensitive Flag: Mark all tokens and secrets as sensitive
- Short-Lived Tokens: Prefer access tokens with auto-refresh over long-lived tokens
- Environment Separation: Use different variables for dev/staging/prod
- Regular Rotation: Periodically rotate tokens and secrets
Strategy 1: By Environment
Rules:
- DEV - All Headers
- STAGING - All Headers
- PROD - All Headers
Strategy 2: By Service
Rules:
- GitHub API
- AWS API
- Internal API
Strategy 3: By Purpose
Rules:
- Authentication Headers
- CORS Headers
- Custom Headers
- Examples - See real-world implementations
- FAQ - Common questions and troubleshooting
- Auto-Refresh Tokens - Deep dive into token refresh
Back to: Auto-Refresh Tokens | Next: Examples