UGC Filter Rules
The ugcFilterRules feature in Amplitude's Session Replay SDK detects and sanitizes sensitive user-generated content (UGC) in URLs before Amplitude records the URLs in session replays and heatmaps. UGC Filter Rules prevent the capture of personally identifiable or sensitive information.
What UGC Filter Rules do
UGC Filter Rules are configuration objects that define patterns to match URLs and specify replacement text. When the SDK captures URLs during session replay and heatmap recording, the SDK applies these rules to sanitize or anonymize sensitive information such as:
- User IDs
- Company names
- Sensitive query parameters
- Dynamic path segments containing private data
Configure UGC Filter Rules
Configure UGC Filter Rules as part of the interactionConfig when initializing the Session Replay SDK:
import { sessionReplay } from '@amplitude/session-replay-browser';
sessionReplay.init('YOUR_API_KEY', {
// ...
// Other Configs
// ...
interactionConfig: {
enabled: true,
ugcFilterRules: [
{
selector: 'https://example.com/user/*/profile',
replacement: 'https://example.com/user/USER_ID/profile'
},
{
selector: 'https://example.com/api/token=*',
replacement: 'https://example.com/api/token=REDACTED'
}
]
}
});
Rule structure
Each UGC Filter Rule is an object with two required properties:
type UGCFilterRule = {
selector: string; // Glob pattern to match URLs
replacement: string; // Text to replace the matched URL
};
Properties
| Property | Description |
|---|---|
selector | A glob pattern string that matches URLs. Supports * (any characters). Supports multiple wildcards in domains and paths. |
replacement | The replacement text that the SDK uses when the selector pattern matches a URL. |
Selector pattern examples
https://*.domain.com/*matches any subdomain and any pathhttps://site.com/*/*matches two path segmentshttps://api.com/*/data/*matches specific patterns with wildcards
Glob pattern syntax
The selector field uses basic glob patterns for URL matching. The current implementation supports:
| Pattern | Description | Example |
|---|---|---|
* | Matches any sequence of characters | https://example.com/* matches https://example.com/anything |
Supported wildcard locations:
| Location | Description | Example |
|---|---|---|
| Multiple wildcards | Use multiple * in a single pattern | https://*.domain.com/*/* |
| Domain wildcards | * works in domain names | *.projecttool.com |
| Path wildcards | Multiple * in URL paths | /projects/*/boards/* |
The SDK does not support advanced glob features such as **, [abc], {option1,option2}, and others.
Examples
Filter project management tool URLs
Remove organization names and sensitive identifiers from project management URLs:
// Filter ticket URLs
{
selector: "https://*.projecttool.com/browse/*",
replacement: "https://ORG_NAME.projecttool.com/browse/TICKET_NUMBER"
}
// Filter project list URLs
{
selector: "https://*.projecttool.com/software/projects/*/list*",
replacement: "https://ORG_NAME.projecttool.com/software/projects/PROJECT_NAME/list"
}
// Filter board URLs
{
selector: "https://*.projecttool.com/software/projects/*/boards/*",
replacement: "https://ORG_NAME.projecttool.com/software/projects/boards/BOARD_ID"
}
// Filter wiki pages
{
selector: "https://*.projecttool.com/wiki/spaces/*/pages/*",
replacement: "https://ORG_NAME.projecttool.com/wiki/spaces/SPACE_NAME/pages/PAGE_NAME"
}
Filter code repository URLs
Remove repository details and sensitive paths:
// Filter repository file browser with branch and file paths
{
selector: "https://codehost.com/*/*/tree/*/*",
replacement: "https://codehost.com/USER/REPO/tree/BRANCH/FILES"
}
// Filter repository branch view
{
selector: "https://codehost.com/*/*/tree/*",
replacement: "https://codehost.com/USER/REPO/tree/BRANCH"
}
Filter user IDs from profile URLs
Remove user IDs from profile URLs:
{
selector: 'https://myapp.com/user/*/profile',
replacement: 'https://myapp.com/user/USER_ID/profile'
}
Before: https://myapp.com/user/12345/profile
After: https://myapp.com/user/USER_ID/profile
Sanitize query parameters
Remove sensitive query parameters:
{
selector: 'https://myapp.com/dashboard?token=*',
replacement: 'https://myapp.com/dashboard?token=REDACTED'
}
Before: https://myapp.com/dashboard?token=abc123xyz
After: https://myapp.com/dashboard?token=REDACTED
Filter URLs with multiple path segments
Filter URLs with multiple dynamic segments:
{
selector: 'https://api.example.com/users/*/documents/*/*',
replacement: 'https://api.example.com/users/USER_ID/documents/CATEGORY/DOCUMENT_ID'
}
Before: https://api.example.com/users/john123/documents/private/contract-2023.pdf
After: https://api.example.com/users/USER_ID/documents/CATEGORY/DOCUMENT_ID
Filter email addresses in URLs
Remove email addresses from URL paths:
{
selector: 'https://myapp.com/user/*/settings',
replacement: 'https://myapp.com/user/EMAIL_ADDRESS/settings'
}
Before: https://myapp.com/user/john.doe@company.com/settings
After: https://myapp.com/user/EMAIL_ADDRESS/settings
Advanced usage
Rule precedence with multiple rules
The SDK applies rules in order, and the first matching rule wins:
ugcFilterRules: [
// More specific rule - will match first
{
selector: 'https://example.com/user/*/profile/settings',
replacement: 'https://example.com/user/USER_ID/profile/settings'
},
// Less specific rule - will only match if first rule doesn't
{
selector: 'https://example.com/user/*/*',
replacement: 'https://example.com/user/USER_ID/ACTION'
}
]
Complete configuration example
import { sessionReplay } from '@amplitude/session-replay-browser';
sessionReplay.init('YOUR_API_KEY', {
interactionConfig: {
enabled: true,
ugcFilterRules: [
// Filter project management tool URLs
{
selector: "https://*.projecttool.com/browse/*",
replacement: "https://ORG_NAME.projecttool.com/browse/TICKET_NUMBER"
},
{
selector: "https://*.projecttool.com/software/projects/*/boards/*",
replacement: "https://ORG_NAME.projecttool.com/software/projects/PROJECT_NAME/boards/BOARD_ID"
},
// Filter code repository URLs
{
selector: "https://codehost.com/*/*/tree/*/*",
replacement: "https://codehost.com/USER/REPO/tree/BRANCH/FILES"
},
{
selector: "https://codehost.com/*/*/tree/*",
replacement: "https://codehost.com/USER/REPO/tree/BRANCH"
},
// Filter internal application URLs
{
selector: 'https://myapp.com/user/*/profile',
replacement: 'https://myapp.com/user/USER_ID/profile'
},
{
selector: 'https://api.myapp.com/*?token=*',
replacement: 'https://api.myapp.com/ENDPOINT?token=REDACTED'
},
// Filter admin URLs completely
{
selector: 'https://myapp.com/admin/*',
replacement: 'https://myapp.com/admin/ADMIN_SECTION'
}
]
}
});
Error handling and validation
The SDK validates UGC Filter Rules during initialization.
Validation rules
| Rule | Requirement |
|---|---|
| Type validation | Both selector and replacement must be strings. |
| URL format validation | The selector must be a valid URL pattern that starts with /, http://, or https://. |
| Non-empty | Selectors cannot be empty or whitespace-only. |
Error examples
// ❌ Invalid - non-string selector
{
selector: 123,
replacement: 'replacement'
}
// Error: ugcFilterRules must be an array of objects with selector and replacement properties
// ❌ Invalid - non-string replacement
{
selector: 'https://example.com/*',
replacement: 456
}
// Error: ugcFilterRules must be an array of objects with selector and replacement properties
// ❌ Invalid - selector doesn't start with / or http(s)://
{
selector: 'example.com/path',
replacement: 'replacement'
}
// Error: ugcFilterRules must be an array of objects with valid globs
// ❌ Invalid - empty selector
{
selector: '',
replacement: 'replacement'
}
// Error: ugcFilterRules must be an array of objects with valid globs
// ❌ Invalid - whitespace-only selector
{
selector: ' ',
replacement: 'replacement'
}
// Error: ugcFilterRules must be an array of objects with valid globs
Best practices
Order rules by specificity
Place more specific patterns before general ones:
ugcFilterRules: [
// More specific patterns first
{
selector: 'https://codehost.com/*/*/tree/*/*',
replacement: 'https://codehost.com/USER/REPO/tree/BRANCH/FILES'
},
// Less specific patterns later
{
selector: 'https://codehost.com/*/*/tree/*',
replacement: 'https://codehost.com/USER/REPO/tree/BRANCH'
},
// Most general patterns last
{
selector: 'https://codehost.com/*/*',
replacement: 'https://codehost.com/USER/REPO'
}
]
Use descriptive replacements
Make replacements clear and meaningful:
// ✅ Good - descriptive
{
selector: 'https://*.projecttool.com/browse/*',
replacement: 'https://ORG_NAME.projecttool.com/browse/TICKET_NUMBER'
}
// ❌ Avoid - unclear
{
selector: 'https://*.projecttool.com/browse/*',
replacement: 'https://XXX.projecttool.com/browse/XXX'
}
Test patterns in a development environment first
Validate that your glob patterns match expected URLs:
// Test with various URL formats
const testUrls = [
'https://mycompany.projecttool.com/browse/PROJ-123',
'https://codehost.com/username/repository/tree/main/src/components',
'https://myapp.com/user/john.doe@email.com/profile'
];
Common issues
| Issue | Resolution |
|---|---|
| Rules not applied | Ensure interactionConfig.enabled is true. |
| Pattern not matching | Only * patterns are supported. |
| Wrong order | Check that specific rules come before general ones. |
| Invalid patterns | Verify that selectors only use supported glob syntax (*). |
Limitations
- The SDK applies rules to full URLs, not individual URL components.
- Limited glob pattern support: only
*(any characters) is supported. - The SDK does not support advanced glob features such as
**,[abc],{option1,option2}, ranges, and negation. - Rules cannot modify URL structure. Rules can only replace entire URLs.
The current implementation uses a simple glob-to-regex conversion. The implementation supports multiple wildcards and domain patterns, but does not support advanced glob features. This covers most common URL filtering scenarios.
Was this helpful?