Dynamic URLs
Normalize dynamic URLs containing user IDs, session tokens, or other variable parameters into consistent patterns. This improves privacy by removing identifying information, prevents accidental collection of personal data, and creates more meaningful analytics by grouping similar pages together.
What Are Dynamic URLs?
Dynamic URLs contain variable segments that change based on user context, making them difficult to analyze collectively:
- User-specific pages -
/users/john123/profile
,/users/mary456/profile
- Product pages -
/products/abc-xyz/reviews
,/products/def-789/reviews
- Content with IDs -
/articles/12345/comments
,/articles/67890/comments
- Session-based URLs -
/dashboard/sess_abc123/overview
,/dashboard/sess_xyz789/overview
- Dashboard sections -
/dashboard/user123/overview
,/dashboard/user456/overview
Without normalization, each unique URL appears as a separate page in your analytics, making it impossible to see aggregate patterns.
Important: Avoid sensitive data in URLs
Never include sensitive or personally identifiable information (PII) in your URLs that could be tracked. This includes, but is not limited to:
- Personal identifiers: email addresses, phone numbers, social security numbers
- Financial data: credit card numbers, bank account details
- Authentication tokens: passwords, API keys, session tokens
- Private information: health records, personal documents
Examples to avoid:
/users/john.doe@email.com/profile
/checkout/card-4532123456789012
/reset-password/token-abc123xyz
Use dynamic URL normalization to mask any remaining identifiers in your URLs.
Basic URL Normalization
Once you’ve installed the Betterlytics tracking script, you can normalize URLs using the data-dynamic-urls
attribute.
Simple Wildcard Patterns
Add URL patterns to your tracking script using comma-separated wildcard patterns:
<script
async
src="https://betterlytics.io/analytics.js"
data-site-id="your-siteid"
data-server-url="https://betterlytics.io/track"
data-dynamic-urls="/users/*,/products/*,/articles/*"
></script>
This configuration will:
- Transform
/users/john123/profile
→/users/*/profile
- Transform
/products/abc-xyz
→/products/*
- Transform
/articles/12345/comments
→/articles/*/comments
Using the NPM Package
If you’re using the Betterlytics npm package, you can configure dynamic URLs during initialization:
import betterlytics from '@betterlytics/tracker';
betterlytics.init("your-siteid", {
dynamicUrls: ["/users/*", "/products/*", "/articles/*"]
});
This method provides the same functionality as the script tag approach but integrates seamlessly with your JavaScript application.
Wildcard Types
The dynamic URL feature supports two types of wildcards:
Single Wildcard (*
)
Matches one URL segment and preserves the path structure:
data-dynamic-urls="/users/*"
Results:
/users/john123
→/users/*
/users/john123/profile
→/users/*/profile
/users/john123/settings/security
→/users/*/settings/security
Double Wildcard (**
)
Matches multiple URL segments and flattens them to a single wildcard:
data-dynamic-urls="/users/**"
Results:
/users/john123
→/users/*
/users/john123/profile
→/users/*
/users/john123/settings/security
→/users/*
Advanced Pattern Matching
Multiple Wildcards
You can use multiple wildcards in a single pattern to normalize complex URLs:
data-dynamic-urls="/dashboard/*/users/*,/workspaces/*/projects/*"
Results:
/dashboard/123/users/456
→/dashboard/*/users/*
/dashboard/123/users/456/profile
→/dashboard/*/users/*/profile
/workspaces/acme/projects/789
→/workspaces/*/projects/*
Mixed Wildcard Types
Combine single and double wildcards for precise control:
data-dynamic-urls="/users/*/posts/**,/admin/**/logs"
Results:
/users/123/posts/456/comments
→/users/*/posts/*
/users/123/posts/456/comments/789
→/users/*/posts/*
/admin/super/user/logs
→/admin/*/logs
/admin/super/user/system/logs
→/admin/*/logs
Pattern Order Matters
Patterns are evaluated in order. Place more specific patterns before general ones:
<!-- Good: Specific before general -->
data-dynamic-urls="/users/*/profile,/users/*"
<!-- Avoid: General pattern matches everything first -->
data-dynamic-urls="/users/*,/users/*/profile"
Common Use Cases
User Profile Pages - Normalize user-specific URLs
<!-- Normalize all user-related pages -->
<script
async
src="https://betterlytics.io/analytics.js"
data-site-id="your-siteid"
data-server-url="https://betterlytics.io/track"
data-dynamic-urls="/users/*,/profiles/*,/accounts/*"
></script>
Before normalization:
/users/john123/profile
(1 unique visitor)/users/mary456/profile
(1 unique visitor)/users/alex789/profile
(1 unique visitor)
After normalization:
/users/*/profile
(3 total visitors)
E-commerce Product Pages - Group product variations
<!-- Normalize product and category pages -->
<script
async
src="https://betterlytics.io/analytics.js"
data-site-id="your-siteid"
data-server-url="https://betterlytics.io/track"
data-dynamic-urls="/products/*,/categories/*/products/*"
></script>
Results:
/products/iphone-15-pro
→/products/*
/products/samsung-galaxy-s24
→/products/*
/categories/electronics/products/laptop-123
→/categories/*/products/*
Dashboard Sections - Normalize dashboard and admin URLs
<!-- Normalize dashboard and admin pages -->
<script
async
src="https://betterlytics.io/analytics.js"
data-site-id="your-siteid"
data-server-url="https://betterlytics.io/track"
data-dynamic-urls="/dashboard/*/analytics,/admin/*/settings,/workspace/*/overview"
></script>
Results:
/dashboard/user123/analytics
→/dashboard/*/analytics
/admin/company456/settings
→/admin/*/settings
/workspace/team789/overview
→/workspace/*/overview
Content Management - Normalize CMS and blog URLs
<!-- Normalize content pages -->
<script
async
src="https://betterlytics.io/analytics.js"
data-site-id="your-siteid"
data-server-url="https://betterlytics.io/track"
data-dynamic-urls="/blog/*/posts/*,/cms/*/pages/**"
></script>
Results:
/blog/tech/posts/how-to-code
→/blog/*/posts/*
/blog/lifestyle/posts/healthy-living
→/blog/*/posts/*
/cms/admin/pages/complex/nested/structure
→/cms/*/pages/*
Multi-tenant Applications - Normalize tenant-specific URLs
<!-- Normalize tenant and workspace URLs -->
<script
async
src="https://betterlytics.io/analytics.js"
data-site-id="your-siteid"
data-server-url="https://betterlytics.io/track"
data-dynamic-urls="/workspaces/*,/tenants/*/dashboard/**"
></script>
Results:
/workspaces/acme-corp/projects
→/workspaces/*/projects
/tenants/client-123/dashboard/analytics/reports
→/tenants/*/dashboard/*
Privacy and UTM Parameters
UTM Parameters Are Preserved
Dynamic URL normalization only affects the path portion of URLs. Query parameters (including UTM parameters) are preserved for campaign tracking:
/users/123?utm_source=google&utm_medium=cpc
→/users/*?utm_source=google&utm_medium=cpc
This ensures your marketing attribution remains intact while still normalizing the private path components.
Pattern Matching Rules
Case Sensitivity
URL patterns are case-sensitive:
- Pattern
/Users/*
will not match/users/123
- Pattern
/users/*
will not match/Users/123
Exact Matching
Patterns must match from the beginning of the path:
- Pattern
/users/*
matches/users/123
âś… - Pattern
/users/*
matches/users/123/profile
âś… - Pattern
users/*
does not match/users/123
❌
Multiple Patterns
When multiple patterns could match a URL, the first matching pattern is used:
data-dynamic-urls="/users/*,/users/**"
For URL /users/123/profile
:
- First pattern
/users/*
matches → Result:/users/*/profile
- Second pattern
/users/**
is ignored
Best Practices
1. Start with Common Patterns
Begin with the most common dynamic URL patterns in your application:
<!-- Start with user and content pages -->
data-dynamic-urls="/users/*,/posts/*,/products/*"
2. Use Specific Patterns
Be as specific as possible to avoid over-normalization:
<!-- Good: Specific to user profiles -->
data-dynamic-urls="/users/*/profile,/users/*/settings"
<!-- Avoid: Too broad, might normalize static pages -->
data-dynamic-urls="/users/**"
3. Test Your Patterns
Verify your patterns work correctly by checking normalized URLs in your analytics:
- Test with real URLs from your application
- Monitor for unexpected normalizations
- Adjust patterns based on actual usage
4. Ensure User Privacy
Use dynamic URLs to improve privacy by removing identifying information:
<!-- Remove session IDs and user tokens -->
data-dynamic-urls="/dashboard/*/overview,/profile/*/settings"
Questions about dynamic URLs? Join our Discord community  for help!